Development notesRelease 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
- If the changes include new features, but the module is still backwards compatible with previous versions, bump the minor number. Run
- If the changes break backwards compatibility, bump the major number. Run
maketargets will do several things:
package.json, setting the new version number.
- Commit the changes to
- Tag the commit with the new version number.
- 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
- Satisfy the needs of Nighthawk.
- Be flexible enough to meet the needs of other APX projects.
- 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.)
- Decoupled panel sizing logic from drawing logic.
- Declarative constraints for sizing panels.
- Declarative specification of mouse event interactivity.
- Reactive to real-time data updates.
CompositionA 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()
NODETYPEThere 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(id) node.id node.type node.dependents node.constraints node.preComputeObject node.computeFunction node.preCompute() node.compute()
Container(id, element) container.width container.height container.element
Panel() panel.x panel.y panel.width panel.height panel.render panel.parent panel.initElement()
container y-axis-panel x-axis-panel horizontal-bar-chart-panel y-axis x-axis horizontal-bar-chart y-scale x-scale
container.width container.height y-axis-panel.width x-axis-panel.height
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