mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
Implement dataset.order (#6268)
Allow sorting datasets based on the `order` property
This commit is contained in:
parent
feaf418d4e
commit
6b6f1a4c51
@ -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
|
||||
|
||||
@ -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 order for stacking, tooltip, and legend.
|
||||
| `xAxisID` | The ID of the x axis to plot this dataset on.
|
||||
| `yAxisID` | The ID of the y axis to plot this dataset on.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -54,6 +54,7 @@ The line chart allows a number of properties to be specified for each dataset. T
|
||||
| [`fill`](#line-styling) | <code>boolean|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`
|
||||
@ -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 order for stacking, tooltip, and legend.
|
||||
| `xAxisID` | The ID of the x axis to plot this dataset on.
|
||||
| `yAxisID` | The ID of the y axis to plot this dataset on.
|
||||
|
||||
|
||||
@ -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
|
||||
});
|
||||
```
|
||||
|
||||
@ -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'`
|
||||
|
||||
|
||||
@ -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',
|
||||
@ -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|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)'`
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -207,21 +207,27 @@ module.exports = DatasetController.extend({
|
||||
*/
|
||||
_getStacks: function(last) {
|
||||
var me = this;
|
||||
var chart = me.chart;
|
||||
var scale = me._getIndexScale();
|
||||
var metasets = scale._getMatchingVisibleMetas(me._type);
|
||||
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) &&
|
||||
(stacked === false ||
|
||||
(stacked === true && stacks.indexOf(meta.stack) === -1) ||
|
||||
(stacked === undefined && (meta.stack === undefined || stacks.indexOf(meta.stack) === -1)))) {
|
||||
meta = metasets[i];
|
||||
// stacked | meta.stack
|
||||
// | found | not found | undefined
|
||||
// false | x | x | x
|
||||
// true | | x |
|
||||
// undefined | | x | x
|
||||
if (stacked === false || stacks.indexOf(meta.stack) === -1 ||
|
||||
(stacked === undefined && meta.stack === undefined)) {
|
||||
stacks.push(meta.stack);
|
||||
}
|
||||
if (meta.index === last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stacks;
|
||||
@ -290,24 +296,26 @@ module.exports = DatasetController.extend({
|
||||
var scale = me._getValueScale();
|
||||
var isHorizontal = scale.isHorizontal();
|
||||
var datasets = chart.data.datasets;
|
||||
var metasets = scale._getMatchingVisibleMetas(me._type);
|
||||
var value = scale._parseValue(datasets[datasetIndex].data[index]);
|
||||
var minBarLength = scale.options.minBarLength;
|
||||
var stacked = scale.options.stacked;
|
||||
var stack = me.getMeta().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)) {
|
||||
|
||||
@ -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 {
|
||||
@ -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() {
|
||||
|
||||
@ -154,6 +154,14 @@ function positionIsHorizontal(position) {
|
||||
return position === 'top' || position === 'bottom';
|
||||
}
|
||||
|
||||
function compare2Level(l1, l2) {
|
||||
return function(a, b) {
|
||||
return a[l1] === b[l1]
|
||||
? a[l2] - b[l2]
|
||||
: a[l1] - b[l1];
|
||||
};
|
||||
}
|
||||
|
||||
var Chart = function(item, config) {
|
||||
this.construct(item, config);
|
||||
return this;
|
||||
@ -422,6 +430,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);
|
||||
@ -513,11 +523,7 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
|
||||
// Do this before render so that any plugins that need final scale updates can use it
|
||||
plugins.notify(me, 'afterUpdate');
|
||||
|
||||
me._layers.sort(function(a, b) {
|
||||
return a.z === b.z
|
||||
? a._idx - b._idx
|
||||
: a.z - b.z;
|
||||
});
|
||||
me._layers.sort(compare2Level('z', '_idx'));
|
||||
|
||||
if (me._bufferedRender) {
|
||||
me._bufferedRequest = {
|
||||
@ -717,6 +723,33 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
|
||||
me.tooltip.transition(easingValue);
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSortedDatasetMetas: function(filterVisible) {
|
||||
var me = this;
|
||||
var datasets = me.data.datasets || [];
|
||||
var result = [];
|
||||
var i, ilen;
|
||||
|
||||
for (i = 0, ilen = datasets.length; i < ilen; ++i) {
|
||||
if (!filterVisible || me.isDatasetVisible(i)) {
|
||||
result.push(me.getDatasetMeta(i));
|
||||
}
|
||||
}
|
||||
|
||||
result.sort(compare2Level('order', 'index'));
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getSortedVisibleDatasetMetas: function() {
|
||||
return this._getSortedDatasetMetas(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`
|
||||
* hook, in which case, plugins will not be called on `afterDatasetsDraw`.
|
||||
@ -724,16 +757,15 @@ helpers.extend(Chart.prototype, /** @lends Chart */ {
|
||||
*/
|
||||
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]);
|
||||
@ -744,12 +776,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
|
||||
};
|
||||
|
||||
@ -829,7 +860,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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -25,17 +25,13 @@ function getRelativePosition(e, chart) {
|
||||
* @param {function} handler - the callback to execute for each visible item
|
||||
*/
|
||||
function parseVisibleItems(chart, handler) {
|
||||
var datasets = chart.data.datasets;
|
||||
var meta, i, j, ilen, jlen;
|
||||
var metasets = chart._getSortedVisibleDatasetMetas();
|
||||
var metadata, i, j, ilen, jlen, element;
|
||||
|
||||
for (i = 0, ilen = datasets.length; i < ilen; ++i) {
|
||||
if (!chart.isDatasetVisible(i)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
meta = chart.getDatasetMeta(i);
|
||||
for (j = 0, jlen = meta.data.length; j < jlen; ++j) {
|
||||
var element = meta.data[j];
|
||||
for (i = 0, ilen = metasets.length; i < ilen; ++i) {
|
||||
metadata = metasets[i].data;
|
||||
for (j = 0, jlen = metadata.length; j < jlen; ++j) {
|
||||
element = metadata[j];
|
||||
if (!element._view.skip) {
|
||||
handler(element);
|
||||
}
|
||||
@ -120,16 +116,13 @@ function indexMode(chart, e, options) {
|
||||
return [];
|
||||
}
|
||||
|
||||
chart.data.datasets.forEach(function(dataset, datasetIndex) {
|
||||
if (chart.isDatasetVisible(datasetIndex)) {
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
chart._getSortedVisibleDatasetMetas().forEach(function(meta) {
|
||||
var element = meta.data[items[0]._index];
|
||||
|
||||
// don't count items that are skipped (null data)
|
||||
if (element && !element._view.skip) {
|
||||
elements.push(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return elements;
|
||||
|
||||
@ -1416,6 +1416,19 @@ var Scale = Element.extend({
|
||||
me._drawLabels.apply(me, arguments);
|
||||
}
|
||||
}];
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getMatchingVisibleMetas: function(type) {
|
||||
var me = this;
|
||||
var isHorizontal = me.isHorizontal();
|
||||
return me.chart._getSortedVisibleDatasetMetas()
|
||||
.filter(function(meta) {
|
||||
return (!type || meta.type === type)
|
||||
&& (isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -995,6 +995,9 @@ var exports = Element.extend({
|
||||
me._active = [];
|
||||
} else {
|
||||
me._active = me._chart.getElementsAtEventForMode(e, options.mode, options);
|
||||
if (options.reverse) {
|
||||
me._active.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
// Remember Last Actives
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -49,16 +49,15 @@ defaults._set('global', {
|
||||
// lineJoin :
|
||||
// lineWidth :
|
||||
generateLabels: function(chart) {
|
||||
var data = chart.data;
|
||||
var datasets = chart.data.datasets;
|
||||
var options = chart.options.legend || {};
|
||||
var usePointStyle = options.labels && options.labels.usePointStyle;
|
||||
|
||||
return helpers.isArray(data.datasets) ? data.datasets.map(function(dataset, i) {
|
||||
var meta = chart.getDatasetMeta(i);
|
||||
return chart._getSortedDatasetMetas().map(function(meta, i) {
|
||||
var style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
|
||||
|
||||
return {
|
||||
text: dataset.label,
|
||||
text: datasets[meta.index].label,
|
||||
fillStyle: style.backgroundColor,
|
||||
hidden: !chart.isDatasetVisible(i),
|
||||
lineCap: style.borderCapStyle,
|
||||
@ -73,7 +72,7 @@ defaults._set('global', {
|
||||
// Below is extra data used for toggling the datasets
|
||||
datasetIndex: i
|
||||
};
|
||||
}, this) : [];
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -11,116 +11,113 @@ var defaultConfig = {
|
||||
}
|
||||
};
|
||||
|
||||
var DEFAULT_MIN = 0;
|
||||
var DEFAULT_MAX = 1;
|
||||
|
||||
function getOrCreateStack(stacks, stacked, meta) {
|
||||
var key = [
|
||||
meta.type,
|
||||
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
|
||||
stacked === undefined && meta.stack === undefined ? meta.index : '',
|
||||
meta.stack
|
||||
].join('.');
|
||||
|
||||
if (stacks[key] === undefined) {
|
||||
stacks[key] = {
|
||||
pos: [],
|
||||
neg: []
|
||||
};
|
||||
}
|
||||
|
||||
return stacks[key];
|
||||
}
|
||||
|
||||
function stackData(scale, stacks, meta, data) {
|
||||
var opts = scale.options;
|
||||
var stacked = opts.stacked;
|
||||
var stack = getOrCreateStack(stacks, stacked, meta);
|
||||
var pos = stack.pos;
|
||||
var neg = stack.neg;
|
||||
var ilen = data.length;
|
||||
var i, value;
|
||||
|
||||
for (i = 0; i < ilen; ++i) {
|
||||
value = scale._parseValue(data[i]);
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pos[i] = pos[i] || 0;
|
||||
neg[i] = neg[i] || 0;
|
||||
|
||||
if (opts.relativePoints) {
|
||||
pos[i] = 100;
|
||||
} else if (value.min < 0 || value.max < 0) {
|
||||
neg[i] += value.min;
|
||||
} else {
|
||||
pos[i] += value.max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateMinMax(scale, meta, data) {
|
||||
var ilen = data.length;
|
||||
var i, value;
|
||||
|
||||
for (i = 0; i < ilen; ++i) {
|
||||
value = scale._parseValue(data[i]);
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
scale.min = Math.min(scale.min, value.min);
|
||||
scale.max = Math.max(scale.max, value.max);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LinearScaleBase.extend({
|
||||
determineDataLimits: function() {
|
||||
var me = this;
|
||||
var opts = me.options;
|
||||
var chart = me.chart;
|
||||
var datasets = chart.data.datasets;
|
||||
var isHorizontal = me.isHorizontal();
|
||||
var DEFAULT_MIN = 0;
|
||||
var DEFAULT_MAX = 1;
|
||||
var datasetIndex, meta, value, data, i, ilen;
|
||||
var metasets = me._getMatchingVisibleMetas();
|
||||
var hasStacks = opts.stacked;
|
||||
var stacks = {};
|
||||
var ilen = metasets.length;
|
||||
var i, meta, data, values;
|
||||
|
||||
function IDMatches(datasetMeta) {
|
||||
return isHorizontal ? datasetMeta.xAxisID === me.id : datasetMeta.yAxisID === me.id;
|
||||
}
|
||||
|
||||
// First Calculate the range
|
||||
me.min = Number.POSITIVE_INFINITY;
|
||||
me.max = Number.NEGATIVE_INFINITY;
|
||||
|
||||
var hasStacks = opts.stacked;
|
||||
if (hasStacks === undefined) {
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && meta.stack !== undefined) {
|
||||
hasStacks = true;
|
||||
break;
|
||||
}
|
||||
for (i = 0; !hasStacks && i < ilen; ++i) {
|
||||
meta = metasets[i];
|
||||
hasStacks = meta.stack !== undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.stacked || hasStacks) {
|
||||
var valuesPerStack = {};
|
||||
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
var key = [
|
||||
meta.type,
|
||||
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
|
||||
((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),
|
||||
meta.stack
|
||||
].join('.');
|
||||
|
||||
if (valuesPerStack[key] === undefined) {
|
||||
valuesPerStack[key] = {
|
||||
positiveValues: [],
|
||||
negativeValues: []
|
||||
};
|
||||
}
|
||||
|
||||
// Store these per type
|
||||
var positiveValues = valuesPerStack[key].positiveValues;
|
||||
var negativeValues = valuesPerStack[key].negativeValues;
|
||||
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
value = me._parseValue(data[i]);
|
||||
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
positiveValues[i] = positiveValues[i] || 0;
|
||||
negativeValues[i] = negativeValues[i] || 0;
|
||||
|
||||
if (value.min === 0 && !opts.ticks.beginAtZero) {
|
||||
value.min = value.max;
|
||||
}
|
||||
|
||||
if (opts.relativePoints) {
|
||||
positiveValues[i] = 100;
|
||||
} else if (value.min < 0 || value.max < 0) {
|
||||
negativeValues[i] += value.min;
|
||||
for (i = 0; i < ilen; ++i) {
|
||||
meta = metasets[i];
|
||||
data = datasets[meta.index].data;
|
||||
if (hasStacks) {
|
||||
stackData(me, stacks, meta, data);
|
||||
} else {
|
||||
positiveValues[i] += value.max;
|
||||
}
|
||||
}
|
||||
updateMinMax(me, meta, data);
|
||||
}
|
||||
}
|
||||
|
||||
helpers.each(valuesPerStack, function(valuesForType) {
|
||||
var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
|
||||
helpers.each(stacks, function(stackValues) {
|
||||
values = stackValues.pos.concat(stackValues.neg);
|
||||
me.min = Math.min(me.min, helpers.min(values));
|
||||
me.max = Math.max(me.max, helpers.max(values));
|
||||
});
|
||||
|
||||
} else {
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
value = me._parseValue(data[i]);
|
||||
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
me.min = Math.min(value.min, me.min);
|
||||
me.max = Math.max(value.max, me.max);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
me.min = helpers.isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
|
||||
me.max = helpers.isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
|
||||
|
||||
// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
|
||||
this.handleTickRangeOptions();
|
||||
me.handleTickRangeOptions();
|
||||
},
|
||||
|
||||
// Returns the maximum number of ticks based on the scale dimension
|
||||
|
||||
42
test/fixtures/controller.bar/stacking/order-default.json
vendored
Normal file
42
test/fixtures/controller.bar/stacking/order-default.json
vendored
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"config": {
|
||||
"type": "bar",
|
||||
"data": {
|
||||
"labels": ["2016", "2018", "2020", "2024", "2030"],
|
||||
"datasets": [{
|
||||
"backgroundColor": "#FF6384",
|
||||
"data": [1, null, 3, 4, 5]
|
||||
}, {
|
||||
"backgroundColor": "#36A2EB",
|
||||
"data": [5, 4, 3, null, 1]
|
||||
}, {
|
||||
"backgroundColor": "#FFCE56",
|
||||
"data": [3, 5, 2, null, 4]
|
||||
}]
|
||||
},
|
||||
"options": {
|
||||
"responsive": false,
|
||||
"legend": false,
|
||||
"title": false,
|
||||
"scales": {
|
||||
"xAxes": [{
|
||||
"display": false,
|
||||
"stacked": true
|
||||
}],
|
||||
"yAxes": [{
|
||||
"display": false,
|
||||
"stacked": true,
|
||||
"ticks": {
|
||||
"beginAtZero": true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"canvas": {
|
||||
"height": 256,
|
||||
"width": 512
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/fixtures/controller.bar/stacking/order-default.png
vendored
Normal file
BIN
test/fixtures/controller.bar/stacking/order-default.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
45
test/fixtures/controller.bar/stacking/order-specified.json
vendored
Normal file
45
test/fixtures/controller.bar/stacking/order-specified.json
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"config": {
|
||||
"type": "bar",
|
||||
"data": {
|
||||
"labels": ["2016", "2018", "2020", "2024", "2030"],
|
||||
"datasets": [{
|
||||
"backgroundColor": "#FF6384",
|
||||
"data": [1, null, 3, 4, 5],
|
||||
"order": 20
|
||||
}, {
|
||||
"backgroundColor": "#36A2EB",
|
||||
"data": [5, 4, 3, null, 1],
|
||||
"order": 25
|
||||
}, {
|
||||
"backgroundColor": "#FFCE56",
|
||||
"data": [3, 5, 2, null, 4],
|
||||
"order": 10
|
||||
}]
|
||||
},
|
||||
"options": {
|
||||
"responsive": false,
|
||||
"legend": false,
|
||||
"title": false,
|
||||
"scales": {
|
||||
"xAxes": [{
|
||||
"display": false,
|
||||
"stacked": true
|
||||
}],
|
||||
"yAxes": [{
|
||||
"display": false,
|
||||
"stacked": true,
|
||||
"ticks": {
|
||||
"beginAtZero": true
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"canvas": {
|
||||
"height": 256,
|
||||
"width": 512
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
test/fixtures/controller.bar/stacking/order-specified.png
vendored
Normal file
BIN
test/fixtures/controller.bar/stacking/order-specified.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
45
test/fixtures/controller.line/fill/order-default.js
vendored
Normal file
45
test/fixtures/controller.line/fill/order-default.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [0, 1, 2, 3, 4, 5],
|
||||
datasets: [
|
||||
{
|
||||
// option in dataset
|
||||
data: [3, 1, 2, 0, 8, 1],
|
||||
backgroundColor: '#ff0000'
|
||||
},
|
||||
{
|
||||
// option in element (fallback)
|
||||
data: [0, 4, 2, 6, 4, 8],
|
||||
backgroundColor: '#00ff00'
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
legend: false,
|
||||
title: false,
|
||||
elements: {
|
||||
line: {
|
||||
fill: true
|
||||
},
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 32
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{display: false}],
|
||||
yAxes: [{display: false}]
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.line/fill/order-default.png
vendored
Normal file
BIN
test/fixtures/controller.line/fill/order-default.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
45
test/fixtures/controller.line/fill/order.js
vendored
Normal file
45
test/fixtures/controller.line/fill/order.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [0, 1, 2, 3, 4, 5],
|
||||
datasets: [
|
||||
{
|
||||
data: [3, 1, 2, 0, 8, 1],
|
||||
backgroundColor: '#ff0000',
|
||||
order: 2
|
||||
},
|
||||
{
|
||||
data: [0, 4, 2, 6, 4, 8],
|
||||
backgroundColor: '#00ff00',
|
||||
order: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
legend: false,
|
||||
title: false,
|
||||
elements: {
|
||||
line: {
|
||||
fill: true
|
||||
},
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 32
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{display: false}],
|
||||
yAxes: [{display: false}]
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.line/fill/order.png
vendored
Normal file
BIN
test/fixtures/controller.line/fill/order.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
45
test/fixtures/controller.line/stacking/order-default.js
vendored
Normal file
45
test/fixtures/controller.line/stacking/order-default.js
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [0, 1, 2, 3, 4, 5],
|
||||
datasets: [
|
||||
{
|
||||
// option in dataset
|
||||
data: [3, 1, 2, 0, 8, 1],
|
||||
backgroundColor: '#ff0000'
|
||||
},
|
||||
{
|
||||
// option in element (fallback)
|
||||
data: [0, 4, 2, 6, 4, 8],
|
||||
backgroundColor: '#00ff00'
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
legend: false,
|
||||
title: false,
|
||||
elements: {
|
||||
line: {
|
||||
fill: true
|
||||
},
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 32
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{stacked: true, display: false}],
|
||||
yAxes: [{stacked: true, display: false}]
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.line/stacking/order-default.png
vendored
Normal file
BIN
test/fixtures/controller.line/stacking/order-default.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
47
test/fixtures/controller.line/stacking/order-specified.js
vendored
Normal file
47
test/fixtures/controller.line/stacking/order-specified.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
module.exports = {
|
||||
config: {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [0, 1, 2, 3, 4, 5],
|
||||
datasets: [
|
||||
{
|
||||
// option in dataset
|
||||
data: [3, 1, 2, 0, 8, 1],
|
||||
backgroundColor: '#ff0000',
|
||||
order: 2
|
||||
},
|
||||
{
|
||||
// option in element (fallback)
|
||||
data: [0, 4, 2, 6, 4, 8],
|
||||
backgroundColor: '#00ff00',
|
||||
order: 1
|
||||
}
|
||||
]
|
||||
},
|
||||
options: {
|
||||
legend: false,
|
||||
title: false,
|
||||
elements: {
|
||||
line: {
|
||||
fill: true
|
||||
},
|
||||
point: {
|
||||
radius: 0
|
||||
}
|
||||
},
|
||||
layout: {
|
||||
padding: 32
|
||||
},
|
||||
scales: {
|
||||
xAxes: [{stacked: true, display: false}],
|
||||
yAxes: [{stacked: true, display: false}]
|
||||
}
|
||||
}
|
||||
},
|
||||
options: {
|
||||
canvas: {
|
||||
height: 256,
|
||||
width: 512
|
||||
}
|
||||
}
|
||||
};
|
||||
BIN
test/fixtures/controller.line/stacking/order-specified.png
vendored
Normal file
BIN
test/fixtures/controller.line/stacking/order-specified.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.8 KiB |
@ -581,6 +581,165 @@ describe('Core.Tooltip', function() {
|
||||
expect(tooltip._view.y).toBeCloseToPixel(155);
|
||||
});
|
||||
|
||||
it('Should allow reversing items', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Dataset 1',
|
||||
data: [10, 20, 30],
|
||||
pointHoverBorderColor: 'rgb(255, 0, 0)',
|
||||
pointHoverBackgroundColor: 'rgb(0, 255, 0)'
|
||||
}, {
|
||||
label: 'Dataset 2',
|
||||
data: [40, 40, 40],
|
||||
pointHoverBorderColor: 'rgb(0, 0, 255)',
|
||||
pointHoverBackgroundColor: 'rgb(0, 255, 255)'
|
||||
}],
|
||||
labels: ['Point 1', 'Point 2', 'Point 3']
|
||||
},
|
||||
options: {
|
||||
tooltips: {
|
||||
mode: 'label',
|
||||
reverse: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger an event over top of the
|
||||
var meta0 = chart.getDatasetMeta(0);
|
||||
var point0 = meta0.data[1];
|
||||
|
||||
var node = chart.canvas;
|
||||
var rect = node.getBoundingClientRect();
|
||||
|
||||
var evt = new MouseEvent('mousemove', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: rect.left + point0._model.x,
|
||||
clientY: rect.top + point0._model.y
|
||||
});
|
||||
|
||||
// Manually trigger rather than having an async test
|
||||
node.dispatchEvent(evt);
|
||||
|
||||
// Check and see if tooltip was displayed
|
||||
var tooltip = chart.tooltip;
|
||||
var globalDefaults = Chart.defaults.global;
|
||||
|
||||
expect(tooltip._view).toEqual(jasmine.objectContaining({
|
||||
// Positioning
|
||||
xAlign: 'left',
|
||||
yAlign: 'center',
|
||||
|
||||
// Text
|
||||
title: ['Point 2'],
|
||||
beforeBody: [],
|
||||
body: [{
|
||||
before: [],
|
||||
lines: ['Dataset 2: 40'],
|
||||
after: []
|
||||
}, {
|
||||
before: [],
|
||||
lines: ['Dataset 1: 20'],
|
||||
after: []
|
||||
}],
|
||||
afterBody: [],
|
||||
footer: [],
|
||||
labelColors: [{
|
||||
borderColor: globalDefaults.defaultColor,
|
||||
backgroundColor: globalDefaults.defaultColor
|
||||
}, {
|
||||
borderColor: globalDefaults.defaultColor,
|
||||
backgroundColor: globalDefaults.defaultColor
|
||||
}]
|
||||
}));
|
||||
|
||||
expect(tooltip._view.x).toBeCloseToPixel(267);
|
||||
expect(tooltip._view.y).toBeCloseToPixel(155);
|
||||
});
|
||||
|
||||
it('Should follow dataset order', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'Dataset 1',
|
||||
data: [10, 20, 30],
|
||||
pointHoverBorderColor: 'rgb(255, 0, 0)',
|
||||
pointHoverBackgroundColor: 'rgb(0, 255, 0)',
|
||||
order: 10
|
||||
}, {
|
||||
label: 'Dataset 2',
|
||||
data: [40, 40, 40],
|
||||
pointHoverBorderColor: 'rgb(0, 0, 255)',
|
||||
pointHoverBackgroundColor: 'rgb(0, 255, 255)',
|
||||
order: 5
|
||||
}],
|
||||
labels: ['Point 1', 'Point 2', 'Point 3']
|
||||
},
|
||||
options: {
|
||||
tooltips: {
|
||||
mode: 'label'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger an event over top of the
|
||||
var meta0 = chart.getDatasetMeta(0);
|
||||
var point0 = meta0.data[1];
|
||||
|
||||
var node = chart.canvas;
|
||||
var rect = node.getBoundingClientRect();
|
||||
|
||||
var evt = new MouseEvent('mousemove', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
clientX: rect.left + point0._model.x,
|
||||
clientY: rect.top + point0._model.y
|
||||
});
|
||||
|
||||
// Manually trigger rather than having an async test
|
||||
node.dispatchEvent(evt);
|
||||
|
||||
// Check and see if tooltip was displayed
|
||||
var tooltip = chart.tooltip;
|
||||
var globalDefaults = Chart.defaults.global;
|
||||
|
||||
expect(tooltip._view).toEqual(jasmine.objectContaining({
|
||||
// Positioning
|
||||
xAlign: 'left',
|
||||
yAlign: 'center',
|
||||
|
||||
// Text
|
||||
title: ['Point 2'],
|
||||
beforeBody: [],
|
||||
body: [{
|
||||
before: [],
|
||||
lines: ['Dataset 2: 40'],
|
||||
after: []
|
||||
}, {
|
||||
before: [],
|
||||
lines: ['Dataset 1: 20'],
|
||||
after: []
|
||||
}],
|
||||
afterBody: [],
|
||||
footer: [],
|
||||
labelColors: [{
|
||||
borderColor: globalDefaults.defaultColor,
|
||||
backgroundColor: globalDefaults.defaultColor
|
||||
}, {
|
||||
borderColor: globalDefaults.defaultColor,
|
||||
backgroundColor: globalDefaults.defaultColor
|
||||
}]
|
||||
}));
|
||||
|
||||
expect(tooltip._view.x).toBeCloseToPixel(267);
|
||||
expect(tooltip._view.y).toBeCloseToPixel(155);
|
||||
});
|
||||
|
||||
it('should filter items from the tooltip using the callback', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
|
||||
@ -163,6 +163,81 @@ describe('Legend block tests', function() {
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should reverse correctly', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
label: 'dataset1',
|
||||
backgroundColor: '#f31',
|
||||
borderCapStyle: 'round',
|
||||
borderDash: [2, 2],
|
||||
borderDashOffset: 5.5,
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset2',
|
||||
hidden: true,
|
||||
borderJoinStyle: 'round',
|
||||
data: []
|
||||
}, {
|
||||
label: 'dataset3',
|
||||
borderWidth: 10,
|
||||
borderColor: 'green',
|
||||
pointStyle: 'crossRot',
|
||||
fill: false,
|
||||
data: []
|
||||
}],
|
||||
labels: []
|
||||
},
|
||||
options: {
|
||||
legend: {
|
||||
reverse: true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
expect(chart.legend.legendItems).toEqual([{
|
||||
text: 'dataset3',
|
||||
fillStyle: 'rgba(0,0,0,0)',
|
||||
hidden: false,
|
||||
lineCap: 'butt',
|
||||
lineDash: [],
|
||||
lineDashOffset: 0,
|
||||
lineJoin: 'miter',
|
||||
lineWidth: 10,
|
||||
strokeStyle: 'green',
|
||||
pointStyle: undefined,
|
||||
rotation: undefined,
|
||||
datasetIndex: 2
|
||||
}, {
|
||||
text: 'dataset2',
|
||||
fillStyle: 'rgba(0,0,0,0.1)',
|
||||
hidden: true,
|
||||
lineCap: 'butt',
|
||||
lineDash: [],
|
||||
lineDashOffset: 0,
|
||||
lineJoin: 'round',
|
||||
lineWidth: 3,
|
||||
strokeStyle: 'rgba(0,0,0,0.1)',
|
||||
pointStyle: undefined,
|
||||
rotation: undefined,
|
||||
datasetIndex: 1
|
||||
}, {
|
||||
text: 'dataset1',
|
||||
fillStyle: '#f31',
|
||||
hidden: false,
|
||||
lineCap: 'round',
|
||||
lineDash: [2, 2],
|
||||
lineDashOffset: 5.5,
|
||||
lineJoin: 'miter',
|
||||
lineWidth: 3,
|
||||
strokeStyle: 'rgba(0,0,0,0.1)',
|
||||
pointStyle: undefined,
|
||||
rotation: undefined,
|
||||
datasetIndex: 0
|
||||
}]);
|
||||
});
|
||||
|
||||
it('should filter items', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'bar',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user