Hover or click on items to update their styling.
The interactions are cleared once the items are deselected or no longer hovered.
New style properties are merged into the current styles, so you don't need to redefine them.
See also
import React, { useRef } from "react";
import { createRoot } from "react-dom/client";
import { Chart } from "regraph";
import { items, styles } from "./data";
import { style } from "@ci/theme/rg/js/storyStyles";
import "@fortawesome/fontawesome-free/css/fontawesome.css";
import "@fortawesome/fontawesome-free/css/solid.css";
function InteractionStyling() {
const chartRef = useRef();
const getHoverStyle = (type, subItem) => {
if (subItem && subItem.type === "glyph") {
return styles.glyph.hover;
}
if (type === "person") {
return styles.person.hover;
}
return styles.car.hover;
};
const getSelectionStyle = (type) => {
if (type === "person") {
return styles.person.selection;
}
return styles.car.selection;
};
const onItemInteractionHandler = ({
hovered,
selected,
id,
item,
setStyle,
subItem,
itemType,
}) => {
let newStyle = {};
if (itemType === "node") {
const { type } = item.data;
if (hovered) {
newStyle = getHoverStyle(type, subItem);
}
if (selected) {
newStyle = { ...newStyle, ...getSelectionStyle(type) };
}
// apply the new styles to the selected/hovered node
// when the node is deselected/un-hovered the original
// styling defined in the items prop is restored.
setStyle({ [id]: newStyle });
}
};
return (
<Chart
items={items}
ref={chartRef}
onItemInteraction={onItemInteractionHandler}
options={{
hoverDelay: 0,
selection: { color: style.colors.transparent, labelColor: style.colors.charcoal },
iconFontFamily: "Font Awesome 5 Free",
imageAlignment: { "fas fa-user": { size: 0.9 } },
navigation: false,
overview: false,
}}
/>
);
}
const FontReadyChart = React.lazy(() =>
document.fonts.load("900 24px 'Font Awesome 5 Free'").then(() => ({
default: InteractionStyling,
}))
);
export function Demo() {
return (
<React.Suspense fallback="">
<FontReadyChart />
</React.Suspense>
);
}
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); import { style } from "@ci/theme/rg/js/storyStyles";
export const styles = {
person: {
hover: {
...style.primary0,
fontIcon: {
...style.primary2,
},
border: { ...style.primary2 },
},
selection: {
...style.primary2,
fontIcon: {
color: style.colors.offWhite,
},
border: { ...style.primary1 },
label: [{ bold: true }],
halos: [{ ...style.secondary1, radius: 37, width: 6 }],
},
},
car: {
hover: {
...style.secondary0,
fontIcon: {
...style.secondary2,
},
border: { ...style.secondary2 },
},
selection: {
...style.secondary2,
fontIcon: {
color: style.colors.offWhite,
},
border: { ...style.secondary1 },
label: [{ bold: true }],
halos: [{ ...style.primary1, radius: 37, width: 6 }],
},
},
glyph: {
hover: {
glyphs: [
{
...style.tertiary0,
fontIcon: { color: style.tertiary2.color },
border: { ...style.tertiary2 },
size: 1.5,
},
],
},
},
};
export const items = {
node1: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
glyphs: [
{
position: "ne",
color: style.colors.offWhite,
fontIcon: { text: "fas fa-credit-card", color: style.tertiary1.color },
border: { ...style.tertiary1 },
},
],
data: { type: "person" },
border: { ...style.primary1 },
label: [{ text: "James", position: "s" }],
},
node2: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
border: { ...style.primary1 },
data: { type: "person" },
label: [{ text: "Matt", position: "s" }],
},
node3: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
border: { ...style.primary1 },
data: { type: "person" },
label: [{ text: "Fred", position: "s" }],
},
node4: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
border: { ...style.primary1 },
data: { type: "person" },
label: [{ text: "Beth", position: "s" }],
},
node5: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
border: { ...style.primary1 },
data: { type: "person" },
label: [{ text: "Amy", position: "s" }],
},
node6: {
fontIcon: { text: "fas fa-user", ...style.primary1 },
color: style.colors.transparent,
border: { ...style.primary1 },
data: { type: "person" },
label: [{ text: "Alex", position: "s" }],
},
node7: {
fontIcon: { text: "fas fa-car", ...style.secondary0 },
color: style.colors.transparent,
border: { ...style.secondary1 },
data: { type: "car" },
label: [{ text: "ABC-1234", position: "s" }],
},
node8: {
fontIcon: { text: "fas fa-car", ...style.secondary0 },
color: style.colors.transparent,
border: { ...style.secondary1 },
data: { type: "car" },
label: [{ text: "DEF-5678", position: "s" }],
},
node9: {
fontIcon: { text: "fas fa-car", ...style.secondary0 },
color: style.colors.transparent,
border: { ...style.secondary1 },
data: { type: "car" },
label: [{ text: "GHI-9012", position: "s" }],
},
node10: {
fontIcon: { text: "fas fa-car", ...style.secondary0 },
color: style.colors.transparent,
border: { ...style.secondary1 },
data: { type: "car" },
label: [{ text: "JKL-3456", position: "s" }],
},
node11: {
fontIcon: { text: "fas fa-car", ...style.secondary0 },
color: style.colors.transparent,
border: { ...style.secondary1 },
data: { type: "car" },
label: [{ text: "MNP-7890", position: "s" }],
},
link1: {
id1: "node1",
id2: "node2",
...style.link,
},
link2: {
id1: "node1",
id2: "node3",
...style.link,
},
link3: {
id1: "node1",
id2: "node4",
...style.link,
},
link4: {
id1: "node1",
id2: "node5",
...style.link,
},
link5: {
id1: "node1",
id2: "node6",
...style.link,
},
link6: {
id1: "node2",
id2: "node7",
...style.link,
},
link7: {
id1: "node3",
id2: "node8",
...style.link,
},
link8: {
id1: "node4",
id2: "node9",
...style.link,
},
link9: {
id1: "node5",
id2: "node10",
...style.link,
},
link10: {
id1: "node6",
id2: "node11",
...style.link,
},
}; <!doctype html>
<html>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>