Double click on nodes or the background to add more data, or use the buttons above the chart.
The layout you choose determines how items in your network are positioned.
When new data is added to an existing chart, it is laid out to fit in with the rest of the network.
See also
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import pickBy from "lodash/pickBy";
import random from "lodash/random";
import { Chart } from "regraph";
import data from "./data";
import { style } from "@ci/theme/rg/js/storyStyles";
import "@ci/theme/rg/css/button.css";
import "@ci/theme/rg/css/layout.css";
const layouts = ["organic", "sequential", "radial"];
export const Demo = () => <Incremental itemData={data()} />;
function Incremental(props) {
const { itemData } = props;
const [state, setState] = useState({
items: itemData,
count: 7,
layout: { name: "organic", level: "level" },
});
const onRunLayout = (name) => {
setState((current) => {
return { ...current, layout: { ...current.layout, name } };
});
};
const createNewItems = (id, level) => {
const newItems = {};
const newNodeCount = 2 + Math.round(Math.random() * 3);
for (let i = 1; i <= newNodeCount; i += 1) {
const nodeId = state.count + i;
const linkId = `${id}-${nodeId}`;
newItems[nodeId] = {
...style.primary1,
data: { level: level + 1 },
};
newItems[linkId] = {
...style.link,
id1: id,
id2: nodeId,
};
}
return newItems;
};
const onAddComponent = () => {
setState((current) => {
const id = current.count + 6;
const itemsToAdd = createNewItems(id, 1);
const newItems = {
...current.items,
...itemsToAdd,
[id]: {
...style.primary2,
data: { level: 1 },
},
};
return { ...current, items: newItems, count: id };
});
};
const addNodesFrom = (id) => {
setState((current) => {
// Add new items to the data
const itemsToAdd = createNewItems(id, current.items[id].data.level);
return {
...current,
items: { ...current.items, ...itemsToAdd },
count: current.count + Object.keys(itemsToAdd).length - 1,
};
});
};
const onAddNodesFromRandom = () => {
// Select a node id at random from the data
const nodes = pickBy(state.items, (item) => !item.id1);
const allNodeIds = Object.keys(nodes);
const id = allNodeIds[random(0, allNodeIds.length - 1)];
// Load new data connected to the random item
addNodesFrom(id);
};
const onAddData = ({ id, itemType }) => {
if (id) {
if (itemType === "node") {
// if it is a node we will expand from it
addNodesFrom(id);
}
} else {
onAddComponent();
}
};
return (
<div className="story">
<Controls
layout={state.layout}
runLayout={onRunLayout}
addNodesFromRandom={onAddNodesFromRandom}
addComponent={onAddComponent}
/>
<div className="chart-wrapper">
<Chart
items={state.items}
layout={state.layout}
onDoubleClick={onAddData}
animation={{ animate: true, time: 850 }}
/>
</div>
</div>
);
}
function Controls(props) {
const { layout, runLayout, addNodesFromRandom, addComponent } = props;
return (
<div className="options">
<button
type="button"
title="Add nodes to the chart from a random node. Double click a node to add data from it."
onClick={addNodesFromRandom}
>
Add Nodes
</button>
<button
type="button"
title="Add a component to the chart. Double click the background to add a new
component."
onClick={addComponent}
>
Add Component
</button>
<span className="separator" />
<span className="label">Layout</span>
{layouts.map((name) => (
<button
type="button"
className={layout.name === name ? "active" : ""}
key={name}
onClick={() => runLayout(name)}
style={{ textTransform: "capitalize" }}
>
{name}
</button>
))}
</div>
);
}
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); import { style } from "@ci/theme/rg/js/storyStyles";
function data() {
return {
1: {
...style.primary3,
data: { level: 1 },
},
2: {
...style.primary2,
data: { level: 2 },
},
3: {
...style.primary2,
data: { level: 2 },
},
4: {
...style.primary2,
data: { level: 2 },
},
5: {
...style.primary2,
data: { level: 2 },
},
6: {
...style.primary2,
data: { level: 2 },
},
7: {
...style.primary2,
data: { level: 2 },
},
"1-2": {
id1: "1",
id2: "2",
...style.link,
},
"1-3": {
id1: "1",
id2: "3",
...style.link,
},
"1-4": {
id1: "1",
id2: "4",
...style.link,
},
"1-5": {
id1: "1",
id2: "5",
...style.link,
},
"1-6": {
id1: "1",
id2: "6",
...style.link,
},
"1-7": {
id1: "1",
id2: "7",
...style.link,
},
};
}
export default data; <!doctype html>
<html>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>