HTMLGraph

Getting Started

Use one of the following options to include the library into your project:

Install NPM package
    
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();

  
Paste the content into HTML
    
<div id="canvas"></div>
<script type="module">
  import { CanvasBuilder } from "https://unpkg.com/@html-graph/html-graph@8.5.0";

  const element = document.getElementById("canvas");
  const canvas = new CanvasBuilder(element).build();
</script>

  
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>

  
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 section explains how to achieve the result shown below. It demonstrates a basic configuration consisting of two nodes connected by an edge. Additionally, it configures transformable viewport, draggable nodes, and background.

While you may opt to review the complete implementation right away, for those seeking a structured approach, follow these sequential steps: Initialization, Adding Nodes, Adding Edges, and Enabling Features


1. Initialization #

As a basis for our application, we will use this simple template. It defines a full-screen canvas and an Application class.

    
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <style>
      html,
      body {
        height: 100%;
        padding: 0;
        margin: 0;
      }

      body {
        position: relative;
      }

      #canvas {
        position: absolute;
        inset: 0;
      }
    </style>
  </head>
  <body>
    <div id="canvas"></div>
    <script type="module">
      import { CanvasBuilder } from "https://unpkg.com/@html-graph/html-graph@8.5.0";

      class Application {
        constructor(element) {
          this.canvas = new CanvasBuilder(element)
            .build();
        }

        initGraph() {
          // the graph will be initialized here
        }
      }

      const element = document.getElementById("canvas");
      const app = new Application(element);

      app.initGraph();
    </script>
  </body>
</html>

  

2. Adding Nodes #

Nodes can be added using the addNode method. This method accepts a specific object, which needs to be constructed first. For this purpose, we add a createNode method to the Application class.

    
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 },
      ],
    };
  }
}

  

The createNode method accepts parameters:

  • name is the text content of a node,
  • x and y are the node’s coordinates,
  • frontPortId and backPortId are port identifiers.

A port is a proxy element through which nodes are connected. It provides more flexibility for managing edges.

* The node element can also be used as a port element simultaneously.

Here’s some CSS to make 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 the 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",
        })
      );
  }

  // ...
}

  

3. Adding Edges #

To connect these two nodes, the addEdge method can be used. It accepts the identifiers of the source port and the 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" });
  }

  // ...
}

  

Edges can be customized, for instance, by adding a target arrow. This can be achieved using the setDefaults method of CanvasBuilder.

    
class Application {
  constructor(element) {
    this.canvas = new CanvasBuilder(element)
      .setDefaults({
        edges: {
          shape: {
            hasTargetArrow: true,
          },
        },
      })
      .build();
  }

  // ...
}

  

Refer to the Defaults page for all available options.


4. Enabling Features #

HTMLGraph supports numerous useful features, including:

  • transformable viewport
  • draggable nodes
  • background rendering
  • and many more …

These features can be enabled by invoking their corresponding methods on the CanvasBuilder instance, like so:

    
class Application {
  constructor(element) {
    this.canvas = new CanvasBuilder(element)
      .setDefaults({
        edges: {
          shape: {
            hasTargetArrow: true,
          },
        },
      })
      .enableUserTransformableViewport()
      .enableUserDraggableNodes()
      .enableBackground()
      .build();
  }

  // ...
}

  

Refer to Features for all available options.