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

networkvizjs

v0.0.6-alpha.3

Published

Draw easy graphs or networks

Downloads

10

Readme

Easy, interactive graphs with networkVizJS

This project is powered by Github 🌟's. Each star matters, thank you!

Examples

... more to come or contribute your own

Why this project exists

Force directed graphs can be a mighty headache especially when trying to dynamically update nodes.

This project aims to abstract away much of the process of drawing a graph leaving you to focus on the things that matter.

Features

  • Dragging.
  • Panning and zooming.
  • Avoid overlapping nodes.
  • Easy interface for adding / removing nodes.
  • Routing the edge lines around nodes.
  • Very stable using Webcola as the layout.
  • Easy handlers that allow you to finely tune the experience for the user.
  • Various layouts supported out of the box:
    • Flow layout for force directed graph (horizontally and vertically)
    • Jaccard layout (where denser node regions spread out)
    • Regular layout allowing a fixed or dynamic edge length.
  • An intuitive API which lets you do what you want.

Adding a node is as easy as graph.addNode(<your node object>)!

Development status

In early development but very usable. Contributions in the form of pull requests and issues extremely welcome.

Lets make prototyping graphs faster and more interactive!

Quickstart using Webpack or another bundler

npm install --save networkvizjs

Import the module:

// ES6
import networkVizJS from "networkVizJS";
// commonjs
var networkVizJS = require('networkVizJS').default;

Given we have an div with id graph1, we can initiate a graph in that div using:

const graph = networkVizJS('graph1', options?);

Node must have at least these two properties: Optionally you can define x and y.

var node = {
    hash: "1",
    shortname: "Node1",
}

To define an edge you use a triplet with the shape:

var someEdge = {
    subject: { /* Node to start at */ }
    predicate: { type: "someType" } // This allows different coloured edges.
    object: { /* Node to finish at */ }
}

With the node shape and edge shape we can now add and remove nodes and edges.

Adding and removing nodes

addNode takes a node object or a list of nodes. They'll be immediately drawn to the svg canvas!

let node = {
    hash: "2",
    shortname: "a fun node!",
}
graph.addNode(node);

removeNode just takes a node hash. It deletes the node and all edges that include that node. It also takes an optional callback which triggers when the node is deleted.

// Called after the node with the hash "2" is deleted.
const afterDelete = () => console.log("Node deleted!");
graph.removeNode("2", afterDelete);

Adding and removing triplets (or edges between nodes)

graph.addTriplet(triplet);
graph.removeTriplet(triplet);

You're pretty much good to go! Below is the rest of the API.

Options object:

These options are all optional. Just pass in the ones you want.

interface OptionsObject {
    canDrag: boolean;           // True: You can drag nodes, False: You can't
    databaseName: string;       // Force the database name
    layoutType: string;         // "linkDistance" | "flowLayout" | "jaccardLinkLengths"
    jaccardModifier: number;    // Modifier for jaccardLinkLengths, number between 0 and 1
    avoidOverlaps: boolean;     // True: No overlaps, False: Overlaps
    handleDisconnected: boolean;// False by default, clumps disconnected nodes
    flowDirection: string;      // If flowLayout: "x" | "y"
    enableEdgeRouting: boolean; // Edges route around nodes
    nodeShape: string;          // Set node shape: "rect" | "circle"
    width: number;              // SVG width
    height: number;             // SVG height
    pad: number;
    margin: number;
    nodeDragStart(): void;      // Called when drag event triggers
    edgeLabelText: string | {(d?: any, i?: number): string};    // Todo: EdgeLabels in predicate.

    // mouse handlers on nodes.
    mouseDownNode(nodeObject?: any, d3Selection?: Selection): void;
    mouseOverNode(nodeObject?: any, d3Selection?: Selection): void;
    mouseOutNode(nodeObject?: any, d3Selection?: Selection): void;
    mouseUpNode(nodeObject?: any, d3Selection?: Selection): void;
    clickNode(nodeObject?: any, d3Selection?: Selection): void;

    clickEdge(edgeObject?: any, d3Selection?: Selection): void;
    
    clickAway(): void;          // Triggers on zooming or clicking on the svg canvas.

    // These options allow you to define a selector to create dynamic attributes
    // based on the nodes properties.
    nodeToColor: string | {(d?: any, i?: number): string};     // Return a valid css colour.
    nodeStrokeWidth: number | {(d?: any, i?: number): number};
    nodeStrokeColor: string | {(d?: any, i?: number): string};

    edgeColor: string | {(d?: any, i?: number): string};
    edgeStroke: number | {(d?: any, i?: number): number};
    edgeLength: number | {(d?: any, i?: number): number};
}

Methods on graph object

// Check if node is drawn.
hasNode(nodeHash: string): Boolean
// Public access to the levelgraph db.
getDB(): levelGraphDB
// Get Stringified representation of the graph.
saveGraph(): string
// Get SVG element. If you want the node use `graph.getSVGElement().node();`
getSVGElement(): d3SVGSelection
// add a directed edge
addTriplet(tripletObject, preventLayout?: Boolean)
// remove an edge
removeTriplet(tripletObject),
// EXPERIMENTAL - DON'T USE YET.
mergeNodeToGroup,
// remove a node and all edges connected to it.
removeNode(node),
// add a node or array of nodes.
addNode(node | nodeArray, preventLayout?: Boolean),
// Restart styles or layout.
restart.styles()
restart.layout()

Todo

  • [ ] Batch node and edge updates without layout refreshing
  • [ ] Stabilise API (need help / guidance)
  • [ ] Add svg tests (need help / guidance)
  • [ ] Document full api