• Stars
    star
    120
  • Rank 295,983 (Top 6 %)
  • Language
    JavaScript
  • License
    BSD 3-Clause "New...
  • Created about 8 years ago
  • Updated almost 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Create lines that indicate where data is missing with gaps or differently styled chunks/line segments.

d3-line-chunked

npm version

A d3 plugin that renders a line with potential gaps in the data by styling the gaps differently from the defined areas. It also provides the ability to style arbitrary chunks of the defined data differently. Single points are rendered as circles and transitions are supported.

Blog: Showing Missing Data in Line Charts

Demo: http://peterbeshai.com/vis/d3-line-chunked/

d3-line-chunked-demo

Example Usage

var lineChunked = d3.lineChunked()
  .x(function (d) { return xScale(d.x); })
  .y(function (d) { return yScale(d.y); })
  .curve(d3.curveLinear)
  .defined(function (d) { return d.y != null; })
  .lineStyles({
    stroke: '#0bb',
  });

d3.select('svg')
  .append('g')
    .datum(lineData)
    .transition()
    .duration(1000)
    .call(lineChunked);

Example with multiple lines

var lineChunked = d3.lineChunked()
  .x(function (d) { return xScale(d.x); })
  .y(function (d) { return yScale(d.y); })
  .defined(function (d) { return d.y != null; })
  .lineStyles({
    stroke: (d, i) => colorScale(i),
  });

var data = [
  [{ 'x': 0, 'y': 42 }, { 'x': 1, 'y': 76 }, { 'x': 2, 'y': 54 }],
  [{ 'x': 0, 'y': 386 }, { 'x': 1 }, { 'x': 2, 'y': 38 }, { 'x': 3, 'y': 192 }],
  [{ 'x': 0, 'y': 325 }, { 'x': 1, 'y': 132 }, { 'x': 2 }, { 'x': 3, 'y': 180 }]
];

// bind data
var binding = d3.select('svg').selectAll('g').data(data);

// append a `<g>` for each line
var entering = binding.enter().append('g');

// call lineChunked on enter + update
binding.merge(entering)
  .transition()
  .call(lineChunked);

// remove `<g>` when exiting
binding.exit().remove();

Development

Get rollup watching for changes and rebuilding

npm run watch

Run a web server in the example directory

cd example
php -S localhost:8000

Go to http://localhost:8000

Installing

If you use NPM, npm install d3-line-chunked. Otherwise, download the latest release.

Note that this project relies on the following d3 features and plugins:

If you are using transitions, you will also need:

The only thing not included in the default d3 v4 build is the plugin d3-interpolate-path. You'll need to get that separately.

API Reference

# d3.lineChunked()

Constructs a new generator for chunked lines with the default settings.

# lineChunked(context)

Render the chunked line to the given context, which may be either a d3 selection of SVG containers (either SVG or G elements) or a corresponding d3 transition. Reads the data for the line from the datum property on the container.

# lineChunked.x([x])

Define an accessor for getting the x value for a data point. See d3 line.x for details.

# lineChunked.y([y])

Define an accessor for getting the y value for a data point. See d3 line.y for details.

# lineChunked.curve([curve])

Get or set the d3 curve factory for the line. See d3 line.curve for details. Define an accessor for getting the curve value for a data point. See d3 line.curve for details.

# lineChunked.defined([defined])

Get or set defined, a function that given a data point (d) returns true if the data is defined for that point and false otherwise. This function is important for determining where gaps are in the data when your data includes points without data in them.

For example, if your data contains attributes x and y, but no y when there is no data available, you might set defined as follows:

// sample data
var data = [{ x: 1, y: 10 }, { x: 2 }, { x: 3 }, { x: 4, y: 15 }, { x: 5, y: 12 }];

// returns true if d has a y value set
function defined(d) {
  return d.y != null;
}

It is only necessary to define this if your dataset includes entries for points without data.

The default returns true for all points.

# lineChunked.isNext([isNext])

Get or set isNext, a function to determine if a data point follows the previous. This function enables detecting gaps in the data when there is an unexpected jump.

For example, if your data contains attributes x and y, and does not include points with missing data, you might set isNext as follows:

// sample data
var data = [{ x: 1, y: 10 }, { x: 4, y: 15 }, { x: 5, y: 12 }];

// returns true if current datum is 1 `x` ahead of previous datum
function isNext(previousDatum, currentDatum) {
  var expectedDelta = 1;
  return (currentDatum.x - previousDatum.x) === expectedDelta;
}

It is only necessary to define this if your data doesn't explicitly include gaps in it.

The default returns true for all points.

# lineChunked.transitionInitial([transitionInitial])

Get or set transitionInitial, a boolean flag that indicates whether to perform a transition on initial render or not. If true and the context that lineChunked is called in is a transition, then the line will animate its y value on initial render. If false, the line will appear rendered immediately with no animation on initial render. This does not affect any subsequent renders and their respective transitions.

