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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@dbx/vizcomp

v3.1.0

Published

Nighthawk Visual Composition Library

Readme

APX Charting Library

The APX Charting Library is a javascript library that allows its users to compose custom interactive data visualizations quickly using common components in a flexible and extensible way.

Development notes

Release a new version of the module

This module is versioned using semantic versioning. When releasing a new version of the module, you must determine whether to bump the PATCH, MINOR, or MAJOR version number.

  • If the changes include only bug fixes, bump the patch number. Run make release-patch
  • If the changes include new features, but the module is still backwards compatible with previous versions, bump the minor number. Run make release-minor.
  • If the changes break backwards compatibility, bump the major number. Run make release-major.

These make targets will do several things:

  1. Modify package.json, setting the new version number.
  2. Commit the changes to package.json.
  3. Tag the commit with the new version number.
  4. Push the new commit (and tag) to the remote.

Once this module is published on the public npm registry, these commands will be updated to also run npm publish.

Goals

  1. Satisfy the needs of Nighthawk.
  2. Be flexible enough to meet the needs of other APX projects.
  3. Be flexible enough to meet the needs of many other projects in the world. (What does this really mean? Be able to compose NY Times style visualizations that have nice interactivity properties including resizing, handling mouse events, real-time updates of data.)

Principles

  1. Decoupled panel sizing logic from drawing logic.
  2. Declarative constraints for sizing panels.
  3. Declarative specification of mouse event interactivity.
  4. Reactive to real-time data updates.

Library Components

Composition

A composition is the base of a top level component that can be used externally. For example, from a composition, one can build a nicely styled bar chart with axes, labels, and interactivity (e.g. good behavior on resizing and mouse hover events on bars). The main data that a composition encapsulates is a node graph where the nodes represent various panels to be displayed as well as models for visualization elements. (I note that a node representing a panel displaying a y-axis is distinct from a node representing the model for a y-axis.) Nodes can be added and removed from a composition's node graph and constraints (edges) can be specified. The constraints specify data dependencies between nodes. The node graph is used to propagate the arrival of new data, mark dirty nodes, and manage the render order of nodes.

Composition()
composition.addNode(node)
composition.removeNode(node)
composition.addConstraint(dependentNodeId, independentNodeIds, constraintObject)
composition.setData(nodeId, dataObject)
composition.render()

NODE_TYPE

There are two different types of nodes, DATA and RENDER. Render nodes are used to display something on the screen. Currently the only render type node is a panel. When rendering to the screen, first a pre-compute function is called on each render node. (This pre-computation is required to not depend on any other node). Second, a compute function is called on each node in a topologically sorted order such that any constraint on a node has its dependencies already computed. Any node can depend on a pre-computed value and this dependency is not specified as a constraint on the node graph. Data nodes do not have a pre-compute function. It only has a compute function. When a data node receives new data, it triggers the compute function down to its dependents stopping before any render nodes.

NODE_TYPE.DATA
NODE_TYPE.RENDER

Node

Node(id)
node.id
node.type
node.dependents
node.constraints
node.preComputeObject
node.computeFunction
node.preCompute()
node.compute()

Container::Node

Container(id, element)
container.width
container.height
container.element

Panel::Node

Panel()
panel.x
panel.y
panel.width
panel.height
panel.render
panel.parent
panel.initElement()

NestedMultiplesLabels::Node

NestedMultiplesLabels()

Chart::Node

Chart()

BarChart::Chart

BarChart()

Axis::Node

Axis()

Gridlines::Node

GridLines()

Highlights::Node

Highlights()

Scale::Node

Scale()

Example

Nodes

container
y-axis-panel
x-axis-panel
horizontal-bar-chart-panel
y-axis
x-axis
horizontal-bar-chart
y-scale
x-scale

Constraints

PreCompute
container.width
container.height
y-axis-panel.width
x-axis-panel.height
Compute
y-axis-panel.height <- container.height - x-axis-panel.height
y-axis-panel.x <- 0
y-axis-panel.y <- 0
y-axis-panel.render <- y-axis
x-axis-panel.width <- container.width - y-axis-panel.width
x-axis-panel.x <- y-axis-panel.width
x-axis-panel.y <- y-axis-panel.height
x-axis-panel.render <- x-axis
horizontal-bar-chart-panel.height <- y-axis-panel.height
horizontal-bar-chart-panel.width <- x-axis-panel.width
horizontal-bar-chart-panel.x <- y-axis-panel.width
horizontal-bar-chart-panel.y <- 0
y-axis.scale <- y-scale.scale
x-axis.scale <- x-scale.scale
horizontal-bar-chart.y-scale <- y-scale.scale
horizontal-bar-chart.x-scale <- x-scale.scale

Topological Sort Order

  1. y-scale
  2. x-scale
  3. y-axis
  4. x-axis
  5. horizontal-bar-chart
  6. container
  7. y-axis-panel
  8. x-axis-panel
  9. horizontal-bar-chart-panel

Other Notions

LayoutStyle

NonLayoutStyle

State

StateStream

Event

EventStream