Click on the buttons to cycle through glyph styles.
Links can be annotated with glyphs by updating the glyphs property.
To add glyphs at a link end, set the glyphs property within end1 or end2.
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/button.css";
const usa = "/img/flags/united-states-of-america.svg";
export const Demo = () => <GlyphStyle />;
const { colorArrays } = style;
const glyphProps = {
blink: { values: [undefined, true], label: "Blink" },
color: { values: [...colorArrays.transparent], label: "Fill color" },
size: { values: [undefined, 2, 4], label: "Size" },
label: {
values: [
undefined,
{ text: "!" },
{ text: "!", bold: true },
{ text: "Text", color: colorArrays.standard[0] },
{ text: "Text", color: colorArrays.standard[1] },
{ text: "Text", color: colorArrays.standard[2] },
{
text: "Text",
fontFamily: "sans serif",
},
{
text: "Text",
fontFamily: "comic sans ms",
},
],
label: "Label",
},
border: {
values: [undefined, { color: colorArrays.dark[0] }, { color: colorArrays.dark[1] }],
label: "Border",
},
image: { values: [usa, undefined], label: "Glyph image" },
};
class GlyphStyle extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
...mapValues(glyphProps, () => 0),
length: 1,
positions: { node1: { x: -100, y: -50 }, node2: { x: 100, y: 50 } },
};
}
update = (id) => {
const { [id]: index, label, image } = this.state;
const { [id]: property } = glyphProps;
const { values } = property;
let result = index + 1;
if (result > values.length - 1) {
result = 0;
}
this.setState({ [id]: result });
if (id === "image" && label > 0) {
// let's get rid of the label, so that we can
// actually see the image
this.setState({ label: 0 });
}
if (id === "label" && image === 0) {
// remove the image so that the label is displayed
this.setState({ image: 1 });
}
};
reset = () => {
const { positions } = this.state;
this.setState({
...mapValues(glyphProps, () => 0),
length: 1,
positions: { ...positions },
});
};
glyphNumber = () => {
const { length } = this.state;
let result = length + 1;
if (result > 4) {
result = 1;
}
this.setState({ length: result });
};
render = () => {
const { length, positions } = this.state;
const glyph = pickBy(
mapValues(glyphProps, (value, key) => {
const { [key]: index } = this.state;
return value.values[index || 0];
}),
(value) => value !== undefined
);
const glyphs = [];
for (let i = 0; i < length; i += 1) {
glyphs.push(glyph);
}
const node1 = { color: "rgba(45, 205, 168, 1)" };
const node2 = { color: "rgba(45, 205, 168, 1)" };
const link1 = {
id1: "node1",
id2: "node2",
glyphs,
};
return (
<div style={{ width: "100%", height: "100%" }}>
<Chart
items={{ node1, node2, link1 }}
positions={positions}
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 glyphs" onClick={this.glyphNumber}>
#
</button>
{Object.keys(glyphProps).map((key) => (
<button
type="button"
title={glyphProps[key].label}
key={key}
onClick={() => this.update(key)}
>
{key}
</button>
))}
</div>
<pre className="properties">{JSON.stringify({ link1 }, 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>