Skip to content

Commit

Permalink
Implement dataset.order
Browse files Browse the repository at this point in the history
  • Loading branch information
kurkle committed Jun 25, 2019
1 parent 0d37542 commit fee3e99
Show file tree
Hide file tree
Showing 24 changed files with 488 additions and 124 deletions.
2 changes: 2 additions & 0 deletions docs/charts/bar.md
Expand Up @@ -77,6 +77,7 @@ the color of the bars is generally set this way.
| [`hoverBorderColor`](#interactions) | [`Color`](../general/colors.md) | - | Yes | `undefined`
| [`hoverBorderWidth`](#interactions) | `number` | - | Yes | `1`
| [`label`](#general) | `string` | - | - | `''`
| [`order`](#general) | `number` | - | - | 0
| [`xAxisID`](#general) | `string` | - | - | first x axis
| [`yAxisID`](#general) | `string` | - | - | first y axis

Expand All @@ -85,6 +86,7 @@ the color of the bars is generally set this way.
| Name | Description
| ---- | ----
| `label` | The label for the dataset which appears in the legend and tooltips.
| `order` | The drawing order of dataset. Also affects stacking order.
| `xAxisID` | The ID of the x axis to plot this dataset on.
| `yAxisID` | The ID of the y axis to plot this dataset on.

Expand Down
10 changes: 7 additions & 3 deletions docs/charts/bubble.md
Expand Up @@ -49,14 +49,18 @@ The bubble chart allows a number of properties to be specified for each dataset.
| [`hoverBorderWidth`](#interactions) | `number` | Yes | Yes | `1`
| [`hoverRadius`](#interactions) | `number` | Yes | Yes | `4`
| [`hitRadius`](#interactions) | `number` | Yes | Yes | `1`
| [`label`](#labeling) | `string` | - | - | `undefined`
| [`label`](#general) | `string` | - | - | `undefined`
| [`order`](#general) | `number` | - | - | 0
| [`pointStyle`](#styling) | `string` | Yes | Yes | `'circle'`
| [`rotation`](#styling) | `number` | Yes | Yes | `0`
| [`radius`](#styling) | `number` | Yes | Yes | `3`

### Labeling
### General

`label` defines the text associated to the dataset and which appears in the legend and tooltips.
| Name | Description
| ---- | ----
| `label` | The label for the dataset which appears in the legend and tooltips.
| `order` | The drawing order of dataset.

### Styling

Expand Down
2 changes: 2 additions & 0 deletions docs/charts/line.md
Expand Up @@ -54,6 +54,7 @@ The line chart allows a number of properties to be specified for each dataset. T
| [`fill`](#line-styling) | <code>boolean&#124;string</code> | Yes | - | `true`
| [`label`](#general) | `string` | - | - | `''`
| [`lineTension`](#line-styling) | `number` | - | - | `0.4`
| [`order`](#general) | `number` | - | - | 0
| [`pointBackgroundColor`](#point-styling) | `Color` | Yes | Yes | `'rgba(0, 0, 0, 0.1)'`
| [`pointBorderColor`](#point-styling) | `Color` | Yes | Yes | `'rgba(0, 0, 0, 0.1)'`
| [`pointBorderWidth`](#point-styling) | `number` | Yes | Yes | `1`
Expand All @@ -76,6 +77,7 @@ The line chart allows a number of properties to be specified for each dataset. T
| Name | Description
| ---- | ----
| `label` | The label for the dataset which appears in the legend and tooltips.
| `order` | The drawing order of dataset. Also affects stacking order.
| `xAxisID` | The ID of the x axis to plot this dataset on.
| `yAxisID` | The ID of the y axis to plot this dataset on.

Expand Down
26 changes: 26 additions & 0 deletions docs/charts/mixed.md
Expand Up @@ -70,3 +70,29 @@ At this point we have a chart rendering how we'd like. It's important to note th
}
}
{% endchartjs %}

## Drawing order

By default, datasets are drawn so that first one is top-most. This can be altered by specifying `order` option to datasets. `order` defaults to `0`.

```javascript
var mixedChart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [{
label: 'Bar Dataset',
data: [10, 20, 30, 40]
// this dataset is drawn below
order: 1
}, {
label: 'Line Dataset',
data: [10, 10, 10, 10],
type: 'line',
// this dataset is drawn on top
order: 2
}],
labels: ['January', 'February', 'March', 'April']
},
options: options
});
```
1 change: 1 addition & 0 deletions docs/charts/polar.md
Expand Up @@ -70,6 +70,7 @@ All these values, if `undefined`, fallback to the associated [`elements.arc.*`](
### Border Alignment

The following values are supported for `borderAlign`.

* `'center'` (default)
* `'inner'`

Expand Down
3 changes: 3 additions & 0 deletions docs/charts/radar.md
Expand Up @@ -52,6 +52,7 @@ They are often useful for comparing the points of two or more different data set
{% endchartjs %}

## Example Usage

```javascript
var myRadarChart = new Chart(ctx, {
type: 'radar',
Expand All @@ -75,6 +76,7 @@ The radar chart allows a number of properties to be specified for each dataset.
| [`borderWidth`](#line-styling) | `number` | Yes | - | `3`
| [`fill`](#line-styling) | <code>boolean&#124;string</code> | Yes | - | `true`
| [`label`](#general) | `string` | - | - | `''`
| [`order`](#general) | `number` | - | - | 0
| [`lineTension`](#line-styling) | `number` | - | - | `0`
| [`pointBackgroundColor`](#point-styling) | `Color` | Yes | Yes | `'rgba(0, 0, 0, 0.1)'`
| [`pointBorderColor`](#point-styling) | `Color` | Yes | Yes | `'rgba(0, 0, 0, 0.1)'`
Expand All @@ -94,6 +96,7 @@ The radar chart allows a number of properties to be specified for each dataset.
| Name | Description
| ---- | ----
| `label` | The label for the dataset which appears in the legend and tooltips.
| `order` | The drawing order of dataset.

### Point Styling

Expand Down
1 change: 1 addition & 0 deletions docs/charts/scatter.md
Expand Up @@ -32,6 +32,7 @@ var scatterChart = new Chart(ctx, {
```

## Dataset Properties

The scatter chart supports all of the same properties as the [line chart](./line.md#dataset-properties).

## Data Structure
Expand Down
34 changes: 24 additions & 10 deletions src/controllers/controller.bar.js
Expand Up @@ -114,6 +114,14 @@ function computeFlexCategoryTraits(index, ruler, options) {
};
}

function getMatchingVisibleMetas(scale) {
var isHorizontal = scale.isHorizontal();
return scale.chart._getSortedVisibleDatasetMetas()
.filter(function(meta) {
return meta.bar && isHorizontal ? meta.xAxisID === scale.id : meta.yAxisID === scale.id;
});
}

module.exports = DatasetController.extend({

dataElementType: elements.Rectangle,
Expand Down Expand Up @@ -210,19 +218,23 @@ module.exports = DatasetController.extend({
var me = this;
var chart = me.chart;
var scale = me._getIndexScale();
var metasets = chart._getSortedVisibleDatasetMetas();
var stacked = scale.options.stacked;
var ilen = last === undefined ? chart.data.datasets.length : last + 1;
var ilen = metasets.length;
var stacks = [];
var i, meta;

for (i = 0; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
if (meta.bar && chart.isDatasetVisible(i) &&
meta = metasets[i];
if (meta.bar &&
(stacked === false ||
(stacked === true && stacks.indexOf(meta.stack) === -1) ||
(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
stacks.push(meta.stack);
}
if (meta.index === last) {
break;
}
}

return stacks;
Expand Down Expand Up @@ -297,24 +309,26 @@ module.exports = DatasetController.extend({
var scale = me._getValueScale();
var isHorizontal = scale.isHorizontal();
var datasets = chart.data.datasets;
var metasets = getMatchingVisibleMetas(scale);
var value = scale._parseValue(datasets[datasetIndex].data[index]);
var minBarLength = scale.options.minBarLength;
var stacked = scale.options.stacked;
var stack = meta.stack;
var start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max;
var length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max;
var ilen = metasets.length;
var i, imeta, ivalue, base, head, size, stackLength;

if (stacked || (stacked === undefined && stack !== undefined)) {
for (i = 0; i < datasetIndex; ++i) {
imeta = chart.getDatasetMeta(i);
for (i = 0; i < ilen; ++i) {
imeta = metasets[i];

if (imeta.bar &&
imeta.stack === stack &&
imeta.controller._getValueScaleId() === scale.id &&
chart.isDatasetVisible(i)) {
if (imeta.index === datasetIndex) {
break;
}

stackLength = scale._parseValue(datasets[i].data[index]);
if (imeta.stack === stack) {
stackLength = scale._parseValue(datasets[imeta.index].data[index]);
ivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min;

if ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) {
Expand Down
24 changes: 14 additions & 10 deletions src/controllers/controller.line.js
Expand Up @@ -183,14 +183,21 @@ module.exports = DatasetController.extend({
var yScale = me._yScale;
var sumPos = 0;
var sumNeg = 0;
var i, ds, dsMeta;
var rightValue = +yScale.getRightValue(value);
var metasets = chart._getSortedVisibleDatasetMetas();
var ilen = metasets.length;
var i, ds, dsMeta, stackedRightValue;

if (yScale.options.stacked) {
for (i = 0; i < datasetIndex; i++) {
ds = chart.data.datasets[i];
dsMeta = chart.getDatasetMeta(i);
if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) {
var stackedRightValue = Number(yScale.getRightValue(ds.data[index]));
for (i = 0; i < ilen; ++i) {
dsMeta = metasets[i];
if (dsMeta.index === datasetIndex) {
break;
}

ds = chart.data.datasets[dsMeta.index];
if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) {
stackedRightValue = +yScale.getRightValue(ds.data[index]);
if (stackedRightValue < 0) {
sumNeg += stackedRightValue || 0;
} else {
Expand All @@ -199,14 +206,11 @@ module.exports = DatasetController.extend({
}
}

var rightValue = Number(yScale.getRightValue(value));
if (rightValue < 0) {
return yScale.getPixelForValue(sumNeg + rightValue);
}
return yScale.getPixelForValue(sumPos + rightValue);
}

return yScale.getPixelForValue(value);
return yScale.getPixelForValue(sumPos + rightValue);
},

updateBezierControlPoints: function() {
Expand Down
44 changes: 35 additions & 9 deletions src/core/core.controller.js
Expand Up @@ -422,6 +422,8 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
meta = me.getDatasetMeta(datasetIndex);
}
meta.type = type;
meta.order = dataset.order || 0;
meta.index = datasetIndex;

if (meta.controller) {
meta.controller.updateIndex(datasetIndex);
Expand Down Expand Up @@ -712,23 +714,46 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
me.tooltip.transition(easingValue);
},

/**
* @private
*/
_getSortedVisibleDatasetMetas: function() {
var me = this;
var datasets = me.data.datasets || [];
var result = [];
var i, ilen;

for (i = 0, ilen = datasets.length; i < ilen; ++i) {
if (me.isDatasetVisible(i)) {
result.push(me.getDatasetMeta(i));
}
}

result.sort(function(a, b) {
return a.order === b.order
? a.index - b.index
: a.order - b.order;
});

return result;
},

/**
* Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
* hook, in which case, plugins will not be called on `afterDatasetsDraw`.
* @private
*/
drawDatasets: function(easingValue) {
var me = this;
var metasets, i;

if (plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {
return;
}

// Draw datasets reversed to support proper line stacking
for (var i = (me.data.datasets || []).length - 1; i >= 0; --i) {
if (me.isDatasetVisible(i)) {
me.drawDataset(i, easingValue);
}
metasets = me._getSortedVisibleDatasetMetas();
for (i = metasets.length - 1; i >= 0; --i) {
me.drawDataset(metasets[i], easingValue);
}

plugins.notify(me, 'afterDatasetsDraw', [easingValue]);
Expand All @@ -739,12 +764,11 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
* hook, in which case, plugins will not be called on `afterDatasetDraw`.
* @private
*/
drawDataset: function(index, easingValue) {
drawDataset: function(meta, easingValue) {
var me = this;
var meta = me.getDatasetMeta(index);
var args = {
meta: meta,
index: index,
index: meta.index,
easingValue: easingValue
};

Expand Down Expand Up @@ -824,7 +848,9 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
controller: null,
hidden: null, // See isDatasetVisible() comment
xAxisID: null,
yAxisID: null
yAxisID: null,
order: dataset.order || 0,
index: datasetIndex
};
}

Expand Down
6 changes: 3 additions & 3 deletions src/plugins/plugin.filler.js
Expand Up @@ -354,12 +354,12 @@ module.exports = {
},

beforeDatasetsDraw: function(chart) {
var count = (chart.data.datasets || []).length - 1;
var metasets = chart._getSortedVisibleDatasetMetas();
var ctx = chart.ctx;
var meta, i, el, view, points, mapper, color;

for (i = count; i >= 0; --i) {
meta = chart.getDatasetMeta(i).$filler;
for (i = metasets.length - 1; i >= 0; --i) {
meta = metasets[i].$filler;

if (!meta || !meta.visible) {
continue;
Expand Down

0 comments on commit fee3e99

Please sign in to comment.