Click on a node to see its styling data in the overlay.
For more advanced design needs, ReGraph lets you create nodes as rectangles or custom font icons, and style your nodes with multiple labels, custom interactions and interaction styling.
See also
import React, { useEffect, useRef, useState } from "react";
import { createRoot } from "react-dom/client";
import isEmpty from "lodash/isEmpty";
import { Chart } from "regraph";
import {
data,
interactionStylePresets,
invertedInteractiveNode,
normalInteractiveNode,
positions,
} from "./data";
import "@fortawesome/fontawesome-free/css/fontawesome.css";
import "@fortawesome/fontawesome-free/css/solid.css";
import "@ci/theme/rg/css/properties.css";
function NodeGallery() {
const [selection, setSelection] = useState({});
const [items, setItems] = useState(data);
const [interactiveNodesState, setInteractiveNodeState] = useState({});
const [buttons, setButtons] = useState({
labelButtons: {},
buttonGroupLabels: {},
});
const [chartClasses, setChartClasses] = useState([]);
const currentSubItem = useRef(null);
const chartRef = useRef();
const { labelButtons, buttonGroupLabels } = buttons;
// register any required label as a button or a button group
useEffect(() => {
const buttonsToRegister = {};
const buttonGroupsToRegister = {};
function registerLabelButton(itemId, labelIndex, onItemInteractionLabelStyle, onClick) {
buttonsToRegister[itemId] = buttonsToRegister[itemId] || {};
buttonsToRegister[itemId][labelIndex] = { onClick };
buttonsToRegister[itemId][onItemInteractionLabelStyle] = onItemInteractionLabelStyle;
}
function registerLabelButtonGroup(
itemId,
labelIndexArray,
onItemInteractionLabelStyle,
onClick
) {
for (const labelIndex of labelIndexArray) {
registerLabelButton(itemId, labelIndex, onItemInteractionLabelStyle, onClick);
buttonGroupsToRegister[itemId] = {
...buttonGroupsToRegister[itemId],
[labelIndex]: labelIndexArray,
};
}
}
function toggleLabelButtons(itemId, labelIndex, style) {
// track which buttons are toggled
const currentNodeInteractiveState = interactiveNodesState[itemId] ?? [];
currentNodeInteractiveState[labelIndex] =
currentNodeInteractiveState[labelIndex] === undefined
? true
: !currentNodeInteractiveState[labelIndex];
setInteractiveNodeState({
...interactiveNodesState,
[itemId]: currentNodeInteractiveState,
});
// make sure all buttons are styled correctly depending on their toggle state
const currentStyle = items[itemId];
const originalStyle = data[itemId];
const toggleStyle = { ...currentStyle, label: [...currentStyle.label] };
toggleStyle.label[labelIndex] = {
...toggleStyle.label[labelIndex],
...style,
};
currentNodeInteractiveState.forEach((toggleValue, index) => {
const originalLabelStyle = { ...originalStyle.label[index] };
const labelStyle = toggleValue ? style : originalLabelStyle;
toggleStyle.label[index] = {
...toggleStyle.label[index],
...labelStyle,
};
});
setItems({ ...items, [itemId]: toggleStyle });
}
function toggleNodeStyle(itemId) {
const interactiveNodeState = interactiveNodesState[itemId];
const nodeStyle = !interactiveNodeState ? invertedInteractiveNode : normalInteractiveNode;
setItems({ ...items, [itemId]: nodeStyle });
const toggleInteractiveNodeState =
interactiveNodesState[itemId] === undefined ? true : !interactiveNodesState[itemId];
setInteractiveNodeState({ ...interactiveNodesState, [itemId]: toggleInteractiveNodeState });
}
registerLabelButton("t2", 2, interactionStylePresets.interactiveNodeHover, () => {
toggleNodeStyle("t2");
});
registerLabelButtonGroup("t2", [3, 4], interactionStylePresets.interactiveNodeHover, () =>
window.open("/docs#advanced-node-styling", "_blank")
);
registerLabelButton(
"outside-buttons-rectangle",
3,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons(
"outside-buttons-rectangle",
3,
interactionStylePresets.outsideLabelHover
);
}
);
registerLabelButton(
"outside-buttons-rectangle",
5,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons(
"outside-buttons-rectangle",
5,
interactionStylePresets.outsideLabelHover
);
}
);
registerLabelButton(
"outside-buttons-rectangle",
7,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons(
"outside-buttons-rectangle",
7,
interactionStylePresets.outsideLabelHover
);
}
);
registerLabelButton(
"outside-buttons-circle",
3,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons("outside-buttons-circle", 3, interactionStylePresets.outsideLabelHover);
}
);
registerLabelButton(
"outside-buttons-circle",
4,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons("outside-buttons-circle", 4, interactionStylePresets.outsideLabelHover);
}
);
registerLabelButton(
"outside-buttons-circle",
5,
interactionStylePresets.outsideLabelActive,
() => {
toggleLabelButtons("outside-buttons-circle", 5, interactionStylePresets.outsideLabelHover);
}
);
setButtons((current) => ({
...current,
labelButtons: buttonsToRegister,
buttonGroupLabels: buttonGroupsToRegister,
}));
}, [data, positions, items, interactiveNodesState]);
const handleChartClick = ({ id, subItem, preventDefault }) => {
if (subItem !== null && subItem.type === "label") {
const labelIndex = subItem.index;
if (labelButtons[id] && labelButtons[id][labelIndex]) {
labelButtons[id][labelIndex].onClick();
preventDefault();
}
}
};
const handleChartChange = (change) => {
if (change.selection) {
setSelection({ ...change.selection });
}
};
const handleItemInteraction = ({ id, subItem, setStyle, hovered, selected }) => {
const style = {};
if (selected) {
style.fade = false;
}
const labelIndex = subItem !== null && subItem.type === "label" ? subItem.index : -1;
const isHoverableLabel = id !== null && labelButtons[id] && labelButtons[id][labelIndex];
const isAButtonGroup = isHoverableLabel && !!buttonGroupLabels?.[id]?.[labelIndex];
const hoverStyle = isHoverableLabel && labelButtons[id][style];
if (hovered && isHoverableLabel && !isAButtonGroup) {
const label = [...items[id].label];
label[labelIndex] = {
...label[labelIndex],
...hoverStyle,
};
style.label = label;
} else if (hovered && isAButtonGroup) {
const label = [...items[id].label];
for (const index of buttonGroupLabels[id][labelIndex]) {
label[index] = {
...label[index],
...hoverStyle,
};
}
style.label = label;
}
// apply hover styling for buttons that are not toggled, otherwise only apply fade to selected nodes
if (id === "t2" || (subItem && currentSubItem.current?.index !== subItem?.index)) {
setStyle({
[id]: style,
});
} else if (selected) {
setStyle({ [id]: { fade: false } });
}
currentSubItem.current = subItem;
};
const handleHover = ({ id, subItem }) => {
// On a hover interaction over a label button, append a class to the chart to style the cursor differently
const labelIndex = subItem !== null && subItem.type === "label" ? subItem.index : -1;
const isHoverableLabel = id !== null && labelButtons[id] && labelButtons[id][labelIndex];
setChartClasses((current) =>
isHoverableLabel
? [...current, "cursor-pointer"]
: current.filter((className) => !className.startsWith("cursor-"))
);
if (id == null) {
currentSubItem.current = null;
}
};
return (
<div style={{ width: "100%", height: "100%" }} className={chartClasses.join(" ")}>
<Chart
items={items}
ref={chartRef}
positions={positions}
onClick={handleChartClick}
onItemInteraction={handleItemInteraction}
onChange={handleChartChange}
onHover={handleHover}
options={{
navigation: false,
overview: false,
iconFontFamily: "Font Awesome 5 Free",
selection: { color: "#FF9933" },
hoverDelay: 0,
}}
animation={{ animate: true, time: 450 }}
/>
{isEmpty(selection) ? (
<pre className="properties empty">Select a node to view its properties.</pre>
) : (
<pre className="properties" style={{ fontFamily: 'monospace, "Material Icons"' }}>
{JSON.stringify(selection, null, 2)}
</pre>
)}
</div>
);
}
const FontReadyChart = React.lazy(() =>
Promise.all([
document.fonts.load("24px 'Raleway'"),
document.fonts.load("24px 'Montserrat'"),
document.fonts.load("24px 'Varela Round'"),
document.fonts.load("24px 'Material Icons'", "air"),
document.fonts.load("900 24px 'Font Awesome 5 Free'"),
]).then(() => ({
default: NodeGallery,
}))
);
export function Demo() {
return (
<React.Suspense fallback="">
<FontReadyChart />
</React.Suspense>
);
}
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); export const interactionStylePresets = {
outsideLabelActive: { backgroundColor: "#d1fae5" },
outsideLabelHover: { backgroundColor: "#6ee7b7" },
interactiveNodeHover: { backgroundColor: "#9A9B9B" },
};
const lineSVG = `data:image/svg+xml;base64,${btoa(
`<svg xmlns="http://www.w3.org/2000/svg" fill="#e2e8f0" width="256px" height="5px">
<g id="SVGRepo_bgCarrier" stroke-width="0">
</g>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round">
</g>
<g id="SVGRepo_iconCarrier">
<rect width="256" height="5" />
</g>
</svg>`
)}`;
function circleSVG(colour) {
return `data:image/svg+xml;base64,${btoa(
`<svg width="256" height="256" xmlns="http://www.w3.org/2000/svg">
<circle cx="128" cy="128" r="128" fill="${colour}"/>
</svg>`
)}`;
}
function hexagonSVG(colour) {
return `data:image/svg+xml;base64,${btoa(
`<svg fill="${colour}" height="256px" width="256px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 184.751 184.751" xml:space="preserve">
<g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" stroke="#CCCCCC" stroke-width="4.803526"></g><g id="SVGRepo_iconCarrier"> <path d="M0,92.375l46.188-80h92.378l46.185,80l-46.185,80H46.188L0,92.375z"></path> </g>
</svg>
`
)}`;
}
function squareSVG(colour) {
return `data:image/svg+xml;base64,${btoa(
`<svg width="256" height="256" xmlns="http://www.w3.org/2000/svg">
<rect width="256" height="256" fill="${colour}"/>
</svg>`
)}`;
}
export const positions = {
"t1-a": {
x: -475,
y: -45,
},
"t1-b": {
x: -350,
y: -45,
},
"t1-c": {
x: -597,
y: -45,
},
t2: {
x: 425,
y: 200,
},
"j1-rectangle": {
x: -105,
y: -361,
},
"j2-rectangle": {
x: -105,
y: -255,
},
"j3-rectangle": {
x: -105,
y: -140,
},
"j4-circle": {
x: 247,
y: 0,
},
"j5-circle": {
x: 120,
y: -22,
},
"j6-circle": {
x: 203,
y: -122,
},
"j7-profile-card": {
x: -500,
y: -300,
},
"c1-circle": {
x: -40,
y: 75,
},
"c1-hexagon": {
x: -105,
y: 200,
},
"c1-square": {
x: 45,
y: 200,
},
c1: {
x: 380,
y: -334,
},
"node_Emanuela Cooper": {
x: 480,
y: -150,
},
"node_Vito Morello": {
x: 480,
y: -45,
},
node_people: {
x: 480,
y: 45,
},
"outside-buttons-rectangle": {
x: -597,
y: 180,
},
"outside-buttons-circle": {
x: -400,
y: 180,
},
};
function makeInteractiveNode(backgroundColour, accentColour) {
return {
type: "node",
border: {
color: accentColour,
radius: [0, 10, 20, 10],
},
shape: {
height: 85,
width: 305,
},
color: backgroundColour,
label: [
{
color: accentColour,
backgroundColor: "transparent",
fontSize: 35,
position: {
horizontal: "left",
vertical: "middle",
},
fontIcon: {
text: "fas fa-desktop",
},
margin: {
left: 17.5,
},
},
{
bold: true,
color: accentColour,
text: "Interactive Node",
backgroundColor: "transparent",
fontSize: 16,
padding: {
top: 0,
right: 10,
bottom: 0,
left: 0,
},
textAlignment: {
horizontal: "left",
},
position: {
horizontal: 70,
vertical: 15,
},
},
{
bold: true,
color: backgroundColour,
text: "Invert Style",
backgroundColor: accentColour,
border: {
radius: [10, 10, 10, 10],
},
margin: {
top: 10,
right: 0,
bottom: 10,
left: 0,
},
minWidth: 60,
padding: {
top: 8,
right: 10,
bottom: 6,
left: 10,
},
position: {
horizontal: 70,
},
},
{
bold: true,
color: backgroundColour,
backgroundColor: accentColour,
fontSize: 13,
margin: {
top: 10,
right: 10,
bottom: 0,
left: 10,
},
border: {
radius: [10, 0, 0, 10],
},
padding: {
top: 9,
right: 10,
bottom: 9.75,
left: 10,
},
position: {
vertical: "inherit",
},
fontIcon: {
text: "fas fa-external-link-alt",
},
},
{
bold: true,
color: backgroundColour,
text: "Go to Docs ",
backgroundColor: accentColour,
border: {
radius: [0, 10, 10, 0],
},
margin: {
top: 10,
right: 0,
bottom: 0,
left: 30,
},
minWidth: 60,
padding: {
top: 8,
right: 10,
bottom: 6,
left: 1,
},
position: {
horizontal: 170,
vertical: "inherit",
},
},
],
};
}
export const invertedInteractiveNode = makeInteractiveNode("#3d405b", "#f4f3ee");
export const normalInteractiveNode = makeInteractiveNode("#f4f3ee", "#3d405b");
function makeProfileCardNode() {
return {
color: "#f1f5f9",
border: {
radius: [10, 10, 6, 6],
},
label: [
{
color: "rgb(81, 136, 168)",
backgroundColor: "#f1f5f9",
fontSize: 90,
border: {
color: "rgb(0, 85, 135)",
width: 5,
radius: [60, 60, 60, 60],
},
margin: {
top: -50,
right: 0,
bottom: 0,
left: 0,
},
minHeight: 100,
minWidth: 100,
position: {
vertical: "top",
},
fontIcon: {
text: "fas fa-user",
},
},
{
bold: true,
color: "rgb(0, 85, 135)",
text: "John Doe",
backgroundColor: "transparent",
fontSize: 30,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
},
{
color: "rgb(81, 136, 168)",
backgroundColor: "transparent",
fontSize: 12,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
fontIcon: {
text: "fas fa-envelope",
},
},
{
color: "rgb(81, 136, 168)",
text: "[email protected]",
backgroundColor: "transparent",
fontSize: 10,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
position: {
vertical: "inherit",
},
},
{
color: "rgb(81, 136, 168)",
backgroundColor: "transparent",
fontSize: 12,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
fontIcon: {
text: "fas fa-code",
},
},
{
color: "#334155",
text: "Software Developer",
backgroundColor: "transparent",
fontSize: 10,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
position: {
vertical: "inherit",
},
},
{
color: "white",
text: "[email protected]",
backgroundColor: "rgb(81, 136, 168)",
fontSize: 10,
border: {
radius: [0, 0, 6, 6],
},
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
minWidth: 300,
padding: {
top: 10,
right: 0,
bottom: 10,
left: 0,
},
position: {
vertical: "bottom",
},
},
],
shape: {
height: "auto",
width: 300,
},
};
}
function makeBusinessProcessNode() {
return {
color: "#ecfdf5",
border: {
color: "#e5e5e5",
width: 2,
radius: [10, 10, 10, 10],
},
label: [
{
color: "#334155",
text: "Business Process 1",
backgroundColor: "transparent",
fontSize: 26,
margin: {
top: 8,
right: 0,
bottom: 0,
left: 8,
},
position: {
horizontal: "left",
vertical: "top",
},
},
{
color: "#334155",
text: "2140.0",
backgroundColor: "transparent",
fontSize: 26,
margin: {
top: 0,
right: 0,
bottom: 20,
left: 8,
},
textAlignment: {
vertical: "bottom",
},
position: {
horizontal: "left",
vertical: "bottom",
},
},
{
color: "#334155",
text: "GBP",
backgroundColor: "transparent",
fontSize: 20,
margin: {
top: 0,
right: 0,
bottom: 21,
left: 0,
},
minHeight: 36,
textAlignment: {
vertical: "bottom",
},
position: {
vertical: "bottom",
},
},
{
margin: {
top: 0,
right: 2,
bottom: 15,
left: 0,
},
fontSize: 36,
backgroundColor: "transparent",
minHeight: 36,
textAlignment: {
vertical: "bottom",
},
position: {
horizontal: "right",
vertical: "bottom",
},
fontIcon: {
text: "fas fa-caret-up",
color: "#10b981",
},
},
{
color: "#10b981",
text: "55.12%",
backgroundColor: "transparent",
fontSize: 20,
minHeight: 36,
textAlignment: {
vertical: "bottom",
},
position: {
vertical: "inherit",
},
margin: {
top: 0,
right: 8,
bottom: 20,
left: 0,
},
},
{
border: {
radius: [0, 0, 9, 9],
},
minHeight: 18,
minWidth: 402,
backgroundColor: "#e5e5e5",
fontSize: 0,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: "center",
vertical: 103,
},
},
{
border: {
radius: [0, 0, 10, 10],
},
margin: {
top: 1,
right: 1,
bottom: 1,
left: 1,
},
fontSize: 10,
backgroundColor: "#f1f5f9",
minWidth: 394,
position: {
horizontal: "left",
vertical: "bottom",
},
},
{
border: {
radius: [0, 0, 0, 10],
},
margin: {
top: 1,
right: 1,
bottom: 1,
left: 1,
},
fontSize: 10,
backgroundColor: "#10b981",
minWidth: 230.5,
position: {
horizontal: "left",
vertical: "bottom",
},
},
{
backgroundColor: "#f1f5f9",
minWidth: 40,
minHeight: 60,
position: { vertical: "middle", horizontal: -46 },
border: {
radius: [5, 0, 0, 5],
width: 2,
color: "#e5e5e5",
},
fontSize: 26,
fontIcon: {
text: "fas fa-people-arrows",
color: "#334155",
},
},
],
shape: {
height: 120,
width: 400,
},
};
}
function makeShadowCircleNode(colour, icon, text) {
return {
type: "node",
color: colour,
border: {
color: "#283618",
width: 2,
},
size: 1.5,
halos: [
{
color: "rgba(220,220,220,1)",
radius: 29,
width: 1,
},
{
color: "rgba(220,220,220,0.8)",
radius: 30,
width: 1,
},
{
color: "rgba(220,220,220,0.6)",
radius: 31,
width: 1,
},
{
color: "rgba(220,220,220,0.4)",
radius: 32,
width: 1,
},
{
color: "rgba(220,220,220,0.2)",
radius: 33,
width: 1,
},
],
label: [
{
color: "#283618",
backgroundColor: "rgba(0, 0, 0, 0)",
fontSize: 30,
padding: {
top: 6,
right: 2,
bottom: 0,
left: 2,
},
position: {
vertical: "top",
},
fontIcon: {
text: icon,
fontFamily: "Material Icons",
},
},
{
bold: true,
color: "#283618",
text: text,
backgroundColor: "rgba(0, 0, 0, 0)",
fontSize: 10,
fontFamily: "Varela Round",
},
],
};
}
function makeMaterialIconLabel(icon, fontSize, colour) {
return {
position: {
horizontal: "centre",
vertical: "middle",
},
fontSize: fontSize,
color: colour,
backgroundColor: "transparent",
fontIcon: {
text: icon,
fontFamily: "Material Icons",
},
padding: {
top: 5,
right: 2,
bottom: 0,
left: 2,
},
};
}
function makeCustomNodeLabel(image, size) {
return {
position: {
horizontal: "centre",
vertical: "middle",
},
backgroundColor: "transparent",
image,
padding: {
top: 5,
right: 2,
bottom: 0,
left: 2,
},
maxHeight: size,
maxWidth: size,
};
}
export const data = {
t2: normalInteractiveNode,
"t1-a": {
color: "#A485D5",
border: {
color: "#69738C",
width: 3,
radius: [10, 10, 10, 10],
},
label: [
{
color: "white",
backgroundColor: "transparent",
fontSize: 50,
position: {
vertical: 24,
},
fontIcon: {
text: "fas fa-server",
},
},
{
bold: true,
color: "white",
text: "Rack A",
backgroundColor: "transparent",
fontSize: 15,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
},
{
color: "white",
text: "OK",
backgroundColor: "transparent",
fontSize: 11,
margin: {
top: 5,
right: 0,
bottom: 0,
left: 0,
},
padding: {
top: 0,
right: 20,
bottom: 0,
left: 20,
},
},
{
border: {
radius: [0, 0, 8.5, 8.5],
},
backgroundColor: "#69738C",
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
minHeight: 21.5,
minWidth: 103,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: -1.5,
vertical: 130,
},
},
{
border: {
radius: [0, 0, 0, 6.5],
},
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
backgroundColor: "#FACA16",
minHeight: 17,
minWidth: 60,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: 0,
vertical: 133,
},
},
],
shape: {
height: 150,
width: 100,
},
},
"t1-b": {
color: "#A485D5",
border: {
color: "#69738C",
width: 3,
radius: [10, 10, 10, 10],
},
label: [
{
color: "white",
backgroundColor: "transparent",
fontSize: 50,
position: {
vertical: 24,
},
fontIcon: {
text: "fas fa-server",
},
},
{
bold: true,
color: "white",
text: "Rack B",
backgroundColor: "transparent",
fontSize: 15,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
},
{
color: "white",
text: "High CPU usage",
backgroundColor: "transparent",
fontSize: 11,
margin: {
top: 5,
right: 0,
bottom: 0,
left: 0,
},
padding: {
top: 0,
right: 20,
bottom: 0,
left: 20,
},
},
{
border: {
radius: [0, 0, 8.5, 8.5],
},
backgroundColor: "#69738C",
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
minHeight: 21.5,
minWidth: 103,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: -1.5,
vertical: 130,
},
},
{
border: {
radius: [0, 0, 0, 6.5],
},
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
backgroundColor: "#FF3C38",
minHeight: 17,
minWidth: 80,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: 0,
vertical: 133,
},
},
],
shape: {
height: 150,
width: 100,
},
},
"t1-c": {
color: "#61A899",
border: {
color: "#69738C",
width: 3,
radius: [10, 10, 10, 10],
},
label: [
{
color: "white",
backgroundColor: "transparent",
fontSize: 50,
position: {
vertical: 24,
},
fontIcon: {
text: "fas fa-hdd",
},
},
{
bold: true,
color: "white",
text: "Blade C",
backgroundColor: "transparent",
fontSize: 15,
margin: {
top: 10,
right: 0,
bottom: 0,
left: 0,
},
},
{
color: "white",
text: "OK",
backgroundColor: "transparent",
fontSize: 11,
margin: {
top: 5,
right: 0,
bottom: 0,
left: 0,
},
padding: {
top: 0,
right: 20,
bottom: 0,
left: 20,
},
},
{
border: {
radius: [0, 0, 8.5, 8.5],
},
backgroundColor: "#69738C",
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
minHeight: 21.5,
minWidth: 103,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: -1.5,
vertical: 130,
},
},
{
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
border: {
radius: [0, 0, 0, 6.5],
},
backgroundColor: "#65B540",
minHeight: 17,
minWidth: 30,
padding: {
top: 0,
right: 0,
bottom: 0,
left: 0,
},
position: {
horizontal: 0,
vertical: 133,
},
},
],
shape: {
height: 150,
width: 100,
},
},
"j1-rectangle": {
color: "#34d399",
label: [
{
color: "#34d399",
backgroundColor: "#404347",
fontSize: 35,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 7.5,
},
minHeight: 55,
padding: {
top: 2,
right: 2,
bottom: 0,
left: 10,
},
fontIcon: {
text: "fas fa-random",
},
},
{
bold: true,
color: "white",
text: "Generate Data",
fontFamily: "Montserrat",
backgroundColor: "#404347",
fontSize: "auto",
margin: {
top: 0,
right: 7.5,
bottom: 0,
left: 0,
},
minHeight: 55,
padding: {
top: 2,
right: 13,
bottom: 0,
left: 13,
},
position: {
vertical: "inherit",
},
},
],
shape: {
height: 70,
width: 230,
},
},
"j2-rectangle": {
color: "#fcd34d",
label: [
{
color: "#fcd34d",
backgroundColor: "#404347",
fontSize: 35,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 7.5,
},
minHeight: 55,
padding: {
top: 2,
right: 2,
bottom: 0,
left: 10,
},
fontIcon: {
text: "fas fa-database",
},
},
{
bold: true,
color: "white",
text: "Open Database",
fontFamily: "Montserrat",
backgroundColor: "#404347",
fontSize: "auto",
margin: {
top: 0,
right: 7.5,
bottom: 0,
left: 0,
},
minHeight: 55,
padding: {
top: 2,
right: 10,
bottom: 0,
left: 10,
},
position: {
vertical: "inherit",
},
},
{
color: "white",
text: "Unavailable",
backgroundColor: "#404347",
fontSize: 12,
border: {
radius: [20, 20, 20, 20],
width: 3,
color: "#fcd34d",
},
margin: {
top: 0,
right: 0,
bottom: -20,
left: -60,
},
padding: {
top: 8,
right: 8,
bottom: 6,
left: 8,
},
position: "ne",
},
],
shape: {
height: 70,
width: 230,
},
},
"j3-rectangle": {
color: "#fb7185",
label: [
{
color: "#fb7185",
backgroundColor: "#404347",
fontSize: 35,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 7.5,
},
minHeight: 55,
padding: {
top: 2,
right: 2,
bottom: 0,
left: 10,
},
fontIcon: {
text: "fas fa-bug",
},
},
{
bold: true,
color: "white",
text: "Debug Console",
fontFamily: "Montserrat",
backgroundColor: "#404347",
fontSize: "auto",
margin: {
top: 0,
right: 7.5,
bottom: 0,
left: 0,
},
minHeight: 55,
padding: {
top: 2,
right: 10,
bottom: 0,
left: 10,
},
position: {
vertical: "inherit",
},
},
{
color: "white",
text: "Unavailable",
backgroundColor: "#404347",
fontSize: 12,
border: {
radius: [20, 20, 20, 20],
width: 3,
color: "#fb7185",
},
margin: {
top: 0,
right: 0,
bottom: -20,
left: -60,
},
padding: {
top: 8,
right: 8,
bottom: 6,
left: 8,
},
position: "ne",
},
],
shape: {
height: 70,
width: 230,
},
},
"j4-circle": makeShadowCircleNode("#fefae0", "local_florist", "Bloom"),
"j5-circle": makeShadowCircleNode("#f4f3ee", "air", "Blow"),
"j6-circle": makeShadowCircleNode("#cd4631", "local_fire_department", "Burn"),
"j7-profile-card": makeProfileCardNode(),
"c1-circle": {
color: "rgba(0,0,0,0)",
label: [
makeCustomNodeLabel(circleSVG("#0f2e18"), 56),
makeCustomNodeLabel(circleSVG("white"), 50),
makeCustomNodeLabel(circleSVG("#0f2e18"), 45),
makeCustomNodeLabel(circleSVG("white"), 40),
makeCustomNodeLabel(circleSVG("#0f2e18"), 35),
{
...makeMaterialIconLabel("flight", 30, "#FFF"),
padding: { top: 0, right: 0, bottom: 0, left: 1 },
},
],
size: 1.7,
shape: "circle",
},
"c1-hexagon": {
color: "rgba(0,0,0,0)",
label: [
makeCustomNodeLabel(hexagonSVG("#001845"), 56 + 8),
makeCustomNodeLabel(hexagonSVG("white"), 50 + 8),
makeCustomNodeLabel(hexagonSVG("#001845"), 45 + 8),
makeCustomNodeLabel(hexagonSVG("white"), 40 + 8),
makeCustomNodeLabel(hexagonSVG("#001845"), 35 + 8),
makeMaterialIconLabel("place", 30, "#FFF"),
],
size: 1.7,
shape: "box",
},
"c1-square": {
color: "rgba(0,0,0,0)",
label: [
makeCustomNodeLabel(squareSVG("#540b0e"), 56),
makeCustomNodeLabel(squareSVG("white"), 50),
makeCustomNodeLabel(squareSVG("#540b0e"), 45),
makeCustomNodeLabel(squareSVG("white"), 40),
makeCustomNodeLabel(squareSVG("#540b0e"), 35),
makeMaterialIconLabel("question_answer", 30, "#FFF"),
],
size: 1.7,
shape: "box",
},
c1: makeBusinessProcessNode(),
"node_Emanuela Cooper": {
color: "#734b6d",
border: {
color: "white",
width: 1,
radius: 10,
},
label: [
{
image: `/img/people/Person3.png`,
position: {
horizontal: "left",
},
margin: 10,
},
{
text: "Emanuela Cooper",
position: {
vertical: "inherit",
},
margin: {
right: 10,
},
backgroundColor: "transparent",
color: "#faf5ff",
},
],
glyphs: [
{
position: "ne",
fontIcon: {
text: "fas fa-plus",
color: "white",
},
backgroundColor: "transparent",
color: "rgba(183, 92, 170, 1)",
size: 1.2,
},
{
fontIcon: {
text: "fas fa-expand-arrows-alt",
color: "white",
},
color: "#513BC4",
backgroundColor: "transparent",
position: "se",
size: 1.2,
},
],
shape: {
width: "auto",
height: "auto",
},
},
"node_Vito Morello": {
color: "#734b6d",
border: {
color: "white",
width: 1,
radius: 10,
},
label: [
{
text: "Vito Morello",
margin: {
left: 10,
},
position: {
horizontal: "left",
},
backgroundColor: "transparent",
color: "#faf5ff",
},
{
image: `/img/people/Person9.png`,
position: {
vertical: "inherit",
},
margin: {
left: 10,
right: 20,
},
},
],
glyphs: [
{
position: "ne",
fontIcon: {
text: "fas fa-plus",
color: "white",
},
backgroundColor: "transparent",
color: "rgba(183, 92, 170, 1)",
size: 1.2,
},
{
fontIcon: {
text: "fas fa-expand-arrows-alt",
color: "white",
},
color: "#513BC4",
backgroundColor: "transparent",
position: "se",
size: 1.2,
},
],
shape: {
width: "auto",
height: 35,
},
},
node_people: {
color: "#734b6d",
border: {
color: "white",
width: 1,
radius: 10,
},
label: [
{
text: "Team",
margin: {
left: 10,
},
position: {
horizontal: "left",
},
backgroundColor: "transparent",
color: "#faf5ff",
},
{
image: `/img/people/Person2.png`,
position: {
vertical: "inherit",
},
maxWidth: 30,
maxHeight: 30,
margin: {
left: 10,
},
},
{
image: `/img/people/Person13.png`,
position: {
vertical: "inherit",
},
maxWidth: 30,
maxHeight: 30,
margin: {
left: -5,
},
},
{
image: `/img/people/Person8.png`,
position: {
vertical: "inherit",
},
maxWidth: 30,
maxHeight: 30,
margin: {
left: -5,
},
},
{
image: `/img/people/Person5.png`,
position: {
vertical: "inherit",
},
maxWidth: 30,
maxHeight: 30,
margin: {
left: -5,
},
},
{
fontIcon: { text: "fas fa-ellipsis-h", color: "#334155" },
position: {
vertical: "inherit",
},
fontSize: 20,
minWidth: 30,
minHeight: 29.5,
border: { radius: 180 },
backgroundColor: "#f8fafc",
padding: [1, 0, 0, 0],
margin: {
left: -5,
right: 10,
},
},
],
shape: {
width: "auto",
height: 50,
},
},
"outside-buttons-rectangle": {
color: "#f3f4f6",
shape: { width: 100, height: 130 },
border: { radius: 10, width: 1, color: "rgba(229, 231, 235, 0.8)" },
label: [
{
fontIcon: { text: "fas fa-file-invoice", color: "#0d9488" },
backgroundColor: "rgba(0,0,0,0)",
fontSize: 40,
position: { horizontal: "center", vertical: "top" },
margin: {
top: 15,
bottom: 10,
},
},
{
text: "Insurance Policy",
backgroundColor: "rgba(0,0,0,0)",
color: "#334155",
textWrap: "normal",
},
{
text: "id: 842 921",
backgroundColor: "rgba(0,0,0,0)",
color: "#64748b",
textWrap: "normal",
fontSize: 12,
margin: { top: 10, bottom: 10 },
},
// side buttons
{
fontIcon: { text: "fas fa-check", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 30,
minWidth: 30,
position: { horizontal: 110, vertical: "top" },
border: { radius: [5, 5, 0, 0] },
},
{
maxHeight: 1,
maxWidth: 34,
backgroundColor: "red",
image: lineSVG,
},
{
fontIcon: { text: "fas fa-bell-slash", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 30,
minWidth: 30,
},
{
maxHeight: 1,
maxWidth: 34,
backgroundColor: "red",
image: lineSVG,
},
{
fontIcon: { text: "fas fa-eye-slash", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 30,
minWidth: 30,
border: { radius: [0, 0, 5, 5] },
},
],
},
"outside-buttons-circle": {
color: "#f3f4f6",
shape: { width: 130, height: 130 },
border: { radius: 180, width: 1, color: "rgba(229, 231, 235, 0.8)" },
label: [
{
fontIcon: { text: "fas fa-file-invoice", color: "#0d9488" },
backgroundColor: "rgba(0,0,0,0)",
fontSize: 40,
position: { horizontal: "center", vertical: "top" },
margin: {
top: 15,
bottom: 10,
},
},
{
text: "Insurance Policy",
backgroundColor: "rgba(0,0,0,0)",
color: "#334155",
textWrap: "normal",
},
{
text: "id: 842 921",
backgroundColor: "rgba(0,0,0,0)",
color: "#64748b",
textWrap: "normal",
fontSize: 12,
margin: { top: 10, bottom: 10 },
},
// side buttons
{
fontIcon: { text: "fas fa-check", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 32,
minWidth: 32,
position: { horizontal: 135, vertical: 10 },
border: { radius: 180 },
margin: 2.5,
padding: 0,
},
{
fontIcon: { text: "fas fa-bell-slash", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 32,
minWidth: 32,
border: { radius: 180 },
margin: 2.5,
padding: 0,
},
{
fontIcon: { text: "fas fa-eye-slash", color: "#0f766e" },
backgroundColor: "#f3f4f6",
fontSize: 18,
minHeight: 32,
minWidth: 32,
border: { radius: 180 },
margin: 2.5,
padding: 0,
},
],
},
}; <!doctype html>
<html>
<head>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html> /* Import for Google Fonts: Montserrat, Raleway and Varela Round */
@import url("https://fonts.googleapis.com/css2?family=Montserrat&family=Raleway&family=Varela+Round&display=swap");
/* Import for Google's Material Icons */
@import url("https://fonts.googleapis.com/icon?family=Material+Icons");
.cursor-pointer canvas {
cursor: pointer !important;
}
pre {
max-width: 60vh;
}