Click on the buttons to cycle through halo styles.
Halos are rings around nodes, usually used to highlight them.
See also
import React from "react";
import { createRoot } from "react-dom/client";
import mapValues from "lodash/mapValues";
import pickBy from "lodash/pickBy";
import { Chart } from "regraph";
import { style } from "@ci/theme/rg/js/storyStyles";
import "@ci/theme/rg/css/properties.css";
import "@ci/theme/rg/css/button.css";
export const Demo = () => <HaloStyle />;
const colors = [style.colors.teal0, style.colors.teal1, style.colors.red1, style.colors.blue1];
const haloProps = {
// all three halo properties are required for a halo to appear
color: { values: colors, label: "color" },
radius: { values: [50, 70, 30], label: "radius" },
width: { values: [5, 10, 20], label: "width" },
};
const numHalosValues = [1, 2, 3, 2, 1, 0];
class HaloStyle extends React.PureComponent {
constructor(props) {
super(props);
this.state = { ...mapValues(haloProps, () => 0), numHalos: 0 };
}
update = (id) => {
const { [id]: index } = this.state;
const { [id]: property } = haloProps;
const { values } = property;
let result = index + 1;
if (result > values.length - 1) {
result = 0;
}
this.setState({ [id]: result });
};
reset = () => {
this.setState({ ...mapValues(haloProps, () => 0), numHalos: 0 });
};
haloNumber = () => {
const { numHalos } = this.state;
let result = numHalos + 1;
if (result >= numHalosValues.length) {
result = 0;
}
this.setState({ numHalos: result });
};
render = () => {
const { numHalos } = this.state;
const length = numHalosValues[numHalos];
const halo = pickBy(
mapValues(haloProps, (value, key) => {
const { [key]: index } = this.state;
return value.values[index || 0];
}),
(value) => value !== undefined
);
const halos = [];
for (let i = 0; i < length; i += 1) {
// give each halo a different r so they don't overlap
halos.push({ ...halo, radius: halo.radius + i * 22 });
}
const node1 = { ...style.primary1, halos };
return (
<div style={{ width: "100%", height: "100%" }}>
<Chart
items={{ node1 }}
animation={{ animate: true, time: 250 }}
options={{ fit: "all", navigation: false, overview: false }}
/>
<div style={{ position: "absolute", top: 0, left: 0 }}>
<button type="button" onClick={this.reset}>
Reset
</button>
<button type="button" title="number of halos" onClick={this.haloNumber}>
#
</button>
{Object.keys(haloProps).map((key) => (
<button
type="button"
title={haloProps[key].label}
key={key}
onClick={() => this.update(key)}
>
{key}
</button>
))}
</div>
<pre className="properties">{JSON.stringify({ node1 }, null, 2)}</pre>
</div>
);
};
}
const root = createRoot(document.getElementById("regraph"));
root.render(<Demo />); <!doctype html>
<html>
<body>
<div id="regraph" style="height: 100vh"></div>
<script type="module" src="./code.jsx"></script>
</body>
</html>