Skip to content

vizdom-dev/vizdom

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

19 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vizdom

Vizdom is a declarative graph layout and rendering engine compiled from Rust to WebAssembly using wasm-pack. It provides an API for creating and rendering directed graphs and producing SVGs.

Goals

  • πŸ’Ύ Low memory footprint
  • πŸŽ‰ No system dependencies
  • πŸš€ Fastest layout and rendering engine powered by WebAssembly
  • πŸ”₯ Works in any client / server configuration

Features

  • πŸ› οΈ Create and manipulate directed graphs.
  • πŸ”€ Handles multiple edges with the same source and target nodes.
  • πŸ”„ Render cyclical directed graphs.
  • 🎨 Support various custom rendering attributes for enhanced visualization.

Installation

Vizdom comes in several distributions:

  • esm (Modern)
  • node (CJS)
  • web (Browser)

Simply select a distribution and install using your favorite package manager following the saming convention @vizdom/vizdom-ts-<dist>.

npm install @vizdom/vizdom-ts-esm
pnpm install @vizdom/vizdom-ts-esm
yarn install @vizdom/vizdom-ts-esm
bun install @vizdom/vizdom-ts-esm

🚴 Usage

In the most basic configuration, all you need is to provide labels for nodes and edges.

import { DirectedGraph } from "@vizdom/vizdom-ts-esm";
// ... or CJS
// const { DirectedGraph } = require("@vizdom/vizdom-ts-node");

// Create a new graph
const graph = new DirectedGraph();

// Add vertices
const v0 = graph.new_vertex({
  render: {
    label: "Hello",
  },
});
const v1 = graph.new_vertex({
  render: {
    label: "World!",
  },
});

// Add an edge between the vertices
graph.new_edge(v0, v1, {
  render: {
    label: "Foo Bar",
  },
});

// Position the graph
const positioned = graph.layout();

// Finally, obtain to an SVG
await fs.writeFile("./graph.svg", positioned.to_svg().to_string());

Check out the basic example, which produces a graph that looks like:

this

☁️ Online Mode

Vizdom offers an online mode that effortlessly syncs your graph with your Vizdom account, eliminating the need for manual positioning and rendering. This ensures your graph is always up-to-date with your latest code changes.

To get started with syncing, sign up for an account.

Once you have an account, syncing your graph is straightforward. Simply add a few additional parameters when constructing your graph:

const graph = new DirectedGraph(
  {}, // <-- Optional layout and render attributes.
  // Must be specified as the second argument.
  {
    client_id: process.env.VIZDOM_CLIENT_ID || "",
    client_secret: process.env.VIZDOM_CLIENT_SECRET || "",
    graph_id: process.env.VIZDOM_GRAPH_ID || "",
  }
);

By specifying these parameters when creating your graph, you can easily manage multiple graphs within the same project, each syncing independently.

Layout Engine

Vizdom can be used as a pure layout engine to obtain positioning information, which is especially useful if you already have a method for rendering your graph.

Specifying Layout Parameters

To use Vizdom for layout purposes, you need to provide the bounding box dimensions. If you are using the library in a browser context, you can retrieve these dimensions by using methods like getBoundingClientRect() on the HTML element. Compute the shape_w (width) and shape_h (height) and pass them as layout parameters.

Additionally, there's an optional argument, compute_bounding_box, which can be set to false. This tells the library to use the provided layout values for the bounding box instead of computing it from the label attribute. By default, the shape is considered to be a Shape.Rectangle for nodes and Shape.Plaintext for edges (which is also a rectangle) and should remain unchanged in this context.

Providing IDs

Each vertex and edge requires an id to map the JSON result correctly. The resulting JSON string will include these IDs, enabling accurate mapping of the nodes and edges.

// ...
const v0 = graph.new_vertex(
  {
    layout: {
      shape_w: 10,
      shape_h: 10,
    },
    render: {
      id: "v0",
    },
  },
  {
    compute_bounding_box: false,
  }
);

// ...

// Similarly, for an edge you have the same API.
const e0 = graph.new_edge(
  v0,
  v1,
  {
    layout: {
      shape_w: 10,
      shape_h: 10,
    },
    render: {
      id: "e1",
    },
  },
  {
    compute_bounding_box: false,
  }
);

