diff --git a/docs/charts/bar.md b/docs/charts/bar.md index bf1ed4a5793..d1048a8c6e8 100644 --- a/docs/charts/bar.md +++ b/docs/charts/bar.md @@ -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: diff --git a/docs/charts/bubble.md b/docs/charts/bubble.md index 6ba1423ab69..72ee960f039 100644 --- a/docs/charts/bubble.md +++ b/docs/charts/bubble.md @@ -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). diff --git a/docs/charts/doughnut.md b/docs/charts/doughnut.md index 9fda1bbf719..9d3e8c5808e 100644 --- a/docs/charts/doughnut.md +++ b/docs/charts/doughnut.md @@ -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 @@ -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. diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index e634e4baff6..6c00e83251f 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -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; } }); diff --git a/test/fixtures/controller.doughnut/backgroundColor/indexable.js b/test/fixtures/controller.doughnut/backgroundColor/indexable.js new file mode 100644 index 00000000000..30262af86a5 --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/controller.doughnut/backgroundColor/indexable.png b/test/fixtures/controller.doughnut/backgroundColor/indexable.png new file mode 100644 index 00000000000..8dd67b0412f Binary files /dev/null and b/test/fixtures/controller.doughnut/backgroundColor/indexable.png differ diff --git a/test/fixtures/controller.doughnut/backgroundColor/scriptable.js b/test/fixtures/controller.doughnut/backgroundColor/scriptable.js new file mode 100644 index 00000000000..e2cf9a2477f --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/controller.doughnut/backgroundColor/scriptable.png b/test/fixtures/controller.doughnut/backgroundColor/scriptable.png new file mode 100644 index 00000000000..801367ba0d7 Binary files /dev/null and b/test/fixtures/controller.doughnut/backgroundColor/scriptable.png differ diff --git a/test/fixtures/controller.doughnut/backgroundColor/value.js b/test/fixtures/controller.doughnut/backgroundColor/value.js new file mode 100644 index 00000000000..0abc394fb1a --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/controller.doughnut/backgroundColor/value.png b/test/fixtures/controller.doughnut/backgroundColor/value.png new file mode 100644 index 00000000000..25e2c73a72f Binary files /dev/null and b/test/fixtures/controller.doughnut/backgroundColor/value.png differ diff --git a/test/fixtures/controller.doughnut/borderAlign/indexable.js b/test/fixtures/controller.doughnut/borderAlign/indexable.js new file mode 100644 index 00000000000..dd7798ed486 --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderAlign/indexable.png b/test/fixtures/controller.doughnut/borderAlign/indexable.png new file mode 100644 index 00000000000..4043b051e76 Binary files /dev/null and b/test/fixtures/controller.doughnut/borderAlign/indexable.png differ diff --git a/test/fixtures/controller.doughnut/borderAlign/scriptable.js b/test/fixtures/controller.doughnut/borderAlign/scriptable.js new file mode 100644 index 00000000000..29582d12b5f --- /dev/null +++ b/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 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderAlign/scriptable.png b/test/fixtures/controller.doughnut/borderAlign/scriptable.png new file mode 100644 index 00000000000..ed0030928e5 Binary files /dev/null and b/test/fixtures/controller.doughnut/borderAlign/scriptable.png differ diff --git a/test/fixtures/controller.doughnut/borderAlign/value.js b/test/fixtures/controller.doughnut/borderAlign/value.js new file mode 100644 index 00000000000..6a3d5334e50 --- /dev/null +++ b/test/fixtures/controller.doughnut/borderAlign/value.js @@ -0,0 +1,38 @@ +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: 'inner', + borderColor: '#00ff00', + }, + { + // option in element (fallback) + data: [0, 2, 4, null, 6, 8], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + arc: { + backgroundColor: 'transparent', + borderAlign: 'center', + borderColor: '#0000ff', + borderWidth: 4, + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderAlign/value.png b/test/fixtures/controller.doughnut/borderAlign/value.png new file mode 100644 index 00000000000..0d7b25355cf Binary files /dev/null and b/test/fixtures/controller.doughnut/borderAlign/value.png differ diff --git a/test/fixtures/controller.doughnut/borderColor/indexable.js b/test/fixtures/controller.doughnut/borderColor/indexable.js new file mode 100644 index 00000000000..d5cfb8022b5 --- /dev/null +++ b/test/fixtures/controller.doughnut/borderColor/indexable.js @@ -0,0 +1,50 @@ +module.exports = { + config: { + type: 'doughnut', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 2, 4, null, 6, 8], + borderColor: [ + '#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: 'transparent', + borderColor: [ + '#ff88ff', + '#888888', + '#ff8800', + '#00ff88', + '#8800ff', + '#ffff88' + ], + borderWidth: 8 + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderColor/indexable.png b/test/fixtures/controller.doughnut/borderColor/indexable.png new file mode 100644 index 00000000000..ccd7b6002a2 Binary files /dev/null and b/test/fixtures/controller.doughnut/borderColor/indexable.png differ diff --git a/test/fixtures/controller.doughnut/borderColor/scriptable.js b/test/fixtures/controller.doughnut/borderColor/scriptable.js new file mode 100644 index 00000000000..a6dc8cc3cfe --- /dev/null +++ b/test/fixtures/controller.doughnut/borderColor/scriptable.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], + borderColor: 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: 'transparent', + borderColor: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? '#ff00ff' + : value > 6 ? '#0000ff' + : value > 2 ? '#ff0000' + : '#00ff00'; + }, + borderWidth: 8 + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderColor/scriptable.png b/test/fixtures/controller.doughnut/borderColor/scriptable.png new file mode 100644 index 00000000000..dad1aaa9f4a Binary files /dev/null and b/test/fixtures/controller.doughnut/borderColor/scriptable.png differ diff --git a/test/fixtures/controller.doughnut/borderColor/value.js b/test/fixtures/controller.doughnut/borderColor/value.js new file mode 100644 index 00000000000..066ea8de4f4 --- /dev/null +++ b/test/fixtures/controller.doughnut/borderColor/value.js @@ -0,0 +1,36 @@ +module.exports = { + config: { + type: 'doughnut', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 2, 4, null, 6, 8], + borderColor: '#ff0000' + }, + { + // option in element (fallback) + data: [0, 2, 4, null, 6, 8], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + arc: { + backgroundColor: 'transparent', + borderColor: '#00ff00', + borderWidth: 8 + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderColor/value.png b/test/fixtures/controller.doughnut/borderColor/value.png new file mode 100644 index 00000000000..553d23d733c Binary files /dev/null and b/test/fixtures/controller.doughnut/borderColor/value.png differ diff --git a/test/fixtures/controller.doughnut/borderWidth/indexable.js b/test/fixtures/controller.doughnut/borderWidth/indexable.js new file mode 100644 index 00000000000..28f82c64fbd --- /dev/null +++ b/test/fixtures/controller.doughnut/borderWidth/indexable.js @@ -0,0 +1,50 @@ +module.exports = { + config: { + type: 'doughnut', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 2, 4, null, 6, 8], + borderWidth: [ + 0, + 1, + 2, + 3, + 4, + 5 + ] + }, + { + // option in element (fallback) + data: [0, 2, 4, null, 6, 8], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + arc: { + backgroundColor: 'transparent', + borderColor: '#888', + borderWidth: [ + 5, + 4, + 3, + 2, + 1, + 0 + ] + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderWidth/indexable.png b/test/fixtures/controller.doughnut/borderWidth/indexable.png new file mode 100644 index 00000000000..a1df22b99af Binary files /dev/null and b/test/fixtures/controller.doughnut/borderWidth/indexable.png differ diff --git a/test/fixtures/controller.doughnut/borderWidth/scriptable.js b/test/fixtures/controller.doughnut/borderWidth/scriptable.js new file mode 100644 index 00000000000..545c8d201ce --- /dev/null +++ b/test/fixtures/controller.doughnut/borderWidth/scriptable.js @@ -0,0 +1,41 @@ +module.exports = { + config: { + type: 'doughnut', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 2, 4, null, 6, 8], + borderWidth: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return Math.abs(value); + } + }, + { + // option in element (fallback) + data: [0, 2, 4, null, 6, 8], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + arc: { + backgroundColor: 'transparent', + borderColor: '#888', + borderWidth: function(ctx) { + return ctx.dataIndex * 2; + } + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderWidth/scriptable.png b/test/fixtures/controller.doughnut/borderWidth/scriptable.png new file mode 100644 index 00000000000..288feb767c9 Binary files /dev/null and b/test/fixtures/controller.doughnut/borderWidth/scriptable.png differ diff --git a/test/fixtures/controller.doughnut/borderWidth/value.js b/test/fixtures/controller.doughnut/borderWidth/value.js new file mode 100644 index 00000000000..4d7d285c6a1 --- /dev/null +++ b/test/fixtures/controller.doughnut/borderWidth/value.js @@ -0,0 +1,36 @@ +module.exports = { + config: { + type: 'doughnut', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 2, 4, null, 6, 8], + borderWidth: 2 + }, + { + // option in element (fallback) + data: [0, 2, 4, null, 6, 8], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + arc: { + backgroundColor: 'transparent', + borderColor: '#888', + borderWidth: 4 + } + }, + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.doughnut/borderWidth/value.png b/test/fixtures/controller.doughnut/borderWidth/value.png new file mode 100644 index 00000000000..92031158d15 Binary files /dev/null and b/test/fixtures/controller.doughnut/borderWidth/value.png differ diff --git a/test/specs/controller.doughnut.tests.js b/test/specs/controller.doughnut.tests.js index e060e0e5a53..2a4ae8f43c3 100644 --- a/test/specs/controller.doughnut.tests.js +++ b/test/specs/controller.doughnut.tests.js @@ -278,136 +278,6 @@ describe('Chart.controllers.doughnut', function() { expect(meta.data[3].draw.calls.count()).toBe(1); }); - it ('should set the hover style of an arc', function() { - var chart = window.acquireChart({ - type: 'doughnut', - data: { - datasets: [{ - data: [10, 15, 0, 4] - }], - labels: ['label0', 'label1', 'label2', 'label3'] - }, - options: { - elements: { - arc: { - backgroundColor: 'rgb(255, 0, 0)', - borderColor: 'rgb(0, 0, 255)', - borderWidth: 2, - } - } - } - }); - - var meta = chart.getDatasetMeta(0); - var arc = meta.data[0]; - - meta.controller.setHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(230, 0, 0)'); - expect(arc._model.borderColor).toBe('rgb(0, 0, 230)'); - expect(arc._model.borderWidth).toBe(2); - - // Set a dataset style to take precedence - chart.data.datasets[0].hoverBackgroundColor = 'rgb(9, 9, 9)'; - chart.data.datasets[0].hoverBorderColor = 'rgb(18, 18, 18)'; - chart.data.datasets[0].hoverBorderWidth = 1.56; - - meta.controller.setHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)'); - expect(arc._model.borderColor).toBe('rgb(18, 18, 18)'); - expect(arc._model.borderWidth).toBe(1.56); - - // Dataset styles can be an array - chart.data.datasets[0].hoverBackgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)']; - chart.data.datasets[0].hoverBorderColor = ['rgb(18, 18, 18)']; - chart.data.datasets[0].hoverBorderWidth = [0.1, 1.56]; - - meta.controller.setHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)'); - expect(arc._model.borderColor).toBe('rgb(18, 18, 18)'); - expect(arc._model.borderWidth).toBe(0.1); - - // Element custom styles also work - arc.custom = { - hoverBackgroundColor: 'rgb(7, 7, 7)', - hoverBorderColor: 'rgb(17, 17, 17)', - hoverBorderWidth: 3.14159, - }; - - meta.controller.setHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)'); - expect(arc._model.borderColor).toBe('rgb(17, 17, 17)'); - expect(arc._model.borderWidth).toBe(3.14159); - }); - - it ('should unset the hover style of an arc', function() { - var chart = window.acquireChart({ - type: 'doughnut', - data: { - datasets: [{ - data: [10, 15, 0, 4] - }], - labels: ['label0', 'label1', 'label2', 'label3'] - }, - options: { - elements: { - arc: { - backgroundColor: 'rgb(255, 0, 0)', - borderColor: 'rgb(0, 0, 255)', - borderWidth: 2, - } - } - } - }); - - var meta = chart.getDatasetMeta(0); - var arc = meta.data[0]; - - chart.update(); - meta.controller.setHoverStyle(arc); - meta.controller.removeHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(255, 0, 0)'); - expect(arc._model.borderColor).toBe('rgb(0, 0, 255)'); - expect(arc._model.borderWidth).toBe(2); - - // Set a dataset style to take precedence - chart.data.datasets[0].backgroundColor = 'rgb(9, 9, 9)'; - chart.data.datasets[0].borderColor = 'rgb(18, 18, 18)'; - chart.data.datasets[0].borderWidth = 1.56; - - chart.update(); - meta.controller.setHoverStyle(arc); - meta.controller.removeHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(9, 9, 9)'); - expect(arc._model.borderColor).toBe('rgb(18, 18, 18)'); - expect(arc._model.borderWidth).toBe(1.56); - - // Dataset styles can be an array - chart.data.datasets[0].backgroundColor = ['rgb(255, 255, 255)', 'rgb(9, 9, 9)']; - chart.data.datasets[0].borderColor = ['rgb(18, 18, 18)']; - chart.data.datasets[0].borderWidth = [0.1, 1.56]; - - chart.update(); - meta.controller.setHoverStyle(arc); - meta.controller.removeHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(255, 255, 255)'); - expect(arc._model.borderColor).toBe('rgb(18, 18, 18)'); - expect(arc._model.borderWidth).toBe(0.1); - - // Element custom styles also work - arc.custom = { - backgroundColor: 'rgb(7, 7, 7)', - borderColor: 'rgb(17, 17, 17)', - borderWidth: 3.14159, - }; - - chart.update(); - meta.controller.setHoverStyle(arc); - meta.controller.removeHoverStyle(arc); - expect(arc._model.backgroundColor).toBe('rgb(7, 7, 7)'); - expect(arc._model.borderColor).toBe('rgb(17, 17, 17)'); - expect(arc._model.borderWidth).toBe(3.14159); - }); - it ('should calculate radiuses based on the border widths of the visible outermost dataset', function() { var chart = window.acquireChart({ type: 'doughnut', @@ -455,4 +325,111 @@ describe('Chart.controllers.doughnut', function() { expect(controller.innerRadius).toBe(126); }); + describe('Interactions', function() { + beforeEach(function() { + this.chart = window.acquireChart({ + type: 'doughnut', + data: { + labels: ['label1', 'label2', 'label3', 'label4'], + datasets: [{ + data: [10, 15, 0, 4] + }] + }, + options: { + cutoutPercentage: 0, + elements: { + arc: { + backgroundColor: 'rgb(100, 150, 200)', + borderColor: 'rgb(50, 100, 150)', + borderWidth: 2, + } + } + } + }); + }); + + it ('should handle default hover styles', function() { + var chart = this.chart; + var arc = chart.getDatasetMeta(0).data[0]; + + jasmine.triggerMouseEvent(chart, 'mousemove', arc); + expect(arc._model.backgroundColor).toBe('rgb(49, 135, 221)'); + expect(arc._model.borderColor).toBe('rgb(22, 89, 156)'); + expect(arc._model.borderWidth).toBe(2); + + jasmine.triggerMouseEvent(chart, 'mouseout', arc); + expect(arc._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(arc._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(arc._model.borderWidth).toBe(2); + }); + + it ('should handle hover styles defined via dataset properties', function() { + var chart = this.chart; + var arc = chart.getDatasetMeta(0).data[0]; + + Chart.helpers.merge(chart.data.datasets[0], { + hoverBackgroundColor: 'rgb(200, 100, 150)', + hoverBorderColor: 'rgb(150, 50, 100)', + hoverBorderWidth: 8.4, + }); + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', arc); + expect(arc._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(arc._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(arc._model.borderWidth).toBe(8.4); + + jasmine.triggerMouseEvent(chart, 'mouseout', arc); + expect(arc._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(arc._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(arc._model.borderWidth).toBe(2); + }); + + it ('should handle hover styles defined via element options', function() { + var chart = this.chart; + var arc = chart.getDatasetMeta(0).data[0]; + + Chart.helpers.merge(chart.options.elements.arc, { + hoverBackgroundColor: 'rgb(200, 100, 150)', + hoverBorderColor: 'rgb(150, 50, 100)', + hoverBorderWidth: 8.4, + }); + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', arc); + expect(arc._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(arc._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(arc._model.borderWidth).toBe(8.4); + + jasmine.triggerMouseEvent(chart, 'mouseout', arc); + expect(arc._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(arc._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(arc._model.borderWidth).toBe(2); + }); + + it ('should handle hover styles defined via element custom', function() { + var chart = this.chart; + var arc = chart.getDatasetMeta(0).data[0]; + + arc.custom = { + hoverBackgroundColor: 'rgb(200, 100, 150)', + hoverBorderColor: 'rgb(150, 50, 100)', + hoverBorderWidth: 8.4, + }; + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', arc); + expect(arc._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(arc._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(arc._model.borderWidth).toBe(8.4); + + jasmine.triggerMouseEvent(chart, 'mouseout', arc); + expect(arc._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(arc._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(arc._model.borderWidth).toBe(2); + }); + }); });