diff --git a/docs/02-Line-Chart.md b/docs/02-Line-Chart.md
index 2202fcb67..aa10c4d8f 100644
--- a/docs/02-Line-Chart.md
+++ b/docs/02-Line-Chart.md
@@ -37,14 +37,16 @@ var data = {
label: "My First dataset",
// Boolean - if true fill the area under the line
- fill: false,
+ fill: false,
+
+ // Tension - bezier curve tension of the line. Set to 0 to draw straight lines connecting points
+ // Used to be called "tension" but was renamed for consistency. The old option name continues to work for compatibility.
+ lineTension: 0.1,
// String - the color to fill the area under the line with if fill is true
- backgroundColor: "rgba(220,220,220,0.2)",
+ backgroundColor: "rgba(220,220,220,0.2)",
- // The properties below allow an array to be specified to change the value of the item at the given index
-
- // String or array - Line color
+ // String - Line color
borderColor: "rgba(220,220,220,1)",
// String - cap style of the line. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineCap
@@ -57,34 +59,39 @@ var data = {
borderDashOffset: 0.0,
// String - line join style. See https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineJoin
- borderJoinStyle: 'miter',
+ borderJoinStyle: 'miter',
+
+ // The properties below allow an array to be specified to change the value of the item at the given index
- // String or array - Point stroke color
+ // String or Array - Point stroke color
pointBorderColor: "rgba(220,220,220,1)",
- // String or array - Point fill color
+ // String or Array - Point fill color
pointBackgroundColor: "#fff",
- // Number or array - Stroke width of point border
+ // Number or Array - Stroke width of point border
pointBorderWidth: 1,
- // Number or array - Radius of point when hovered
+ // Number or Array - Radius of point when hovered
pointHoverRadius: 5,
- // String or array - point background color when hovered
+ // String or Array - point background color when hovered
pointHoverBackgroundColor: "rgba(220,220,220,1)",
- // Point border color when hovered
+ // String or Array - Point border color when hovered
pointHoverBorderColor: "rgba(220,220,220,1)",
- // Number or array - border width of point when hovered
- pointHoverBorderWidth: 2,
+ // Number or Array - border width of point when hovered
+ pointHoverBorderWidth: 2,
- // Tension - bezier curve tension of the line. Set to 0 to draw straight Wlines connecting points
- tension: 0.1,
-
- // Number - the pixel size of the point shape. Can be set to 0 to not render a circle over the point
- radius: 1,
+ // Number or Array - the pixel size of the point shape. Can be set to 0 to not render a circle over the point
+ // Used to be called "radius" but was renamed for consistency. The old option name continues to work for compatibility.
+ pointRadius: 1,
+
+ // Number or Array - the pixel size of the non-displayed point that reacts to mouse hover events
+ //
+ // Used to be called "hitRadius" but was renamed for consistency. The old option name continues to work for compatibility.
+ pointHitRadius: 10,
// The actual data
data: [65, 59, 80, 81, 56, 55, 40],
diff --git a/samples/different-point-sizes.html b/samples/different-point-sizes.html
new file mode 100644
index 000000000..926eecfba
--- /dev/null
+++ b/samples/different-point-sizes.html
@@ -0,0 +1,154 @@
+
+
+
+
+ Line Chart
+
+
+
+
+
+
+
+
+
+
+
+ Randomize Data
+ Add Data
+ Remove Data
+
+
+
+
diff --git a/samples/line-legend.html b/samples/line-legend.html
index e454eb08f..92e5e5b5a 100644
--- a/samples/line-legend.html
+++ b/samples/line-legend.html
@@ -52,8 +52,9 @@
fill: false,
borderDash: [5, 5],
}, {
- label: "My Third dataset",
+ label: "My Third dataset - No bezier",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
+ lineTension: 0,
fill: false,
}, {
label: "My Fourth dataset",
diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js
index dcce78f99..a62b285ac 100644
--- a/src/controllers/controller.line.js
+++ b/src/controllers/controller.line.js
@@ -86,9 +86,16 @@ module.exports = function(Chart) {
// Data
line._children = points;
// Model
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined))
+ {
+ this.getDataset().lineTension = this.getDataset().tension;
+ }
+
line._model = {
// Appearance
- tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
+ tension: line.custom && line.custom.tension ? line.custom.tension : helpers.getValueOrDefault(this.getDataset().lineTension, this.chart.options.elements.line.tension),
backgroundColor: line.custom && line.custom.backgroundColor ? line.custom.backgroundColor : (this.getDataset().backgroundColor || this.chart.options.elements.line.backgroundColor),
borderWidth: line.custom && line.custom.borderWidth ? line.custom.borderWidth : (this.getDataset().borderWidth || this.chart.options.elements.line.borderWidth),
borderColor: line.custom && line.custom.borderColor ? line.custom.borderColor : (this.getDataset().borderColor || this.chart.options.elements.line.borderColor),
@@ -178,18 +185,28 @@ module.exports = function(Chart) {
point._index = index;
// Desired view properties
+
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined))
+ {
+ this.getDataset().pointRadius = this.getDataset().radius;
+ }
+ if ((this.getDataset().hitRadius !== undefined) && (this.getDataset().pointHitRadius === undefined))
+ {
+ this.getDataset().pointHitRadius = this.getDataset().hitRadius;
+ }
+
point._model = {
x: xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo),
y: reset ? scaleBase : this.calculatePointY(this.getDataset().data[index], index, this.index, this.chart.isCombo),
// Appearance
- tension: point.custom && point.custom.tension ? point.custom.tension : helpers.getValueOrDefault(this.getDataset().tension, this.chart.options.elements.line.tension),
- radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius),
+ radius: point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius),
pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle),
backgroundColor: this.getPointBackgroundColor(point, index),
borderColor: this.getPointBorderColor(point, index),
borderWidth: this.getPointBorderWidth(point, index),
// Tooltip
- hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius)
+ hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointHitRadius, index, this.chart.options.elements.point.hitRadius)
};
point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y));
@@ -233,7 +250,7 @@ module.exports = function(Chart) {
helpers.previousItem(this.getDataset().metaData, index)._model,
point._model,
helpers.nextItem(this.getDataset().metaData, index)._model,
- point._model.tension
+ this.getDataset().metaDataset._model.tension
);
// Prevent the bezier going outside of the bounds of the graph
@@ -281,7 +298,13 @@ module.exports = function(Chart) {
var dataset = this.chart.data.datasets[point._datasetIndex];
var index = point._index;
- point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius);
+ // Compatibility: If the properties are defined with only the old name, use those values
+ if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined))
+ {
+ this.getDataset().pointRadius = this.getDataset().radius;
+ }
+
+ point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().pointRadius, index, this.chart.options.elements.point.radius);
point._model.backgroundColor = this.getPointBackgroundColor(point, index);
point._model.borderColor = this.getPointBorderColor(point, index);
point._model.borderWidth = this.getPointBorderWidth(point, index);
diff --git a/test/controller.line.tests.js b/test/controller.line.tests.js
index a4d12bdb3..0d93cd2fb 100644
--- a/test/controller.line.tests.js
+++ b/test/controller.line.tests.js
@@ -284,7 +284,6 @@ describe('Line controller tests', function() {
radius: 3,
pointStyle: 'circle',
skip: false,
- tension: 0.1,
// Point
x: 82,
@@ -300,7 +299,6 @@ describe('Line controller tests', function() {
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 132,
y: 15,
- tension: 0.1,
radius: 3,
pointStyle: 'circle',
backgroundColor: 'rgba(0,0,0,0.1)',
@@ -317,7 +315,6 @@ describe('Line controller tests', function() {
expect(chart.data.datasets[0].metaData[2]._model).toEqual({
x: 182,
y: 156,
- tension: 0.1,
radius: 3,
pointStyle: 'circle',
backgroundColor: 'rgba(0,0,0,0.1)',
@@ -339,7 +336,6 @@ describe('Line controller tests', function() {
radius: 3,
pointStyle: 'circle',
skip: false,
- tension: 0.1,
// Point
x: 232,
@@ -391,7 +387,6 @@ describe('Line controller tests', function() {
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 82,
y: 62,
- tension: 0,
radius: 22,
pointStyle: 'circle',
backgroundColor: 'rgb(128, 129, 130)',
@@ -408,7 +403,6 @@ describe('Line controller tests', function() {
expect(chart.data.datasets[0].metaData[1]._model).toEqual({
x: 132,
y: 15,
- tension: 0,
radius: 22,
pointStyle: 'circle',
backgroundColor: 'rgb(128, 129, 130)',
@@ -430,7 +424,6 @@ describe('Line controller tests', function() {
radius: 22,
pointStyle: 'circle',
skip: false,
- tension: 0,
// Point
x: 182,
@@ -451,7 +444,6 @@ describe('Line controller tests', function() {
radius: 22,
pointStyle: 'circle',
skip: false,
- tension: 0,
// Point
x: 232,
@@ -464,9 +456,174 @@ describe('Line controller tests', function() {
controlPointNextY: 194,
});
+ // Use the consistent name "lineTension", setting but overwriting
+ // another value in "tension"
+ chart.data.datasets[0].lineTension = 0.5;
+ chart.data.datasets[0].tension = 0.7;
+
+ controller.update();
+
+ expect(chart.data.datasets[0].metaDataset._model).toEqual({
+ backgroundColor: 'rgb(98, 98, 98)',
+ borderCapStyle: 'butt',
+ borderColor: 'rgb(8, 8, 8)',
+ borderDash: [2, 3],
+ borderDashOffset: 7,
+ borderJoinStyle: 'miter',
+ borderWidth: 0.55,
+ fill: false,
+ tension: 0.5,
+
+ scaleTop: 0,
+ scaleBottom: 200,
+ scaleZero: 156,
+ });
+
+ expect(chart.data.datasets[0].metaData[0]._model).toEqual({
+ x: 82,
+ y: 62,
+ radius: 22,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 3.3,
+ skip: false,
+ controlPointPreviousX: 82,
+ controlPointPreviousY: 62,
+ controlPointNextX: 107,
+ controlPointNextY: 38.5
+ });
+
+ expect(chart.data.datasets[0].metaData[1]._model).toEqual({
+ x: 132,
+ y: 15,
+ radius: 22,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 3.3,
+ skip: false,
+ controlPointPreviousX: 116.2771987579006,
+ controlPointPreviousY: 0.22056683242656483,
+ controlPointNextX: 166.2771987579006,
+ controlPointNextY: 47.22056683242656
+ });
+
+ // Use the consistent name "pointRadius", setting but overwriting
+ // another value in "radius"
+ chart.data.datasets[0].pointRadius = 250;
+ chart.data.datasets[0].radius = 20;
+
+ controller.update();
+
+ expect(chart.data.datasets[0].metaDataset._model).toEqual({
+ backgroundColor: 'rgb(98, 98, 98)',
+ borderCapStyle: 'butt',
+ borderColor: 'rgb(8, 8, 8)',
+ borderDash: [2, 3],
+ borderDashOffset: 7,
+ borderJoinStyle: 'miter',
+ borderWidth: 0.55,
+ fill: false,
+ tension: 0.5,
+
+ scaleTop: 0,
+ scaleBottom: 200,
+ scaleZero: 156,
+ });
+
+ expect(chart.data.datasets[0].metaData[0]._model).toEqual({
+ x: 82,
+ y: 62,
+ radius: 250,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 3.3,
+ skip: false,
+ controlPointPreviousX: 82,
+ controlPointPreviousY: 62,
+ controlPointNextX: 107,
+ controlPointNextY: 38.5
+ });
+
+ expect(chart.data.datasets[0].metaData[1]._model).toEqual({
+ x: 132,
+ y: 15,
+ radius: 250,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 3.3,
+ skip: false,
+ controlPointPreviousX: 116.2771987579006,
+ controlPointPreviousY: 0.22056683242656483,
+ controlPointNextX: 166.2771987579006,
+ controlPointNextY: 47.22056683242656
+ });
+
+ // Use the consistent name "pointHitRadius", setting but overwriting
+ // another value in "hitRadius"
+ chart.data.datasets[0].pointHitRadius = 123;
+ chart.data.datasets[0].hitRadius = 23;
+
+ controller.update();
+
+ expect(chart.data.datasets[0].metaDataset._model).toEqual({
+ backgroundColor: 'rgb(98, 98, 98)',
+ borderCapStyle: 'butt',
+ borderColor: 'rgb(8, 8, 8)',
+ borderDash: [2, 3],
+ borderDashOffset: 7,
+ borderJoinStyle: 'miter',
+ borderWidth: 0.55,
+ fill: false,
+ tension: 0.5,
+
+ scaleTop: 0,
+ scaleBottom: 200,
+ scaleZero: 156,
+ });
+
+ expect(chart.data.datasets[0].metaData[0]._model).toEqual({
+ x: 82,
+ y: 62,
+ radius: 250,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 123,
+ skip: false,
+ controlPointPreviousX: 82,
+ controlPointPreviousY: 62,
+ controlPointNextX: 107,
+ controlPointNextY: 38.5
+ });
+
+ expect(chart.data.datasets[0].metaData[1]._model).toEqual({
+ x: 132,
+ y: 15,
+ radius: 250,
+ pointStyle: 'circle',
+ backgroundColor: 'rgb(128, 129, 130)',
+ borderColor: 'rgb(56, 57, 58)',
+ borderWidth: 1.123,
+ hitRadius: 123,
+ skip: false,
+ controlPointPreviousX: 116.2771987579006,
+ controlPointPreviousY: 0.22056683242656483,
+ controlPointNextX: 166.2771987579006,
+ controlPointNextY: 47.22056683242656
+ });
+
// Use custom styles for lines & first point
chart.data.datasets[0].metaDataset.custom = {
- tension: 0.25,
+ tension: 0.15,
backgroundColor: 'rgb(55, 55, 54)',
borderColor: 'rgb(8, 7, 6)',
borderWidth: 0.3,
@@ -483,7 +640,6 @@ describe('Line controller tests', function() {
backgroundColor: 'rgb(0, 1, 3)',
borderColor: 'rgb(4, 6, 8)',
borderWidth: 0.787,
- tension: 0.15,
skip: true,
hitRadius: 5,
};
@@ -499,7 +655,7 @@ describe('Line controller tests', function() {
borderJoinStyle: 'round',
borderWidth: 0.3,
fill: true,
- tension: 0.25,
+ tension: 0.15,
scaleTop: 0,
scaleBottom: 200,
@@ -509,7 +665,6 @@ describe('Line controller tests', function() {
expect(chart.data.datasets[0].metaData[0]._model).toEqual({
x: 82,
y: 62,
- tension: 0.15,
radius: 2.2,
pointStyle: 'circle',
backgroundColor: 'rgb(0, 1, 3)',
@@ -1281,6 +1436,17 @@ describe('Line controller tests', function() {
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;
+
+ 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,
@@ -1423,6 +1589,17 @@ describe('Line controller tests', function() {
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;
+
+ controller.removeHoverStyle(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(250);
+
// Custom style
point.custom = {
radius: 4.4,