npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

graph-data-structure

v4.3.0

Published

A graph data structure with topological sort.

Downloads

939,699

Readme

graph-data-structure

A graph data structure with topological sort.

This library provides a minimalist implementation of a directed graph data structure. Nodes are represented by unique strings or any other object. Internally, an adjacency list is used to represent nodes and edges.

The primary use case for this library is in implementing dataflow programming or reactive programming. The key algorithm necessary for these is topological sorting, to get an ordering of nodes such that for each edge (u -> v), u comes before v in the sorted order. The topological sorting algorithm exposed here has modifications useful for computing the order in which functions in a data flow graph should be executed, namely specifying source nodes for propagation and specifying to exclude the source nodes themselves from the result.

Table of Contents

Installing

This library is distributed only via NPM. Install by running

npm install graph-data-structure

Require it in your code like this.

import {
  Graph,
  serializeGraph,
  deserializeGraph,
  topologicalSort,
  shortestPath,
} from 'graph-data-structure';

Examples

ABC

Start by creating a new Graph object.

var graph = new Graph();

Add some nodes and edges with addNode and addEdge.

graph.addNode('a');
graph.addNode('b');
graph.addEdge('a', 'b');

Nodes are added implicitly when edges are added.

graph.addEdge('b', 'c');

Now we have the following graph.

Topological sorting can be done by invoking the standalone function topologicalSort like this.

topologicalSort(graph); // Returns ["a", "b", "c"]

Getting Dressed

Here's an example of topological sort with getting dressed (from Cormen et al. "Introduction to Algorithms" page 550).

const graph = new Graph();
graph
  .addEdge('socks', 'shoes')
  .addEdge('shirt', 'belt')
  .addEdge('shirt', 'tie')
  .addEdge('tie', 'jacket')
  .addEdge('belt', 'jacket')
  .addEdge('pants', 'shoes')
  .addEdge('underpants', 'pants')
  .addEdge('pants', 'belt');

// prints [ "underpants", "pants", "shirt", "tie", "belt", "jacket", "socks", "shoes" ]
console.log(topologicalSort(graph));

For more detailed example code that shows more methods, have a look at the tests.

API Reference

Creating a Graph

# Graph([serialized])

Constructs an instance of the graph data structure.

The optional argument serialized is a serialized graph that may have been generated by serializeGraph. If serialized is present, it is deserialized by invoking deserializeGraph(mySerializedObject).

Adding and Removing Nodes

# graph.addNode(node)

Adds a node to the graph. Returns graph to support method chaining. If the given node was already added to the graph, this function does nothing.

# graph.removeNode(node)

Removes the specified node. Returns graph to support method chaining. The argument node is a string or object identifier for the node to remove. This function also removes all edges connected to the specified node, both incoming and outgoing.

Note: You have to remove them using the exact same reference as when they were created. One can use getNode() to retrieve such reference.

Adding and Removing Edges

# graph.addEdge(u, v[,weight])

Adds an edge from node u to node v. Returns graph to support method chaining. The arguments u and v are node references (either objects or strings). This function also adds u and v as nodes if they were not already added.

The last argument weight (optional) specifies the weight of this edge.

# graph.removeEdge(u, v)

Removes the edge from node u to node v. Returns graph to support method chaining. The arguments u and v are node references. This function does not remove the nodes u and v. Does nothing if the edge does not exist.

# graph.hasEdge(u, v)

Returns true if there exists an edge from node u to node v. Returns false otherwise.

Working with Edge Weights

# graph.setEdgeWeight(u, v, weight)

Sets the weight (a number) of the edge from node u to node v.

# graph.getEdgeWeight(u, v)

Gets the weight of the edge from node u to node v. If no weight was previously set on this edge, then the value 1 is returned.

Querying the Graph

# graph.adjacent(node)

Gets the adjacent node list for the specified node. The argument node is a node reference (object or string). Returns a Set of adjacent node references or undefined if the node is not found.

Serialization

# serializeGraph(graph)

Serializes the graph. Returns an object with the following properties.

  • nodes An array of objects, each representing a node reference.
  • links An array of objects representing edges, each with the following properties.
    • source The node reference of the source node (u).
    • target The node reference of the target node (v).
    • weight The weight of the edge between the source and target nodes.

Here's example code for serializing a graph.

var graph = new Graph();
graph.addEdge('a', 'b');
graph.addEdge('b', 'c');
var serialized = serializeGraph(graph);

# deserializeGraph(serialized)

Deserializes the given serialized graph. Returns a new graph. The argument serialized is a graph representation with the structure described in serializeGraph.

Graph Algorithms

# topologicalSort(graph)

Performs [Topological Sort](

https://en.wikipedia.org/wiki/Topological_sorting). Returns an array of node identifier strings. The returned array includes nodes in topologically sorted order. This means that for each visited edge (u -> v), u comes before v in the topologically sorted order.

Note: this function raises a CycleError when the input is not a DAG.

# shortestPath(graph, sourceNode, destinationNode)

Performs Dijkstra's Algorithm. Returns an object with two properties: nodes, an array of node references representing the path, and weight, the total weight of the path.

var result = shortestPath(graph, 'a', 'c');
console.log(result.nodes); // Prints the array of nodes in the shortest path
console.log(result.weight); // Prints the total weight of the path