The default value is true.

# lineChunked.extendEnds([[xMin, xMax]])

Get or set extendEnds, an array [xMin, xMax] specifying the minimum and maximum x pixel values (e.g., xScale.range()). If defined, the undefined line will extend to the values provided, otherwise it will end at the last defined points.

# lineChunked.accessData([accessData])

Get or set accessData, a function that specifies how to map from a dataset entry to the array of line data. This is only useful if your input data doesn't use the standard form of [point1, point2, point3, ...]. For example, if you pass in your data as { results: [point1, point2, point3, ...] }, you would want to set accessData to data => data.results. For convenience, if your accessData function simply accesses a key of an object, you can pass it in directly: accessData('results') is equivalent to accessData(data => data.results).

The default value is the identity function data => data.

# lineChunked.lineStyles([lineStyles])

Get or set lineStyles, an object mapping style keys to style values to be applied to both defined and undefined lines. Uses syntax similar to d3-selection-multi.

# lineChunked.lineAttrs([lineAttrs])

Get or set lineAttrs, an object mapping attribute keys to attribute values to be applied to both defined and undefined lines. The passed in lineAttrs are merged with the defaults. Uses syntax similar to d3-selection-multi.

The default attrs are:

{
  fill: 'none',
  stroke: '#222',
  'stroke-width': 1.5,
  'stroke-opacity': 1,
}

# lineChunked.gapStyles([gapStyles])

Get or set gapStyles, an object mapping style keys to style values to be applied only to undefined lines. It overrides values provided in lineStyles. Uses syntax similar to d3-selection-multi.

# lineChunked.gapAttrs([gapAttrs])

Get or set gapAttrs, an object mapping attribute keys to attribute values to be applied only to undefined lines. It overrides values provided in lineAttrs. The passed in gapAttrs are merged with the defaults. Uses syntax similar to d3-selection-multi.

The default attrs are:

{
  'stroke-dasharray': '2 2',
  'stroke-opacity': 0.2,
}

# lineChunked.pointStyles([pointStyles])

Get or set pointStyles, an object mapping style keys to style values to be applied to points. Uses syntax similar to d3-selection-multi.

# lineChunked.pointAttrs([pointAttrs])

Get or set pointAttrs, an object mapping attr keys to attr values to be applied to points (circles). Note that if fill is not defined in pointStyles or pointAttrs, it will be read from the stroke color on the line itself. Uses syntax similar to d3-selection-multi.

# lineChunked.chunk([chunk])

Get or set chunk, a function that given a data point (d) returns the name of the chunk it belongs to. This is necessary if you want to have multiple styled chunks of the defined data. There are two reserved chunk names: "line" for the default line for defined data, and "gap" for undefined data. It is not recommended that you use "gap" in this function. The default value maps all data points to "line".

For example, if you wanted all points with y values less than 10 to be in the "below-threshold" chunk, you could do the following:

// sample data
var data = [{ x: 1, y: 5 }, { x: 2, y: 8 }, { x: 3, y: 12 }, { x: 4, y: 15 }, { x: 5, y: 6 }];

// inspects the y value to determine which chunk to use.
function chunk(d) {
  return d.y < 10 ? 'below-threshold' : 'line';
}

# lineChunked.chunkLineResolver([chunkLineResolver])

Get or set chunkLineResolver, a function that decides what chunk the line should be rendered in when given two adjacent defined points that may or may not be in the same chunk via chunk(). The function takes three parameters:

  • chunkNameLeft (String): The name of the chunk for the point on the left
  • chunkNameRight (String): The name of the chunk for the point on the right
  • chunkNames (String[]): The ordered list of chunk names from chunkDefinitions

It returns the name of the chunk that the line segment should be rendered in. By default it uses the order of the keys in the chunkDefinition object..

For example, if you wanted all lines between two different chunks to use the styling of the chunk that the left point belongs to, you could define chunkLineResolver as follows:

// always take the chunk of the item on the left
function chunkLineResolver(chunkNameA, chunkNameB, chunkNames) {
  return chunkNameA;
}

# lineChunked.chunkDefinitions([chunkDefinitions])

Get or set chunkDefinitions, an object mapping chunk names to styling and attribute assignments for each chunk. The format is as follows:

{
  chunkName1: {
    styles: {},
    attrs: {},
    pointStyles: {},
    pointAttrs: {},
  },
  ...
}

Note that by using the reserved chunk names "line" and "gap", you can accomplish the equivalent of setting lineStyles, lineAttrs, gapStyles, gapAttrs, pointStyles, and pointAttrs individually. Chunks default to reading settings defined for the chunk "line" (or by lineStyles, lineAttrs), so you can place base styles for all chunks there and not have to duplicate them.

