Double-click on the user nodes to request more data from the API.
You can use a function like the one in the data tab to convert the output of a REST API call into the ReGraph format.
See also
import React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
import { Chart } from "regraph";
import { convertOrganization, convertOrgMembers } from "./data";
const API_URL = "https://api.github.com";
const getOrgMembersURL = ({ org }) => `${API_URL}/orgs/${org}/members`;
const getUserOrgsURL = ({ username }) => `${API_URL}/users/${username}/orgs`;
const fetchData = async (url) => {
const result = await fetch(url);
return result.json();
};
export const Demo = () => <Fetch />;
function Fetch() {
const [items, setItems] = useState({});
useEffect(() => {
const initialUrl = getOrgMembersURL({ org: "reactjs" });
fetchData(initialUrl).then((response) => setItems(convertOrgMembers(response, "reactjs")));
}, []);
async function expand({ itemType, id }) {
if (itemType !== "node" || items[id].data.type !== "user") {
return;
}
const { name } = items[id].data;
const url = getUserOrgsURL({ username: name });
const data = await fetchData(url);
setItems((currentItems) => ({ ...currentItems, ...convertOrganization(data, name) }));
}
return (
<Chart
animation={{ time: 1000 }}
items={items}
options={{
labels: { maxLength: 20 },
}}
onDoubleClick={expand}
/>
);
}
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); import { style } from "@ci/theme/rg/js/storyStyles";
const colors = {
transparent: "rgba(0,0,0,0)",
red: style.colors.red2,
};
function makeNode({ name, image, type, color = style.primary1.color }) {
return {
color: image ? colors.transparent : color,
label: [
{
text: name,
...style.darkLabelLow,
fontSize: 10,
},
],
size: image ? 1.2 : 1,
cutout: true,
image,
data: { type, name },
};
}
function makeLink(id1, id2) {
return { id1, id2, width: 3 };
}
export function convertOrgMembers(data, orgName) {
if (data == null) {
return { error: makeNode({ name: "Could not load data", color: colors.red }) };
}
const items = { [orgName]: makeNode({ name: orgName, type: "organization" }) };
data.forEach(({ avatar_url: avatarUrl, login: userName }) => {
items[userName] = makeNode({ image: avatarUrl, name: userName, type: "user" });
items[`${orgName}-${userName}`] = makeLink(orgName, userName);
});
return items;
}
export function convertOrganization(data, userName) {
if (data == null) {
return { error: makeNode({ name: "Could not load data", color: colors.red }) };
}
const items = {};
data.forEach(({ login: orgName }) => {
items[orgName] = makeNode({ name: orgName, type: "organization" });
items[`${orgName}-${userName}`] = makeLink(orgName, userName);
});
return items;
} <!doctype html>
<html>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>