UNPKG

d2b

Version:

A d3-based reusable chart library.

81 lines (66 loc) 1.96 kB
import { range } from 'd3-array'; import { set } from 'd3-collection'; import { stack as d3Stack } from 'd3-shape'; import base from '../model/base'; // d2b.stack will stack the x and y values in place for // some datum and d3.stack configuration. export default function () { const $$ = {}; const stack = function (datum) { const original = datum; // for simplicity map datum to just array of values arrays datum = datum.map($$.values); // format values to be in the form // [ // {x_1: y_1, x_2: y_2, .. }, // {x_1: y_1, x_2: y_2, .. }, // .. // ] let xset = []; let vals = datum.map(d => { const nodes = {}; d.forEach((d, i) => { const x = $$.x.call(this, d, i); xset.push(x); nodes[x] = $$.y.call(this, d, i); }); return nodes; }); // find unique set of x values xset = set(xset).values(); // value => index mapping of x values let xmap = xset.reduce(function(o, v, i) { o[v] = i; return o; }, {}); // graph keys (just use index) let keys = range(0, datum.length); // transpose values for d3.stack let tvals = xset.map(col => vals.map(row => row[col] || 0)); // stack transposed values $$.stack .keys(keys) .value((d, k) => d[k] || 0); let stacking = $$.stack(tvals); // reassociate the stacked values with the original datum datum.forEach((d, i) => { d.forEach((val, ind) => { const x = $$.x.call(this, val, ind); const ys = stacking[i][xmap[x]]; $$.out.call(this, val, ys[0], ys[1], x); }); }); return original; }; /* Inherit from base model */ base(stack, $$) .addProp('stack', d3Stack()) .addPropFunctor('values', d => d) .addPropFunctor('x', d => d.x) .addPropFunctor('y', d => d.y) .addProp('out', (d, y0, y1) => { d.y0 = y0; d.y1 = y1; }); return stack; }