Skip to content

Commit

Permalink
Implement scriptable options for doughnut charts (chartjs#5966)
Browse files Browse the repository at this point in the history
  • Loading branch information
etimberg authored and simonbrunel committed Jan 10, 2019
1 parent 4c73f52 commit f7b06e1
Show file tree
Hide file tree
Showing 29 changed files with 719 additions and 149 deletions.
4 changes: 2 additions & 2 deletions docs/charts/bar.md
Expand Up @@ -120,10 +120,10 @@ The interaction with each bar can be controlled with the following properties:
| Name | Description
| ---- | -----------
| `hoverBackgroundColor` | The bar background color when hovered.
| `hoverBorderColor` | The bar border color hovered.
| `hoverBorderColor` | The bar border color when hovered.
| `hoverBorderWidth` | The bar border width when hovered (in pixels).

All these values, if `undefined`, fallback to the associated [`elements.point.*`](../configuration/elements.md#point-configuration) options.
All these values, if `undefined`, fallback to the associated [`elements.rectangle.*`](../configuration/elements.md#rectangle-configuration) options.

## Scale Configuration
The bar chart accepts the following configuration from the associated `scale` options:
Expand Down
2 changes: 1 addition & 1 deletion docs/charts/bubble.md
Expand Up @@ -80,7 +80,7 @@ The interaction with each bubble can be controlled with the following properties
| Name | Description
| ---- | -----------
| `hoverBackgroundColor` | bubble background color when hovered.
| `hoverBorderColor` | bubble border color hovered.
| `hoverBorderColor` | bubble border color when hovered.
| `hoverBorderWidth` | bubble border width when hovered (in pixels).
| `hoverRadius` | bubble **additional** radius when hovered (in pixels).
| `hitRadius` | bubble **additional** radius for hit detection (in pixels).
Expand Down
43 changes: 34 additions & 9 deletions docs/charts/doughnut.md
Expand Up @@ -53,15 +53,28 @@ var myDoughnutChart = new Chart(ctx, {

The doughnut/pie chart allows a number of properties to be specified for each dataset. These are used to set display properties for a specific dataset. For example, the colour of a the dataset's arc are generally set this way.

| Name | Type | Description
| ---- | ---- | -----------
| `backgroundColor` | `Color/Color[]` | The fill color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
| `borderColor` | `Color/Color[]` | The border color of the arcs in the dataset. See [Colors](../general/colors.md#colors).
| `borderWidth` | `Number/Number[]` | The border width of the arcs in the dataset.
| `borderAlign` | `String/String[]` | The border alignment of the arcs in the dataset. [more...](#border-alignment)
| `hoverBackgroundColor` | `Color/Color[]` | The fill colour of the arcs when hovered.
| `hoverBorderColor` | `Color/Color[]` | The stroke colour of the arcs when hovered.
| `hoverBorderWidth` | `Number/Number[]` | The stroke width of the arcs when hovered.
| Name | Type | [Scriptable](../general/options.md#scriptable-options) | [Indexable](../general/options.md#indexable-options) | Default
| ---- | ---- | :----: | :----: | ----
| [`backgroundColor`](#styling) | [`Color`](../general/colors.md) | Yes | Yes | `'rgba(0,0,0,0.1)'`
| [`borderAlign`](#border-alignment) | `String` | Yes | Yes | `'center'`
| [`borderColor`](#styling) | [`Color`](../general/colors.md) | Yes | Yes | `'#fff'`
| [`borderWidth`](#styling) | `Number` | Yes | Yes | `2`
| [`data`](#data-structure) | `Number[]` | - | - | **required**
| [`hoverBackgroundColor`](#interations) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
| [`hoverBorderColor`](#interactions) | [`Color`](../general/colors.md) | Yes | Yes | `undefined`
| [`hoverBorderWidth`](#interactions) | `Number` | Yes | Yes | `undefined`

### Styling

The style of each arc can be controlled with the following properties:

| Name | Description
| ---- | ----
| `backgroundColor` | arc background color.
| `borderColor` | arc border color.
| `borderWidth` | arc border width (in pixels).

All these values, if `undefined`, fallback to the associated [`elements.arc.*`](../configuration/elements.md#arc-configuration) options.

### Border Alignment

Expand All @@ -71,6 +84,18 @@ The following values are supported for `borderAlign`.

When `'center'` is set, the borders of arcs next to each other will overlap. When `'inner'` is set, it is guaranteed that all the borders are not overlap.

### Interactions

The interaction with each arc can be controlled with the following properties:

| Name | Description
| ---- | -----------
| `hoverBackgroundColor` | arc background color when hovered.
| `hoverBorderColor` | arc border color when hovered.
| `hoverBorderWidth` | arc border width when hovered (in pixels).

All these values, if `undefined`, fallback to the associated [`elements.arc.*`](../configuration/elements.md#arc-configuration) options.

## Config Options

These are the customisation options specific to Pie & Doughnut charts. These options are merged with the global chart configuration options, and form the options of the chart.
Expand Down
59 changes: 52 additions & 7 deletions src/controllers/controller.doughnut.js
Expand Up @@ -315,20 +315,65 @@ module.exports = DatasetController.extend({
return max;
},

/**
* @protected
*/
setHoverStyle: function(arc) {
var model = arc._model;
var options = arc._options;
var getHoverColor = helpers.getHoverColor;
var valueOrDefault = helpers.valueOrDefault;

arc.$previousStyle = {
backgroundColor: model.backgroundColor,
borderColor: model.borderColor,
borderWidth: model.borderWidth,
};

model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));
model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));
model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);
},

/**
* @private
*/
_resolveElementOptions: function(arc, index) {
var me = this;
var chart = me.chart;
var dataset = me.getDataset();
var custom = arc.custom || {};
var options = me.chart.options.elements.arc;

return {
backgroundColor: resolve([custom.backgroundColor, dataset.backgroundColor, options.backgroundColor], undefined, index),
borderColor: resolve([custom.borderColor, dataset.borderColor, options.borderColor], undefined, index),
borderWidth: resolve([custom.borderWidth, dataset.borderWidth, options.borderWidth], undefined, index),
borderAlign: resolve([custom.borderAlign, dataset.borderAlign, options.borderAlign], undefined, index)
var options = chart.options.elements.arc;
var values = {};
var i, ilen, key;

// Scriptable options
var context = {
chart: chart,
dataIndex: index,
dataset: dataset,
datasetIndex: me.index
};

var keys = [
'backgroundColor',
'borderColor',
'borderWidth',
'borderAlign',
'hoverBackgroundColor',
'hoverBorderColor',
'hoverBorderWidth',
];

for (i = 0, ilen = keys.length; i < ilen; ++i) {
key = keys[i];
values[key] = resolve([
custom[key],
dataset[key],
options[key]
], context, index);
}

return values;
}
});
48 changes: 48 additions & 0 deletions test/fixtures/controller.doughnut/backgroundColor/indexable.js
@@ -0,0 +1,48 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: [0, 1, 2, 3, 4, 5],
datasets: [
{
// option in dataset
data: [0, 2, 4, null, 6, 8],
backgroundColor: [
'#ff0000',
'#00ff00',
'#0000ff',
'#ffff00',
'#ff00ff',
'#000000'
]
},
{
// option in element (fallback)
data: [0, 2, 4, null, 6, 8],
}
]
},
options: {
legend: false,
title: false,
elements: {
arc: {
backgroundColor: [
'#ff88ff',
'#888888',
'#ff8800',
'#00ff88',
'#8800ff',
'#ffff88'
]
}
},
}
},
options: {
canvas: {
height: 256,
width: 512
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions test/fixtures/controller.doughnut/backgroundColor/scriptable.js
@@ -0,0 +1,46 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: [0, 1, 2, 3, 4, 5],
datasets: [
{
// option in dataset
data: [0, 2, 4, null, 6, 8],
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex] || 0;
return value > 8 ? '#ff0000'
: value > 6 ? '#00ff00'
: value > 2 ? '#0000ff'
: '#ff00ff';
}
},
{
// option in element (fallback)
data: [0, 2, 4, null, 6, 8],
}
]
},
options: {
legend: false,
title: false,
elements: {
arc: {
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex] || 0;
return value > 8 ? '#ff0000'
: value > 6 ? '#00ff00'
: value > 2 ? '#0000ff'
: '#ff00ff';
}
}
},
}
},
options: {
canvas: {
height: 256,
width: 512
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions test/fixtures/controller.doughnut/backgroundColor/value.js
@@ -0,0 +1,34 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: [0, 1, 2, 3, 4, 5],
datasets: [
{
// option in dataset
data: [0, 2, 4, null, 6, 8],
backgroundColor: '#ff0000'
},
{
// option in element (fallback)
data: [0, 2, 4, null, 6, 8],
}
]
},
options: {
legend: false,
title: false,
elements: {
arc: {
backgroundColor: '#00ff00'
}
},
}
},
options: {
canvas: {
height: 256,
width: 512
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions test/fixtures/controller.doughnut/borderAlign/indexable.js
@@ -0,0 +1,52 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: [0, 1, 2, 3, 4, 5],
datasets: [
{
// option in dataset
data: [0, 2, 4, null, 6, 8],
borderAlign: [
'center',
'inner',
'center',
'inner',
'center',
'inner',
],
borderColor: '#00ff00'
},
{
// option in element (fallback)
data: [0, 2, 4, null, 6, 8],
}
]
},
options: {
legend: false,
title: false,
elements: {
arc: {
backgroundColor: 'transparent',
borderColor: '#ff0000',
borderWidth: 5,
borderAlign: [
'center',
'inner',
'center',
'inner',
'center',
'inner',
]
}
},
}
},
options: {
canvas: {
height: 256,
width: 512
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 44 additions & 0 deletions test/fixtures/controller.doughnut/borderAlign/scriptable.js
@@ -0,0 +1,44 @@
module.exports = {
config: {
type: 'doughnut',
data: {
labels: [0, 1, 2, 3, 4, 5],
datasets: [
{
// option in dataset
data: [0, 2, 4, null, 6, 8],
borderAlign: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex] || 0;
return value > 4 ? 'inner' : 'center';
},
borderColor: '#0000ff',
},
{
// option in element (fallback)
data: [0, 2, 4, null, 6, 8],
}
]
},
options: {
legend: false,
title: false,
elements: {
arc: {
backgroundColor: 'transparent',
borderColor: '#ff00ff',
borderWidth: 8,
borderAlign: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex] || 0;
return value > 4 ? 'center' : 'inner';
}
}
},
}
},
options: {
canvas: {
height: 256,
width: 512
}
}
};
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f7b06e1

Please sign in to comment.