Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A parallel coordinates plot in canvas. This is a d3 chart that is unstable and in development.
branch: master

This branch is 195 commits behind syntagmatic:master

Parallel Coordinates

An implementation of parallel coordinates in d3 as a reusable chart








# d3.parcoords(config)

Setup a new parallel coordinates chart.

# parcoords(selector)

Create the chart within a container. The selector can also be a d3 selection.


Add data to the chart by passing in an array of values.

A single value may be either an object or an array. All values should be the same format.

// objects
var foods = [
  {name: "Asparagus", protein: 2.2, calcium: 0.024, sodium: 0.002},
  {name: "Butter", protein: 0.85, calcium: 0.024, sodium: 0.714},
  {name: "Coffeecake", protein: 6.8, calcium: 0.054, sodium: 0.351},
  {name: "Pork", protein: 28.5, calcium: 0.016, sodium: 0.056},
  {name: "Provolone", protein: 25.58, calcium: 0.756, sodium: 0.876}

// arrays
var cube = [
  [0, 0, 0],
  [1, 0, 0],
  [0, 1, 0],
  [1, 1, 0],
  [0, 0, 1],
  [1, 0, 1],
  [0, 1, 1],
  [1, 1, 1]

# parcoords.render()

Renders the polylines.

If no dimensions have been specified, it will attempt to detect quantitative dimensions based on the first data entry. If scales haven't been set, it will autoscale based on the extent for each dimension.

# parcoords.dimensions(dimensions)

If dimensions is specified, sets the quantitative dimensions to be visualized. The format is an array of dimension names. This will update the xscale domain, but will not trigger re-rendering of lines or axes.

var dimensions = ['protein', 'calcium', 'sodium'];

If no dimensions are specified, then it returns the currently set dimensions.

# parcoords.types(object)

If types is specified, sets the data types for the dimensions. The format is an object where the keys are dimension names and the values are type strings.

For example:

var types = {
  "name": "string",
  "protein": "number",
  "calcium": "number"

If no types are specified, then it returns the currently set types.

Detected types are automatically populated by detectDimensions using d3.parcoords.detectDimensionTypes.

# parcoords.color(color)

If a color is a string, polylines will be rendered as that color. If color is a function, that function will be run for each data element and the polyline color will be the return value.

To set all lines to a transparent green:


TODO: function example

If no color is specified, then it returns the currently set color.

# parcoords.state()

Returns an object which contains the state of the chart. This is particularly useful for debugging with a JavaScript console.

# parcoords.state

Exposes the public state of parallel coordinates. Useful for debugging in a JavaScript console. Avoid modifying values directly, instead use methods such as to update the state.

The design of this object is experimental and contributed by Ziggy Jonsson. Read more at this d3-js mailing list discussion.

When the public state is updated through a method, an event will fire.

# parcoords.createAxes()

Create static SVG axes with dimension names, ticks, and labels.

# parcoords.removeAxes()

Remove SVG axes.

# parcoords.updateAxes()

Update SVG axes. Call this after updating the dimension order.

# parcoords.brushable()

Enable brushing of axes. Automatically creates axes if they don't exist.

Click and drag vertically on an axis line to create a brush. The brush is both draggable and resizeable.

To delete an axis, click the axis line (behind the brush extent).

The behavior is identical to that of the original d3.js parallel coordinates.

# parcoords.brushed()

For brushable plots, returns the selected data.

# parcoords.brushReset()

TODO. This is supposed to reset all brushes, but may not work presently.

# parcoords.reorderable()

Enable reordering of axes. Automatically creates axes if they don't exist.

The behavior is identical to that of the original reorderable d3.js parallel coordinates.

# parcoords.axisDots()

Mark the points where polylines meet an axis with dots.

# parcoords.shadows()

Active greyed-out background shadows.

# parcoords.width()


# parcoords.height()


# parcoords.margin()

  top: 100,
  left: 0,
  right: 0,
  bottom: 20

# parcoords.composite()

Change foreground context's globalCompositeOperation

  • source-over
  • source-in
  • source-out
  • source-atop
  • destination-over
  • destination-in
  • destination-out
  • destination-atop
  • lighter
  • darker
  • xor
  • copy

# parcoords.alpha()

Change the opacity of the polylines, also the foreground context's globalAlpha.

# parcoords.autoscale()

Set the xscale, yscale, and canvas sizes. Usually this is called automatically, such as on render() or resize() events

# parcoords.mode(type)

Toggle the rendering mode. Currently there are two options:

  • "default" renders instantaneously, but is less responsive with more than ~2000 rows of data
  • "queue" puts the data in a queue, and renders progressively. This way the user can interact with the chart during rendering.

# parcoords.rate(integer)

Change the number of lines drawn each frame when the rendering mode is set to "queue". Some suggested values for different machines are:

  • Mobile phone or iPad: 12-30
  • Normal PC with Firefox: 20-60
  • Normal PC with Chrome/Safari: 30-100
  • Fast PC with Chrome/Safari: 100-300

In the future, an automatic rate adjuster will be included to optimize this number on-the-fly.

# parcoords.detectDimensions()

Set the quantative dimensions using based on the first row of data.

# parcoords.highlight([values])

Pass an array of data to overlay the data on the chart, masking the foreground.

# parcoords.unhighlight([values])

Clear the highlighting layer. This is equivalent to calling parcoords.clear("highlight").

# parcoords.interactive()

Activate interactive mode for use with a JavaScript console. The concept is that for each method that modifies a chart, everything that needs to happen to update the rendered chart will run automatically.

Currently this only affects adding/removing/reordering dimensions. Normally the chart must be re-rendered and axes updated:


In interactive mode, just specify the new dimensions array.


# parcoords.clear(layer)

Clear the layer, which could be "foreground", "shadows", "marks", "extents" or "highlight".

# parcoords.canvas

An object containing the canvas elements.

# parcoords.ctx

An object containing the canvas 2d rendering contexts. Use this to modify canvas rendering styles, except for the foreground stroke which is controlled by parcoords.color().

# parcoords.on(event, listener)

Trigger a listener when an event fires. The value of this in the listener refers to parcoords. The data passed into the listener depends on type of event:

  • "render" returns no data
  • "resize" returns an object containing the width, height and margin
  • "highlight" returns the highlighted data
  • "brush" returns the brushed data

When values in the state are updated through methods, an event of the same name fires (except height, width and margin which fire resize). The data passed into the listener is an object containing the new value, value, and the old value, previous.

Custom values must be passed into the original chart config to register events.

  • "dimensions"
  • "data"
  • "color"
  • "composite"
  • "alpha"


The following methods are available from d3.svg.axis: ticks, orient, tickValues, tickSubdivide, tickSize, tickPadding, tickFormat.


This library created with examples, suggestions and encouragement from Mike Bostock, Jason Davies, Mary Becica, Stephen Boak, Ziggy Jonsson, Ger Hobbelt, Johan Sundström, Raffael Marty, Hugo Lopez, Bob Monteverde, Vadim Ogievetsky, Chris Rich, Patrick Martin, and Alfred Inselberg.

Something went wrong with that request. Please try again.