From: Evert Timberg Date: Tue, 15 Jan 2019 08:24:12 +0000 (-0500) Subject: Implement scriptable options for points in line charts (#5973) X-Git-Tag: v2.8.0-rc.1~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a655da076e6a53918b94406dec7be54be45b154c;p=thirdparty%2FChart.js.git Implement scriptable options for points in line charts (#5973) --- diff --git a/docs/charts/line.md b/docs/charts/line.md index 5078a2604..4783c5514 100644 --- a/docs/charts/line.md +++ b/docs/charts/line.md @@ -41,37 +41,90 @@ var myLineChart = new Chart(ctx, { The line 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 line is generally set this way. -All point* properties can be specified as an array. If these are set to an array value, the first value applies to the first point, the second value to the second point, and so on. - -| Name | Type | Description -| ---- | ---- | ----------- -| `label` | `String` | The label for the dataset which appears in the legend and tooltips. -| `xAxisID` | `String` | The ID of the x axis to plot this dataset on. If not specified, this defaults to the ID of the first found x axis. -| `yAxisID` | `String` | The ID of the y axis to plot this dataset on. If not specified, this defaults to the ID of the first found y axis. -| `backgroundColor` | `Color` | The fill color under the line. See [Colors](../general/colors.md#colors). -| `borderColor` | `Color` | The color of the line. See [Colors](../general/colors.md#colors). -| `borderWidth` | `Number` | The width of the line in pixels. -| `borderDash` | `Number[]` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash). -| `borderDashOffset` | `Number` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). -| `borderCapStyle` | `String` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap). -| `borderJoinStyle` | `String` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin). -| `cubicInterpolationMode` | `String` | Algorithm used to interpolate a smooth curve from the discrete data points. [more...](#cubicinterpolationmode) -| `fill` | `Boolean/String` | How to fill the area under the line. See [area charts](area.md). -| `lineTension` | `Number` | Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used. -| `pointBackgroundColor` | `Color/Color[]` | The fill color for points. -| `pointBorderColor` | `Color/Color[]` | The border color for points. -| `pointBorderWidth` | `Number/Number[]` | The width of the point border in pixels. -| `pointRadius` | `Number/Number[]` | The radius of the point shape. If set to 0, the point is not rendered. -| `pointStyle` | `String/String[]/Image/Image[]` | Style of the point. [more...](../configuration/elements#point-styles) -| `pointRotation` | `Number/Number[]` | The rotation of the point in degrees. -| `pointHitRadius` | `Number/Number[]` | The pixel size of the non-displayed point that reacts to mouse events. -| `pointHoverBackgroundColor` | `Color/Color[]` | Point background color when hovered. -| `pointHoverBorderColor` | `Color/Color[]` | Point border color when hovered. -| `pointHoverBorderWidth` | `Number/Number[]` | Border width of point when hovered. -| `pointHoverRadius` | `Number/Number[]` | The radius of the point when hovered. -| `showLine` | `Boolean` | If false, the line is not drawn for this dataset. -| `spanGaps` | `Boolean` | If true, lines will be drawn between points with no or null data. If false, points with `NaN` data will create a break in the line. -| `steppedLine` | `Boolean/String` | If the line is shown as a stepped line. [more...](#stepped-line) +| Name | Type | [Scriptable](../general/options.md#scriptable-options) | [Indexable](../general/options.md#indexable-options) | Default +| ---- | ---- | :----: | :----: | ---- +| [`backgroundColor`](#line-styling) | [`Color`](../general/colors.md) | - | - | `'rgba(0,0,0,0.1)'` +| [`borderCapStyle`](#line-styling) | `String` | - | - | `'butt'` +| [`borderColor`](#line-styling) | [`Color`](../general/colors.md) | - | - | `'rgba(0,0,0,0.1)'` +| [`borderDash`](#line-styling) | `Number[]` | - | - | `[]` +| [`borderDashOffset`](#line-styling) | `Number` | - | - | `0` +| [`borderJoinStyle`](#line-styling) | `String` | - | - | `'miter'` +| [`borderWidth`](#line-styling) | `Number` | - | - | `0` +| [`cubicInterpolationMode`](#cubicInterpolationMode) | `String` | - | - | `''` +| [`fill`](#line-styling) | `Boolean/String` | - | - | `true` +| [`label`](#general) | `String` | - | - | `''` +| [`lineTension`](#line-styling) | `Number` | - | - | `0.4` +| [`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` +| [`pointHitRadius`](#point-styling) | `Number` | Yes | Yes | `1` +| [`pointHoverBackgroundColor`](#interactions) | `Color` | Yes | Yes | `undefined` +| [`pointHoverBorderColor`](#interactions) | `Color` | Yes | Yes | `undefined` +| [`pointHoverBorderWidth`](#interactions) | `Number` | Yes | Yes | `undefined` +| [`pointHoverRadius`](#interactions) | `Number` | Yes | Yes | `undefined` +| [`pointRadius`](#point-styling) | `Number` | Yes | Yes | `3` +| [`pointRotation`](#point-styling) | `Number` | Yes | Yes | `1` +| [`pointStyle`](#point-styling) | `String/Image` | Yes | Yes | `'circle'` +| [`showLine`](#general) | `Boolean` | - | - | `undefined` +| [`spanGaps`](#general) | `Boolean` | - | - | `false` +| [`steppedLine`](#stepped-line) | `Boolean/String` | - | - | `false` +| [`xAxisID`](#general) | `String` | - | - | first x axis +| [`yAxisID`](#general) | `String` | - | - | first y axis + +### General + +| Name | Description +| ---- | ---- +| `label` | The label for the dataset which appears in the legend and tooltips. +| `xAxisID` | The ID of the x axis to plot this dataset on. +| `yAxisID` | The ID of the y axis to plot this dataset on. + +### Point Styling + +The style of each point can be controlled with the following properties: + +| Name | Description +| ---- | ---- +| `pointBackgroundColor` | The fill color for points. +| `pointBorderColor` | The border color for points. +| `pointBorderWidth` | The width of the point border in pixels. +| `pointHitRadius` | The pixel size of the non-displayed point that reacts to mouse events. +| `pointRadius` | The radius of the point shape. If set to 0, the point is not rendered. +| `pointRotation` | The rotation of the point in degrees. +| `pointStyle` | Style of the point. [more...](../configuration/elements#point-styles) + +All these values, if `undefined`, fallback first to the dataset options then to the associated [`elements.point.*`](../configuration/elements.md#point-configuration) options. + +### Line Styling + +The style of the line can be controlled with the following properties: + +| Name | Description +| ---- | ---- +| `backgroundColor` | The line fill color. +| `borderCapStyle` | Cap style of the line. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap). +| `borderColor` | The line color. +| `borderDash` | Length and spacing of dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/setLineDash). +| `borderDashOffset` | Offset for line dashes. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineDashOffset). +| `borderJoinStyle` | Line joint style. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin). +| `borderWidth` | The line width (in pixels). +| `fill` | How to fill the area under the line. See [area charts](area.md). +| `lineTension` | Bezier curve tension of the line. Set to 0 to draw straightlines. This option is ignored if monotone cubic interpolation is used. +| `showLine` | If false, the line is not drawn for this dataset. +| `spanGaps` | If true, lines will be drawn between points with no or null data. If false, points with `NaN` data will create a break in the line. + +All these values, if `undefined`, fallback to the associated [`elements.line.*`](../configuration/elements.md#line-configuration) options. + +### Interactions + +The interaction with each point can be controlled with the following properties: + +| Name | Description +| ---- | ----------- +| `pointHoverBackgroundColor` | Point background color when hovered. +| `pointHoverBorderColor` | Point border color when hovered. +| `pointHoverBorderWidth` | Border width of point when hovered. +| `pointHoverRadius` | The radius of the point when hovered. ### cubicInterpolationMode The following interpolation modes are supported. diff --git a/docs/general/options.md b/docs/general/options.md index e05cd33ee..37f154613 100644 --- a/docs/general/options.md +++ b/docs/general/options.md @@ -2,7 +2,7 @@ ## Scriptable Options -Scriptable options also accept a function which is called for each data and that takes the unique argument `context` representing contextual information (see [option context](options.md#option-context)). +Scriptable options also accept a function which is called for each of the underlying data values and that takes the unique argument `context` representing contextual information (see [option context](options.md#option-context)). Example: diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 0e313116e..e57d5e2ff 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -103,52 +103,6 @@ module.exports = DatasetController.extend({ } }, - getPointBackgroundColor: function(point, index) { - var dataset = this.getDataset(); - var custom = point.custom || {}; - - return resolve([ - custom.backgroundColor, - dataset.pointBackgroundColor, - dataset.backgroundColor, - this.chart.options.elements.point.backgroundColor - ], undefined, index); - }, - - getPointBorderColor: function(point, index) { - var dataset = this.getDataset(); - var custom = point.custom || {}; - - return resolve([ - custom.borderColor, - dataset.pointBorderColor, - dataset.borderColor, - this.chart.options.elements.point.borderColor - ], undefined, index); - }, - - getPointBorderWidth: function(point, index) { - var dataset = this.getDataset(); - var custom = point.custom || {}; - - return resolve([ - custom.borderWidth, - dataset.pointBorderWidth, - dataset.borderWidth, - this.chart.options.elements.point.borderWidth - ], undefined, index); - }, - - getPointRotation: function(point, index) { - var custom = point.custom || {}; - - return resolve([ - custom.rotation, - this.getDataset().pointRotation, - this.chart.options.elements.point.rotation - ], undefined, index); - }, - updateElement: function(point, index, reset) { var me = this; var meta = me.getMeta(); @@ -158,16 +112,9 @@ module.exports = DatasetController.extend({ var value = dataset.data[index]; var yScale = me.getScaleForId(meta.yAxisID); var xScale = me.getScaleForId(meta.xAxisID); - var pointOptions = me.chart.options.elements.point; var x, y; - // Compatibility: If the properties are defined with only the old name, use those values - if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { - dataset.pointRadius = dataset.radius; - } - if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { - dataset.pointHitRadius = dataset.hitRadius; - } + var options = me._resolveElementOptions(point, index); x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex); y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex); @@ -175,6 +122,7 @@ module.exports = DatasetController.extend({ // Utility point._xScale = xScale; point._yScale = yScale; + point._options = options; point._datasetIndex = datasetIndex; point._index = index; @@ -184,19 +132,68 @@ module.exports = DatasetController.extend({ y: y, skip: custom.skip || isNaN(x) || isNaN(y), // Appearance - radius: resolve([custom.radius, dataset.pointRadius, pointOptions.radius], undefined, index), - pointStyle: resolve([custom.pointStyle, dataset.pointStyle, pointOptions.pointStyle], undefined, index), - rotation: me.getPointRotation(point, index), - backgroundColor: me.getPointBackgroundColor(point, index), - borderColor: me.getPointBorderColor(point, index), - borderWidth: me.getPointBorderWidth(point, index), + radius: options.radius, + pointStyle: options.pointStyle, + rotation: options.rotation, + backgroundColor: options.backgroundColor, + borderColor: options.borderColor, + borderWidth: options.borderWidth, tension: meta.dataset._model ? meta.dataset._model.tension : 0, steppedLine: meta.dataset._model ? meta.dataset._model.steppedLine : false, // Tooltip - hitRadius: resolve([custom.hitRadius, dataset.pointHitRadius, pointOptions.hitRadius], undefined, index) + hitRadius: options.hitRadius, }; }, + /** + * @private + */ + _resolveElementOptions: function(point, index) { + var me = this; + var chart = me.chart; + var datasets = chart.data.datasets; + var dataset = datasets[me.index]; + var custom = point.custom || {}; + var options = chart.options.elements.point; + var values = {}; + var i, ilen, key; + + // Scriptable options + var context = { + chart: chart, + dataIndex: index, + dataset: dataset, + datasetIndex: me.index + }; + + var ELEMENT_OPTIONS = { + backgroundColor: 'pointBackgroundColor', + borderColor: 'pointBorderColor', + borderWidth: 'pointBorderWidth', + hitRadius: 'pointHitRadius', + hoverBackgroundColor: 'pointHoverBackgroundColor', + hoverBorderColor: 'pointHoverBorderColor', + hoverBorderWidth: 'pointHoverBorderWidth', + hoverRadius: 'pointHoverRadius', + pointStyle: 'pointStyle', + radius: 'pointRadius', + rotation: 'pointRotation', + }; + var keys = Object.keys(ELEMENT_OPTIONS); + + for (i = 0, ilen = keys.length; i < ilen; ++i) { + key = keys[i]; + values[key] = resolve([ + custom[key], + dataset[ELEMENT_OPTIONS[key]], + dataset[key], + options[key] + ], context, index); + } + + return values; + }, + calculatePointY: function(value, index, datasetIndex) { var me = this; var chart = me.chart; @@ -317,24 +314,24 @@ module.exports = DatasetController.extend({ } }, - setHoverStyle: function(element) { - // Point - var dataset = this.chart.data.datasets[element._datasetIndex]; - var index = element._index; - var custom = element.custom || {}; - var model = element._model; + /** + * @protected + */ + setHoverStyle: function(point) { + var model = point._model; + var options = point._options; var getHoverColor = helpers.getHoverColor; - element.$previousStyle = { + point.$previousStyle = { backgroundColor: model.backgroundColor, borderColor: model.borderColor, borderWidth: model.borderWidth, radius: model.radius }; - model.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.pointHoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index); - model.borderColor = resolve([custom.hoverBorderColor, dataset.pointHoverBorderColor, getHoverColor(model.borderColor)], undefined, index); - model.borderWidth = resolve([custom.hoverBorderWidth, dataset.pointHoverBorderWidth, model.borderWidth], undefined, index); - model.radius = resolve([custom.hoverRadius, dataset.pointHoverRadius, this.chart.options.elements.point.hoverRadius], undefined, index); - } + model.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor)); + model.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor)); + model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth); + model.radius = valueOrDefault(options.hoverRadius, options.radius); + }, }); diff --git a/test/fixtures/controller.line/backgroundColor/indexable.js b/test/fixtures/controller.line/backgroundColor/indexable.js new file mode 100644 index 000000000..7b939724e --- /dev/null +++ b/test/fixtures/controller.line/backgroundColor/indexable.js @@ -0,0 +1,56 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: [ + '#ff0000', + '#00ff00', + '#0000ff', + '#ffff00', + '#ff00ff', + '#000000' + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: [ + '#ff88ff', + '#888888', + '#ff8800', + '#00ff88', + '#8800ff', + '#ffff88' + ], + radius: 10 + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/backgroundColor/indexable.png b/test/fixtures/controller.line/backgroundColor/indexable.png new file mode 100644 index 000000000..d41579644 Binary files /dev/null and b/test/fixtures/controller.line/backgroundColor/indexable.png differ diff --git a/test/fixtures/controller.line/backgroundColor/scriptable.js b/test/fixtures/controller.line/backgroundColor/scriptable.js new file mode 100644 index 000000000..6ede2cb0c --- /dev/null +++ b/test/fixtures/controller.line/backgroundColor/scriptable.js @@ -0,0 +1,61 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? '#ff0000' + : value > 0 ? '#00ff00' + : value > -8 ? '#0000ff' + : '#ff00ff'; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? '#ff00ff' + : value > 0 ? '#0000ff' + : value > -8 ? '#ff0000' + : '#00ff00'; + }, + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/backgroundColor/scriptable.png b/test/fixtures/controller.line/backgroundColor/scriptable.png new file mode 100644 index 000000000..c366b6cfa Binary files /dev/null and b/test/fixtures/controller.line/backgroundColor/scriptable.png differ diff --git a/test/fixtures/controller.line/backgroundColor/value.js b/test/fixtures/controller.line/backgroundColor/value.js new file mode 100644 index 000000000..a096cae00 --- /dev/null +++ b/test/fixtures/controller.line/backgroundColor/value.js @@ -0,0 +1,42 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#ff0000' + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#00ff00', + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/backgroundColor/value.png b/test/fixtures/controller.line/backgroundColor/value.png new file mode 100644 index 000000000..88c75c897 Binary files /dev/null and b/test/fixtures/controller.line/backgroundColor/value.png differ diff --git a/test/fixtures/controller.line/borderColor/indexable.js b/test/fixtures/controller.line/borderColor/indexable.js new file mode 100644 index 000000000..9a186e950 --- /dev/null +++ b/test/fixtures/controller.line/borderColor/indexable.js @@ -0,0 +1,56 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: [ + '#ff0000', + '#00ff00', + '#0000ff', + '#ffff00', + '#ff00ff', + '#000000' + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: [ + '#ff88ff', + '#888888', + '#ff8800', + '#00ff88', + '#8800ff', + '#ffff88' + ], + radius: 10 + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderColor/indexable.png b/test/fixtures/controller.line/borderColor/indexable.png new file mode 100644 index 000000000..c50bdf045 Binary files /dev/null and b/test/fixtures/controller.line/borderColor/indexable.png differ diff --git a/test/fixtures/controller.line/borderColor/scriptable.js b/test/fixtures/controller.line/borderColor/scriptable.js new file mode 100644 index 000000000..04b123606 --- /dev/null +++ b/test/fixtures/controller.line/borderColor/scriptable.js @@ -0,0 +1,61 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? '#ff0000' + : value > 0 ? '#00ff00' + : value > -8 ? '#0000ff' + : '#ff00ff'; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? '#ff00ff' + : value > 0 ? '#0000ff' + : value > -8 ? '#ff0000' + : '#00ff00'; + }, + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderColor/scriptable.png b/test/fixtures/controller.line/borderColor/scriptable.png new file mode 100644 index 000000000..6366828ec Binary files /dev/null and b/test/fixtures/controller.line/borderColor/scriptable.png differ diff --git a/test/fixtures/controller.line/borderColor/value.js b/test/fixtures/controller.line/borderColor/value.js new file mode 100644 index 000000000..84e4d6adf --- /dev/null +++ b/test/fixtures/controller.line/borderColor/value.js @@ -0,0 +1,42 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#ff0000' + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#00ff00', + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderColor/value.png b/test/fixtures/controller.line/borderColor/value.png new file mode 100644 index 000000000..6bfde92f5 Binary files /dev/null and b/test/fixtures/controller.line/borderColor/value.png differ diff --git a/test/fixtures/controller.line/borderWidth/indexable.js b/test/fixtures/controller.line/borderWidth/indexable.js new file mode 100644 index 000000000..fad97da1e --- /dev/null +++ b/test/fixtures/controller.line/borderWidth/indexable.js @@ -0,0 +1,48 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#00ff00', + pointBorderWidth: [ + 1, 2, 3, 4, 5, 6 + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#ff0000', + borderWidth: [ + 6, 5, 4, 3, 2, 1 + ], + radius: 10 + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderWidth/indexable.png b/test/fixtures/controller.line/borderWidth/indexable.png new file mode 100644 index 000000000..b38c1b6b9 Binary files /dev/null and b/test/fixtures/controller.line/borderWidth/indexable.png differ diff --git a/test/fixtures/controller.line/borderWidth/scriptable.js b/test/fixtures/controller.line/borderWidth/scriptable.js new file mode 100644 index 000000000..a40ac1cb0 --- /dev/null +++ b/test/fixtures/controller.line/borderWidth/scriptable.js @@ -0,0 +1,61 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#0000ff', + pointBorderWidth: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 10 + : value > -4 ? 5 + : 2; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#ff0000', + borderWidth: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 2 + : value > -4 ? 5 + : 10; + }, + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderWidth/scriptable.png b/test/fixtures/controller.line/borderWidth/scriptable.png new file mode 100644 index 000000000..7bb6b1b3c Binary files /dev/null and b/test/fixtures/controller.line/borderWidth/scriptable.png differ diff --git a/test/fixtures/controller.line/borderWidth/value.js b/test/fixtures/controller.line/borderWidth/value.js new file mode 100644 index 000000000..291f422e5 --- /dev/null +++ b/test/fixtures/controller.line/borderWidth/value.js @@ -0,0 +1,44 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#0000ff', + pointBorderWidth: 6 + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#00ff00', + borderWidth: 3, + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/borderWidth/value.png b/test/fixtures/controller.line/borderWidth/value.png new file mode 100644 index 000000000..0b8f38c1d Binary files /dev/null and b/test/fixtures/controller.line/borderWidth/value.png differ diff --git a/test/fixtures/controller.line/pointStyle/indexable.js b/test/fixtures/controller.line/pointStyle/indexable.js new file mode 100644 index 000000000..508087086 --- /dev/null +++ b/test/fixtures/controller.line/pointStyle/indexable.js @@ -0,0 +1,60 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#ff0000', + pointBorderColor: '#ff0000', + pointStyle: [ + 'circle', + 'cross', + 'crossRot', + 'dash', + 'line', + 'rect', + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#00ff00', + borderColor: '#00ff00', + pointStyle: [ + 'line', + 'rect', + 'rectRounded', + 'rectRot', + 'star', + 'triangle' + ], + radius: 10 + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/pointStyle/indexable.png b/test/fixtures/controller.line/pointStyle/indexable.png new file mode 100644 index 000000000..9534602ab Binary files /dev/null and b/test/fixtures/controller.line/pointStyle/indexable.png differ diff --git a/test/fixtures/controller.line/pointStyle/scriptable.js b/test/fixtures/controller.line/pointStyle/scriptable.js new file mode 100644 index 000000000..c2a48ce82 --- /dev/null +++ b/test/fixtures/controller.line/pointStyle/scriptable.js @@ -0,0 +1,65 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#ff0000', + pointBorderColor: '#ff0000', + pointStyle: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? 'rect' + : value > 0 ? 'star' + : value > -8 ? 'cross' + : 'triangle'; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#0000ff', + borderColor: '#0000ff', + pointStyle: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 8 ? 'triangle' + : value > 0 ? 'cross' + : value > -8 ? 'star' + : 'rect'; + }, + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/pointStyle/scriptable.png b/test/fixtures/controller.line/pointStyle/scriptable.png new file mode 100644 index 000000000..970439ee7 Binary files /dev/null and b/test/fixtures/controller.line/pointStyle/scriptable.png differ diff --git a/test/fixtures/controller.line/pointStyle/value.js b/test/fixtures/controller.line/pointStyle/value.js new file mode 100644 index 000000000..3e2f2cf58 --- /dev/null +++ b/test/fixtures/controller.line/pointStyle/value.js @@ -0,0 +1,44 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#ff0000', + pointStyle: 'star', + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#00ff00', + pointStyle: 'rect', + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/pointStyle/value.png b/test/fixtures/controller.line/pointStyle/value.png new file mode 100644 index 000000000..c8c488166 Binary files /dev/null and b/test/fixtures/controller.line/pointStyle/value.png differ diff --git a/test/fixtures/controller.line/radius/indexable.js b/test/fixtures/controller.line/radius/indexable.js new file mode 100644 index 000000000..f2b70d385 --- /dev/null +++ b/test/fixtures/controller.line/radius/indexable.js @@ -0,0 +1,47 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#00ff00', + pointRadius: [ + 1, 2, 3, 4, 5, 6 + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#ff0000', + radius: [ + 6, 5, 4, 3, 2, 1 + ], + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/radius/indexable.png b/test/fixtures/controller.line/radius/indexable.png new file mode 100644 index 000000000..6de406261 Binary files /dev/null and b/test/fixtures/controller.line/radius/indexable.png differ diff --git a/test/fixtures/controller.line/radius/scriptable.js b/test/fixtures/controller.line/radius/scriptable.js new file mode 100644 index 000000000..7e2068a4f --- /dev/null +++ b/test/fixtures/controller.line/radius/scriptable.js @@ -0,0 +1,60 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#0000ff', + pointRadius: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 10 + : value > -4 ? 5 + : 2; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#ff0000', + radius: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 2 + : value > -4 ? 5 + : 10; + }, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/radius/scriptable.png b/test/fixtures/controller.line/radius/scriptable.png new file mode 100644 index 000000000..4ee9c9f1f Binary files /dev/null and b/test/fixtures/controller.line/radius/scriptable.png differ diff --git a/test/fixtures/controller.line/radius/value.js b/test/fixtures/controller.line/radius/value.js new file mode 100644 index 000000000..bba6146ec --- /dev/null +++ b/test/fixtures/controller.line/radius/value.js @@ -0,0 +1,43 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBackgroundColor: '#0000ff', + pointRadius: 6 + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + backgroundColor: '#00ff00', + radius: 3, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/radius/value.png b/test/fixtures/controller.line/radius/value.png new file mode 100644 index 000000000..3ad5310d8 Binary files /dev/null and b/test/fixtures/controller.line/radius/value.png differ diff --git a/test/fixtures/controller.line/rotation/indexable.js b/test/fixtures/controller.line/rotation/indexable.js new file mode 100644 index 000000000..4aea90a87 --- /dev/null +++ b/test/fixtures/controller.line/rotation/indexable.js @@ -0,0 +1,49 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#00ff00', + pointRotation: [ + 0, 30, 60, 90, 120, 150 + ] + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#ff0000', + borderWidth: 10, + pointStyle: 'line', + rotation: [ + 150, 120, 90, 60, 30, 0 + ], + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/rotation/indexable.png b/test/fixtures/controller.line/rotation/indexable.png new file mode 100644 index 000000000..e6c71897a Binary files /dev/null and b/test/fixtures/controller.line/rotation/indexable.png differ diff --git a/test/fixtures/controller.line/rotation/scriptable.js b/test/fixtures/controller.line/rotation/scriptable.js new file mode 100644 index 000000000..5a130f29e --- /dev/null +++ b/test/fixtures/controller.line/rotation/scriptable.js @@ -0,0 +1,62 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#0000ff', + pointRotation: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 120 + : value > -4 ? 60 + : 0; + } + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#ff0000', + rotation: function(ctx) { + var value = ctx.dataset.data[ctx.dataIndex] || 0; + return value > 4 ? 0 + : value > -4 ? 60 + : 120; + }, + pointStyle: 'line', + radius: 10, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [ + { + display: false, + ticks: { + beginAtZero: true + } + } + ] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/rotation/scriptable.png b/test/fixtures/controller.line/rotation/scriptable.png new file mode 100644 index 000000000..29571fad7 Binary files /dev/null and b/test/fixtures/controller.line/rotation/scriptable.png differ diff --git a/test/fixtures/controller.line/rotation/value.js b/test/fixtures/controller.line/rotation/value.js new file mode 100644 index 000000000..7cc6e2e57 --- /dev/null +++ b/test/fixtures/controller.line/rotation/value.js @@ -0,0 +1,45 @@ +module.exports = { + config: { + type: 'line', + data: { + labels: [0, 1, 2, 3, 4, 5], + datasets: [ + { + // option in dataset + data: [0, 5, 10, null, -10, -5], + pointBorderColor: '#0000ff', + pointRotation: 90 + }, + { + // option in element (fallback) + data: [4, -5, -10, null, 10, 5], + } + ] + }, + options: { + legend: false, + title: false, + elements: { + line: { + fill: false, + }, + point: { + borderColor: '#00ff00', + pointStyle: 'line', + radius: 10, + rotation: 0, + } + }, + scales: { + xAxes: [{display: false}], + yAxes: [{display: false}] + } + } + }, + options: { + canvas: { + height: 256, + width: 512 + } + } +}; diff --git a/test/fixtures/controller.line/rotation/value.png b/test/fixtures/controller.line/rotation/value.png new file mode 100644 index 000000000..3c1f82d6f Binary files /dev/null and b/test/fixtures/controller.line/rotation/value.png differ diff --git a/test/specs/controller.line.tests.js b/test/specs/controller.line.tests.js index f3a3351de..285f5c988 100644 --- a/test/specs/controller.line.tests.js +++ b/test/specs/controller.line.tests.js @@ -603,157 +603,123 @@ describe('Chart.controllers.line', function() { expect(meta.data[4] instanceof Chart.elements.Point).toBe(true); }); - it('should set point hover styles', function() { - var chart = window.acquireChart({ - type: 'line', - data: { - datasets: [{ - data: [10, 15, 0, -4], - label: 'dataset1', - }], - labels: ['label1', 'label2', 'label3', 'label4'] - }, - options: { - elements: { - point: { - backgroundColor: 'rgb(255, 255, 0)', - borderWidth: 1, - borderColor: 'rgb(255, 255, 255)', - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1, - radius: 3, + describe('Interactions', function() { + beforeEach(function() { + this.chart = window.acquireChart({ + type: 'line', + data: { + labels: ['label1', 'label2', 'label3', 'label4'], + datasets: [{ + data: [10, 15, 0, -4] + }] + }, + options: { + elements: { + point: { + backgroundColor: 'rgb(100, 150, 200)', + borderColor: 'rgb(50, 100, 150)', + borderWidth: 2, + radius: 3 + } } } - } + }); }); - var meta = chart.getDatasetMeta(0); - var point = meta.data[0]; - - meta.controller.setHoverStyle(point); - expect(point._model.backgroundColor).toBe('rgb(229, 230, 0)'); - expect(point._model.borderColor).toBe('rgb(230, 230, 230)'); - expect(point._model.borderWidth).toBe(1); - expect(point._model.radius).toBe(4); - - // Can set hover style per dataset - chart.data.datasets[0].pointHoverRadius = 3.3; - chart.data.datasets[0].pointHoverBackgroundColor = 'rgb(77, 79, 81)'; - chart.data.datasets[0].pointHoverBorderColor = 'rgb(123, 125, 127)'; - chart.data.datasets[0].pointHoverBorderWidth = 2.1; - - meta.controller.setHoverStyle(point); - expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)'); - expect(point._model.borderColor).toBe('rgb(123, 125, 127)'); - expect(point._model.borderWidth).toBe(2.1); - expect(point._model.radius).toBe(3.3); - - // Use the consistent name "pointRadius", setting but overwriting - // another value in "radius" - chart.data.datasets[0].pointRadius = 250; - chart.data.datasets[0].radius = 20; - - meta.controller.setHoverStyle(point); - expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)'); - expect(point._model.borderColor).toBe('rgb(123, 125, 127)'); - expect(point._model.borderWidth).toBe(2.1); - expect(point._model.radius).toBe(3.3); - - // Custom style - point.custom = { - hoverRadius: 4.4, - hoverBorderWidth: 5.5, - hoverBackgroundColor: 'rgb(0, 0, 0)', - hoverBorderColor: 'rgb(10, 10, 10)' - }; - - meta.controller.setHoverStyle(point); - expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)'); - expect(point._model.borderColor).toBe('rgb(10, 10, 10)'); - expect(point._model.borderWidth).toBe(5.5); - expect(point._model.radius).toBe(4.4); - }); - - it('should remove hover styles', function() { - var chart = window.acquireChart({ - type: 'line', - data: { - datasets: [{ - data: [10, 15, 0, -4], - label: 'dataset1', - }], - labels: ['label1', 'label2', 'label3', 'label4'] - }, - options: { - elements: { - point: { - backgroundColor: 'rgb(255, 255, 0)', - borderWidth: 1, - borderColor: 'rgb(255, 255, 255)', - hitRadius: 1, - hoverRadius: 4, - hoverBorderWidth: 1, - radius: 3, - } - } - } + it ('should handle default hover styles', function() { + var chart = this.chart; + var point = chart.getDatasetMeta(0).data[0]; + + jasmine.triggerMouseEvent(chart, 'mousemove', point); + expect(point._model.backgroundColor).toBe('rgb(49, 135, 221)'); + expect(point._model.borderColor).toBe('rgb(22, 89, 156)'); + expect(point._model.borderWidth).toBe(1); + expect(point._model.radius).toBe(4); + + jasmine.triggerMouseEvent(chart, 'mouseout', point); + expect(point._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(point._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(point._model.borderWidth).toBe(2); + expect(point._model.radius).toBe(3); }); - var meta = chart.getDatasetMeta(0); - var point = meta.data[0]; - - chart.options.elements.point.backgroundColor = 'rgb(45, 46, 47)'; - chart.options.elements.point.borderColor = 'rgb(50, 51, 52)'; - chart.options.elements.point.borderWidth = 10.1; - chart.options.elements.point.radius = 1.01; - - meta.controller.removeHoverStyle(point); - chart.update(); - expect(point._model.backgroundColor).toBe('rgb(45, 46, 47)'); - expect(point._model.borderColor).toBe('rgb(50, 51, 52)'); - expect(point._model.borderWidth).toBe(10.1); - expect(point._model.radius).toBe(1.01); - - // Can set hover style per dataset - chart.data.datasets[0].radius = 3.3; - chart.data.datasets[0].pointBackgroundColor = 'rgb(77, 79, 81)'; - chart.data.datasets[0].pointBorderColor = 'rgb(123, 125, 127)'; - chart.data.datasets[0].pointBorderWidth = 2.1; - - meta.controller.removeHoverStyle(point); - chart.update(); - expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)'); - expect(point._model.borderColor).toBe('rgb(123, 125, 127)'); - expect(point._model.borderWidth).toBe(2.1); - expect(point._model.radius).toBe(3.3); + it ('should handle hover styles defined via dataset properties', function() { + var chart = this.chart; + var point = 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, + hoverRadius: 4.2 + }); + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', point); + expect(point._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(point._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(point._model.borderWidth).toBe(8.4); + expect(point._model.radius).toBe(4.2); + + jasmine.triggerMouseEvent(chart, 'mouseout', point); + expect(point._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(point._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(point._model.borderWidth).toBe(2); + expect(point._model.radius).toBe(3); + }); - // Use the consistent name "pointRadius", setting but overwriting - // another value in "radius" - chart.data.datasets[0].pointRadius = 250; - chart.data.datasets[0].radius = 20; + it ('should handle hover styles defined via element options', function() { + var chart = this.chart; + var point = chart.getDatasetMeta(0).data[0]; + + Chart.helpers.merge(chart.options.elements.point, { + hoverBackgroundColor: 'rgb(200, 100, 150)', + hoverBorderColor: 'rgb(150, 50, 100)', + hoverBorderWidth: 8.4, + hoverRadius: 4.2 + }); + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', point); + expect(point._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(point._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(point._model.borderWidth).toBe(8.4); + expect(point._model.radius).toBe(4.2); + + jasmine.triggerMouseEvent(chart, 'mouseout', point); + expect(point._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(point._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(point._model.borderWidth).toBe(2); + expect(point._model.radius).toBe(3); + }); - meta.controller.removeHoverStyle(point); - chart.update(); - expect(point._model.backgroundColor).toBe('rgb(77, 79, 81)'); - expect(point._model.borderColor).toBe('rgb(123, 125, 127)'); - expect(point._model.borderWidth).toBe(2.1); - expect(point._model.radius).toBe(250); - - // Custom style - point.custom = { - radius: 4.4, - borderWidth: 5.5, - backgroundColor: 'rgb(0, 0, 0)', - borderColor: 'rgb(10, 10, 10)' - }; - - meta.controller.removeHoverStyle(point); - chart.update(); - expect(point._model.backgroundColor).toBe('rgb(0, 0, 0)'); - expect(point._model.borderColor).toBe('rgb(10, 10, 10)'); - expect(point._model.borderWidth).toBe(5.5); - expect(point._model.radius).toBe(4.4); + it ('should handle hover styles defined via element custom', function() { + var chart = this.chart; + var point = chart.getDatasetMeta(0).data[0]; + + point.custom = { + hoverBackgroundColor: 'rgb(200, 100, 150)', + hoverBorderColor: 'rgb(150, 50, 100)', + hoverBorderWidth: 8.4, + hoverRadius: 4.2 + }; + + chart.update(); + + jasmine.triggerMouseEvent(chart, 'mousemove', point); + expect(point._model.backgroundColor).toBe('rgb(200, 100, 150)'); + expect(point._model.borderColor).toBe('rgb(150, 50, 100)'); + expect(point._model.borderWidth).toBe(8.4); + expect(point._model.radius).toBe(4.2); + + jasmine.triggerMouseEvent(chart, 'mouseout', point); + expect(point._model.backgroundColor).toBe('rgb(100, 150, 200)'); + expect(point._model.borderColor).toBe('rgb(50, 100, 150)'); + expect(point._model.borderWidth).toBe(2); + expect(point._model.radius).toBe(3); + }); }); it('should allow 0 as a point border width', function() {