dc.js Source: series-chart.js (original) (raw)
/**
A series chart is a chart that shows multiple series of data overlaid on one chart, where the
series is specified in the data. It is a specialization of Composite Chart and inherits all
composite features other than recomposing the chart.
Examples:
- {@link http://dc-js.github.io/dc.js/examples/series.html Series Chart}
@class seriesChart
@memberof dc
@mixes dc.compositeChart
@example
// create a series chart under #chart-container1 element using the default global chart group
var seriesChart1 = dc.seriesChart("#chart-container1");
// create a series chart under #chart-container2 element using chart group A
var seriesChart2 = dc.seriesChart("#chart-container2", "chartGroupA");
@param {String|node|d3.selection} parent - Any valid
{@link https://github.com/d3/d3-selection/blob/master/README.md#select d3 single selector} specifying
a dom block element such as a div; or a dom element or d3 selection.
@param {String} [chartGroup] - The name of the chart group this chart instance should be placed in.
Interaction with a chart will only trigger events and redraws within the chart's group.
@returns {dc.seriesChart} */ dc.seriesChart = function (parent, chartGroup) { var _chart = dc.compositeChart(parent, chartGroup);
function keySort (a, b) { return d3.ascending(_chart.keyAccessor()(a), _chart.keyAccessor()(b)); }
var _charts = {}; var _chartFunction = dc.lineChart; var _seriesAccessor; var _seriesSort = d3.ascending; var _valueSort = keySort;
_chart._mandatoryAttributes().push('seriesAccessor', 'chart'); _chart.shareColors(true);
_chart._preprocessData = function () { var keep = []; var childrenChanged; var nester = d3.nest().key(_seriesAccessor); if (_seriesSort) { nester.sortKeys(_seriesSort); } if (_valueSort) { nester.sortValues(_valueSort); } var nesting = nester.entries(_chart.data()); var children = nesting.map(function (sub, i) { var subChart = _charts[sub.key] || _chartFunction.call(_chart, _chart, chartGroup, sub.key, i); if (!_charts[sub.key]) { childrenChanged = true; } _charts[sub.key] = subChart; keep.push(sub.key); return subChart .dimension(_chart.dimension()) .group({ all: typeof sub.values === 'function' ? sub.values : dc.utils.constant(sub.values) }, sub.key) .keyAccessor(_chart.keyAccessor()) .valueAccessor(_chart.valueAccessor()) .brushOn(false); }); // this works around the fact compositeChart doesn't really // have a removal interface Object.keys(_charts) .filter(function (c) {return keep.indexOf(c) === -1;}) .forEach(function (c) { clearChart(c); childrenChanged = true; }); _chart._compose(children); if (childrenChanged && _chart.legend()) { _chart.legend().render(); } };
function clearChart (c) { if (_charts[c].g()) { _charts[c].g().remove(); } delete _charts[c]; }
function resetChildren () { Object.keys(_charts).map(clearChart); _charts = {}; }
/**
- Get or set the chart function, which generates the child charts.
- @method chart
- @memberof dc.seriesChart
- @instance
- @example
- // put curve on the line charts used for the series
- chart.chart(function(c) { return dc.lineChart(c).curve(d3.curveBasis); })
- // do a scatter series chart
- chart.chart(dc.scatterPlot)
- @param {Function} [chartFunction=dc.lineChart]
- @returns {Function|dc.seriesChart} */ _chart.chart = function (chartFunction) { if (!arguments.length) { return _chartFunction; } _chartFunction = chartFunction; resetChildren(); return _chart; };
/**
- mandatory
- Get or set accessor function for the displayed series. Given a datum, this function
- should return the series that datum belongs to.
- @method seriesAccessor
- @memberof dc.seriesChart
- @instance
- @example
- // simple series accessor
- chart.seriesAccessor(function(d) { return "Expt: " + d.key[0]; })
- @param {Function} [accessor]
- @returns {Function|dc.seriesChart} */ _chart.seriesAccessor = function (accessor) { if (!arguments.length) { return _seriesAccessor; } _seriesAccessor = accessor; resetChildren(); return _chart; };
/**
- Get or set a function to sort the list of series by, given series values.
- @method seriesSort
- @memberof dc.seriesChart
- @instance
- @see {@link https://github.com/d3/d3-array/blob/master/README.md#ascending d3.ascending}
- @see {@link https://github.com/d3/d3-array/blob/master/README.md#descending d3.descending}
- @example
- chart.seriesSort(d3.descending);
- @param {Function} [sortFunction=d3.ascending]
- @returns {Function|dc.seriesChart} */ _chart.seriesSort = function (sortFunction) { if (!arguments.length) { return _seriesSort; } _seriesSort = sortFunction; resetChildren(); return _chart; };
/**
- Get or set a function to sort each series values by. By default this is the key accessor which,
- for example, will ensure a lineChart series connects its points in increasing key/x order,
- rather than haphazardly.
- @method valueSort
- @memberof dc.seriesChart
- @instance
- @see {@link https://github.com/d3/d3-array/blob/master/README.md#ascending d3.ascending}
- @see {@link https://github.com/d3/d3-array/blob/master/README.md#descending d3.descending}
- @example
- // Default value sort
- _chart.valueSort(function keySort (a, b) {
return d3.ascending(_chart.keyAccessor()(a), _chart.keyAccessor()(b));
- });
- @param {Function} [sortFunction]
- @returns {Function|dc.seriesChart} */ _chart.valueSort = function (sortFunction) { if (!arguments.length) { return _valueSort; } _valueSort = sortFunction; resetChildren(); return _chart; };
// make compose private _chart._compose = _chart.compose; delete _chart.compose;
return _chart;
};