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

cytoscape-tidytree

v0.2.0

Published

Cytoscape.js layout extension for positioning trees

Downloads

987

Readme

cytoscape-tidytree

A Cytoscape.js layout extension for tree layouts which allows for variable sizes of nodes while using a non-layered tree layout and moving nodes further down than its siblings. Uses van der Ploeg's extension of the Reingold-Tilford algorithm from the paper Drawing Non-layered Tidy Trees in Linear Time.

Demo

All demos are available on GitHub Pages

Download

Both bundled and unbundled files are available:

  • ./dist for files bundled by esbuild
    • ./dist/cytoscape-tidytree.js
    • ./dist/cytoscape-tidytree.min.js
  • ./lib for unbundled files compiled by tsc as ES module
    • Entrypoint ./lib/index.js

npm

npm install cytoscape-tidytree

CDN

Preferably use jsdelivr.

    <script src="https://cdn.jsdelivr.net/npm/cytoscape-tidytree/dist/cytoscape-tidytree.js"></script>

You can also use any other CDN which can serve npm packages automatically.

Direct download

Available in Releases

Import

Browser

<script src="./cytoscape.min.js"></script>
<script src="./cytoscape-tidytree.js"></script>

The extension is automatically registered into Cytoscape.js

Node

import cytoscape from "cytoscape";
import tidytree from "cytoscape-tidytree";
cytoscape.use(tidytree);

Usage

Call the layout method and run on the returned layout object:

cy.layout({ name: "tidytree" }).run()

You can also run the layout only for some nodes and edges:

// collection of nodes and edges with the "tree" class
const elesToLayout = cy.$(".tree")

// run the layout as if elesToLayout were the only elements in the graph
elesToLayout.layout({ name: "tidytree" }).run()

Options

options = {
    name: "tidytree",
    horizontalSpacing: 20,
    verticalSpacing: 40,
}

// run layout with the options specified
cy.layout(options).run()

Following options are currently available:

class DefaultOptions implements TidytreeLayoutOptions {

    //** Needed to for the layout to be called from cytoscape */
    name: "tidytree" = "tidytree" as const;

    /**
     * Specific layout options
     */

    dataOnly: boolean = false;       // when enabled, nodes' positions aren't set, only data is calculated
    horizontalSpacing: number = 20;  // the width of the space between nodes in cytoscape units
    verticalSpacing: number = 40;    // the height of the space between parent and child in cytoscape units

    // an object from node's id to how much space should be added between it and its parent
    extraVerticalSpacings: Record<string, number> = {};

    // an object from node's id to how much space should be added for the node to have this y position
    // overrides extraVerticalSpacings if both are set for a particular node
    // if the y position would result in the child not being below the parent, the setting is ignored and a warning is printed
    customYs: Record<string, number> = {};

    // the width of the space left after a node is moved down
    lineWidth: number = 5;

    // forces nodes to be positioned on multiples of this value if set
    layerHeight: number | undefined = undefined;

    // a sorting function for the children array of the tree representation
    // if undefined, the order is based on the order of the collection the layout was called on
    edgeComparator: ((edgeA: EdgeSingular, edgeB: EdgeSingular) => number) | undefined = undefined;

    // when not changed, the width and height of each node is read directly from the node
    // this parameter allows to supply your own sizes
    // if the h or w property is missing from the returned object, it is taken from the node
    sizeGetter: ((node: NodeSingular) => { w?: number, h?: number }) = () => ({});

    /**
     * Layout options passed to nodes.layoutPositions()
     * https://js.cytoscape.org/#nodes.layoutPositions
     */

    fit: boolean = true;   // if true, fits the viewport to the graph
    padding: number = 30;  // the padding between the viewport and the graph on fit
    pan: Position | undefined = undefined;  // pan to a specified position, ignored if fit is enabled
    zoom: number | undefined = undefined;   // how much to zoom the viewport, ignored if fit is enabled

    // a positive value which adjusts spacing between nodes (>1 means greater than usual spacing)
    spacingFactor: number = 1;

    // allows to transform a given node's position before it is applied
    transform: (node: NodeSingular, position: Position) => Position = (n, p) => p;


    animate: boolean = false;         // animate the layout`s changes
    animationDuration: number = 500;  // duration of the animation in ms
    animationEasing: Css.TransitionTimingFunction | undefined = undefined;  // easing of animation

    // returns true for nodes that should be animated, or false when the position should be set immediately
    animateFilter: (node: NodeSingular, index: number) => boolean = () => true;
    ready: ((e: LayoutEventObject) => void) | undefined = undefined;  // callback for the start of the layout
    stop: ((e: LayoutEventObject) => void) | undefined = undefined;   // callback for the layout`s finish

    /**
     * Layout options passed to node.layoutDimensions()
     * https://js.cytoscape.org/#node.layoutDimensions
     */
    nodeDimensionsIncludeLabels: boolean = true;  // if overflowing labels should count in the width or height of the node
}

Build from source

git clone [email protected]:chuckzel/cytoscape-tidytree.git
cd ./cytoscape-tidytree
npm install

npm run prepare will run automatically and build all .js and .d.ts files.

After that, you can use one of:

npm run build  # builds for development (no minified version)
npm run build:all  # builds everything
npm run watch  # runs "build" task in watch mode

For more see scripts in package.json.

See also

PLOEG, Atze van der. Drawing non-layered tidy trees in linear time. Software: Practice and Experience. 2014, vol. 44, no. 12, pp. 1467–1484. Available from doi: 10.1002/spe.2213.

  • d3-flextree - A D3.js plugin using the same algorithm
  • AEON Client - An example of advanced usage and the project for which this library was developed