From 2dd49f0c9217759e7e670d69c82e77c7a043dbdb Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 19 Jun 2015 19:13:31 -0400 Subject: [PATCH 1/4] Fix a missing `this` in the scale `generateTicks` method when manually overriding. Added a sample to test this. --- samples/line-scale-override.html | 131 +++++++++++++++++++++++++++++++ src/scales/scale.linear.js | 2 +- src/scales/scale.radialLinear.js | 2 +- 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 samples/line-scale-override.html diff --git a/samples/line-scale-override.html b/samples/line-scale-override.html new file mode 100644 index 000000000..6603b5c04 --- /dev/null +++ b/samples/line-scale-override.html @@ -0,0 +1,131 @@ + + + + + Line Chart with Scale Override + + + + + +
+ +
+
+
+ + + + + + + + + diff --git a/src/scales/scale.linear.js b/src/scales/scale.linear.js index 21a6e4322..ceeae97c1 100644 --- a/src/scales/scale.linear.js +++ b/src/scales/scale.linear.js @@ -61,7 +61,7 @@ // we get the final line for (var i = 0; i <= this.options.override.steps; ++i) { var value = this.options.override.start + (i * this.options.override.stepWidth); - ticks.push(value); + this.ticks.push(value); } } else { // Figure out what the max number of ticks we can support it is based on the size of diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index 0a1a26b45..0e9c763b3 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -129,7 +129,7 @@ // we get the final line for (var i = 0; i <= this.options.override.steps; ++i) { var value = this.options.override.start + (i * this.options.override.stepWidth); - ticks.push(value); + this.ticks.push(value); } } else { // Figure out what the max number of ticks we can support it is based on the size of From 46af76a8ed01dc705ea80d5aa5fb0362dcd6b5d1 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 19 Jun 2015 19:51:28 -0400 Subject: [PATCH 2/4] addData is now supported by the doughnut chart + updated the sample to match. --- samples/doughnut.html | 40 ++++++++-- src/controllers/controller.doughnut.js | 106 +++++++++++++++---------- src/core/core.controller.js | 7 +- 3 files changed, 104 insertions(+), 49 deletions(-) diff --git a/samples/doughnut.html b/samples/doughnut.html index f2746557a..f2c4282f8 100644 --- a/samples/doughnut.html +++ b/samples/doughnut.html @@ -24,6 +24,8 @@ + + diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index dc8cbdc35..454ec5498 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -63,7 +63,25 @@ }); }, this); }, + addElementAndReset: function(index, colorForNewElement) { + this.getDataset().metaData = this.getDataset().metaData || []; + var arc = new Chart.elements.Arc({ + _chart: this.chart.chart, + _datasetIndex: this.index, + _index: index, + }); + this.getDataset().backgroundColor.splice(index, 0, colorForNewElement); + + // Reset the point + this.updateElement(arc, index, true); + + // Add to the points array + this.getDataset().metaData.splice(index, 0, arc); + }, + removeElement: function(index) { + this.getDataset().metaData.splice(index, 1); + }, reset: function() { this.update(true); }, @@ -84,58 +102,60 @@ this.innerRadius = this.outerRadius - this.chart.radiusLength; helpers.each(this.getDataset().metaData, function(arc, index) { + this.updateElement(arc, index, reset); + }, this); + }, + updateElement: function(arc, index, reset) { + var resetModel = { + x: this.chart.chart.width / 2, + y: this.chart.chart.height / 2, + startAngle: Math.PI * -0.5, // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function + circumference: (this.chart.options.animation.animateRotate) ? 0 : this.calculateCircumference(this.getDataset().data[index]), + outerRadius: (this.chart.options.animation.animateScale) ? 0 : this.outerRadius, + innerRadius: (this.chart.options.animation.animateScale) ? 0 : this.innerRadius, + }; - var resetModel = { + helpers.extend(arc, { + // Utility + _chart: this.chart.chart, + _datasetIndex: this.index, + _index: index, + + // Desired view properties + _model: reset ? resetModel : { x: this.chart.chart.width / 2, y: this.chart.chart.height / 2, - startAngle: Math.PI * -0.5, // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function - circumference: (this.chart.options.animation.animateRotate) ? 0 : this.calculateCircumference(this.getDataset().data[index]), - outerRadius: (this.chart.options.animation.animateScale) ? 0 : this.outerRadius, - innerRadius: (this.chart.options.animation.animateScale) ? 0 : this.innerRadius, - }; + circumference: this.calculateCircumference(this.getDataset().data[index]), + outerRadius: this.outerRadius, + innerRadius: this.innerRadius, - helpers.extend(arc, { - // Utility - _chart: this.chart.chart, - _datasetIndex: this.index, - _index: index, + backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), + hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor), + borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), + borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), - // Desired view properties - _model: reset ? resetModel : { - x: this.chart.chart.width / 2, - y: this.chart.chart.height / 2, - circumference: this.calculateCircumference(this.getDataset().data[index]), - outerRadius: this.outerRadius, - innerRadius: this.innerRadius, + label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index]) + }, + }); - backgroundColor: arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor), - hoverBackgroundColor: arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().hoverBackgroundColor, index, this.chart.options.elements.arc.hoverBackgroundColor), - borderWidth: arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth), - borderColor: arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor), + if (!reset) { - label: helpers.getValueAtIndexOrDefault(this.getDataset().label, index, this.chart.data.labels[index]) - }, - }); - - if (!reset) { - - if (index === 0) { - arc._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function - } else { - arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle; - } - - arc._model.endAngle = arc._model.startAngle + arc._model.circumference; - - - //Check to see if it's the last arc, if not get the next and update its start angle - if (index < this.getDataset().data.length - 1) { - this.getDataset().metaData[index + 1]._model.startAngle = arc._model.endAngle; - } + if (index === 0) { + arc._model.startAngle = Math.PI * -0.5; // use - PI / 2 instead of 3PI / 2 to make animations better. It means that we never deal with overflow during the transition function + } else { + arc._model.startAngle = this.getDataset().metaData[index - 1]._model.endAngle; } - arc.pivot(); - }, this); + arc._model.endAngle = arc._model.startAngle + arc._model.circumference; + + + //Check to see if it's the last arc, if not get the next and update its start angle + if (index < this.getDataset().data.length - 1) { + this.getDataset().metaData[index + 1]._model.startAngle = arc._model.endAngle; + } + } + + arc.pivot(); }, draw: function(ease) { diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 94df818a6..439fe5230 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -102,8 +102,13 @@ index = this.data.datasets[datasetIndex].data.length; } + var addElementArgs = [index]; + for (var i = 3; i < arguments.length; ++i) { + addElementArgs.push(arguments[i]); + } + this.data.datasets[datasetIndex].data.splice(index, 0, data); - this.data.datasets[datasetIndex].controller.addElementAndReset(index); + this.data.datasets[datasetIndex].controller.addElementAndReset.apply(this.data.datasets[datasetIndex].controller, addElementArgs); this.update(); } }, From 48be4edbdd0ed0f485abbf510c38d2225f4beed8 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 19 Jun 2015 20:24:14 -0400 Subject: [PATCH 3/4] Category scale label rotation improvements --- src/scales/scale.category.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/scales/scale.category.js b/src/scales/scale.category.js index ffac6fe21..7e861dfd7 100644 --- a/src/scales/scale.category.js +++ b/src/scales/scale.category.js @@ -113,7 +113,7 @@ var gridWidth = Math.floor(this.getPixelForValue(0, 1) - this.getPixelForValue(0, 0)) - 6; //Max label rotate should be 90 - also act as a loop counter - while ((this.labelWidth > gridWidth && this.labelRotation === 0) || (this.labelWidth > gridWidth && this.labelRotation <= 90 && this.labelRotation > 0)) { + while (this.labelWidth > gridWidth && this.labelRotation <= 90) { cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); @@ -157,6 +157,13 @@ // @param {number} maxHeight: the max height the axis can be // @return {object} minSize : the minimum size needed to draw the axis fit: function(maxWidth, maxHeight, margins) { + // Set the unconstrained dimension before label rotation + if (this.isHorizontal()) { + this.width = maxWidth; + } else { + this.height = maxHeight; + } + this.calculateLabelRotation(maxHeight, margins); var minSize = { @@ -170,17 +177,16 @@ // Width if (this.isHorizontal()) { minSize.width = maxWidth; - this.width = maxWidth; } else if (this.options.display) { minSize.width = Math.min(longestLabelWidth + 6, maxWidth); } // Height if (this.isHorizontal() && this.options.display) { - var labelHeight = (Math.cos(helpers.toRadians(this.labelRotation)) * longestLabelWidth) + 1.5 * this.options.labels.fontSize; + var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * longestLabelWidth) + 1.5 * this.options.labels.fontSize; minSize.height = Math.min(labelHeight, maxHeight); } else if (this.options.display) { - minSize.width = Math.min(longestLabelWidth + 6, maxWidth); + minSize.height = maxHeight; } this.width = minSize.width; From 82de2f135135f63ba07ad2ae6598c538a97653f0 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Sat, 20 Jun 2015 09:47:35 -0400 Subject: [PATCH 4/4] Can now change more properties for line drawing. Updated the sample file to demo --- samples/line.html | 1 + src/controllers/controller.line.js | 4 ++++ src/elements/element.line.js | 12 +++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/samples/line.html b/samples/line.html index f4962480f..edcca91ec 100644 --- a/samples/line.html +++ b/samples/line.html @@ -42,6 +42,7 @@ label: "My First dataset", data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()], fill: false, + borderDash: [5, 5], }, { label: "My Second dataset", data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()], diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index 34680dc06..d007498a8 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -131,6 +131,10 @@ 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), + borderCapStyle: line.custom && line.custom.borderCapStyle ? line.custom.borderCapStyle : (this.getDataset().borderCapStyle || this.chart.options.elements.line.borderCapStyle), + borderDash: line.custom && line.custom.borderDash ? line.custom.borderDash : (this.getDataset().borderDash || this.chart.options.elements.line.borderDash), + borderDashOffset: line.custom && line.custom.borderDashOffset ? line.custom.borderDashOffset : (this.getDataset().borderDashOffset || this.chart.options.elements.line.borderDashOffset), + borderJoinStyle: line.custom && line.custom.borderJoinStyle ? line.custom.borderJoinStyle : (this.getDataset().borderJoinStyle || this.chart.options.elements.line.borderJoinStyle), fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), skipNull: this.getDataset().skipNull !== undefined ? this.getDataset().skipNull : this.chart.options.elements.line.skipNull, drawNull: this.getDataset().drawNull !== undefined ? this.getDataset().drawNull : this.chart.options.elements.line.drawNull, diff --git a/src/elements/element.line.js b/src/elements/element.line.js index bd5ba8326..c03f06684 100644 --- a/src/elements/element.line.js +++ b/src/elements/element.line.js @@ -22,6 +22,10 @@ backgroundColor: Chart.defaults.global.defaultColor, borderWidth: 3, borderColor: Chart.defaults.global.defaultColor, + borderCapStyle: 'butt', + borderDash: [], + borderDashOffset: 0.0, + borderJoinStyle: 'miter', fill: true, // do we fill in the area between the line and its base axis skipNull: true, drawNull: false, @@ -36,6 +40,8 @@ var first = this._children[0]; var last = this._children[this._children.length - 1]; + ctx.save(); + // Draw the background first (so the border is always on top) helpers.each(this._children, function(point, index) { var previous = helpers.previousItem(this._children, index); @@ -107,6 +113,10 @@ // Now draw the line between all the points with any borders + ctx.lineCap = vm.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle; + ctx.setLineDash(vm.borderDash || Chart.defaults.global.elements.line.borderDash); + ctx.lineDashOffset = vm.borderDashOffset || Chart.defaults.global.elements.line.borderDashOffset; + ctx.lineJoin = vm.borderJoinStyle || Chart.defaults.global.elements.line.borderJoinStyle; ctx.lineWidth = vm.borderWidth || Chart.defaults.global.defaultColor; ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor; ctx.beginPath(); @@ -171,7 +181,7 @@ ctx.stroke(); - + ctx.restore(); }, });