Combos use the same style properties as regular nodes.
To style items created by combining nodes, use the setStyle function passed to the onCombineNodes and onCombineLinks event handlers.
See also
import React from "react";
import { createRoot } from "react-dom/client";
import { Chart } from "regraph";
import { calculateWidth, colors, data } from "./data";
export const Demo = () => <StyledCombos items={data()} />;
const combine = {
properties: ["group"],
level: 1,
};
const layout = { name: "lens" };
const options = {
selection: {
color: colors.teal,
},
navigation: false,
overview: false,
};
const StyledCombos = (props) => {
const { items } = props;
const combineLinksHandler = ({ setStyle, links, id1, id2 }) => {
/*
Add the data.amount value of each link in this combo.
This is so that we can determine the width of the
combo link.
*/
const keys = Object.keys(links);
let totalAmount = 0;
keys.forEach((key) => {
totalAmount += links[key].data.amount;
});
setStyle({
color: colors.darkTeal,
width: calculateWidth(totalAmount),
lineStyle: "dashed",
label: {
fontSize: 22,
text: totalAmount >= 1000 ? `$${(totalAmount / 1000).toFixed(1)}B` : `$${totalAmount}M`,
},
// point arrow heads at the Media combo
end1: { arrow: id1 === "_combonode_Media" },
end2: { arrow: id2 === "_combonode_Media" },
});
};
function combineNodesHandler({ setStyle, combo }) {
let borderColor;
let color = colors.lightTeal;
const { group } = combo;
switch (group) {
case "Software":
borderColor = colors.darkTeal;
break;
case "Media":
borderColor = colors.darkTeal;
break;
case "Hardware":
borderColor = colors.red;
break;
case "Artificial Intelligence":
borderColor = colors.darkRed;
color = colors.lightRed;
break;
default:
borderColor = "black";
}
setStyle({
color,
border: { color: borderColor },
label: { fontSize: 26, text: group },
});
}
return (
<Chart
combine={combine}
items={items}
layout={layout}
options={options}
animation={{ animate: false }}
onCombineLinks={combineLinksHandler}
onCombineNodes={combineNodesHandler}
/>
);
};
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); import { style } from "@ci/theme/rg/js/storyStyles";
const colors = {
lightTeal: style.colors.tealFaded,
teal: style.colors.teal1,
darkTeal: style.colors.teal2,
lightRed: style.colors.redFaded,
red: style.colors.red1,
darkRed: style.colors.red2,
};
const calculateWidth = (amount) => Math.sqrt(amount / 100);
function data() {
return {
google: {
...style.primary1,
data: { group: "Media" },
size: 1.2,
label: [
{
...style.primaryLabel1,
position: "s",
fontSize: 20,
text: "Alphabet\n(Google)",
},
],
},
facebook: {
...style.primary1,
data: { group: "Media" },
size: 1.2,
label: [
{
...style.primaryLabel1,
position: "s",
fontSize: 20,
text: "Facebook",
},
],
},
nest: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Nest",
},
data: { group: "Hardware" },
},
motorola: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Motorola",
},
data: { group: "Hardware" },
},
doubleClick: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "DoubleClick",
},
data: { group: "Media" },
},
youTube: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "YouTube",
},
data: { group: "Media" },
},
waze: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Waze",
},
data: { group: "Software" },
},
ita: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "ITA Software",
},
data: { group: "Software" },
},
deepMind: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "DeepMind Technologies",
},
data: { group: "Artificial Intelligence" },
},
whatsApp: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "WhatsApp",
},
data: { group: "Software" },
},
oculus: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Oculus VR",
},
data: { group: "Hardware" },
},
instagram: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Instagram",
},
data: { group: "Media" },
},
liveRail: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "LiveRail",
},
data: { group: "Media" },
},
face: {
...style.primary2,
label: {
...style.primaryLabel2,
text: "Face.com",
},
data: { group: "Artificial Intelligence" },
},
"facebook-face": {
id1: "facebook",
id2: "face",
end1: {
arrow: true,
},
label: { text: "$100M" },
width: calculateWidth(100),
data: {
amount: 100,
},
},
"facebook-liveRail": {
id1: "facebook",
id2: "liveRail",
end1: {
arrow: true,
},
label: { text: "$450M" },
width: calculateWidth(450),
data: {
amount: 450,
},
},
"facebook-instagram": {
id1: "facebook",
id2: "instagram",
end1: {
arrow: true,
},
label: { text: "$1B" },
width: calculateWidth(1000),
data: {
amount: 1000,
},
},
"facebook-whatsApp": {
id1: "facebook",
id2: "whatsApp",
end1: {
arrow: true,
},
label: { text: "$19B" },
width: calculateWidth(19000),
data: {
amount: 19000,
},
},
"facebook-oculus": {
id1: "facebook",
id2: "oculus",
end1: {
arrow: true,
},
label: { text: "$2B" },
width: calculateWidth(2000),
data: {
amount: 2000,
},
},
"google-nest": {
id1: "google",
id2: "nest",
end1: {
arrow: true,
},
label: { text: "$3.2B" },
width: calculateWidth(3200),
data: {
amount: 3200,
},
},
"google-motorola": {
id1: "google",
id2: "motorola",
end1: {
arrow: true,
},
label: { text: "$12.5B" },
width: calculateWidth(12500),
data: {
amount: 12500,
},
},
"google-youTube": {
id1: "google",
id2: "youTube",
end1: {
arrow: true,
},
label: { text: "$1.65B" },
width: calculateWidth(1650),
data: {
amount: 1650,
},
},
"google-waze": {
id1: "google",
id2: "waze",
end1: {
arrow: true,
},
label: { text: "$966M" },
width: calculateWidth(966),
data: {
amount: 966,
},
},
"google-doubleClick": {
id1: "google",
id2: "doubleClick",
end1: {
arrow: true,
},
label: { text: "$3.1B" },
width: calculateWidth(3100),
data: {
amount: 3100,
},
},
"google-ita": {
id1: "google",
id2: "ita",
end1: {
arrow: true,
},
label: { text: "$676M" },
width: calculateWidth(676),
data: {
amount: 676,
},
},
"google-deepMind": {
id1: "google",
id2: "deepMind",
end1: {
arrow: true,
},
label: { text: "$625M" },
width: calculateWidth(625),
data: {
amount: 625,
},
},
};
}
export { data, calculateWidth, colors }; <!doctype html>
<html>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>