Getting Started
Getting started with Graphly D3 is easy. This is a step-by-step guide to get you started with Graphly D3 and create your first template.
And feel free to checkout Graphly Hub to get inspired by other templates. It is currently in closed beta but you are welcome to take a look and see how we and others use Graphly D3 and its template system.
Step 1: Create a new project
The first step is to create a new web project with the tooling you want to use. You just need to install the npm package for graphly-d3
.
npm install @livereader/graphly-d3
Your DOM has to contain a <svg>
element that will be used to render the force-directed graph.
<svg id="mySVG" width="100%" height="100%"></svg>
Step 2: Embed Graphly D3
In your script you need to import the ForceSimulation
class from graphly-d3
. Instantiate a new ForceSimulation
and pass it the <svg>
element you want to render the graph in.
You will also want to import the style.css
file from the graphly-d3
package. This provides the necessary styles for the graph visualization.
// app.js
import { ForceSimulation } from "@livereader/graphly-d3";
import "@livereader/graphly-d3/style.css";
const mySVG = document.getElementById("mySVG");
const simulation = new ForceSimulation(mySVG);
Step 3: Create a template
Now create a new file containing your template code and add it to the ForceSimulation
templateStore
.
// hexagon.js
export default {
shapeSize: 120,
shapeBuilder: shapeBuilder,
};
function shapeBuilder(data, Template) {
const { Shape, SVGShape, TextCollection, CollectionStyle, ShapeStyle, Alignment, OnZoom, LODStyle } = Template;
const shape = SVGShape(`
<g transform="matrix(1,0,0,1,-101.915,-40.1924)">
<g transform="matrix(8.33117e-17,-1.36058,1.36058,8.33117e-17,9.05891,870.52)">
<path id="path" d="M384.617,88.155C406.11,75.826 432.531,75.826 454.023,88.155C488.394,107.873 540.748,137.906 575.236,157.69C596.908,170.123 610.273,193.199 610.273,218.184L610.273,356.483C610.273,381.468 596.908,404.544 575.236,416.977C540.748,436.761 488.394,466.794 454.023,486.512C432.531,498.841 406.11,498.841 384.617,486.512C350.246,466.794 297.892,436.761 263.405,416.977C241.733,404.544 228.367,381.468 228.367,356.483L228.367,218.184C228.367,193.199 241.733,170.123 263.405,157.69C297.892,137.906 350.246,107.873 384.617,88.155Z" />
</g>
</g>
`);
shape.select("path").style("fill", data.payload?.color ?? "#9575cd");
const bbox = Shape.getBBox(shape);
const titleShape = TextCollection(
data.payload?.title ?? "",
CollectionStyle(200, bbox.width * 0.8, bbox.width * 0.1, bbox.height * 0.45, 10, 10, 2, Alignment.Center),
[ShapeStyle("class", "gly_text.light"), ShapeStyle("font-size", "5em")]
);
shape.append(() => titleShape.node());
OnZoom(data, [0.6], [LODStyle(titleShape, "class", "hidden", (k) => k < 0.6)]);
return shape;
}
// app.js
import Hexagon from "./hexagon";
simulation.templateStore.add("hexagon", Hexagon);
Step 4: Create a graph
Now create a graph object that contains the nodes and links following the required format. To render this graph you need to call the render()
method of the ForceSimulation
instance and pass the graph object as an argument.
const graph = {
nodes: [
{
id: "node1",
shape: {
type: "hexagon",
scale: 1,
},
x: -150,
y: 30,
payload: {
title: "",
color: "#9575cd",
},
},
{
id: "node2",
shape: {
type: "hexagon",
scale: 1,
},
x: 150,
y: -30,
payload: {
title: "",
color: "#9575cd",
},
},
],
links: [
{
source: "node1",
target: "node2",
directed: true,
strength: "weak",
},
],
};
simulation.render(graph);
That's it! This should render a graph with two nodes and a link between them.
Full Example
<!-- index.html -->
<html>
<head>
<title>Graphly D3</title>
</head>
<body>
<svg id="mySVG" width="100%" height="100%"></svg>
<script src="./app.js" type="module"></script>
</body>
</html>
// app.js
import { ForceSimulation } from "@livereader/graphly-d3";
import "@livereader/graphly-d3/style.css";
import Hexagon from "./hexagon";
const mySVG = document.getElementById("mySVG");
const simulation = new ForceSimulation(mySVG);
simulation.templateStore.add("hexagon", Hexagon);
const graph = {
nodes: [
{
id: "node1",
shape: {
type: "hexagon",
scale: 1,
},
x: -150,
y: 30,
payload: {
title: "",
color: "#9575cd",
},
},
{
id: "node2",
shape: {
type: "hexagon",
scale: 1,
},
x: 150,
y: -30,
payload: {
title: "",
color: "#9575cd",
},
},
],
links: [
{
source: "node1",
target: "node2",
directed: true,
strength: "weak",
},
],
};
simulation.render(graph);
// hexagon.js
export default {
shapeSize: 120,
shapeBuilder: shapeBuilder,
};
function shapeBuilder(data, Template) {
const { Shape, SVGShape, TextCollection, CollectionStyle, ShapeStyle, Alignment, OnZoom, LODStyle } = Template;
const shape = SVGShape(`
<g transform="matrix(1,0,0,1,-101.915,-40.1924)">
<g transform="matrix(8.33117e-17,-1.36058,1.36058,8.33117e-17,9.05891,870.52)">
<path id="path" d="M384.617,88.155C406.11,75.826 432.531,75.826 454.023,88.155C488.394,107.873 540.748,137.906 575.236,157.69C596.908,170.123 610.273,193.199 610.273,218.184L610.273,356.483C610.273,381.468 596.908,404.544 575.236,416.977C540.748,436.761 488.394,466.794 454.023,486.512C432.531,498.841 406.11,498.841 384.617,486.512C350.246,466.794 297.892,436.761 263.405,416.977C241.733,404.544 228.367,381.468 228.367,356.483L228.367,218.184C228.367,193.199 241.733,170.123 263.405,157.69C297.892,137.906 350.246,107.873 384.617,88.155Z" />
</g>
</g>
`);
shape.select("path").style("fill", data.payload?.color ?? "#9575cd");
const bbox = Shape.getBBox(shape);
const titleShape = TextCollection(
data.payload?.title ?? "",
CollectionStyle(200, bbox.width * 0.8, bbox.width * 0.1, bbox.height * 0.45, 10, 10, 2, Alignment.Center),
[ShapeStyle("class", "gly_text.light"), ShapeStyle("font-size", "5em")]
);
shape.append(() => titleShape.node());
OnZoom(data, [0.6], [LODStyle(titleShape, "class", "hidden", (k) => k < 0.6)]);
return shape;
}
Expected Result
After you are done with these simple steps, your result should look something like this:
INFO
Take a look at the Tutorial to learn more about how to use Graphly D3 or dig deeper into the documentation on the Data Structure, Simulation API and Template API.