HTMLGraph

Custom Edge Shape (advanced)

When built-in edge shapes are insufficent, it is possible to provide a custom edge shape.

The following example demonstrates implementation of a custom edge shape using TypeScript.

    
import { EdgeShape, EdgeRenderParams } from "@html-graph/html-graph";

class MyCustomEdgeShape implements EdgeShape {
  readonly svg: SVGSVGElement;

  private readonly line: SVGPathElement;

  constructor() {
    this.svg = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "svg",
    );

    this.svg.style.pointerEvents = "none";
    this.svg.style.position = "absolute";
    this.svg.style.top = "0";
    this.svg.style.left = "0";
    this.svg.style.overflow = "visible";

    this.line = document.createElementNS(
      "http://www.w3.org/2000/svg",
      "path",
    );

    this.line.setAttribute("stroke", "#777777");
    this.line.setAttribute("stroke-width", "1");
    this.line.setAttribute("fill", "none");
    this.line.classList.add("custom-line");

    this.svg.appendChild(this.line);
  }

  render(params: EdgeRenderParams): void {
    const { from, to } = params;

    const centerFrom = {
      x: from.x + from.width / 2,
      y: from.y + from.height / 2,
    };

    const centerTo = {
      x: to.x + to.width / 2,
      y: to.y + to.height / 2,
    };

    const x = Math.min(centerFrom.x, centerTo.x);
    const y = Math.min(centerFrom.y, centerTo.y);
    const width = Math.abs(centerTo.x - centerFrom.x);
    const height = Math.abs(centerTo.y - centerFrom.y);

    this.svg.style.width = `${width}px`;
    this.svg.style.height = `${height}px`;
    this.svg.style.transform = `translate(${x}px, ${y}px)`;

    const fromPoint = { x: centerFrom.x - x, y: centerFrom.y - y };
    const toPoint = { x: centerTo.x - x, y: centerTo.y - y };

    const linePath = `M ${fromPoint.x} ${fromPoint.y} L ${toPoint.x} ${toPoint.y}`;

    this.line.setAttribute("d", linePath);
  }
}

  

As shown above, any custom edge shape must implement the EdgeShape interface.

This interface requires:

  • public property svg, which stores edge svg element
  • method render, which updates svg property based on provided parameters

A custom edge shape can be provided via a factory function in the setDefaults method of CanvasBuilder.

    
const element = document.getElementById("canvas");

const canvas = new CanvasBuilder(element)
  .setDefaults({
    edges: {
      shape: (edgeId) => new MyCustomEdgeShape(),
    },
  })
  .build();

  

You can also apply a custom shape to a specific edge using the addEdge and updateEdge methods.

    
canvas.addEdge({
  from: "port-1",
  to: "port-2",
  shape: new MyCustomEdgeShape(),
});

  
    
canvas.updateEdge("edge-1", {
  shape: new MyCustomEdgeShape(),
});