diff --git a/docs/charts/line.md b/docs/charts/line.md index 5078a2604de..4783c551470 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 e05cd33ee4a..37f15461302 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 0e313116ef4..e57d5e2ffb2 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 00000000000..7b939724e6b --- /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 00000000000..d4157964479 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 00000000000..6ede2cb0c15 --- /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 00000000000..c366b6cfadf 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 00000000000..a096cae00ea --- /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 00000000000..88c75c89771 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 00000000000..9a186e95040 --- /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 00000000000..c50bdf04535 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 00000000000..04b12360647 --- /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 00000000000..6366828ecfc 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 00000000000..84e4d6adfb9 --- /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 00000000000..6bfde92f541 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 00000000000..fad97da1e5c --- /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 00000000000..b38c1b6b94d 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 00000000000..a40ac1cb0a4 --- /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 00000000000..7bb6b1b3c77 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 00000000000..291f422e527 --- /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 00000000000..0b8f38c1d62 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 00000000000..50808708615 --- /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 00000000000..9534602ab2d 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 00000000000..c2a48ce8249 --- /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 00000000000..970439ee785 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 00000000000..3e2f2cf58ad --- /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 00000000000..c8c488166a4 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 00000000000..f2b70d385d8 --- /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 00000000000..6de4062614d 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 00000000000..7e2068a4f91 --- /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 00000000000..4ee9c9f1f99 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 00000000000..bba6146ec62 --- /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 00000000000..3ad5310d8fc 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 00000000000..4aea90a873f --- /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 00000000000..e6c71897a6a 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 00000000000..5a130f29e87 --- /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 00000000000..29571fad7d6 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 00000000000..7cc6e2e5757 --- /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 00000000000..3c1f82d6f93 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 f3a3351de9c..285f5c988a2 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() {