From bea68f142406df0eed7cbd5b63e621ddc406de08 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Fri, 13 May 2016 22:07:39 -0500 Subject: [PATCH 1/5] Performance and minification improvements --- .editorconfig | 10 ++ src/charts/Chart.Radar.js | 10 +- src/controllers/controller.bar.js | 51 ++++--- src/core/core.controller.js | 54 ++++--- src/core/core.plugin.js | 2 +- src/core/core.scale.js | 242 +++++++++++++++--------------- src/core/core.tooltip.js | 59 ++++---- src/elements/element.line.js | 20 +-- src/scales/scale.radialLinear.js | 31 ++-- 9 files changed, 255 insertions(+), 224 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..4e0d877ef --- /dev/null +++ b/.editorconfig @@ -0,0 +1,10 @@ +# http://editorconfig.org +root = true + +[*] +indent_style = tab +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = false diff --git a/src/charts/Chart.Radar.js b/src/charts/Chart.Radar.js index c8560ec7b..322c4544a 100644 --- a/src/charts/Chart.Radar.js +++ b/src/charts/Chart.Radar.js @@ -1,15 +1,9 @@ "use strict"; module.exports = function(Chart) { - - var helpers = Chart.helpers; - - var defaultConfig = { - aspectRatio: 1 - }; - + Chart.Radar = function(context, config) { - config.options = helpers.configMerge(defaultConfig, config.options); + config.options = Chart.helpers.configMerge({ aspectRatio: 1 }, config.options); config.type = 'radar'; return new Chart(context, config); diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 103f26570..bf3e50b3d 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -96,6 +96,10 @@ module.exports = function(Chart) { yScalePoint = yScale.getPixelForValue(0); } + var rectangleElementOptions = this.chart.options.elements.rectangle; + var custom = rectangle.custom; + var dataset = this.getDataset(); + helpers.extend(rectangle, { // Utility _chart: this.chart.chart, @@ -112,15 +116,15 @@ module.exports = function(Chart) { // Tooltip label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, + datasetLabel: dataset.label, // Appearance base: reset ? yScalePoint : this.calculateBarBase(this.index, index), width: this.calculateBarWidth(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) + backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom && custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) } }); rectangle.pivot(); @@ -134,22 +138,23 @@ module.exports = function(Chart) { var base = 0; if (yScale.options.stacked) { - - var value = this.chart.data.datasets[datasetIndex].data[index]; + var chart = this.chart; + var datasets = chart.data.datasets; + var value = datasets[datasetIndex].data[index]; if (value < 0) { for (var i = 0; i < datasetIndex; i++) { - var negDS = this.chart.data.datasets[i]; - var negDSMeta = this.chart.getDatasetMeta(i); - if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(i)) { + var negDS = datasets[i]; + var negDSMeta = chart.getDatasetMeta(i); + if (negDSMeta.bar && negDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(i)) { base += negDS.data[index] < 0 ? negDS.data[index] : 0; } } } else { for (var j = 0; j < datasetIndex; j++) { - var posDS = this.chart.data.datasets[j]; - var posDSMeta = this.chart.getDatasetMeta(j); - if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && this.chart.isDatasetVisible(j)) { + var posDS = datasets[j]; + var posDSMeta = chart.getDatasetMeta(j); + if (posDSMeta.bar && posDSMeta.yAxisID === yScale.id && chart.isDatasetVisible(j)) { base += posDS.data[index] > 0 ? posDS.data[index] : 0; } } @@ -299,18 +304,18 @@ module.exports = function(Chart) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.hoverBackgroundColor ? rectangle.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(rectangle._model.backgroundColor)); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.hoverBorderColor ? rectangle.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(rectangle._model.borderColor)); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.hoverBorderWidth ? rectangle.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); + rectangle._model.backgroundColor = customr && customr.hoverBackgroundColor ? customr.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(rectangle._model.backgroundColor)); + rectangle._model.borderColor = customr && customr.hoverBorderColor ? customr.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(rectangle._model.borderColor)); + rectangle._model.borderWidth = customr && customr.hoverBorderWidth ? customr.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); }, removeHoverStyle: function(rectangle) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; - rectangle._model.backgroundColor = rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); - rectangle._model.borderColor = rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); - rectangle._model.borderWidth = rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); + rectangle._model.backgroundColor = customr && customr.backgroundColor ? customr.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); + rectangle._model.borderColor = customr && customr.borderColor ? customr.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); + rectangle._model.borderWidth = customr && customr.borderWidth ? customr.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); } }); @@ -408,10 +413,10 @@ module.exports = function(Chart) { // Appearance base: reset ? xScalePoint : this.calculateBarBase(this.index, index), height: this.calculateBarHeight(numBars), - backgroundColor: rectangle.custom && rectangle.custom.backgroundColor ? rectangle.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: rectangle.custom && rectangle.custom.borderSkipped ? rectangle.custom.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: rectangle.custom && rectangle.custom.borderColor ? rectangle.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: rectangle.custom && rectangle.custom.borderWidth ? rectangle.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) + backgroundColor: customr && customr.backgroundColor ? customr.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), + borderSkipped: customr && customr.borderSkipped ? customr.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, + borderColor: customr && customr.borderColor ? customr.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), + borderWidth: customr && customr.borderWidth ? customr.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) }, draw: function () { diff --git a/src/core/core.controller.js b/src/core/core.controller.js index aa6be982a..ca38642cb 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -279,10 +279,11 @@ module.exports = function(Chart) { render: function render(duration, lazy) { Chart.pluginService.notifyPlugins('beforeRender', [this]); - if (this.options.animation && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && this.options.animation.duration !== 0))) { + var animationOptions = this.options.animation; + if (animationOptions && ((typeof duration !== 'undefined' && duration !== 0) || (typeof duration === 'undefined' && animationOptions.duration !== 0))) { var animation = new Chart.Animation(); - animation.numSteps = (duration || this.options.animation.duration) / 16.66; //60 fps - animation.easing = this.options.animation.easing; + animation.numSteps = (duration || animationOptions.duration) / 16.66; //60 fps + animation.easing = animationOptions.easing; // render function animation.render = function(chartInstance, animationObject) { @@ -294,14 +295,14 @@ module.exports = function(Chart) { }; // user events - animation.onAnimationProgress = this.options.animation.onProgress; - animation.onAnimationComplete = this.options.animation.onComplete; + animation.onAnimationProgress = animationOptions.onProgress; + animation.onAnimationComplete = animationOptions.onComplete; Chart.animationService.addAnimation(this, animation, duration, lazy); } else { this.draw(); - if (this.options.animation && this.options.animation.onComplete && this.options.animation.onComplete.call) { - this.options.animation.onComplete.call(this); + if (animationOptions && animationOptions.onComplete && animationOptions.onComplete.call) { + animationOptions.onComplete.call(this); } } return this; @@ -322,10 +323,11 @@ module.exports = function(Chart) { } // Clip out the chart area so that anything outside does not draw. This is necessary for zoom and pan to function - this.chart.ctx.save(); - this.chart.ctx.beginPath(); - this.chart.ctx.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top); - this.chart.ctx.clip(); + var context = this.chart.ctx; + context.save(); + context.beginPath(); + context.rect(this.chartArea.left, this.chartArea.top, this.chartArea.right - this.chartArea.left, this.chartArea.bottom - this.chartArea.top); + context.clip(); // Draw each dataset via its respective controller (reversed to support proper line stacking) helpers.each(this.data.datasets, function(dataset, datasetIndex) { @@ -335,7 +337,7 @@ module.exports = function(Chart) { }, this, true); // Restore from the clipping operation - this.chart.ctx.restore(); + context.restore(); // Finally draw the tooltip this.tooltip.transition(easingDecimal).draw(); @@ -540,13 +542,15 @@ module.exports = function(Chart) { if (this.lastActive.length) { switch (this.options.hover.mode) { case 'single': - this.getDatasetMeta(this.lastActive[0]._datasetIndex).controller.removeHoverStyle(this.lastActive[0], this.lastActive[0]._datasetIndex, this.lastActive[0]._index); + var lastActive = this.lastActive[0]; + this.getDatasetMeta(lastActive._datasetIndex).controller.removeHoverStyle(lastActive, lastActive._datasetIndex, lastActive._index); break; case 'label': case 'dataset': for (var i = 0; i < this.lastActive.length; i++) { - if (this.lastActive[i]) - this.getDatasetMeta(this.lastActive[i]._datasetIndex).controller.removeHoverStyle(this.lastActive[i], this.lastActive[i]._datasetIndex, this.lastActive[i]._index); + var lastActive = this.lastActive[i]; + if (lastActive) + this.getDatasetMeta(lastActive._datasetIndex).controller.removeHoverStyle(lastActive, lastActive._datasetIndex, lastActive._index); } break; default: @@ -558,13 +562,15 @@ module.exports = function(Chart) { if (this.active.length && this.options.hover.mode) { switch (this.options.hover.mode) { case 'single': - this.getDatasetMeta(this.active[0]._datasetIndex).controller.setHoverStyle(this.active[0]); + var active = this.active[0]; + this.getDatasetMeta(active._datasetIndex).controller.setHoverStyle(active); break; case 'label': case 'dataset': for (var j = 0; j < this.active.length; j++) { - if (this.active[j]) - this.getDatasetMeta(this.active[j]._datasetIndex).controller.setHoverStyle(this.active[j]); + var active = this.active[j]; + if (active) + this.getDatasetMeta(active._datasetIndex).controller.setHoverStyle(active); } break; default: @@ -572,18 +578,18 @@ module.exports = function(Chart) { } } - + var tooltip = this.tooltip; // Built in Tooltips if (this.options.tooltips.enabled || this.options.tooltips.custom) { // The usual updates - this.tooltip.initialize(); - this.tooltip._active = this.tooltipActive; - this.tooltip.update(true); + tooltip.initialize(); + tooltip._active = this.tooltipActive; + tooltip.update(true); } // Hover animations - this.tooltip.pivot(); + tooltip.pivot(); if (!this.animating) { var changed; @@ -608,7 +614,7 @@ module.exports = function(Chart) { this.stop(); if (this.options.tooltips.enabled || this.options.tooltips.custom) { - this.tooltip.update(true); + tooltip.update(true); } // We only need to render at this point. Updating will cause scales to be recomputed generating flicker & using more diff --git a/src/core/core.plugin.js b/src/core/core.plugin.js index 01c8db6ab..31be4d48b 100644 --- a/src/core/core.plugin.js +++ b/src/core/core.plugin.js @@ -56,6 +56,6 @@ module.exports = function(Chart) { afterDraw: noop, // Called during destroy - destroy: noop, + destroy: noop }); }; diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 31a9b8a2a..81303bc36 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -3,6 +3,7 @@ module.exports = function(Chart) { var helpers = Chart.helpers; + var globalDefaults = Chart.defaults.global; Chart.defaults.scale = { display: true, @@ -180,19 +181,22 @@ module.exports = function(Chart) { helpers.callCallback(this.options.beforeCalculateTickRotation, [this]); }, calculateTickRotation: function() { + var context = this.ctx; + var optionTicks = this.options.ticks; + //Get the width of each grid by calculating the difference //between x offsets between 0 and 1. - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); + var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily); var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - this.ctx.font = tickLabelFont; + context.font = tickLabelFont; - var firstWidth = this.ctx.measureText(this.ticks[0]).width; - var lastWidth = this.ctx.measureText(this.ticks[this.ticks.length - 1]).width; + var firstWidth = context.measureText(this.ticks[0]).width; + var lastWidth = context.measureText(this.ticks[this.ticks.length - 1]).width; var firstRotated; - this.labelRotation = this.options.ticks.minRotation || 0; + this.labelRotation = optionTicks.minRotation || 0; this.paddingRight = 0; this.paddingLeft = 0; @@ -204,7 +208,7 @@ module.exports = function(Chart) { if (!this.longestTextCache) { this.longestTextCache = {}; } - var originalLabelWidth = helpers.longestText(this.ctx, tickLabelFont, this.ticks, this.longestTextCache); + var originalLabelWidth = helpers.longestText(context, tickLabelFont, this.ticks, this.longestTextCache); var labelWidth = originalLabelWidth; var cosRotation; var sinRotation; @@ -214,7 +218,7 @@ module.exports = function(Chart) { var tickWidth = this.getPixelForTick(1) - this.getPixelForTick(0) - 6; //Max label rotation can be set or default to 90 - also act as a loop counter - while (labelWidth > tickWidth && this.labelRotation < this.options.ticks.maxRotation) { + while (labelWidth > tickWidth && this.labelRotation < optionTicks.maxRotation) { cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); @@ -263,18 +267,17 @@ module.exports = function(Chart) { var opts = this.options; var tickOpts = opts.ticks; var scaleLabelOpts = opts.scaleLabel; - var globalOpts = Chart.defaults.global; var display = opts.display; var isHorizontal = this.isHorizontal(); - var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalOpts.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalOpts.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalOpts.defaultFontFamily); + var tickFontSize = helpers.getValueOrDefault(tickOpts.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(tickOpts.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(tickOpts.fontFamily, globalDefaults.defaultFontFamily); var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalOpts.defaultFontSize); - var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabelOpts.fontStyle, globalOpts.defaultFontStyle); - var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabelOpts.fontFamily, globalOpts.defaultFontFamily); + var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabelOpts.fontSize, globalDefaults.defaultFontSize); + var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabelOpts.fontStyle, globalDefaults.defaultFontStyle); + var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabelOpts.fontFamily, globalDefaults.defaultFontFamily); var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); var tickMarkLength = opts.gridLines.tickMarkLength; @@ -450,42 +453,46 @@ module.exports = function(Chart) { // @param {rectangle} chartArea : the area of the chart to draw full grid lines on draw: function(chartArea) { if (this.options.display) { + var context = this.ctx; + var ticks = this.options.ticks; + var gridLines = this.options.gridLines; + var scaleLabel = this.options.scaleLabel; var setContextLineSettings; var isRotated = this.labelRotation !== 0; var skipRatio; var scaleLabelX; var scaleLabelY; - var useAutoskipper = this.options.ticks.autoSkip; +] var useAutoskipper = ticks.autoSkip; // figure out the maximum number of gridlines to show var maxTicks; - - if (this.options.ticks.maxTicksLimit) { - maxTicks = this.options.ticks.maxTicksLimit; + if (ticks.maxTicksLimit) { + maxTicks = ticks.maxTicksLimit; } - var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, Chart.defaults.global.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); + var tickFontColor = helpers.getValueOrDefault(ticks.fontColor, globalDefaults.defaultFontColor); + var tickFontSize = helpers.getValueOrDefault(ticks.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(ticks.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(ticks.fontFamily, globalDefaults.defaultFontFamily); var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - var tl = this.options.gridLines.tickMarkLength; + var tl = gridLines.tickMarkLength; - var scaleLabelFontColor = helpers.getValueOrDefault(this.options.scaleLabel.fontColor, Chart.defaults.global.defaultFontColor); - var scaleLabelFontSize = helpers.getValueOrDefault(this.options.scaleLabel.fontSize, Chart.defaults.global.defaultFontSize); - var scaleLabelFontStyle = helpers.getValueOrDefault(this.options.scaleLabel.fontStyle, Chart.defaults.global.defaultFontStyle); - var scaleLabelFontFamily = helpers.getValueOrDefault(this.options.scaleLabel.fontFamily, Chart.defaults.global.defaultFontFamily); + var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor); + var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize); + var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle); + var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily); var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); - var cosRotation = Math.cos(helpers.toRadians(this.labelRotation)); - var sinRotation = Math.sin(helpers.toRadians(this.labelRotation)); + var labelRotationRadians = helpers.toRadians(this.labelRotation); + var cosRotation = Math.cos(labelRotationRadians); + var sinRotation = Math.sin(labelRotationRadians); var longestRotatedLabel = this.longestLabelWidth * cosRotation; var rotatedLabelHeight = tickFontSize * sinRotation; // Make sure we draw text in the correct color and font - this.ctx.fillStyle = tickFontColor; + context.fillStyle = tickFontColor; if (this.isHorizontal()) { setContextLineSettings = true; @@ -493,8 +500,8 @@ module.exports = function(Chart) { var yTickEnd = this.options.position === "bottom" ? this.top + tl : this.bottom; skipRatio = false; - if (((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { - skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + this.options.ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); + if (((longestRotatedLabel / 2) + ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { + skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); } // if they defined a max number of ticks, @@ -522,63 +529,63 @@ module.exports = function(Chart) { return; } var xLineValue = this.getPixelForTick(index); // xvalues for grid lines - var xLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) + var xLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) - if (this.options.gridLines.display) { + if (gridLines.display) { if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { // Draw the first index specially - this.ctx.lineWidth = this.options.gridLines.zeroLineWidth; - this.ctx.strokeStyle = this.options.gridLines.zeroLineColor; + context.lineWidth = gridLines.zeroLineWidth; + context.strokeStyle = gridLines.zeroLineColor; setContextLineSettings = true; // reset next time } else if (setContextLineSettings) { - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; setContextLineSettings = false; } - xLineValue += helpers.aliasPixel(this.ctx.lineWidth); + xLineValue += helpers.aliasPixel(context.lineWidth); // Draw the label area - this.ctx.beginPath(); + context.beginPath(); - if (this.options.gridLines.drawTicks) { - this.ctx.moveTo(xLineValue, yTickStart); - this.ctx.lineTo(xLineValue, yTickEnd); + if (gridLines.drawTicks) { + context.moveTo(xLineValue, yTickStart); + context.lineTo(xLineValue, yTickEnd); } // Draw the chart area - if (this.options.gridLines.drawOnChartArea) { - this.ctx.moveTo(xLineValue, chartArea.top); - this.ctx.lineTo(xLineValue, chartArea.bottom); + if (gridLines.drawOnChartArea) { + context.moveTo(xLineValue, chartArea.top); + context.lineTo(xLineValue, chartArea.bottom); } // Need to stroke in the loop because we are potentially changing line widths & colours - this.ctx.stroke(); + context.stroke(); } - if (this.options.ticks.display) { - this.ctx.save(); - this.ctx.translate(xLabelValue + this.options.ticks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); - this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1); - this.ctx.font = tickLabelFont; - this.ctx.textAlign = (isRotated) ? "right" : "center"; - this.ctx.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top"; - this.ctx.fillText(label, 0, 0); - this.ctx.restore(); + if (ticks.display) { + context.save(); + context.translate(xLabelValue + ticks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); + context.rotate(labelRotationRadians * -1); + context.font = tickLabelFont; + context.textAlign = (isRotated) ? "right" : "center"; + context.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top"; + context.fillText(label, 0, 0); + context.restore(); } }, this); - if (this.options.scaleLabel.display) { + if (scaleLabel.display) { // Draw the scale label - this.ctx.textAlign = "center"; - this.ctx.textBaseline = 'middle'; - this.ctx.fillStyle = scaleLabelFontColor; // render in correct colour - this.ctx.font = scaleLabelFont; + context.textAlign = "center"; + context.textBaseline = 'middle'; + context.fillStyle = scaleLabelFontColor; // render in correct colour + context.font = scaleLabelFont; scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width scaleLabelY = this.options.position === 'bottom' ? this.bottom - (scaleLabelFontSize / 2) : this.top + (scaleLabelFontSize / 2); - this.ctx.fillText(this.options.scaleLabel.labelString, scaleLabelX, scaleLabelY); + context.fillText(scaleLabel.labelString, scaleLabelX, scaleLabelY); } } else { @@ -594,112 +601,113 @@ module.exports = function(Chart) { var yLineValue = this.getPixelForTick(index); // xvalues for grid lines - if (this.options.gridLines.display) { + if (gridLines.display) { if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { // Draw the first index specially - this.ctx.lineWidth = this.options.gridLines.zeroLineWidth; - this.ctx.strokeStyle = this.options.gridLines.zeroLineColor; + context.lineWidth = gridLines.zeroLineWidth; + context.strokeStyle = gridLines.zeroLineColor; setContextLineSettings = true; // reset next time } else if (setContextLineSettings) { - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; setContextLineSettings = false; } - yLineValue += helpers.aliasPixel(this.ctx.lineWidth); + yLineValue += helpers.aliasPixel(context.lineWidth); // Draw the label area - this.ctx.beginPath(); + context.beginPath(); - if (this.options.gridLines.drawTicks) { - this.ctx.moveTo(xTickStart, yLineValue); - this.ctx.lineTo(xTickEnd, yLineValue); + if (gridLines.drawTicks) { + context.moveTo(xTickStart, yLineValue); + context.lineTo(xTickEnd, yLineValue); } // Draw the chart area - if (this.options.gridLines.drawOnChartArea) { - this.ctx.moveTo(chartArea.left, yLineValue); - this.ctx.lineTo(chartArea.right, yLineValue); + if (gridLines.drawOnChartArea) { + context.moveTo(chartArea.left, yLineValue); + context.lineTo(chartArea.right, yLineValue); } // Need to stroke in the loop because we are potentially changing line widths & colours - this.ctx.stroke(); + context.stroke(); } - if (this.options.ticks.display) { + if (ticks.display) { var xLabelValue; - var yLabelValue = this.getPixelForTick(index, this.options.gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) + var yLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) - this.ctx.save(); + context.save(); if (this.options.position === "left") { - if (this.options.ticks.mirror) { - xLabelValue = this.right + this.options.ticks.padding; - this.ctx.textAlign = "left"; + if (ticks.mirror) { + xLabelValue = this.right + ticks.padding; + context.textAlign = "left"; } else { - xLabelValue = this.right - this.options.ticks.padding; - this.ctx.textAlign = "right"; + xLabelValue = this.right - ticks.padding; + context.textAlign = "right"; } } else { // right side - if (this.options.ticks.mirror) { - xLabelValue = this.left - this.options.ticks.padding; - this.ctx.textAlign = "right"; + if (ticks.mirror) { + xLabelValue = this.left - ticks.padding; + context.textAlign = "right"; } else { - xLabelValue = this.left + this.options.ticks.padding; - this.ctx.textAlign = "left"; + xLabelValue = this.left + ticks.padding; + context.textAlign = "left"; } } - this.ctx.translate(xLabelValue, yLabelValue + this.options.ticks.labelOffset); - this.ctx.rotate(helpers.toRadians(this.labelRotation) * -1); - this.ctx.font = tickLabelFont; - this.ctx.textBaseline = "middle"; - this.ctx.fillText(label, 0, 0); - this.ctx.restore(); + context.translate(xLabelValue, yLabelValue + ticks.labelOffset); + context.rotate(labelRotationRadians * -1); + context.font = tickLabelFont; + context.textBaseline = "middle"; + context.fillText(label, 0, 0); + context.restore(); } }, this); - if (this.options.scaleLabel.display) { + if (scaleLabel.display) { // Draw the scale label scaleLabelX = this.options.position === 'left' ? this.left + (scaleLabelFontSize / 2) : this.right - (scaleLabelFontSize / 2); scaleLabelY = this.top + ((this.bottom - this.top) / 2); var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI; - this.ctx.save(); - this.ctx.translate(scaleLabelX, scaleLabelY); - this.ctx.rotate(rotation); - this.ctx.textAlign = "center"; - this.ctx.fillStyle =scaleLabelFontColor; // render in correct colour - this.ctx.font = scaleLabelFont; - this.ctx.textBaseline = 'middle'; - this.ctx.fillText(this.options.scaleLabel.labelString, 0, 0); - this.ctx.restore(); + context.save(); + context.translate(scaleLabelX, scaleLabelY); + context.rotate(rotation); + context.textAlign = "center"; + context.fillStyle =scaleLabelFontColor; // render in correct colour + context.font = scaleLabelFont; + context.textBaseline = 'middle'; + context.fillText(scaleLabel.labelString, 0, 0); + context.restore(); } } // Draw the line at the edge of the axis - this.ctx.lineWidth = this.options.gridLines.lineWidth; - this.ctx.strokeStyle = this.options.gridLines.color; + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; var x1 = this.left, x2 = this.right, y1 = this.top, y2 = this.bottom; + var aliasPixel = helpers.aliasPixel(context.lineWidth); if (this.isHorizontal()) { y1 = y2 = this.options.position === 'top' ? this.bottom : this.top; - y1 += helpers.aliasPixel(this.ctx.lineWidth); - y2 += helpers.aliasPixel(this.ctx.lineWidth); + y1 += aliasPixel; + y2 += aliasPixel; } else { x1 = x2 = this.options.position === 'left' ? this.right : this.left; - x1 += helpers.aliasPixel(this.ctx.lineWidth); - x2 += helpers.aliasPixel(this.ctx.lineWidth); + x1 += aliasPixel; + x2 += aliasPixel; } - this.ctx.beginPath(); - this.ctx.moveTo(x1, y1); - this.ctx.lineTo(x2, y2); - this.ctx.stroke(); + context.beginPath(); + context.moveTo(x1, y1); + context.lineTo(x2, y2); + context.stroke(); } } }); diff --git a/src/core/core.tooltip.js b/src/core/core.tooltip.js index be5f1c85b..38ec6eac9 100644 --- a/src/core/core.tooltip.js +++ b/src/core/core.tooltip.js @@ -84,47 +84,50 @@ module.exports = function(Chart) { Chart.Tooltip = Chart.Element.extend({ initialize: function() { + var globalDefaults = Chart.defaults.global; var options = this._options; + var tooltips = options.tooltips; + helpers.extend(this, { _model: { // Positioning - xPadding: options.tooltips.xPadding, - yPadding: options.tooltips.yPadding, - xAlign : options.tooltips.yAlign, - yAlign : options.tooltips.xAlign, + xPadding: tooltips.xPadding, + yPadding: tooltips.yPadding, + xAlign : tooltips.yAlign, + yAlign : tooltips.xAlign, // Body - bodyColor: options.tooltips.bodyColor, - _bodyFontFamily: helpers.getValueOrDefault(options.tooltips.bodyFontFamily, Chart.defaults.global.defaultFontFamily), - _bodyFontStyle: helpers.getValueOrDefault(options.tooltips.bodyFontStyle, Chart.defaults.global.defaultFontStyle), - _bodyAlign: options.tooltips.bodyAlign, - bodyFontSize: helpers.getValueOrDefault(options.tooltips.bodyFontSize, Chart.defaults.global.defaultFontSize), - bodySpacing: options.tooltips.bodySpacing, + bodyColor: tooltips.bodyColor, + _bodyFontFamily: helpers.getValueOrDefault(tooltips.bodyFontFamily, globalDefaults.defaultFontFamily), + _bodyFontStyle: helpers.getValueOrDefault(tooltips.bodyFontStyle, globalDefaults.defaultFontStyle), + _bodyAlign: tooltips.bodyAlign, + bodyFontSize: helpers.getValueOrDefault(tooltips.bodyFontSize, globalDefaults.defaultFontSize), + bodySpacing: tooltips.bodySpacing, // Title - titleColor: options.tooltips.titleColor, - _titleFontFamily: helpers.getValueOrDefault(options.tooltips.titleFontFamily, Chart.defaults.global.defaultFontFamily), - _titleFontStyle: helpers.getValueOrDefault(options.tooltips.titleFontStyle, Chart.defaults.global.defaultFontStyle), - titleFontSize: helpers.getValueOrDefault(options.tooltips.titleFontSize, Chart.defaults.global.defaultFontSize), - _titleAlign: options.tooltips.titleAlign, - titleSpacing: options.tooltips.titleSpacing, - titleMarginBottom: options.tooltips.titleMarginBottom, + titleColor: tooltips.titleColor, + _titleFontFamily: helpers.getValueOrDefault(tooltips.titleFontFamily, globalDefaults.defaultFontFamily), + _titleFontStyle: helpers.getValueOrDefault(tooltips.titleFontStyle, globalDefaults.defaultFontStyle), + titleFontSize: helpers.getValueOrDefault(tooltips.titleFontSize, globalDefaults.defaultFontSize), + _titleAlign: tooltips.titleAlign, + titleSpacing: tooltips.titleSpacing, + titleMarginBottom: tooltips.titleMarginBottom, // Footer - footerColor: options.tooltips.footerColor, - _footerFontFamily: helpers.getValueOrDefault(options.tooltips.footerFontFamily, Chart.defaults.global.defaultFontFamily), - _footerFontStyle: helpers.getValueOrDefault(options.tooltips.footerFontStyle, Chart.defaults.global.defaultFontStyle), - footerFontSize: helpers.getValueOrDefault(options.tooltips.footerFontSize, Chart.defaults.global.defaultFontSize), - _footerAlign: options.tooltips.footerAlign, - footerSpacing: options.tooltips.footerSpacing, - footerMarginTop: options.tooltips.footerMarginTop, + footerColor: tooltips.footerColor, + _footerFontFamily: helpers.getValueOrDefault(tooltips.footerFontFamily, globalDefaults.defaultFontFamily), + _footerFontStyle: helpers.getValueOrDefault(tooltips.footerFontStyle, globalDefaults.defaultFontStyle), + footerFontSize: helpers.getValueOrDefault(tooltips.footerFontSize, globalDefaults.defaultFontSize), + _footerAlign: tooltips.footerAlign, + footerSpacing: tooltips.footerSpacing, + footerMarginTop: tooltips.footerMarginTop, // Appearance - caretSize: options.tooltips.caretSize, - cornerRadius: options.tooltips.cornerRadius, - backgroundColor: options.tooltips.backgroundColor, + caretSize: tooltips.caretSize, + cornerRadius: tooltips.cornerRadius, + backgroundColor: tooltips.backgroundColor, opacity: 0, - legendColorBackground: options.tooltips.multiKeyBackground + legendColorBackground: tooltips.multiKeyBackground } }); }, diff --git a/src/elements/element.line.js b/src/elements/element.line.js index b46ba6e68..997dec5e7 100644 --- a/src/elements/element.line.js +++ b/src/elements/element.line.js @@ -3,12 +3,13 @@ module.exports = function(Chart) { var helpers = Chart.helpers; + var globalDefaults = Chart.defaults.global; Chart.defaults.global.elements.line = { tension: 0.4, - backgroundColor: Chart.defaults.global.defaultColor, + backgroundColor: globalDefaults.defaultColor, borderWidth: 3, - borderColor: Chart.defaults.global.defaultColor, + borderColor: globalDefaults.defaultColor, borderCapStyle: 'butt', borderDash: [], borderDashOffset: 0.0, @@ -115,23 +116,24 @@ module.exports = function(Chart) { ctx.lineTo(this._children[0]._view.x, vm.scaleZero); } - ctx.fillStyle = vm.backgroundColor || Chart.defaults.global.defaultColor; + ctx.fillStyle = vm.backgroundColor || globalDefaults.defaultColor; ctx.closePath(); ctx.fill(); } + var globalOptionLineElements = globalDefaults.elements.line; // Now draw the line between all the points with any borders - ctx.lineCap = vm.borderCapStyle || Chart.defaults.global.elements.line.borderCapStyle; + ctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle; // IE 9 and 10 do not support line dash if (ctx.setLineDash) { - ctx.setLineDash(vm.borderDash || Chart.defaults.global.elements.line.borderDash); + ctx.setLineDash(vm.borderDash || globalOptionLineElements.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.elements.line.borderWidth; - ctx.strokeStyle = vm.borderColor || Chart.defaults.global.defaultColor; + ctx.lineDashOffset = vm.borderDashOffset || globalOptionLineElements.borderDashOffset; + ctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle; + ctx.lineWidth = vm.borderWidth || globalOptionLineElements.borderWidth; + ctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor; ctx.beginPath(); helpers.each(this._children, function(point, index) { diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index 11b9b2417..ef6d3b607 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -3,6 +3,7 @@ module.exports = function(Chart) { var helpers = Chart.helpers; + var globalDefaults = globalDefaults; var defaultConfig = { display: true, @@ -49,6 +50,7 @@ module.exports = function(Chart) { return this.chart.data.labels.length; }, setDimensions: function() { + var options = this.options; // Set the unconstrained dimension before label rotation this.width = this.maxWidth; this.height = this.maxHeight; @@ -56,8 +58,8 @@ module.exports = function(Chart) { this.yCenter = Math.round(this.height / 2); var minSize = helpers.min([this.height, this.width]); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - this.drawingArea = (this.options.display) ? (minSize / 2) - (tickFontSize / 2 + this.options.ticks.backdropPaddingY) : (minSize / 2); + var tickFontSize = helpers.getValueOrDefault(options.ticks.fontSize, globalDefaults.defaultFontSize); + this.drawingArea = (options.display) ? (minSize / 2) - (tickFontSize / 2 + options.ticks.backdropPaddingY) : (minSize / 2); }, determineDataLimits: function() { this.min = null; @@ -129,7 +131,7 @@ module.exports = function(Chart) { // the axis area. For now, we say that the minimum tick spacing in pixels must be 50 // We also limit the maximum number of ticks to 11 which gives a nice 10 squares on // the graph - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); + var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, globalDefaults.defaultFontSize); var maxTicks = Math.min(this.options.ticks.maxTicksLimit ? this.options.ticks.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * tickFontSize))); maxTicks = Math.max(2, maxTicks); // Make sure we always have at least 2 ticks @@ -206,9 +208,10 @@ module.exports = function(Chart) { * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif */ - var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize); - var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle); - var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily); + var pointLabels = this.options.pointLabels; + var pointLabelFontSize = helpers.getValueOrDefault(pointLabels.fontSize, globalDefaults.defaultFontSize); + var pointLabeFontStyle = helpers.getValueOrDefault(pointLabels.fontStyle, globalDefaults.defaultFontStyle); + var pointLabeFontFamily = helpers.getValueOrDefault(pointLabels.fontFamily, globalDefaults.defaultFontFamily); var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); // Get maximum radius of the polygon. Either half the height (minus the text width) or half the width. @@ -355,10 +358,10 @@ module.exports = function(Chart) { } if (this.options.ticks.display) { - var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, Chart.defaults.global.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, Chart.defaults.global.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, Chart.defaults.global.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, Chart.defaults.global.defaultFontFamily); + var tickFontColor = helpers.getValueOrDefault(this.options.ticks.fontColor, globalDefaults.defaultFontColor); + var tickFontSize = helpers.getValueOrDefault(this.options.ticks.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(this.options.ticks.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(this.options.ticks.fontFamily, globalDefaults.defaultFontFamily); var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); ctx.font = tickLabelFont; @@ -397,10 +400,10 @@ module.exports = function(Chart) { // Extra 3px out for some label spacing var pointLabelPosition = this.getPointPosition(i, this.getDistanceFromCenterForValue(this.options.reverse ? this.min : this.max) + 5); - var pointLabelFontColor = helpers.getValueOrDefault(this.options.pointLabels.fontColor, Chart.defaults.global.defaultFontColor); - var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, Chart.defaults.global.defaultFontSize); - var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, Chart.defaults.global.defaultFontStyle); - var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, Chart.defaults.global.defaultFontFamily); + var pointLabelFontColor = helpers.getValueOrDefault(this.options.pointLabels.fontColor, globalDefaults.defaultFontColor); + var pointLabelFontSize = helpers.getValueOrDefault(this.options.pointLabels.fontSize, globalDefaults.defaultFontSize); + var pointLabeFontStyle = helpers.getValueOrDefault(this.options.pointLabels.fontStyle, globalDefaults.defaultFontStyle); + var pointLabeFontFamily = helpers.getValueOrDefault(this.options.pointLabels.fontFamily, globalDefaults.defaultFontFamily); var pointLabeFont = helpers.fontString(pointLabelFontSize, pointLabeFontStyle, pointLabeFontFamily); ctx.font = pointLabeFont; From b4a269da19cc235654f7f30d746323f355079f73 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Fri, 13 May 2016 22:16:28 -0500 Subject: [PATCH 2/5] Updated magnification and possible bug fix in removeHoverStyle --- .gitignore | 2 +- src/controllers/controller.bar.js | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index a3589d291..a79806fdf 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,5 @@ docs/index.md bower_components/ coverage/* - +.idea nbproject/* diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index bf3e50b3d..35d1f5925 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -304,18 +304,23 @@ module.exports = function(Chart) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; - rectangle._model.backgroundColor = customr && customr.hoverBackgroundColor ? customr.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(rectangle._model.backgroundColor)); - rectangle._model.borderColor = customr && customr.hoverBorderColor ? customr.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(rectangle._model.borderColor)); - rectangle._model.borderWidth = customr && customr.hoverBorderWidth ? customr.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, rectangle._model.borderWidth); + var custom = rectangle.custom; + var model = rectangle._model; + model.backgroundColor = custom && custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom && custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom && custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); }, removeHoverStyle: function(rectangle) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; + var custom = rectangle.custom; + var model = rectangle._model; + var rectangleElementOptions = this.chart.options.elements.rectangle; - rectangle._model.backgroundColor = customr && customr.backgroundColor ? customr.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor); - rectangle._model.borderColor = customr && customr.borderColor ? customr.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor); - rectangle._model.borderWidth = customr && customr.borderWidth ? customr.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth); + model.backgroundColor = custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); + model.borderColor = custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); + model.borderWidth = custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); } }); From 53b08415ade30c12493f4f651a660841407f2166 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Fri, 13 May 2016 22:23:34 -0500 Subject: [PATCH 3/5] There were conflicting tick variables --- src/core/core.scale.js | 49 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 81303bc36..41a754a39 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -454,7 +454,7 @@ module.exports = function(Chart) { draw: function(chartArea) { if (this.options.display) { var context = this.ctx; - var ticks = this.options.ticks; + var optionTicks = this.options.ticks; var gridLines = this.options.gridLines; var scaleLabel = this.options.scaleLabel; @@ -463,19 +463,18 @@ module.exports = function(Chart) { var skipRatio; var scaleLabelX; var scaleLabelY; -] var useAutoskipper = ticks.autoSkip; - +] var useAutoskipper = optionTicks.autoSkip; // figure out the maximum number of gridlines to show var maxTicks; - if (ticks.maxTicksLimit) { - maxTicks = ticks.maxTicksLimit; + if (optionTicks.maxTicksLimit) { + maxTicks = optionTicks.maxTicksLimit; } - var tickFontColor = helpers.getValueOrDefault(ticks.fontColor, globalDefaults.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(ticks.fontSize, globalDefaults.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(ticks.fontStyle, globalDefaults.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(ticks.fontFamily, globalDefaults.defaultFontFamily); + var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor); + var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily); var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); var tl = gridLines.tickMarkLength; @@ -500,11 +499,11 @@ module.exports = function(Chart) { var yTickEnd = this.options.position === "bottom" ? this.top + tl : this.bottom; skipRatio = false; - if (((longestRotatedLabel / 2) + ticks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { - skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + ticks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); + if (((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { + skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); } - // if they defined a max number of ticks, + // if they defined a max number of optionTicks, // increase skipRatio until that number is met if (maxTicks && this.ticks.length > maxTicks) { while (!skipRatio || this.ticks.length / (skipRatio || 1) > maxTicks) { @@ -520,7 +519,7 @@ module.exports = function(Chart) { } helpers.each(this.ticks, function(label, index) { - // Blank ticks + // Blank optionTicks var isLastTick = this.ticks.length === index + 1; // Since we always show the last tick,we need may need to hide the last shown one before @@ -529,7 +528,7 @@ module.exports = function(Chart) { return; } var xLineValue = this.getPixelForTick(index); // xvalues for grid lines - var xLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) + var xLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) if (gridLines.display) { if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { @@ -563,9 +562,9 @@ module.exports = function(Chart) { context.stroke(); } - if (ticks.display) { + if (optionTicks.display) { context.save(); - context.translate(xLabelValue + ticks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); + context.translate(xLabelValue + optionTicks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); context.rotate(labelRotationRadians * -1); context.font = tickLabelFont; context.textAlign = (isRotated) ? "right" : "center"; @@ -633,32 +632,32 @@ module.exports = function(Chart) { context.stroke(); } - if (ticks.display) { + if (optionTicks.display) { var xLabelValue; - var yLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for ticks (need to consider offsetLabel option) + var yLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) context.save(); if (this.options.position === "left") { - if (ticks.mirror) { - xLabelValue = this.right + ticks.padding; + if (optionTicks.mirror) { + xLabelValue = this.right + optionTicks.padding; context.textAlign = "left"; } else { - xLabelValue = this.right - ticks.padding; + xLabelValue = this.right - optionTicks.padding; context.textAlign = "right"; } } else { // right side - if (ticks.mirror) { - xLabelValue = this.left - ticks.padding; + if (optionTicks.mirror) { + xLabelValue = this.left - optionTicks.padding; context.textAlign = "right"; } else { - xLabelValue = this.left + ticks.padding; + xLabelValue = this.left + optionTicks.padding; context.textAlign = "left"; } } - context.translate(xLabelValue, yLabelValue + ticks.labelOffset); + context.translate(xLabelValue, yLabelValue + optionTicks.labelOffset); context.rotate(labelRotationRadians * -1); context.font = tickLabelFont; context.textBaseline = "middle"; From 7e85245e4fccd0bda27ad0df32fd3651c72f06d8 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Fri, 13 May 2016 22:39:11 -0500 Subject: [PATCH 4/5] Fixed unit tests :D --- src/controllers/controller.bar.js | 13 ++++++++----- src/core/core.controller.js | 10 ++++++---- src/core/core.scale.js | 3 ++- src/scales/scale.radialLinear.js | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 35d1f5925..328b96ff6 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -398,6 +398,9 @@ module.exports = function(Chart) { xScalePoint = xScale.getPixelForValue(0); } + var custom = rectangle.custom; + var dataset = this.getDataset(); + var rectangleElementOptions = this.chart.options.elements.rectangle; helpers.extend(rectangle, { // Utility _chart: this.chart.chart, @@ -413,15 +416,15 @@ module.exports = function(Chart) { // Tooltip label: this.chart.data.labels[index], - datasetLabel: this.getDataset().label, + datasetLabel: dataset.label, // Appearance base: reset ? xScalePoint : this.calculateBarBase(this.index, index), height: this.calculateBarHeight(numBars), - backgroundColor: customr && customr.backgroundColor ? customr.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.rectangle.backgroundColor), - borderSkipped: customr && customr.borderSkipped ? customr.borderSkipped : this.chart.options.elements.rectangle.borderSkipped, - borderColor: customr && customr.borderColor ? customr.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.rectangle.borderColor), - borderWidth: customr && customr.borderWidth ? customr.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.rectangle.borderWidth) + backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom && custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) }, draw: function () { diff --git a/src/core/core.controller.js b/src/core/core.controller.js index ca38642cb..439cce27d 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -540,15 +540,16 @@ module.exports = function(Chart) { // Remove styling for last active (even if it may still be active) if (this.lastActive.length) { + var lastActive; switch (this.options.hover.mode) { case 'single': - var lastActive = this.lastActive[0]; + lastActive = this.lastActive[0]; this.getDatasetMeta(lastActive._datasetIndex).controller.removeHoverStyle(lastActive, lastActive._datasetIndex, lastActive._index); break; case 'label': case 'dataset': for (var i = 0; i < this.lastActive.length; i++) { - var lastActive = this.lastActive[i]; + lastActive = this.lastActive[i]; if (lastActive) this.getDatasetMeta(lastActive._datasetIndex).controller.removeHoverStyle(lastActive, lastActive._datasetIndex, lastActive._index); } @@ -560,15 +561,16 @@ module.exports = function(Chart) { // Built in hover styling if (this.active.length && this.options.hover.mode) { + var active; switch (this.options.hover.mode) { case 'single': - var active = this.active[0]; + active = this.active[0]; this.getDatasetMeta(active._datasetIndex).controller.setHoverStyle(active); break; case 'label': case 'dataset': for (var j = 0; j < this.active.length; j++) { - var active = this.active[j]; + active = this.active[j]; if (active) this.getDatasetMeta(active._datasetIndex).controller.setHoverStyle(active); } diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 41a754a39..9802995da 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -265,6 +265,7 @@ module.exports = function(Chart) { }; var opts = this.options; + var globalDefaults = Chart.defaults.global; var tickOpts = opts.ticks; var scaleLabelOpts = opts.scaleLabel; var display = opts.display; @@ -463,7 +464,7 @@ module.exports = function(Chart) { var skipRatio; var scaleLabelX; var scaleLabelY; -] var useAutoskipper = optionTicks.autoSkip; + var useAutoskipper = optionTicks.autoSkip; // figure out the maximum number of gridlines to show var maxTicks; diff --git a/src/scales/scale.radialLinear.js b/src/scales/scale.radialLinear.js index ef6d3b607..5d46f26ee 100644 --- a/src/scales/scale.radialLinear.js +++ b/src/scales/scale.radialLinear.js @@ -3,7 +3,7 @@ module.exports = function(Chart) { var helpers = Chart.helpers; - var globalDefaults = globalDefaults; + var globalDefaults = Chart.defaults.global; var defaultConfig = { display: true, From a3d75d20870ff96d9075eeb678ec7c370fc56574 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Sat, 14 May 2016 08:58:42 -0500 Subject: [PATCH 5/5] More perf and minification changes based on feedback --- src/controllers/controller.bar.js | 36 +- src/controllers/controller.bubble.js | 43 ++- src/controllers/controller.doughnut.js | 20 +- src/controllers/controller.line.js | 96 +++-- src/controllers/controller.polarArea.js | 22 +- src/controllers/controller.radar.js | 89 +++-- src/core/core.datasetController.js | 16 +- src/core/core.scale.js | 484 ++++++++++++------------ 8 files changed, 424 insertions(+), 382 deletions(-) diff --git a/src/controllers/controller.bar.js b/src/controllers/controller.bar.js index 328b96ff6..957111549 100644 --- a/src/controllers/controller.bar.js +++ b/src/controllers/controller.bar.js @@ -97,7 +97,7 @@ module.exports = function(Chart) { } var rectangleElementOptions = this.chart.options.elements.rectangle; - var custom = rectangle.custom; + var custom = rectangle.custom || {}; var dataset = this.getDataset(); helpers.extend(rectangle, { @@ -121,10 +121,10 @@ module.exports = function(Chart) { // Appearance base: reset ? yScalePoint : this.calculateBarBase(this.index, index), width: this.calculateBarWidth(numBars), - backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), - borderSkipped: custom && custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, - borderColor: custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), - borderWidth: custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) } }); rectangle.pivot(); @@ -304,23 +304,23 @@ module.exports = function(Chart) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; - var custom = rectangle.custom; + var custom = rectangle.custom || {}; var model = rectangle._model; - model.backgroundColor = custom && custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); - model.borderColor = custom && custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); - model.borderWidth = custom && custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); }, removeHoverStyle: function(rectangle) { var dataset = this.chart.data.datasets[rectangle._datasetIndex]; var index = rectangle._index; - var custom = rectangle.custom; + var custom = rectangle.custom || {}; var model = rectangle._model; var rectangleElementOptions = this.chart.options.elements.rectangle; - model.backgroundColor = custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); - model.borderColor = custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); - model.borderWidth = custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth); } }); @@ -398,7 +398,7 @@ module.exports = function(Chart) { xScalePoint = xScale.getPixelForValue(0); } - var custom = rectangle.custom; + var custom = rectangle.custom || {}; var dataset = this.getDataset(); var rectangleElementOptions = this.chart.options.elements.rectangle; helpers.extend(rectangle, { @@ -421,10 +421,10 @@ module.exports = function(Chart) { // Appearance base: reset ? xScalePoint : this.calculateBarBase(this.index, index), height: this.calculateBarHeight(numBars), - backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), - borderSkipped: custom && custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, - borderColor: custom && custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), - borderWidth: custom && custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, rectangleElementOptions.backgroundColor), + borderSkipped: custom.borderSkipped ? custom.borderSkipped : rectangleElementOptions.borderSkipped, + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, rectangleElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, rectangleElementOptions.borderWidth) }, draw: function () { diff --git a/src/controllers/controller.bubble.js b/src/controllers/controller.bubble.js index 23500c29f..581287bd5 100644 --- a/src/controllers/controller.bubble.js +++ b/src/controllers/controller.bubble.js @@ -89,6 +89,11 @@ module.exports = function(Chart) { var xScale = this.getScaleForId(meta.xAxisID); var scaleBase; + var custom = point.custom || {}; + var dataset = this.getDataset(); + var data = dataset.data[index]; + var pointElementOptions = this.chart.options.elements.point; + if (yScale.min < 0 && yScale.max < 0) { scaleBase = yScale.getPixelForValue(yScale.max); } else if (yScale.min > 0 && yScale.max > 0) { @@ -107,20 +112,21 @@ module.exports = function(Chart) { // Desired view properties _model: { - x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(this.getDataset().data[index], index, this.index, this.chart.isCombo), - y: reset ? scaleBase : yScale.getPixelForValue(this.getDataset().data[index], index, this.index), + x: reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(data, index, this.index, this.chart.isCombo), + y: reset ? scaleBase : yScale.getPixelForValue(data, index, this.index), // Appearance - radius: reset ? 0 : point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[index]), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth), + radius: reset ? 0 : custom.radius ? custom.radius : this.getRadius(data), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, pointElementOptions.backgroundColor), + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, pointElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, pointElementOptions.borderWidth), // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) } }); - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); + var model = point._model; + model.skip = custom.skip ? custom.skip : (isNaN(model.x) || isNaN(model.y)); point.pivot(); }, @@ -144,21 +150,26 @@ module.exports = function(Chart) { // Point var dataset = this.chart.data.datasets[point._datasetIndex]; var index = point._index; + var custom = point.custom || {}; + var model = point._model; - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(point._model.backgroundColor)); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(point._model.borderColor)); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, point._model.borderWidth); + model.radius = custom.hoverRadius ? custom.hoverRadius : (helpers.getValueAtIndexOrDefault(dataset.hoverRadius, index, this.chart.options.elements.point.hoverRadius)) + this.getRadius(this.getDataset().data[point._index]); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.hoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.hoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); }, removeHoverStyle: function(point) { var dataset = this.chart.data.datasets[point._datasetIndex]; var index = point._index; + var custom = point.custom || {}; + var model = point._model; + var pointElementOptions = this.chart.options.elements.point; - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : this.getRadius(this.getDataset().data[point._index]); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().backgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().borderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().borderWidth, index, this.chart.options.elements.point.borderWidth); + model.radius = custom.radius ? custom.radius : this.getRadius(dataset.data[point._index]); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.backgroundColor, index, pointElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.borderColor, index, pointElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.borderWidth, index, pointElementOptions.borderWidth); } }); }; diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 8a68a68cf..00152fb00 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -46,12 +46,12 @@ module.exports = function(Chart) { var meta = chart.getDatasetMeta(0); var ds = data.datasets[0]; var arc = meta.data[i]; - var custom = arc.custom; + var custom = arc.custom || {}; var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; var arcOpts = chart.options.elements.arc; - var fill = custom && custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); - var stroke = custom && custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); - var bw = custom && custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); return { text: label, @@ -170,7 +170,7 @@ module.exports = function(Chart) { availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth, minSize = Math.min(availableWidth, availableHeight), offset = { - x: 0, + x: 0, y: 0 }, meta = _this.getMeta(), @@ -227,7 +227,7 @@ module.exports = function(Chart) { circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : _this.calculateCircumference(dataset.data[index]) * (opts.circumference / (2.0 * Math.PI)), innerRadius = reset && animationOpts.animateScale ? 0 : _this.innerRadius, outerRadius = reset && animationOpts.animateScale ? 0 : _this.outerRadius, - custom = arc.custom, + custom = arc.custom || {}, valueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; helpers.extend(arc, { @@ -250,10 +250,10 @@ module.exports = function(Chart) { }); var model = arc._model; - model.backgroundColor = custom && custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor); - model.hoverBackgroundColor = custom && custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, arcOpts.hoverBackgroundColor); - model.borderWidth = custom && custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth); - model.borderColor = custom && custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor); + model.hoverBackgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueAtIndexOrDefault(dataset.hoverBackgroundColor, index, arcOpts.hoverBackgroundColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : valueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth); + model.borderColor = custom.borderColor ? custom.borderColor : valueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor); // Set correct angles if not resetting if (!reset || !animationOpts.animateRotate) { diff --git a/src/controllers/controller.line.js b/src/controllers/controller.line.js index e863399b8..58349034c 100644 --- a/src/controllers/controller.line.js +++ b/src/controllers/controller.line.js @@ -61,6 +61,7 @@ module.exports = function(Chart) { update: function update(reset) { var meta = this.getMeta(); var line = meta.dataset; + var lineElementOptions = this.chart.options.elements.line; var points = meta.data; var yScale = this.getScaleForId(meta.yAxisID); @@ -84,23 +85,24 @@ module.exports = function(Chart) { line._children = points; // Model + var dataset = this.getDataset(); + var custom = line.custom || {}; // 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; + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { + dataset.lineTension = dataset.tension; } line._model = { // Appearance - 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), - 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), + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), // Scale scaleTop: yScale.top, scaleBottom: yScale.bottom, @@ -114,16 +116,18 @@ module.exports = function(Chart) { this.updateElement(point, index, reset); }, this); - if (this.chart.options.showLines && this.chart.options.elements.line.tension !== 0) + if (this.chart.options.showLines && lineElementOptions.tension !== 0) { this.updateBezierControlPoints(); + } }, getPointBackgroundColor: function(point, index) { var backgroundColor = this.chart.options.elements.point.backgroundColor; var dataset = this.getDataset(); + var custom = point.custom || {}; - if (point.custom && point.custom.backgroundColor) { - backgroundColor = point.custom.backgroundColor; + if (custom.backgroundColor) { + backgroundColor = custom.backgroundColor; } else if (dataset.pointBackgroundColor) { backgroundColor = helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, backgroundColor); } else if (dataset.backgroundColor) { @@ -135,11 +139,12 @@ module.exports = function(Chart) { getPointBorderColor: function(point, index) { var borderColor = this.chart.options.elements.point.borderColor; var dataset = this.getDataset(); + var custom = point.custom || {}; - if (point.custom && point.custom.borderColor) { - borderColor = point.custom.borderColor; + if (custom.borderColor) { + borderColor = custom.borderColor; } else if (dataset.pointBorderColor) { - borderColor = helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, borderColor); + borderColor = helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, borderColor); } else if (dataset.borderColor) { borderColor = dataset.borderColor; } @@ -149,12 +154,13 @@ module.exports = function(Chart) { getPointBorderWidth: function(point, index) { var borderWidth = this.chart.options.elements.point.borderWidth; var dataset = this.getDataset(); + var custom = point.custom || {}; - if (point.custom && point.custom.borderWidth !== undefined) { - borderWidth = point.custom.borderWidth; - } else if (dataset.pointBorderWidth !== undefined) { + if (custom.borderWidth) { + borderWidth = custom.borderWidth; + } else if (dataset.pointBorderWidth) { borderWidth = helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, borderWidth); - } else if (dataset.borderWidth !== undefined) { + } else if (dataset.borderWidth) { borderWidth = dataset.borderWidth; } @@ -163,6 +169,8 @@ module.exports = function(Chart) { updateElement: function(point, index, reset) { var meta = this.getMeta(); + var custom = point.custom || {}; + var dataset = this.getDataset(); var yScale = this.getScaleForId(meta.yAxisID); var xScale = this.getScaleForId(meta.xAxisID); var scaleBase; @@ -185,30 +193,30 @@ module.exports = function(Chart) { // 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)) + if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { - this.getDataset().pointRadius = this.getDataset().radius; + dataset.pointRadius = dataset.radius; } - if ((this.getDataset().hitRadius !== undefined) && (this.getDataset().pointHitRadius === undefined)) + if ((dataset.hitRadius !== undefined) && (dataset.pointHitRadius === undefined)) { - this.getDataset().pointHitRadius = this.getDataset().hitRadius; + dataset.pointHitRadius = dataset.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), + x: xScale.getPixelForValue(dataset.data[index], index, this.index, this.chart.isCombo), + y: reset ? scaleBase : this.calculatePointY(dataset.data[index], index, this.index, this.chart.isCombo), // Appearance - 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), + radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, this.chart.options.elements.point.radius), + pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, this.chart.options.elements.point.pointStyle), backgroundColor: this.getPointBackgroundColor(point, index), borderColor: this.getPointBorderColor(point, index), borderWidth: this.getPointBorderWidth(point, index), tension: meta.dataset._model ? meta.dataset._model.tension : 0, // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().pointHitRadius, index, this.chart.options.elements.point.hitRadius) + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.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)); + point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); }, calculatePointY: function(value, index, datasetIndex, isCombo) { @@ -289,27 +297,31 @@ module.exports = function(Chart) { // Point var dataset = this.chart.data.datasets[point._datasetIndex]; var index = point._index; + var custom = point.custom || {}; + var model = point._model; - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(point._model.backgroundColor)); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(point._model.borderColor)); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); + model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); }, removeHoverStyle: function(point) { var dataset = this.chart.data.datasets[point._datasetIndex]; var index = point._index; + var custom = point.custom || {}; + var model = point._model; // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().radius !== undefined) && (this.getDataset().pointRadius === undefined)) + if ((dataset.radius !== undefined) && (dataset.pointRadius === undefined)) { - this.getDataset().pointRadius = this.getDataset().radius; + dataset.pointRadius = dataset.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); + model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, this.chart.options.elements.point.radius); + model.backgroundColor = this.getPointBackgroundColor(point, index); + model.borderColor = this.getPointBorderColor(point, index); + model.borderWidth = this.getPointBorderWidth(point, index); } }); }; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 2308be89b..1523cfb1d 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -48,12 +48,12 @@ module.exports = function(Chart) { var meta = chart.getDatasetMeta(0); var ds = data.datasets[0]; var arc = meta.data[i]; - var custom = arc.custom; + var custom = arc.custom || {}; var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; var arcOpts = chart.options.elements.arc; - var fill = custom && custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); - var stroke = custom && custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); - var bw = custom && custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); + var fill = custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(ds.backgroundColor, i, arcOpts.backgroundColor); + var stroke = custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(ds.borderColor, i, arcOpts.borderColor); + var bw = custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(ds.borderWidth, i, arcOpts.borderWidth); return { text: label, @@ -158,7 +158,7 @@ module.exports = function(Chart) { var opts = chart.options; var animationOpts = opts.animation; var arcOpts = opts.elements.arc; - var custom = arc.custom; + var custom = arc.custom || {}; var scale = chart.scale; var getValueAtIndexOrDefault = helpers.getValueAtIndexOrDefault; var labels = chart.data.labels; @@ -189,9 +189,9 @@ module.exports = function(Chart) { startAngle: animationOpts.animateRotate ? Math.PI * -0.5 : startAngle, endAngle: animationOpts.animateRotate ? Math.PI * -0.5 : endAngle, - backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), - borderWidth: custom && custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), - borderColor: custom && custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), label: getValueAtIndexOrDefault(labels, index, labels[index]) }; @@ -212,9 +212,9 @@ module.exports = function(Chart) { startAngle: startAngle, endAngle: endAngle, - backgroundColor: custom && custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), - borderWidth: custom && custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), - borderColor: custom && custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : getValueAtIndexOrDefault(dataset.backgroundColor, index, arcOpts.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : getValueAtIndexOrDefault(dataset.borderWidth, index, arcOpts.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : getValueAtIndexOrDefault(dataset.borderColor, index, arcOpts.borderColor), label: getValueAtIndexOrDefault(labels, index, labels[index]) } diff --git a/src/controllers/controller.radar.js b/src/controllers/controller.radar.js index 423c3ed97..f4a3f1e4b 100644 --- a/src/controllers/controller.radar.js +++ b/src/controllers/controller.radar.js @@ -62,6 +62,9 @@ module.exports = function(Chart) { var meta = this.getMeta(); var line = meta.dataset; var points = meta.data; + var custom = line.custom || {}; + var dataset = this.getDataset(); + var lineElementOptions = this.chart.options.elements.line; var scale = this.chart.scale; var scaleBase; @@ -75,9 +78,9 @@ module.exports = function(Chart) { } // Compatibility: If the properties are defined with only the old name, use those values - if ((this.getDataset().tension !== undefined) && (this.getDataset().lineTension === undefined)) + if ((dataset.tension !== undefined) && (dataset.lineTension === undefined)) { - this.getDataset().lineTension = this.getDataset().tension; + dataset.lineTension = dataset.tension; } helpers.extend(meta.dataset, { @@ -88,15 +91,15 @@ module.exports = function(Chart) { // Model _model: { // Appearance - 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), - fill: line.custom && line.custom.fill ? line.custom.fill : (this.getDataset().fill !== undefined ? this.getDataset().fill : this.chart.options.elements.line.fill), - 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), + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.lineTension, lineElementOptions.tension), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : (dataset.backgroundColor || lineElementOptions.backgroundColor), + borderWidth: custom.borderWidth ? custom.borderWidth : (dataset.borderWidth || lineElementOptions.borderWidth), + borderColor: custom.borderColor ? custom.borderColor : (dataset.borderColor || lineElementOptions.borderColor), + fill: custom.fill ? custom.fill : (dataset.fill !== undefined ? dataset.fill : lineElementOptions.fill), + borderCapStyle: custom.borderCapStyle ? custom.borderCapStyle : (dataset.borderCapStyle || lineElementOptions.borderCapStyle), + borderDash: custom.borderDash ? custom.borderDash : (dataset.borderDash || lineElementOptions.borderDash), + borderDashOffset: custom.borderDashOffset ? custom.borderDashOffset : (dataset.borderDashOffset || lineElementOptions.borderDashOffset), + borderJoinStyle: custom.borderJoinStyle ? custom.borderJoinStyle : (dataset.borderJoinStyle || lineElementOptions.borderJoinStyle), // Scale scaleTop: scale.top, @@ -117,50 +120,57 @@ module.exports = function(Chart) { this.updateBezierControlPoints(); }, updateElement: function(point, index, reset) { - var pointPosition = this.chart.scale.getPointPositionForValue(index, this.getDataset().data[index]); + var custom = point.custom || {}; + var dataset = this.getDataset(); + var scale = this.chart.scale; + var pointElementOptions = this.chart.options.elements.point; + var pointPosition = scale.getPointPositionForValue(index, dataset.data[index]); helpers.extend(point, { // Utility _datasetIndex: this.index, _index: index, - _scale: this.chart.scale, + _scale: scale, // Desired view properties _model: { - x: reset ? this.chart.scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales - y: reset ? this.chart.scale.yCenter : pointPosition.y, + x: reset ? scale.xCenter : pointPosition.x, // value not used in dataset scale, but we want a consistent API between scales + y: reset ? scale.yCenter : pointPosition.y, // 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().pointRadius, index, this.chart.options.elements.point.radius), - backgroundColor: point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor), - borderColor: point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor), - borderWidth: point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth), - pointStyle: point.custom && point.custom.pointStyle ? point.custom.pointStyle : helpers.getValueAtIndexOrDefault(this.getDataset().pointStyle, index, this.chart.options.elements.point.pointStyle), + tension: custom.tension ? custom.tension : helpers.getValueOrDefault(dataset.tension, this.chart.options.elements.line.tension), + radius: custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.pointRadius, index, pointElementOptions.radius), + backgroundColor: custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor), + borderColor: custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor), + borderWidth: custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth), + pointStyle: custom.pointStyle ? custom.pointStyle : helpers.getValueAtIndexOrDefault(dataset.pointStyle, index, pointElementOptions.pointStyle), // Tooltip - hitRadius: point.custom && point.custom.hitRadius ? point.custom.hitRadius : helpers.getValueAtIndexOrDefault(this.getDataset().hitRadius, index, this.chart.options.elements.point.hitRadius) + hitRadius: custom.hitRadius ? custom.hitRadius : helpers.getValueAtIndexOrDefault(dataset.hitRadius, index, pointElementOptions.hitRadius) } }); - point._model.skip = point.custom && point.custom.skip ? point.custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); + point._model.skip = custom.skip ? custom.skip : (isNaN(point._model.x) || isNaN(point._model.y)); }, updateBezierControlPoints: function() { + var chartArea = this.chart.chartArea; var meta = this.getMeta(); + helpers.each(meta.data, function(point, index) { + var model = point._model; var controlPoints = helpers.splineCurve( helpers.previousItem(meta.data, index, true)._model, - point._model, + model, helpers.nextItem(meta.data, index, true)._model, - point._model.tension + model.tension ); // Prevent the bezier going outside of the bounds of the graph - point._model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, this.chart.chartArea.bottom), this.chart.chartArea.top); + model.controlPointPreviousX = Math.max(Math.min(controlPoints.previous.x, chartArea.right), chartArea.left); + model.controlPointPreviousY = Math.max(Math.min(controlPoints.previous.y, chartArea.bottom), chartArea.top); - point._model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, this.chart.chartArea.right), this.chart.chartArea.left); - point._model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, this.chart.chartArea.bottom), this.chart.chartArea.top); + model.controlPointNextX = Math.max(Math.min(controlPoints.next.x, chartArea.right), chartArea.left); + model.controlPointNextY = Math.max(Math.min(controlPoints.next.y, chartArea.bottom), chartArea.top); // Now pivot the point for animation point.pivot(); @@ -188,22 +198,27 @@ module.exports = function(Chart) { setHoverStyle: function(point) { // Point var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; var index = point._index; + var model = point._model; - point._model.radius = point.custom && point.custom.hoverRadius ? point.custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); - point._model.backgroundColor = point.custom && point.custom.hoverBackgroundColor ? point.custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(point._model.backgroundColor)); - point._model.borderColor = point.custom && point.custom.hoverBorderColor ? point.custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(point._model.borderColor)); - point._model.borderWidth = point.custom && point.custom.hoverBorderWidth ? point.custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, point._model.borderWidth); + model.radius = custom.hoverRadius ? custom.hoverRadius : helpers.getValueAtIndexOrDefault(dataset.pointHoverRadius, index, this.chart.options.elements.point.hoverRadius); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBackgroundColor, index, helpers.getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderColor, index, helpers.getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : helpers.getValueAtIndexOrDefault(dataset.pointHoverBorderWidth, index, model.borderWidth); }, removeHoverStyle: function(point) { var dataset = this.chart.data.datasets[point._datasetIndex]; + var custom = point.custom || {}; var index = point._index; + var model = point._model; + var pointElementOptions = this.chart.options.elements.point; - point._model.radius = point.custom && point.custom.radius ? point.custom.radius : helpers.getValueAtIndexOrDefault(this.getDataset().radius, index, this.chart.options.elements.point.radius); - point._model.backgroundColor = point.custom && point.custom.backgroundColor ? point.custom.backgroundColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBackgroundColor, index, this.chart.options.elements.point.backgroundColor); - point._model.borderColor = point.custom && point.custom.borderColor ? point.custom.borderColor : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderColor, index, this.chart.options.elements.point.borderColor); - point._model.borderWidth = point.custom && point.custom.borderWidth ? point.custom.borderWidth : helpers.getValueAtIndexOrDefault(this.getDataset().pointBorderWidth, index, this.chart.options.elements.point.borderWidth); + model.radius = custom.radius ? custom.radius : helpers.getValueAtIndexOrDefault(dataset.radius, index, pointElementOptions.radius); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : helpers.getValueAtIndexOrDefault(dataset.pointBackgroundColor, index, pointElementOptions.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : helpers.getValueAtIndexOrDefault(dataset.pointBorderColor, index, pointElementOptions.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : helpers.getValueAtIndexOrDefault(dataset.pointBorderWidth, index, pointElementOptions.borderWidth); } }); }; diff --git a/src/core/core.datasetController.js b/src/core/core.datasetController.js index cfd069ef8..835d0858f 100644 --- a/src/core/core.datasetController.js +++ b/src/core/core.datasetController.js @@ -80,27 +80,27 @@ module.exports = function(Chart) { removeHoverStyle: function(element, elementOpts) { var dataset = this.chart.data.datasets[element._datasetIndex], index = element._index, - custom = element.custom, + custom = element.custom || {}, valueOrDefault = helpers.getValueAtIndexOrDefault, color = helpers.color, model = element._model; - model.backgroundColor = custom && custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor); - model.borderColor = custom && custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor); - model.borderWidth = custom && custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth); + model.backgroundColor = custom.backgroundColor ? custom.backgroundColor : valueOrDefault(dataset.backgroundColor, index, elementOpts.backgroundColor); + model.borderColor = custom.borderColor ? custom.borderColor : valueOrDefault(dataset.borderColor, index, elementOpts.borderColor); + model.borderWidth = custom.borderWidth ? custom.borderWidth : valueOrDefault(dataset.borderWidth, index, elementOpts.borderWidth); }, setHoverStyle: function(element) { var dataset = this.chart.data.datasets[element._datasetIndex], index = element._index, - custom = element.custom, + custom = element.custom || {}, valueOrDefault = helpers.getValueAtIndexOrDefault, color = helpers.color, getHoverColor = helpers.getHoverColor, model = element._model; - model.backgroundColor = custom && custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor)); - model.borderColor = custom && custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor)); - model.borderWidth = custom && custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); + model.backgroundColor = custom.hoverBackgroundColor ? custom.hoverBackgroundColor : valueOrDefault(dataset.hoverBackgroundColor, index, getHoverColor(model.backgroundColor)); + model.borderColor = custom.hoverBorderColor ? custom.hoverBorderColor : valueOrDefault(dataset.hoverBorderColor, index, getHoverColor(model.borderColor)); + model.borderWidth = custom.hoverBorderWidth ? custom.hoverBorderWidth : valueOrDefault(dataset.hoverBorderWidth, index, model.borderWidth); }, update: noop }); diff --git a/src/core/core.scale.js b/src/core/core.scale.js index 9802995da..24d3c1bfe 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -3,7 +3,6 @@ module.exports = function(Chart) { var helpers = Chart.helpers; - var globalDefaults = Chart.defaults.global; Chart.defaults.scale = { display: true, @@ -182,6 +181,7 @@ module.exports = function(Chart) { }, calculateTickRotation: function() { var context = this.ctx; + var globalDefaults = Chart.defaults.global; var optionTicks = this.options.ticks; //Get the width of each grid by calculating the difference @@ -453,262 +453,266 @@ module.exports = function(Chart) { // Actualy draw the scale on the canvas // @param {rectangle} chartArea : the area of the chart to draw full grid lines on draw: function(chartArea) { - if (this.options.display) { - var context = this.ctx; - var optionTicks = this.options.ticks; - var gridLines = this.options.gridLines; - var scaleLabel = this.options.scaleLabel; + var options = this.options; + if (!options.display) { + return; + } - var setContextLineSettings; - var isRotated = this.labelRotation !== 0; - var skipRatio; - var scaleLabelX; - var scaleLabelY; - var useAutoskipper = optionTicks.autoSkip; + var context = this.ctx; + var globalDefaults = Chart.defaults.global; + var optionTicks = options.ticks; + var gridLines = options.gridLines; + var scaleLabel = options.scaleLabel; - // figure out the maximum number of gridlines to show - var maxTicks; - if (optionTicks.maxTicksLimit) { - maxTicks = optionTicks.maxTicksLimit; + var setContextLineSettings; + var isRotated = this.labelRotation !== 0; + var skipRatio; + var scaleLabelX; + var scaleLabelY; + var useAutoskipper = optionTicks.autoSkip; + + // figure out the maximum number of gridlines to show + var maxTicks; + if (optionTicks.maxTicksLimit) { + maxTicks = optionTicks.maxTicksLimit; + } + + var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor); + var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize); + var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle); + var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily); + var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); + var tl = gridLines.tickMarkLength; + + var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor); + var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize); + var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle); + var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily); + var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); + + var labelRotationRadians = helpers.toRadians(this.labelRotation); + var cosRotation = Math.cos(labelRotationRadians); + var sinRotation = Math.sin(labelRotationRadians); + var longestRotatedLabel = this.longestLabelWidth * cosRotation; + var rotatedLabelHeight = tickFontSize * sinRotation; + + // Make sure we draw text in the correct color and font + context.fillStyle = tickFontColor; + + if (this.isHorizontal()) { + setContextLineSettings = true; + var yTickStart = options.position === "bottom" ? this.top : this.bottom - tl; + var yTickEnd = options.position === "bottom" ? this.top + tl : this.bottom; + skipRatio = false; + + if (((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { + skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); } - var tickFontColor = helpers.getValueOrDefault(optionTicks.fontColor, globalDefaults.defaultFontColor); - var tickFontSize = helpers.getValueOrDefault(optionTicks.fontSize, globalDefaults.defaultFontSize); - var tickFontStyle = helpers.getValueOrDefault(optionTicks.fontStyle, globalDefaults.defaultFontStyle); - var tickFontFamily = helpers.getValueOrDefault(optionTicks.fontFamily, globalDefaults.defaultFontFamily); - var tickLabelFont = helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily); - var tl = gridLines.tickMarkLength; + // if they defined a max number of optionTicks, + // increase skipRatio until that number is met + if (maxTicks && this.ticks.length > maxTicks) { + while (!skipRatio || this.ticks.length / (skipRatio || 1) > maxTicks) { + if (!skipRatio) { + skipRatio = 1; + } + skipRatio += 1; + } + } - var scaleLabelFontColor = helpers.getValueOrDefault(scaleLabel.fontColor, globalDefaults.defaultFontColor); - var scaleLabelFontSize = helpers.getValueOrDefault(scaleLabel.fontSize, globalDefaults.defaultFontSize); - var scaleLabelFontStyle = helpers.getValueOrDefault(scaleLabel.fontStyle, globalDefaults.defaultFontStyle); - var scaleLabelFontFamily = helpers.getValueOrDefault(scaleLabel.fontFamily, globalDefaults.defaultFontFamily); - var scaleLabelFont = helpers.fontString(scaleLabelFontSize, scaleLabelFontStyle, scaleLabelFontFamily); - - var labelRotationRadians = helpers.toRadians(this.labelRotation); - var cosRotation = Math.cos(labelRotationRadians); - var sinRotation = Math.sin(labelRotationRadians); - var longestRotatedLabel = this.longestLabelWidth * cosRotation; - var rotatedLabelHeight = tickFontSize * sinRotation; - - // Make sure we draw text in the correct color and font - context.fillStyle = tickFontColor; - - if (this.isHorizontal()) { - setContextLineSettings = true; - var yTickStart = this.options.position === "bottom" ? this.top : this.bottom - tl; - var yTickEnd = this.options.position === "bottom" ? this.top + tl : this.bottom; + if (!useAutoskipper) { skipRatio = false; + } - if (((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length > (this.width - (this.paddingLeft + this.paddingRight))) { - skipRatio = 1 + Math.floor((((longestRotatedLabel / 2) + optionTicks.autoSkipPadding) * this.ticks.length) / (this.width - (this.paddingLeft + this.paddingRight))); + helpers.each(this.ticks, function (label, index) { + // Blank optionTicks + var isLastTick = this.ticks.length === index + 1; + + // Since we always show the last tick,we need may need to hide the last shown one before + var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio > this.ticks.length); + if (shouldSkip && !isLastTick || (label === undefined || label === null)) { + return; + } + var xLineValue = this.getPixelForTick(index); // xvalues for grid lines + var xLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) + + if (gridLines.display) { + if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { + // Draw the first index specially + context.lineWidth = gridLines.zeroLineWidth; + context.strokeStyle = gridLines.zeroLineColor; + setContextLineSettings = true; // reset next time + } else if (setContextLineSettings) { + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; + setContextLineSettings = false; + } + + xLineValue += helpers.aliasPixel(context.lineWidth); + + // Draw the label area + context.beginPath(); + + if (gridLines.drawTicks) { + context.moveTo(xLineValue, yTickStart); + context.lineTo(xLineValue, yTickEnd); + } + + // Draw the chart area + if (gridLines.drawOnChartArea) { + context.moveTo(xLineValue, chartArea.top); + context.lineTo(xLineValue, chartArea.bottom); + } + + // Need to stroke in the loop because we are potentially changing line widths & colours + context.stroke(); } - // if they defined a max number of optionTicks, - // increase skipRatio until that number is met - if (maxTicks && this.ticks.length > maxTicks) { - while (!skipRatio || this.ticks.length / (skipRatio || 1) > maxTicks) { - if (!skipRatio) { - skipRatio = 1; - } - skipRatio += 1; - } - } - - if (!useAutoskipper) { - skipRatio = false; - } - - helpers.each(this.ticks, function(label, index) { - // Blank optionTicks - var isLastTick = this.ticks.length === index + 1; - - // Since we always show the last tick,we need may need to hide the last shown one before - var shouldSkip = (skipRatio > 1 && index % skipRatio > 0) || (index % skipRatio === 0 && index + skipRatio > this.ticks.length); - if (shouldSkip && !isLastTick || (label === undefined || label === null)) { - return; - } - var xLineValue = this.getPixelForTick(index); // xvalues for grid lines - var xLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) - - if (gridLines.display) { - if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { - // Draw the first index specially - context.lineWidth = gridLines.zeroLineWidth; - context.strokeStyle = gridLines.zeroLineColor; - setContextLineSettings = true; // reset next time - } else if (setContextLineSettings) { - context.lineWidth = gridLines.lineWidth; - context.strokeStyle = gridLines.color; - setContextLineSettings = false; - } - - xLineValue += helpers.aliasPixel(context.lineWidth); - - // Draw the label area - context.beginPath(); - - if (gridLines.drawTicks) { - context.moveTo(xLineValue, yTickStart); - context.lineTo(xLineValue, yTickEnd); - } - - // Draw the chart area - if (gridLines.drawOnChartArea) { - context.moveTo(xLineValue, chartArea.top); - context.lineTo(xLineValue, chartArea.bottom); - } - - // Need to stroke in the loop because we are potentially changing line widths & colours - context.stroke(); - } - - if (optionTicks.display) { - context.save(); - context.translate(xLabelValue + optionTicks.labelOffset, (isRotated) ? this.top + 12 : this.options.position === "top" ? this.bottom - tl : this.top + tl); - context.rotate(labelRotationRadians * -1); - context.font = tickLabelFont; - context.textAlign = (isRotated) ? "right" : "center"; - context.textBaseline = (isRotated) ? "middle" : this.options.position === "top" ? "bottom" : "top"; - context.fillText(label, 0, 0); - context.restore(); - } - }, this); - - if (scaleLabel.display) { - // Draw the scale label - context.textAlign = "center"; - context.textBaseline = 'middle'; - context.fillStyle = scaleLabelFontColor; // render in correct colour - context.font = scaleLabelFont; - - scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width - scaleLabelY = this.options.position === 'bottom' ? this.bottom - (scaleLabelFontSize / 2) : this.top + (scaleLabelFontSize / 2); - - context.fillText(scaleLabel.labelString, scaleLabelX, scaleLabelY); - } - - } else { - setContextLineSettings = true; - var xTickStart = this.options.position === "right" ? this.left : this.right - 5; - var xTickEnd = this.options.position === "right" ? this.left + 5 : this.right; - - helpers.each(this.ticks, function(label, index) { - // If the callback returned a null or undefined value, do not draw this line - if (label === undefined || label === null) { - return; - } - - var yLineValue = this.getPixelForTick(index); // xvalues for grid lines - - if (gridLines.display) { - if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { - // Draw the first index specially - context.lineWidth = gridLines.zeroLineWidth; - context.strokeStyle = gridLines.zeroLineColor; - setContextLineSettings = true; // reset next time - } else if (setContextLineSettings) { - context.lineWidth = gridLines.lineWidth; - context.strokeStyle = gridLines.color; - setContextLineSettings = false; - } - - yLineValue += helpers.aliasPixel(context.lineWidth); - - // Draw the label area - context.beginPath(); - - if (gridLines.drawTicks) { - context.moveTo(xTickStart, yLineValue); - context.lineTo(xTickEnd, yLineValue); - } - - // Draw the chart area - if (gridLines.drawOnChartArea) { - context.moveTo(chartArea.left, yLineValue); - context.lineTo(chartArea.right, yLineValue); - } - - // Need to stroke in the loop because we are potentially changing line widths & colours - context.stroke(); - } - - if (optionTicks.display) { - var xLabelValue; - var yLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) - - context.save(); - - if (this.options.position === "left") { - if (optionTicks.mirror) { - xLabelValue = this.right + optionTicks.padding; - context.textAlign = "left"; - } else { - xLabelValue = this.right - optionTicks.padding; - context.textAlign = "right"; - } - } else { - // right side - if (optionTicks.mirror) { - xLabelValue = this.left - optionTicks.padding; - context.textAlign = "right"; - } else { - xLabelValue = this.left + optionTicks.padding; - context.textAlign = "left"; - } - } - - context.translate(xLabelValue, yLabelValue + optionTicks.labelOffset); - context.rotate(labelRotationRadians * -1); - context.font = tickLabelFont; - context.textBaseline = "middle"; - context.fillText(label, 0, 0); - context.restore(); - } - }, this); - - if (scaleLabel.display) { - // Draw the scale label - scaleLabelX = this.options.position === 'left' ? this.left + (scaleLabelFontSize / 2) : this.right - (scaleLabelFontSize / 2); - scaleLabelY = this.top + ((this.bottom - this.top) / 2); - var rotation = this.options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI; - + if (optionTicks.display) { context.save(); - context.translate(scaleLabelX, scaleLabelY); - context.rotate(rotation); - context.textAlign = "center"; - context.fillStyle =scaleLabelFontColor; // render in correct colour - context.font = scaleLabelFont; - context.textBaseline = 'middle'; - context.fillText(scaleLabel.labelString, 0, 0); + context.translate(xLabelValue + optionTicks.labelOffset, (isRotated) ? this.top + 12 : options.position === "top" ? this.bottom - tl : this.top + tl); + context.rotate(labelRotationRadians * -1); + context.font = tickLabelFont; + context.textAlign = (isRotated) ? "right" : "center"; + context.textBaseline = (isRotated) ? "middle" : options.position === "top" ? "bottom" : "top"; + context.fillText(label, 0, 0); context.restore(); } + }, this); + + if (scaleLabel.display) { + // Draw the scale label + context.textAlign = "center"; + context.textBaseline = 'middle'; + context.fillStyle = scaleLabelFontColor; // render in correct colour + context.font = scaleLabelFont; + + scaleLabelX = this.left + ((this.right - this.left) / 2); // midpoint of the width + scaleLabelY = options.position === 'bottom' ? this.bottom - (scaleLabelFontSize / 2) : this.top + (scaleLabelFontSize / 2); + + context.fillText(scaleLabel.labelString, scaleLabelX, scaleLabelY); } - // Draw the line at the edge of the axis - context.lineWidth = gridLines.lineWidth; - context.strokeStyle = gridLines.color; - var x1 = this.left, - x2 = this.right, - y1 = this.top, - y2 = this.bottom; + } else { + setContextLineSettings = true; + var xTickStart = options.position === "right" ? this.left : this.right - 5; + var xTickEnd = options.position === "right" ? this.left + 5 : this.right; - var aliasPixel = helpers.aliasPixel(context.lineWidth); - if (this.isHorizontal()) { - y1 = y2 = this.options.position === 'top' ? this.bottom : this.top; - y1 += aliasPixel; - y2 += aliasPixel; - } else { - x1 = x2 = this.options.position === 'left' ? this.right : this.left; - x1 += aliasPixel; - x2 += aliasPixel; + helpers.each(this.ticks, function (label, index) { + // If the callback returned a null or undefined value, do not draw this line + if (label === undefined || label === null) { + return; + } + + var yLineValue = this.getPixelForTick(index); // xvalues for grid lines + + if (gridLines.display) { + if (index === (typeof this.zeroLineIndex !== 'undefined' ? this.zeroLineIndex : 0)) { + // Draw the first index specially + context.lineWidth = gridLines.zeroLineWidth; + context.strokeStyle = gridLines.zeroLineColor; + setContextLineSettings = true; // reset next time + } else if (setContextLineSettings) { + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; + setContextLineSettings = false; + } + + yLineValue += helpers.aliasPixel(context.lineWidth); + + // Draw the label area + context.beginPath(); + + if (gridLines.drawTicks) { + context.moveTo(xTickStart, yLineValue); + context.lineTo(xTickEnd, yLineValue); + } + + // Draw the chart area + if (gridLines.drawOnChartArea) { + context.moveTo(chartArea.left, yLineValue); + context.lineTo(chartArea.right, yLineValue); + } + + // Need to stroke in the loop because we are potentially changing line widths & colours + context.stroke(); + } + + if (optionTicks.display) { + var xLabelValue; + var yLabelValue = this.getPixelForTick(index, gridLines.offsetGridLines); // x values for optionTicks (need to consider offsetLabel option) + + context.save(); + + if (options.position === "left") { + if (optionTicks.mirror) { + xLabelValue = this.right + optionTicks.padding; + context.textAlign = "left"; + } else { + xLabelValue = this.right - optionTicks.padding; + context.textAlign = "right"; + } + } else { + // right side + if (optionTicks.mirror) { + xLabelValue = this.left - optionTicks.padding; + context.textAlign = "right"; + } else { + xLabelValue = this.left + optionTicks.padding; + context.textAlign = "left"; + } + } + + context.translate(xLabelValue, yLabelValue + optionTicks.labelOffset); + context.rotate(labelRotationRadians * -1); + context.font = tickLabelFont; + context.textBaseline = "middle"; + context.fillText(label, 0, 0); + context.restore(); + } + }, this); + + if (scaleLabel.display) { + // Draw the scale label + scaleLabelX = options.position === 'left' ? this.left + (scaleLabelFontSize / 2) : this.right - (scaleLabelFontSize / 2); + scaleLabelY = this.top + ((this.bottom - this.top) / 2); + var rotation = options.position === 'left' ? -0.5 * Math.PI : 0.5 * Math.PI; + + context.save(); + context.translate(scaleLabelX, scaleLabelY); + context.rotate(rotation); + context.textAlign = "center"; + context.fillStyle = scaleLabelFontColor; // render in correct colour + context.font = scaleLabelFont; + context.textBaseline = 'middle'; + context.fillText(scaleLabel.labelString, 0, 0); + context.restore(); } - - context.beginPath(); - context.moveTo(x1, y1); - context.lineTo(x2, y2); - context.stroke(); } + + // Draw the line at the edge of the axis + context.lineWidth = gridLines.lineWidth; + context.strokeStyle = gridLines.color; + var x1 = this.left, + x2 = this.right, + y1 = this.top, + y2 = this.bottom; + + var aliasPixel = helpers.aliasPixel(context.lineWidth); + if (this.isHorizontal()) { + y1 = y2 = options.position === 'top' ? this.bottom : this.top; + y1 += aliasPixel; + y2 += aliasPixel; + } else { + x1 = x2 = options.position === 'left' ? this.right : this.left; + x1 += aliasPixel; + x2 += aliasPixel; + } + + context.beginPath(); + context.moveTo(x1, y1); + context.lineTo(x2, y2); + context.stroke(); } }); };