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

d-svg

v1.7.0

Published

a lightweight script to make directed graph svgs using dagre

Downloads

8

Readme

d-svg

d-svg is a lightweight script to make directed graph svgs using dagre. Dagre itself doesn't have a renderer, just a layout engine, so fills that role. Some more popular renderers are dagre-d3 and cytoscape, but this renderer is much more lightweight, and you may find that it exposes a different set of options. If needed, it also provides a script that will parse a rudimentary grammar for creating directed graphs.

Features

  • supports multiline labels
  • supports clustering
  • supports nested clustering
  • supports nodes as hyperlinks
  • supports customizable node color, node border, edge stroke
  • supports dagre graph options (see the "graph"-related rows of the "Configuring the layout" table here)
  • can turn arrowheads on/off
  • can optionally bold first line
  • can add invisible edges (helpful for manually tweaking the layout of your graph)

Drawbacks

  • only works in your browser for now (no node.js support yet)

How to Use

There are two ways to start making directed graphs. You can specify your graphs using JSON or as a string. See the demo here: https://andrewfulrich.gitlab.io/dagre-svg/

Use a live editor here: https://andrewfulrich.gitlab.io/dagre-svg/editor.html

Specifying graphs with JSON

Include the script along with dagre:

<script src="dagre.min.js"></script>
<script src="d-svg.js"></script>

then specify your nodes, edges, and options:

const nodes={
  iAmANode:'I am a node and this is my label',
  iAmAnotherNode:'I am another node',
  oneMoreNode:'one more node'
}
const edges=[
  ['iAmANode','iAmAnotherNode','I am an edge label'],
  ['oneMoreNode','iAmANode'] // edge labels are optional
]
const options={
  margin:5
}
//optional array of flags to turn edges invisible, each flag corresponds to an element of the edges array
const ghostEdgeFlags=[
  false,
  false,
  true
]

Note that labels can be multiline- line breaks will be detected and honored.

then feed it into createGraph:

const myResultingSVG=createGraph(nodes,edges,options,ghostEdgeFlags)

Specifying graphs with strings

Include dagre, the core script, and the string parser script:

<script src="dagre.min.js"></script>
<script src="d-svg.js"></script>
<script src="parser.js"></script>

then specify your nodes, edges, and options in a string:

const myGraphAsAString=`
margin:5
iAmANode[I am a node and this is my label] ->[I am an edge label] iAmAnotherNode[I am another node]
aNodeWithNoLabel -> iAmANode
iAmInvisiblyConnected _> toThisNode
`;

Each thing is on a different line. (if you want multiline, use the literal characters \n to specify a line break)

  • For options, the key and value are separated by a colon.
  • nodes with arrows to other nodes create an edge, _> arrows are invisible while -> arrows are visible
  • things in square brackets are labels

then parse the string with parseToDiagram and feed it into createGraph:

const myResultingSVG=createGraph(parseString(myGraphAsAString))

Creating Clusters

using JSON, just put the cluster inside the nodes object and give it opts and nodes child objects:

const nodes={
  iAmAnotherNode:'I am another node',
  iAmACluster:{
          opts:{
            label:'I am a Cluster'
          },
          nodes:{
            iAmANode:'I am a node and this is my label',
            oneMoreNode:'one more node',
          }
        }
}

using strings, specify the nodes in the cluster with curly braces, and give the cluster a label:

margin:5
iAmANode[I am a node and this is my label] -> iAmAnotherNode[I am another node]
oneMoreNode -> iAmANode
{oneMoreNode,iAmANode}[I am a Cluster]

To nest clusters, you can give them an id and then include that id in another cluster:

oneMoreNode -> iAmANode
innerCluster{oneMoreNode,iAmANode}[I am a Cluster]
anotherNode
{innerCluster,anotherNode}

Clusters Can Override Options

As of version 1.2, you can specify options at the cluster level in addition to the graph level. This allows you to, say, have nodes in a cluster be a different color than nodes outside it.

using JSON, just put your options inside the cluster opts:

const nodes={
  iAmAnotherNode:'I am another node',
  iAmACluster:{
          opts:{
            label:'I am a Cluster',
            nodeColor:'#FFcccc'
          },
          nodes:{
            iAmANode:'I am a node and this is my label',
            oneMoreNode:'one more node',
          }
        }
}

using strings, use parentheses after a cluster definition with comma-separated options like so:

margin:5
nodeColor:#ccccFF
iAmANode[I am a node and this is my label] -> iAmAnotherNode[I am another node]
oneMoreNode -> iAmANode
{oneMoreNode,iAmANode}[I am a Cluster](margin:10,nodeColor:#ccFFcc)

Nodes as Hyperlinks

To make a node into a clickable link, you need to specify the url associated with that node.

In JSON, add it to the urls object in the options object:

const options={
  urls:{
    iAmANode:'http://www.example.com',
    oneMoreNode:'http://www.example.com/coolStuff'
  }
}

using strings, specify the url in parens after the label:

iAmANode[I am a node and this is my label](http://www.example.com) -> iAmAnotherNode[I am another node]

Graph Display Options

| option | description | default | |---------------|---------------------------------------------------------------------|---------| | margin | the node margin size in pixels | 0 | | nodeColor | the color of the nodes | #FFF | | nodeBorder | whether or not to have a border on your nodes | false | | edgeColor | color of the edges | #000 | | edgeOpacity | opacity of the edges | 1 | | hasArrows | whether the edges should have an arrowhead | true | | edgeWidth | the width of the edges, in pixels | 1 | | arrowSize | size of the arrowhead, in pixels | 6 | | boldFirstLine | whether to bold the first line of the node, useful if it is a title | false | | urls | a mapping of nodes to their urls- only for JSON, not for strings | | | autoWrapLength | the maximum number of characters on a line in a node before it is word-wrapped (set to false for no word wrapping) | 50 | | cornerRadius | the radius of a corner if you want rounded corners. Can also be "pill" for a pill shape (rx=width/2) or "ellipse" (rx=width/2, ry=height/2) for an ellipse shape | 3 | | graphOpts | any dagre graph options you want (see the dagre wiki) | | | showIds | show the id of each node in its upper-left corner. Useful when you have a big graph and forget which node has which id. | false |l

Custom Options for Specific Nodes

If you want specific nodes to have custom styles, you can use the last optional parameter in createGraph, which takes a map of node name to option object, like so:

nodeOptions:{
  myNode1:{
    nodeColor:'#FFFFFF'
  },
  myNode2:{
    nodeColor:'#000000'
  }
}

Specifying as a string looks like this:

<myNode1>(nodeColor:#FFFFFF)
<myNode2,myNode3>(nodeColor:#000000)

Note you can specify multiple nodes at once when using the string option.