Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
ts-graphviz
Advanced tools
The ts-graphviz package is a TypeScript library for creating and manipulating Graphviz graphs. It provides a fluent API to build and render graphs programmatically, making it easier to generate complex diagrams and visualizations.
Creating a Graph
This feature allows you to create a directed graph with nodes and edges. The code sample demonstrates how to create a simple graph with two nodes, 'A' and 'B', and an edge from 'A' to 'B'.
const { digraph } = require('ts-graphviz');
const g = digraph('G', (g) => {
g.node('A');
g.node('B');
g.edge(['A', 'B']);
});
console.log(g.toDot());
Customizing Nodes and Edges
This feature allows you to customize the appearance of nodes and edges. The code sample shows how to set the color of a node, change the shape of another node, and add a label to an edge.
const { digraph } = require('ts-graphviz');
const g = digraph('G', (g) => {
g.node('A', { color: 'red' });
g.node('B', { shape: 'box' });
g.edge(['A', 'B'], { label: 'A to B' });
});
console.log(g.toDot());
Subgraphs
This feature allows you to create subgraphs within a graph. The code sample demonstrates how to create two subgraphs, each with its own nodes and edges, and then connect nodes from different subgraphs.
const { digraph, subgraph } = require('ts-graphviz');
const g = digraph('G', (g) => {
g.subgraph('cluster_0', (s) => {
s.node('A');
s.node('B');
s.edge(['A', 'B']);
});
g.subgraph('cluster_1', (s) => {
s.node('C');
s.node('D');
s.edge(['C', 'D']);
});
g.edge(['A', 'C']);
});
console.log(g.toDot());
The graphviz package is a Node.js wrapper for the Graphviz graph visualization software. It allows you to create and render graphs using the Graphviz DOT language. Compared to ts-graphviz, it is more focused on providing a direct interface to Graphviz's capabilities and may require more manual handling of DOT syntax.
The viz.js package is a JavaScript library that provides a way to render Graphviz graphs in the browser using WebAssembly. It allows you to generate and display graphs directly in web applications. Compared to ts-graphviz, viz.js is more suitable for client-side rendering and visualization.
The d3-graphviz package is a D3-based library for rendering Graphviz graphs in the browser. It integrates with the D3.js ecosystem, allowing for interactive and dynamic graph visualizations. Compared to ts-graphviz, d3-graphviz is more focused on web-based visualizations and interactivity.
ts-graphviz
package provides models and ASTs for the Graphviz DOT language fully integrated with TypeScript.
This package can then be installed using a package manager.
# npm
$ npm install -S ts-graphviz
# or yarn
$ yarn add ts-graphviz
# or pnpm
$ pnpm add ts-graphviz
Note Want to try before installing? Check out Runkit to see how it works.
Deno v1.28 and above supports npm.
You can install and use the package by specifying the following:
import { toDot } from 'npm:ts-graphviz';
This section provides an overview of the package.
For more detailed API specifications, please refer to the comments in the TypeScript type definitions and the document automatically generated based on them.
ts-graphviz
Module 🚩This module provides Model, an interface for working with the DOT language in JavaScript/TypeScript.
Model is designed to be object-oriented and provides classes Digraph
, Graph
, Subgraph
, Node
, and Edge
.
Provides a toDot
function to convert Model to DOT (DOT language string).
import { attribute as _, Digraph, Subgraph, Node, Edge, toDot } from 'ts-graphviz';
const G = new Digraph();
const A = new Subgraph('A');
const node1 = new Node('node1', {
[_.color]: 'red'
});
const node2 = new Node('node2', {
[_.color]: 'blue'
});
const edge = new Edge([node1, node2], {
[_.label]: 'Edge Label',
[_.color]: 'pink'
});
G.addSubgraph(A);
A.addNode(node1);
A.addNode(node2);
A.addEdge(edge);
const dot = toDot(G);
// digraph {
// subgraph "A" {
// "node1" [
// color = "red",
// ];
// "node2" [
// color = "blue",
// ];
// "node1" -> "node2" [
// label = "Edge Label",
// color = "pink",
// ];
// }
// }
You can also add your own implementation by inheriting from the class.
import { Digraph, Node, Edge, EdgeTargetTuple, attribute as _, toDot } from 'ts-graphviz';
class MyCustomDigraph extends Digraph {
constructor() {
super('G', {
[_.label]: 'This is Custom Digraph',
});
}
}
class MyCustomNode extends Node {
constructor(id: string) {
super(`node_${id}`, {
[_.label]: `This is Custom Node ${id}`,
});
}
}
class MyCustomEdge extends Edge {
constructor(targets: EdgeTargetTuple) {
super(targets, {
[_.label]: 'This is Custom Edge',
});
}
}
const digraph = new MyCustomDigraph();
const node1 = new MyCustomNode('A');
const node2 = new MyCustomNode('B');
const edge = new MyCustomEdge([node1, node2]);
digraph.addNode(node1);
digraph.addNode(node2);
digraph.addEdge(edge);
const dot = toDot(digraph);
// digraph "G" {
// label = "This is Custom Digraph";
// "node_A" [
// label = "This is Custom Node A";
// ];
// "node_B" [
// label = "This is Custom Node B";
// ];
// "node_A" -> "node_B" [
// label = "This is Custom Edge";
// ];
// }
with
method) 🧅You can also use the Models Context API to create custom classes for objects generated inside of Graph.
The with
methods of Digraph
, Graph
, and Subgraph
, which are implementations of GraphBaseModel
, are provided to predefine custom models.
const g = new Digraph();
g.with({
Node: MyCustomNode,
Edge: MyCustomEdge,
});
const a = g.createNode('A'); // MyCustomNode
const b = g.createNode('B'); // MyCustomNode
g.createEdge([a, b]); // MyCustomEdge
const dot = toDot(g);
// digraph {
// "node_A" [
// label = "This is Custom Node A";
// ];
// "node_B" [
// label = "This is Custom Node B";
// ];
// "node_A" -> "node_B" [
// label = "This is Custom Edge";
// ];
// }
fromDot
function ⏪The status of this function is ! beta.
The main scenario for using this library is to use the toDot
function, but it also supports conversions in the reverse direction.
By converting DOT to Model, a portion of the code can be written in the DOT language.
const G = fromDot(
`digraph {
node_A [
label = "This is a Label of Node A";
];
}`,
);
G.edge(['node_A', 'node_B']);
const dot = toDot(G)
// digraph {
// "node_A" [
// label = "This is a Label of Node A";
// ];
// "node_A" -> "node_B";
// }
When creating Graph
or Digraph
, you can use Model Factory to provide a notation more similar to the DOT language.
Model also has a declarative API, so you can consistently choose a declarative paradigm.
import { attribute as _, digraph, toDot } from 'ts-graphviz';
const G = digraph('G', (g) => {
const a = g.node('aa');
const b = g.node('bb');
const c = g.node('cc');
g.edge([a, b, c], {
[_.color]: 'red'
});
g.subgraph('A', (A) => {
const Aa = A.node('Aaa', {
[_.color]: 'pink'
});
const Ab = A.node('Abb', {
[_.color]: 'violet'
});
const Ac = A.node('Acc');
A.edge([Aa.port('a'), Ab, Ac, 'E'], {
[_.color]: 'red'
});
});
});
const dot = toDot(G);
// digraph "G" {
// "aa";
// "bb";
// "cc";
// subgraph "A" {
// "Aaa" [
// color = "pink",
// ];
// "Abb" [
// color = "violet",
// ];
// "Acc";
// "Aaa":"a" -> "Abb" -> "Acc" -> "E" [
// color = "red",
// ];
// }
// "aa" -> "bb" -> "cc" [
// color = "red",
// ];
// }
Note Of course, we also provide an API for creating strict mode graphs.
import { strict, toDot } from 'ts-graphviz'; const G = strict.graph(...); const dot = toDot(G); // strict graph { // }
withContext
function ) 💈The withContext
function returns a Model Factory function.
This Model Factory provides a means to replace RootGraphModel
with a custom class, such as Digraph
or Graph
.
This API provides a way to integrate declarative APIs and custom classes.
const { digraph } = withContext({
Digraph: MyCustomDigraph,
Node: MyCustomNode,
Edge: MyCustomEdge,
});
const G = digraph((g) => {
const a = g.node('A'); // MyCustomNode
const b = g.node('B'); // MyCustomNode
g.edge([a, b]); // MyCustomEdge
});
const dot = toDot(g);
// digraph "G" {
// label = "This is Custom Digraph";
// "node_A" [
// label = "This is Custom Node A";
// ];
// "node_B" [
// label = "This is Custom Node B";
// ];
// "node_A" -> "node_B" [
// label = "This is Custom Edge";
// ];
// }
@ts-graphviz/adapter
Module 🔌This module status is .
Provides an interface to run Graphviz dot commands.
Graphviz must be installed so that the dot command can be executed.
Execute the dot command to output a DOT language string to a stream or file.
This module provides the following functions.
toStream
function converts DOT to Stream.
import { toStream } from 'ts-graphviz/adapter';
const dot = `
digraph example {
node1 [
label = "My Node",
]
}
`;
const stream = await toStream(dot, { format: 'svg' });
// Node.js
stream.pipe(process.stdout);
// Deno
await stream.pipeTo(Deno.stdout.writable);
toFile
function
import { toFile } from 'ts-graphviz/adapter';
const dot = `
digraph example {
node1 [
label = "My Node",
]
}
`;
await toFile(dot, './result.svg', { format: 'svg' });
Note Designed to work with Node.js and Deno, Stream is runtime native.
@ts-graphviz/ast
Module 🔢This module status is .
An API is provided to handle ASTs for advanced use.
The following functions are provided as described in the state transition diagram.
fromModel
function converts Model to AST.toModel
function converts AST to Model.stringify
function converts AST to DOT.parse
function to convert from DOT to AST.Note As you can see from the above figure, the
toDot
function provided by thets-graphviz
package is a composite offromModel
andstringify
. ThefromDot
function is a composite ofparse
andtoModel
.
Detailed usage is TODO. Please refer to the TypeScript type definition.
import { parse } from '@ts-graphviz/ast';
const ast = parse(`
digraph example {
node1 [
label = "My Node",
]
}
`);
// {
// type: 'Dot',
// location: {
// start: { offset: 3, line: 2, column: 3 },
// end: { offset: 68, line: 7, column: 1 }
// },
// children: [
// {
// id: {
// value: 'example',
// quoted: false,
// type: 'Literal',
// location: {
// start: { offset: 11, line: 2, column: 11 },
// end: { offset: 18, line: 2, column: 18 }
// },
// children: []
// },
// directed: true,
// strict: false,
// type: 'Graph',
// location: {
// start: { offset: 3, line: 2, column: 3 },
// end: { offset: 67, line: 6, column: 4 }
// },
// children: [
// {
// id: {
// value: 'node1',
// quoted: false,
// type: 'Literal',
// location: {
// start: { offset: 25, line: 3, column: 5 },
// end: { offset: 30, line: 3, column: 10 }
// },
// children: []
// },
// type: 'Node',
// location: {
// start: { offset: 25, line: 3, column: 5 },
// end: { offset: 63, line: 5, column: 6 }
// },
// children: [
// {
// key: {
// value: 'label',
// quoted: false,
// type: 'Literal',
// location: {
// start: { offset: 39, line: 4, column: 7 },
// end: { offset: 44, line: 4, column: 12 }
// },
// children: []
// },
// value: {
// value: 'My Node',
// quoted: true,
// type: 'Literal',
// location: {
// start: { offset: 47, line: 4, column: 15 },
// end: { offset: 56, line: 4, column: 24 }
// },
// children: []
// },
// location: {
// start: { offset: 39, line: 4, column: 7 },
// end: { offset: 57, line: 4, column: 25 }
// },
// type: 'Attribute',
// children: []
// }
// ]
// }
// ]
// }
// ]
// }
The status of this feature is .
With ts-graphviz, you can extend the library's type system to customize graph visualization solutions to meet specific needs.
Note To allow for customization, types are named with the
$
symbol.If you want to extend a type definition in cases not listed below, check the source code to see if you can extend it with
$...
.If not, please create an issue or pull request.
import { $keywords } from '@ts-graphviz/common';
import { toFile } from '@ts-graphviz/adapter';
// 1. Declare the '@ts-graphviz/adapter' module.
declare module '@ts-graphviz/adapter' {
export namespace Layout {
// 2. Define the $values interface in the Layout namespace.
// 3. Inherit from $keywords<'my-custom-algorithm'> and specify the name of the new layout engine in <...>.
export interface $values extends $keywords<'my-custom-algorithm'> {}
}
export namespace Format {
// 4. Define the $values interface in the Format namespace.
// 5. Inherit from $keywords<'mp4'> and specify the name of the new output format in <...>.
export interface $values extends $keywords<'mp4'> {}
}
}
toFile('digraph { a -> b }', '/path/to/file', {
layout: 'my-custom-algorithm',
format: 'mp4',
});
import { $keywords } from '@ts-graphviz/common';
import { digraph, toDot, attribute as _ } from 'ts-graphviz';
// 1. Declare the '@ts-graphviz/common' module.
declare module '@ts-graphviz/common' {
export namespace GraphAttributeKey {
// 2. Define the $values interface in the GraphAttributeKey namespace.
// 3. Inherit from $keywords<'hoge'> and specify the name of the new attribute in <...>.
export interface $values extends $keywords<'hoge'> {}
}
export namespace Attribute {
// 4. Define the $keys interface in the Attribute namespace.
// 5. Inherit from $keywords<'hoge'> and specify the name of the new attribute in <...>.
export interface $keys extends $keywords<'hoge'> {}
// 6. Define the $types interface in the Attribute namespace.
// 7. Specify the new attribute in the key and define its corresponding value in the value.
export interface $types {
hoge: string;
}
}
}
console.log(
toDot(
digraph((g) => {
g.set(_.hoge, 'fuga');
}),
),
);
See ARCHITECTURE.md for more details.
See SECURITY.md for more details.
ts-graphviz
📜Note Let us know that you're using
ts-graphviz
on GitHub Discussions 🙏
Related projects can be found at ts-graphviz GitHub Organization.
The TypeScript/JavaScript ecosystem provides a variety of OSS with the goal of making Graphviz more connected and easier to use.
Thanks goes to these wonderful people (emoji key):
This project follows the all-contributors specification. Contributions of any kind welcome!
The easiest way to contribute is to use the library and star repository.
Feel free to ask questions on GitHub Discussions.
Please register at GitHub Issues.
See CONTRIBUTING.md.
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. Become a sponsor
Thank you to all our backers! 🙏 Become a backer
Please support ts-graphviz on Open Collective or GitHub Sponsors.
Note Even just a dollar is enough motivation to develop 😊
Available as part of the Tidelift Subscription.
The maintainers of ts-graphviz and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open-source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use.
This software is released under the MIT License, see LICENSE.
FAQs
Graphviz library for TypeScript
The npm package ts-graphviz receives a total of 561,774 weekly downloads. As such, ts-graphviz popularity was classified as popular.
We found that ts-graphviz demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.