backbone-and-d3 icon indicating copy to clipboard operation
backbone-and-d3 copied to clipboard

Backbone.js + D3.js

Backbone.js + D3.js

D3.js has quickly become the visualization kernel for data visualization on the web, and Backbone.js is an MV* framework used frequently for its flexibility and ease-of-use.

D3 is a low-level framework for creating data-driven documents, which has empowered developers to create highly bespoke and unique data visualizations. D3 development is not without downside, however, as development typically entails considerable refactoring when attempting to apply a similar design framework in different data contexts.

Recently, the idea of reusable charts has gained considerable traction. The primary aim is to develop a consistent chart API to facilitate code reuse and modularity. While several efforts have attempted to create reusable chart APIs building atop D3, most of these have followed a similar functional (and declarative) paradigm, as originally outlined by Mike Bostock, D3's principle maintainer. This approach has its merits, allowing a consistent API through closures.

Nevertheless, the closure approach requires that we first define exactly what can and what cannot be accessible. Once defined, the result is a monolithic function encompassing all behavior and the only way of changing behavior is by directly modifying the source code. In contrast, we may prefer an approach which permits extensibility, similar to that which we find in OOP paradigm class hierarchies.

Backbone provides such facilities through its `extend' method. Hence, we may ask whether we can leverage Backbone and D3 to create a framework which explicitly separates concerns pertaining to data models and views and explicitly addresses the layered nature of statistical graphics.


Models

Several models form the basis for a chart.

  • DataPoint: the atomic data unit, even if not actually displayed, e.g., in a line chart.
  • DataSeries: extends the DataPoint model to manage a collection of data points, i.e., a data series. This is the primary unit for a line chart.
  • ChartModel: this is a ViewModel which contains meta data related to the View representation, such as chart margins, axis labels, transition parameters, etc.
  • DataCollection: the array of Models to be translated into graphical units. For a line chart, the collection is of data series.

Views

Views correspond to chart layers. Each additional layer within a hierarchy extends the Views of layers below. This makes the implementation more modular and provides flexibility to include layers (functionality) only as needed.

Layers

Multiple layers comprise a chart.

  • Chart Base: the layer which creates the base canvas and defines chart dimensions
    • this layer exists as 'ChartBase'
  • Chart Area: the layer which creates axes (lines, ticks, labels) and specifies the x and y scales
    • this layer exists as 'ChartArea'
  • Line Chart: the layer which actually plots the data
    • this layer exists as 'DataLayer'
  • Annotations: the layer which provides chart annotations, e.g., title, caption, data labels, etc.
    • this layer exists as 'AnnotationLayer'
  • Listeners: a meta-layer which coordinates model updates and corresponding view changes
    • this layer exists as 'ListenerLayer'
  • Interaction: the layer which enables user interaction, e.g., providing additional context upon hover
    • this layer exists as 'InteractionLayer'
  • Animation: the layer which introduces transition animations for various lifecycle events
    • this layer exists as 'AnimationLayer'

Classes

Classes are assigned within each chart layer, providing a more direct API for CSS and JS targeting.

  • base: canvas layer, i.e., the SVG element
  • chart: chart layer, i.e., the SVG group element holding all chart contents
  • axis: axes layer, which is further classed by
    • x: x axis
    • y: y axis
  • label: axes labels
  • title: chart title
  • caption: chart caption
  • data-series: the group of data sets plotted, even if only 1 data set
  • line: the SVG path element for an individual data series, which is further classed in order of generation
    • line0: first line
    • line1: second line
    • ...
    • line(M-1): mth line

Dependencies

This implementation uses multiple libraries/frameworks.


References

Several works have influenced this implementation. In no particular order:


Copyright

Copyright (c) 2013. Kristofer Gryte. License: MIT