// Position the graph
const positioned = graph.layout();

// Obtain the json instance
const json = positioned.to_json();

// Get a JS/TS Object adhereing to the `IJsonPosition` interface.
const jsonObj = json.to_obj();

// Or get the JSON string directly
const jsonString: string = json.to_string();
// const jsonStringPretty: string = json.to_string_pretty();

For a practical example, check out the json example, which generates a positional JSON string similar to this.

Styling Attributes

Vizdom supports several layout and rendering options for those who want more control over the appearance of their graphs.

const v0 = graph.new_vertex({
  render: {
    label: "Foo",
    color: "#ff2f8e",
    fill_color: "#ff2f8eaa",
    shape: Shape.Triangle,
    style: VertexStyle.Dashed,
  },
});

Check out the style example, which produces a graph that looks like:

this

DOT Language Support

Vizdom offers partial support for the DOT language, commonly used for defining graphs. Most styling attributes are supported; however, please note that undirected diagrams are currently not parsed. Additionally, while DOT files may specify layout engines, Vizdom will always use its own layout engine for positioning.

The parser fully supports cluster graphs, allowing for subgraph IDs with the cluster_ prefix or subgraph statements containing a cluster=true attribute.

Unsupported styles are gracefully ignored, defaulting to safe visual options to ensure smooth rendering.

import { DotParser } from "@vizdom/vizdom-ts-esm";
// ... or CJS
// const { DotParser } = require("@vizdom/vizdom-ts-node");

// Create a new Dot Parser
const parser = new DotParser();
const dotGraph = parser.parse("digraph { a -> b }");
const directedGraph = dotGraph.to_directed();
const positioned = directedGraph.layout();

// Once positioned, the graph can be exported as SVG or JSON.
await fs.writeFile("./graph.svg", positioned.to_svg().to_string());
const jsonObj = positioned.to_json().to_obj();
console.log(
  util.inspect(jsonObj, { showHidden: false, depth: null, colors: true })
);

Check out the dot example, which produces a graph that looks like:

this

You may also sync a parsed DOT to your Vizdom account by specifying the options like the following:

// ...
const parser = new DotParser({
  client_id: process.env.VIZDOM_CLIENT_ID || "",
  client_secret: process.env.VIZDOM_CLIENT_SECRET || "",
  graph_id: process.env.VIZDOM_GRAPH_ID || "",
});
const dotGraph = parser.parse("digraph { a -> b }");
// Sync complete!

Once synced to Vizdom, there's no need to manually convert the parsed AST to a directed graph (to_directed()), apply layout (layout()) nor rendering (to_svg(), to_json()) methods. These processes are automatically handled in the browser when viewing your graph.

πŸ“ˆ Diff Viewer πŸ“‰

You can visually compare two graphs with Vizdom. Ensure that the id attributes are set and unique to track changes effectively. The resulting graphs will be annotated with a 'glow' effect to highlight differences:

  • ❌ Removed elements (id no longer exists) are highlighted in red.
  • βœ… Added elements (id is new) are highlighted in green.
  • 🟧 Modified elements (id is the same, but other attributes have changed) are highlighted in orange.

Check out the diff example, which produces two graphs that look like:

graph 0

and

graph 1

License

Licensed under the Apache License, Version 2.0. See the LICENSE file or visit https://www.apache.org/licenses/LICENSE-2.0

Third Party Licenses

This project makes use of third-party components, each with its own licensing terms:

  • Dagre.js: Some of the layout algorithms in this project are inspired by Dagre.js, which is licensed under the MIT License. The full license text can be found in the third_party/dagre/LICENSE file.

  • NotoSans Font: The NotoSans font used in this project is licensed under the SIL Open Font License. The full license text can be found in the third_party/noto_sans/LICENSE file.

  • Others: Can be found in the third_party/licenses.html file.

Closed-Source Notice

Please note that while Vizdom is freely available for use under the Apache License 2.0, the Rust WebAssembly binary included in this library is closed-source. You are free to use the library, but the source code for the Rust WebAssembly binary is not publicly available.

Releases

No releases published

Packages

No packages published