HTMLGraph logo HTMLGraph

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@5.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:

  • name is a text content of a node
  • x and y are node’s coordinates,
  • frontPortId and backPortId are 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);

    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.

Basic example