Full multiple chunks example:

const lineChunked = d3.lineChunked()
  .defined(function (d) { return d[1] !== null; })
  .chunkDefinitions({
    line: {
      styles: {
        stroke: '#0bb',
      },
    },
    gap: {
      styles: {
        stroke: 'none'
      }
    },
    'below-threshold': {
      styles: {
        'stroke-dasharray': '2, 2',
        'stroke-opacity': 0.35,
      },
      pointStyles: {
        'fill': '#fff',
        'stroke': '#0bb',
      }
    }
  })
  .chunk(function (d) { return d[1] < 2 ? 'below-threshold' : 'line'; });

More Repositories

1

use-query-params

React Hook for managing state in URL query parameters with easy serialization.
TypeScript
2,133
star
2

tidy

Tidy up your data with JavaScript, inspired by dplyr and the tidyverse
TypeScript
723
star
3

d3-interpolate-path

Interpolates path `d` attribute smoothly when A and B have different number of points.
JavaScript
315
star
4

react-url-query

A library for managing state through query parameters in the URL in React
JavaScript
195
star
5

3dpie

gaudy 3d pie generator in react and three.js
JavaScript
115
star
6

serialize-query-params

A javascript library for simplifying encoding and decoding URL query parameters
TypeScript
71
star
7

vis-utils

A collection of utility functions for helping with data visualization
JavaScript
51
star
8

linked-highlighting-react-vega-redux

Example of doing linked highlighting with React, Vega, and Redux
JavaScript
51
star
9

react-express-example

A basic example of using Express and Facebook's React for both client-side and server-side rendering.
JavaScript
45
star
10

p5js-ccapture

An example of using p5.js with CCapture.js for exporting frames
HTML
44
star
11

deckgl-point-animation

Demo of animating points in deck.gl
JavaScript
40
star
12

linked-highlighting-react-d3-reflux

An example of doing linked highlighting using React, d3.js and Reflux
JavaScript
39
star
13

d3-scale-interactive

An interactive UI for editing d3 v4 scales in your browser
JavaScript
36
star
14

react-map-demo

Created for ReactJS Boston Meetup, a demo of using react-map-gl and deck.gl to draw a basic map with some different layers.
JavaScript
30
star
15

react-taco-table

A table component for React based on column configuration ๐ŸŒฎ
JavaScript
30
star
16

react-basic-vis-examples

A few basic visualization examples that build on each other, using React and D3.js.
JavaScript
28
star
17

react-computed-props

A higher-order component for React to add computed or derived props to the wrapped component for better performance.
JavaScript
26
star
18

peterbeshai.com

HTML
15
star
19

cra-snowpack

Example of using Snowpack's dev server in a Create-React-App app
JavaScript
12
star
20

beshai-makes-code

Code for BeshaiMakes.com Articles
HTML
8
star
21

shots3D

Render basketball shots from the NBA using WebGL
JavaScript
6
star
22

recreating-the-past

Sketches for the Recreating the Past class at the MIT Media Lab (Fall 2019)
C++
5
star
23

stats

Examples for doing stats on experimental data
R
4
star
24

geo-explore

Simple demonstrative examples of mapping techniques for the web
HTML
3
star
25

d3-webpack-loader

Automatically bundle D3 v4 modules under a single `d3` import with D3 Webpack Loader.
JavaScript
3
star
26

rhombus

Rhombus Classroom Synchronous Participation System
Shell
2
star
27

react-library-starter

A starting place for creating a React library or component to share with others
JavaScript
2
star
28

react-autosize

Component to automatically provide width and height props to its child
JavaScript
2
star
29

react-auto-width

Set the width of a Reactjs component to its parent's width
JavaScript
2
star
30

nba-draft

JavaScript
2
star
31

rhombus-id-server

ID Server for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
32

rhombus-web-app-basic

Barebones Web App for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
33

rhombus-web-app-game-theory

Web App with Game Theory games for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
34

rhombus-clicker-server

Clicker Server for Rhombus Classroom Synchronous Participation System
Java
1
star
35

tree-csv

Explore a CSV containing hierarchical data as a tree
JavaScript
1
star
36

rhombus-web-framework

Web Framework for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
37

rhombus-web-app-experiment

Web App for 7-Segment Display Recognition Experiment for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
38

protoweb

Web prototype scaffolding and hot-reloading server
JavaScript
1
star
39

rhombus-web-app-sandbox

Sandbox for various apps for Rhombus Classroom Synchronous Participation System
JavaScript
1
star
40

rhombus-clicker-server-filter-multiple-instructor

Multiple Instructor filter for the Clicker Server for Rhombus Classroom Synchronous Participation System
Java
1
star
41

rhombus-grunt-socket-server

HTTP/Socket.io server used by Rhombus Classroom Synchronous Participation System
JavaScript
1
star