From db981807bb48ed0853de6a28bec83fc424b95ad9 Mon Sep 17 00:00:00 2001 From: Tanner Linsley Date: Tue, 16 Jun 2015 00:39:04 -0600 Subject: [PATCH] Polar Area Draws, but has scale resizing issues --- samples/polar-area.html | 14 +- src/controllers/controller.polarArea.js | 451 ++++++++---------------- 2 files changed, 151 insertions(+), 314 deletions(-) diff --git a/samples/polar-area.html b/samples/polar-area.html index 8119fd517..4388a73ca 100644 --- a/samples/polar-area.html +++ b/samples/polar-area.html @@ -38,14 +38,14 @@ "#949FB1", "#4D5360", ], - labels: [ - "Red", - "Green", - "Yellow", - "Grey", - "Dark Grey" - ] }], + labels: [ + "Red", + "Green", + "Yellow", + "Grey", + "Dark Grey" + ] }, options: { responsive: true diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 22b0fbb3a..2aa0e4989 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -1,14 +1,13 @@ (function() { "use strict"; - return; - var root = this, Chart = root.Chart, //Cache a local reference to Chart.helpers helpers = Chart.helpers; - var defaultConfig = { + + Chart.defaults.polarArea = { scale: { type: "radialLinear", @@ -19,330 +18,168 @@ animateRotate: true, }; + Chart.controllers.polarArea = function(chart, datasetIndex) { + this.initialize.call(this, chart, datasetIndex); + }; - Chart.Type.extend({ - //Passing in a name registers this chart in the Chart namespace - name: "PolarArea", - //Providing a defaults will also register the deafults in the chart namespace - defaults: defaultConfig, - //Initialize is fired when the chart is initialized - Data is passed in as a parameter - //Config is automatically merged by the core of Chart.js, and is available at this.options - initialize: function() { + helpers.extend(Chart.controllers.polarArea.prototype, { - // Scale setup - var self = this; - var ScaleClass = Chart.scaleService.getScaleConstructor(this.options.scale.type); - this.scale = new ScaleClass({ - options: this.options.scale, - lineArc: true, - width: this.chart.width, - height: this.chart.height, - xCenter: this.chart.width / 2, - yCenter: this.chart.height / 2, - ctx: this.chart.ctx, - valuesCount: this.data.length, - data: this.data - }); + initialize: function(chart, datasetIndex) { + this.chart = chart; + this.index = datasetIndex; + this.linkScales(); + this.addElements(); + }, - helpers.bindEvents(this, this.options.events, this.events); + linkScales: function() { + // no scales for doughnut + }, - //Set up tooltip events on the chart - helpers.bindEvents(this, this.options.events, this.events); + getDataset: function() { + return this.chart.data.datasets[this.index]; + }, - //Create a new bar for each piece of data - helpers.each(this.data.datasets, function(dataset, datasetIndex) { - dataset.metaData = []; - helpers.each(dataset.data, function(dataPoint, index) { - dataset.metaData.push(new Chart.Arc({ - _chart: this.chart, - _datasetIndex: datasetIndex, - _index: index, - _model: {} - })); - }, this); + getScaleForId: function(scaleID) { + return this.chart.scales[scaleID]; + }, + + addElements: function() { + this.getDataset().metaData = this.getDataset().metaData || []; + helpers.each(this.getDataset().data, function(value, index) { + this.getDataset().metaData[index] = this.getDataset().metaData[index] || new Chart.elements.Arc({ + _chart: this.chart.chart, + _datasetIndex: this.index, + _index: index, + }); }, this); + }, - // Create tooltip instance exclusively for this chart with some defaults. - this.tooltip = new Chart.Tooltip({ - _chart: this.chart, - _data: this.data, - _options: this.options, - }, this); + reset: function() { + this.update(true); + }, + + update: function(reset) { - // Fit the scale before we animate - this.updateScaleRange(); - this.scale.calculateRange(); Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); + //this.chart.scale.setScaleSize(); + this.chart.scale.calculateRange(); + this.chart.scale.generateTicks(); + this.chart.scale.buildYLabels(); - // so that we animate nicely - this.resetElements(); + this.chart.outerRadius = (helpers.min([this.chart.chart.width, this.chart.chart.height]) - this.chart.options.elements.arc.borderWidth / 2) / 2; + this.chart.innerRadius = this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1; + this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.data.datasets.length; - // Update the chart with the latest data. - this.update(); + this.getDataset().total = 0; + helpers.each(this.getDataset().data, function(value) { + this.getDataset().total += Math.abs(value); + }, this); + this.outerRadius = this.chart.outerRadius - (this.chart.radiusLength * this.index); + this.innerRadius = this.outerRadius - this.chart.radiusLength; + + helpers.each(this.getDataset().metaData, function(arc, index) { + + var resetModel = { + x: this.chart.chart.width / 2, + y: this.chart.chart.height / 2, + innerRadius: 0, + outerRadius: 0, + startAngle: Math.PI * -0.5, + endAngle: Math.PI * -0.5, + + 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), + + label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) + }; + + var circumference = 1 / this.getDataset().data.length * 2; + var startAngle = (-0.5 * Math.PI) + (Math.PI * circumference) * index; + var endAngle = startAngle + (circumference * Math.PI); + + console.log() + + 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, + innerRadius: 0, + outerRadius: this.chart.scale.getDistanceFromCenterForValue(this.getDataset().data[index]), + startAngle: startAngle, + endAngle: endAngle, + + 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), + + label: helpers.getValueAtIndexOrDefault(this.chart.data.labels, index, this.chart.data.labels[index]) + }, + }); + + arc.pivot(); + }, this); + }, + + draw: function(ease) { + var easingDecimal = ease || 1; + helpers.each(this.getDataset().metaData, function(arc, index) { + arc.transition(easingDecimal).draw(); + console.log(arc); + }, this); + }, + + + + setHoverStyle: function(arc) { + var dataset = this.chart.data.datasets[arc._datasetIndex]; + var index = arc._index; + + arc._model.backgroundColor = arc.custom && arc.custom.hoverBackgroundColor ? arc.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.color(arc._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); + arc._model.borderColor = arc.custom && arc.custom.hoverBorderColor ? arc.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.color(arc._model.borderColor).saturate(0.5).darken(0.1).rgbString()); + arc._model.borderWidth = arc.custom && arc.custom.hoverBorderWidth ? arc.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, arc._model.borderWidth); + }, + + removeHoverStyle: function(arc) { + var dataset = this.chart.data.datasets[arc._datasetIndex]; + var index = arc._index; + + arc._model.backgroundColor = arc.custom && arc.custom.backgroundColor ? arc.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.arc.backgroundColor); + arc._model.borderColor = arc.custom && arc.custom.borderColor ? arc.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.arc.borderColor); + arc._model.borderWidth = arc.custom && arc.custom.borderWidth ? arc.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.arc.borderWidth); + }, + + calculateCircumference: function(value) { + if (this.getDataset().total > 0) { + return (Math.PI * 2) * (value / this.getDataset().total); + } else { + return 0; + } }, updateScaleRange: function() { - helpers.extend(this.scale, { + helpers.extend(this.chart.scale, { size: helpers.min([this.chart.width, this.chart.height]), xCenter: this.chart.width / 2, yCenter: this.chart.height / 2 }); }, - resetElements: function() { - var circumference = 1 / this.data.datasets[0].data.length * 2; - // Map new data to data points - helpers.each(this.data.datasets[0].metaData, function(slice, index) { - - var value = this.data.datasets[0].data[index]; - - helpers.extend(slice, { - _index: index, - _model: { - x: this.chart.width / 2, - y: this.chart.height / 2, - innerRadius: 0, - outerRadius: 0, - startAngle: Math.PI * -0.5, - endAngle: Math.PI * -0.5, - - backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].backgroundColor, index, this.options.elements.arc.backgroundColor), - hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].hoverBackgroundColor, index, this.options.elements.arc.hoverBackgroundColor), - borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.data.datasets[0].borderWidth, index, this.options.elements.arc.borderWidth), - borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].borderColor, index, this.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.data.datasets[0].labels, index, this.data.datasets[0].labels[index]) - }, - }); - - slice.pivot(); - }, this); - }, - update: function(animationDuration) { - - this.updateScaleRange(); - this.scale.calculateRange(); - this.scale.generateTicks(); - this.scale.buildYLabels(); - - Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height); - - var circumference = 1 / this.data.datasets[0].data.length * 2; - - // Map new data to data points - helpers.each(this.data.datasets[0].metaData, function(slice, index) { - - var value = this.data.datasets[0].data[index]; - - var startAngle = (-0.5 * Math.PI) + (Math.PI * circumference) * index; - var endAngle = startAngle + (circumference * Math.PI); - - helpers.extend(slice, { - _index: index, - _model: { - x: this.chart.width / 2, - y: this.chart.height / 2, - innerRadius: 0, - outerRadius: this.scale.getDistanceFromCenterForValue(value), - startAngle: startAngle, - endAngle: endAngle, - - backgroundColor: slice.custom && slice.custom.backgroundColor ? slice.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].backgroundColor, index, this.options.elements.arc.backgroundColor), - hoverBackgroundColor: slice.custom && slice.custom.hoverBackgroundColor ? slice.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].hoverBackgroundColor, index, this.options.elements.arc.hoverBackgroundColor), - borderWidth: slice.custom && slice.custom.borderWidth ? slice.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.data.datasets[0].borderWidth, index, this.options.elements.arc.borderWidth), - borderColor: slice.custom && slice.custom.borderColor ? slice.custom.borderColor : helpers.getValueAtIndexOrDefault(this.data.datasets[0].borderColor, index, this.options.elements.arc.borderColor), - - label: helpers.getValueAtIndexOrDefault(this.data.datasets[0].labels, index, this.data.datasets[0].labels[index]) - }, - }); - slice.pivot(); - - console.log(slice); - - }, this); - - this.render(animationDuration); - }, - draw: function(ease) { - var easingDecimal = ease || 1; - - this.clear(); - - helpers.each(this.data.datasets[0].metaData, function(slice, index) { - slice.transition(easingDecimal).draw(); - }, this); - - this.scale.draw(); - - this.tooltip.transition(easingDecimal).draw(); - }, - events: function(e) { - - // If exiting chart - if (e.type == 'mouseout') { - return this; - } - - this.lastActive = this.lastActive || []; - - // Find Active Elements - this.active = function() { - switch (this.options.hover.mode) { - case 'single': - return this.getSliceAtEvent(e); - case 'label': - return this.getSlicesAtEvent(e); - case 'dataset': - return this.getDatasetAtEvent(e); - default: - return e; - } - }.call(this); - - // On Hover hook - if (this.options.hover.onHover) { - this.options.hover.onHover.call(this, this.active); - } - - if (e.type == 'mouseup' || e.type == 'click') { - if (this.options.onClick) { - this.options.onClick.call(this, e, this.active); - } - } - - var dataset; - var index; - // Remove styling for last active (even if it may still be active) - if (this.lastActive.length) { - switch (this.options.hover.mode) { - case 'single': - dataset = this.data.datasets[this.lastActive[0]._datasetIndex]; - index = this.lastActive[0]._index; - - this.lastActive[0]._model.backgroundColor = this.lastActive[0].custom && this.lastActive[0].custom.backgroundColor ? this.lastActive[0].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.arc.backgroundColor); - this.lastActive[0]._model.borderColor = this.lastActive[0].custom && this.lastActive[0].custom.borderColor ? this.lastActive[0].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.arc.borderColor); - this.lastActive[0]._model.borderWidth = this.lastActive[0].custom && this.lastActive[0].custom.borderWidth ? this.lastActive[0].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.arc.borderWidth); - break; - case 'label': - for (var i = 0; i < this.lastActive.length; i++) { - dataset = this.data.datasets[this.lastActive[i]._datasetIndex]; - index = this.lastActive[i]._index; - - this.lastActive[i]._model.backgroundColor = this.lastActive[i].custom && this.lastActive[i].custom.backgroundColor ? this.lastActive[i].custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, this.options.elements.arc.backgroundColor); - this.lastActive[i]._model.borderColor = this.lastActive[i].custom && this.lastActive[i].custom.borderColor ? this.lastActive[i].custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, this.options.elements.arc.borderColor); - this.lastActive[i]._model.borderWidth = this.lastActive[i].custom && this.lastActive[i].custom.borderWidth ? this.lastActive[i].custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, this.options.elements.arc.borderWidth); - } - break; - case 'dataset': - break; - default: - // Don't change anything - } - } - - // Built in hover styling - if (this.active.length && this.options.hover.mode) { - switch (this.options.hover.mode) { - case 'single': - dataset = this.data.datasets[this.active[0]._datasetIndex]; - index = this.active[0]._index; - - this.active[0]._model.radius = this.active[0].custom && this.active[0].custom.hoverRadius ? this.active[0].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[0]._model.radius + 1); - this.active[0]._model.backgroundColor = this.active[0].custom && this.active[0].custom.hoverBackgroundColor ? this.active[0].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[0]._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - this.active[0]._model.borderColor = this.active[0].custom && this.active[0].custom.hoverBorderColor ? this.active[0].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[0]._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - this.active[0]._model.borderWidth = this.active[0].custom && this.active[0].custom.hoverBorderWidth ? this.active[0].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[0]._model.borderWidth); - break; - case 'label': - for (var i = 0; i < this.active.length; i++) { - dataset = this.data.datasets[this.active[i]._datasetIndex]; - index = this.active[i]._index; - - this.active[i]._model.radius = this.active[i].custom && this.active[i].custom.hoverRadius ? this.active[i].custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.active[i]._model.radius + 1); - this.active[i]._model.backgroundColor = this.active[i].custom && this.active[i].custom.hoverBackgroundColor ? this.active[i].custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.color(this.active[i]._model.backgroundColor).saturate(0.5).darken(0.1).rgbString()); - this.active[i]._model.borderColor = this.active[i].custom && this.active[i].custom.hoverBorderColor ? this.active[i].custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.color(this.active[i]._model.borderColor).saturate(0.5).darken(0.1).rgbString()); - this.active[i]._model.borderWidth = this.active[i].custom && this.active[i].custom.hoverBorderWidth ? this.active[i].custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, this.active[i]._model.borderWidth); - } - break; - case 'dataset': - break; - default: - // Don't change anything - } - } - - - // Built in Tooltips - if (this.options.tooltips.enabled) { - - // The usual updates - this.tooltip.initialize(); - - // Active - if (this.active.length) { - this.tooltip._model.opacity = 1; - - helpers.extend(this.tooltip, { - _active: this.active, - }); - - this.tooltip.update(); - } else { - // Inactive - this.tooltip._model.opacity = 0; - } - } - - - // Hover animations - this.tooltip.pivot(); - - if (!this.animating) { - var changed; - - helpers.each(this.active, function(element, index) { - if (element !== this.lastActive[index]) { - changed = true; - } - }, this); - - // If entering, leaving, or changing elements, animate the change via pivot - if ((!this.lastActive.length && this.active.length) || - (this.lastActive.length && !this.active.length) || - (this.lastActive.length && this.active.length && changed)) { - - this.stop(); - this.render(this.options.hover.animationDuration); - } - } - - // Remember Last Active - this.lastActive = this.active; - return this; - }, - getSliceAtEvent: function(e) { - var elements = []; - - var location = helpers.getRelativePosition(e); - - this.eachElement(function(slice, index) { - if (slice.inRange(location.x, location.y)) { - elements.push(slice); - } - }, this); - return elements; - }, - /*getSlicesAtEvent: function(e) { - var elements = []; - - var location = helpers.getRelativePosition(e); - - this.eachElement(function(slice, index) { - if (slice.inLabelRange(location.x, location.y)) { - elements.push(slice); - } - }, this); - return elements; - },*/ }); + + + return; + + + Chart.Type.extend({}); + }).call(this);