Getting Started
First, include the library in your project and create a canvas. You have several options:
1. Install via npm
npm i @html-graph/html-graph
Then use it:
<div id="canvas"></div>
import { CanvasBuilder } from "@html-graph/html-graph";
const element = document.getElementById('canvas');
const canvas = new CanvasBuilder(element).build();
2. Use script from CDN as ES module
<div id="canvas"></div>
<script type="module">
import { CanvasBuilder } from "https://unpkg.com/@html-graph/html-graph@6.0.0";
const element = document.getElementById('canvas');
const canvas = new CanvasBuilder(element).build();
</script>
3. Use local file as ES module
Download html-graph.js from releases and use:
<div id="canvas"></div>
<script type="module">
import { CanvasBuilder } from "/html-graph.js";
const element = document.getElementById('canvas');
const canvas = new CanvasBuilder(element).build();
</script>
4. Use local file as UMD
Download html-graph.umd.cjs from releases and use:
<div id="canvas"></div>
<script src="/html-graph.umd.cjs"></script>
<script>
const element = document.getElementById('canvas');
const canvas = new HtmlGraph.CanvasBuilder(element).build();
</script>
The next part will guide you through graph visualization step-by-step. If you prefer to see the final implementation first, you can jump directly to the end result and explore the details afterwards.
Now that we’ve initialized the canvas, let’s define a proper application structure. Usage of ES6 classes helps to organize code:
class Application {
constructor(element) {
this.canvas = new CanvasBuilder(element)
.build();
}
initGraph() {
// the graph will be initialized there
}
}
const element = document.getElementById("canvas");
const app = new Application(element);
app.initGraph();
Also we need to add some basic CSS so that we have a full screen canvas.
html,
body {
height: 100%;
padding: 0;
margin: 0;
}
body {
position: relative;
}
#canvas {
position: absolute;
inset: 0;
}
At this point everything is ready for graph visualization. Lets create a basic node. For this purpose we create a method, that returns a data structure, which is expected in addNode method.
The createNode method of Application class accepts parameters:
nameis a text content of a nodexandyare node’s coordinates,frontPortIdandbackPortIdare port identifiers.
Port is a proxy element via which nodes are connected. It provides more flexibility at managing edges, unlike connecting nodes directly (although node element itself can be used as a port at the same time).
class Application {
// ...
createNode({ name, x, y, frontPortId, backPortId }) {
const node = document.createElement("div");
const text = document.createElement("div");
const frontPort = document.createElement("div");
const backPort = document.createElement("div");
node.classList.add("node");
frontPort.classList.add("node-port");
backPort.classList.add("node-port");
text.innerText = name;
node.appendChild(frontPort);
node.appendChild(text);
node.appendChild(backPort);
// this data structure is expected in canvas.addNode method
return {
element: node,
x: x,
y: y,
ports: [
{ id: frontPortId, element: frontPort },
{ id: backPortId, element: backPort },
],
};
}
}
Also here is some CSS so that our nodes look nice:
.node {
display: flex;
justify-content: space-between;
align-items: center;
width: 100px;
height: 100px;
background: #daedbd;
border: 1px solid #9e9e9e;
box-shadow: 0 0 5px #9e9e9e;
border-radius: 50%;
user-select: none;
}
.node-port {
position: relative;
width: 0;
}
.node-port::after {
content: "";
position: absolute;
top: -3px;
left: -3px;
width: 6px;
height: 6px;
background: #777777;
border-radius: 3px;
}
Nodes are fully customizable using HTML and CSS.
It’s time to use created method in initGraph.
class Application {
// ...
initGraph() {
this.canvas
.addNode(
this.createNode({
name: "Node 1",
x: 200,
y: 200,
frontPortId: "node-1-in",
backPortId: "node-1-out",
}),
)
.addNode(
this.createNode({
name: "Node 2",
x: 600,
y: 300,
frontPortId: "node-2-in",
backPortId: "node-2-out",
}),
);
}
// ...
}
At this point we have two nodes, but they are not connected. To connect them we will use addEdge method. It accepts identifiers of source port and target port.
class Application {
// ...
initGraph() {
this.canvas
.addNode(
this.createNode({
name: "Node 1",
x: 200,
y: 200,
frontPortId: "node-1-in",
backPortId: "node-1-out",
}),
)
.addNode(
this.createNode({
name: "Node 2",
x: 600,
y: 300,
frontPortId: "node-2-in",
backPortId: "node-2-out",
}),
)
.addEdge({ from: "node-1-out", to: "node-2-in" });
}
// ...
}
We can customize edges, for example we can add a target arrow.
This can be done using setDefaults method of CanvasBuilder.
class Application {
constructor(element) {
this.canvas = new CanvasBuilder(element)
.setDefaults({
edges: {
shape: {
hasTargetArrow: true,
}
}
})
.build();
}
// ...
}
But the resulted graph is static. We can enable transformable viewport, draggable nodes and other features. Refer to Features for all available features.
class Application {
constructor(element) {
this.canvas = new CanvasBuilder(element)
.setDefaults({
edges: {
shape: {
hasTargetArrow: true,
}
}
})
.enableUserTransformableViewport()
.enableUserDraggableNodes()
.enableBackground()
.build();
}
// ...
}
The end result is presented below.
Every example in this documentation is a single HTML page, so you can copy/paste the implementation, and it will work immediately.