From 2f38a3894a271167fda0a59a80384853ca5fe0ed Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 4 Sep 2015 22:55:41 -0400 Subject: [PATCH 1/9] Get resize listener helper --- gulpfile.js | 3 ++- package.json | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index 42fd09b09..d55101d52 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -33,7 +33,8 @@ var srcFiles = [ './src/scales/**', './src/elements/**', './src/charts/**', - './node_modules/color/dist/color.min.js' + './node_modules/color/dist/color.min.js', + './node_modules/javascript-detect-element-resize/detect-element-resize.js' ]; diff --git a/package.json b/package.json index 0e7b31939..8295f2bde 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "inquirer": "^0.5.1", "jasmine": "^2.3.2", "jasmine-core": "^2.3.4", + "javascript-detect-element-resize": "git://github.com/chartjs/javascript-detect-element-resize.git", "jquery": "^2.1.4", "karma": "^0.12.37", "karma-chrome-launcher": "^0.2.0", From 6b6c388a1a2f97122f481625fd827d6ff5699489 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 4 Sep 2015 22:55:57 -0400 Subject: [PATCH 2/9] Helper for resize listener --- src/core/core.helpers.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 46ad752d8..1a299079c 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -758,6 +758,15 @@ } return window.Color(color); }, + addResizeListener = helpers.addResizeListener = function(node, callback) { + if (window.addResizeListener) { + if (node) { + window.addResizeListener(node, callback); + } + } else { + console.log('Add resize listener not found') + } + }, isArray = helpers.isArray = function(obj) { if (!Array.isArray) { return Object.prototype.toString.call(arg) === '[object Array]'; From 3f75aabbc5dfbffe72bec8aaba26ddee5f1d387b Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Sat, 5 Sep 2015 13:27:06 -0400 Subject: [PATCH 3/9] Better scale fitting algorithm to handle when label rotation changes due to the application of margins on the scale --- src/core/core.scale.js | 48 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/core/core.scale.js b/src/core/core.scale.js index c738f1f58..1159a9050 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -219,6 +219,54 @@ } }); + // Recalculate because the size of each scale might have changed slightly due to the margins (label rotation for instance) + totalLeftWidth = xPadding; + totalRightWidth = xPadding; + totalTopHeight = yPadding; + totalBottomHeight = yPadding; + + helpers.each(leftScales, function(scaleInstance) { + totalLeftWidth += scaleInstance.width; + }); + + helpers.each(rightScales, function(scaleInstance) { + totalRightWidth += scaleInstance.width; + }); + + helpers.each(topScales, function(scaleInstance) { + totalTopHeight += scaleInstance.height; + }); + helpers.each(bottomScales, function(scaleInstance) { + totalBottomHeight += scaleInstance.height; + }); + + // Figure out if our chart area changed. This would occur if the dataset scale label rotation + // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do + // without calling `fit` again + var newMaxChartHeight = height - totalTopHeight - totalBottomHeight; + var newMaxChartWidth = width - totalLeftWidth - totalRightWidth; + + if (newMaxChartWidth !== maxChartWidth || newMaxChartHeight !== maxChartHeight) { + helpers.each(leftScales, function(scale) { + scale.height = newMaxChartHeight; + }); + + helpers.each(rightScales, function(scale) { + scale.height = newMaxChartHeight; + }); + + helpers.each(topScales, function(scale) { + scale.width = newMaxChartWidth; + }); + + helpers.each(bottomScales, function(scale) { + scale.width = newMaxChartWidth; + }); + + maxChartHeight = newMaxChartHeight; + maxChartWidth = newMaxChartWidth; + } + // Step 7 // Position the scales var left = xPadding; From a36a3f8c09b5424dbf4e140d08a5ceb24d7a5ecb Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Wed, 9 Sep 2015 20:28:34 -0400 Subject: [PATCH 4/9] Commit built version of scale algo changes --- Chart.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Chart.js b/Chart.js index 35a27e8db..9e0cef320 100644 --- a/Chart.js +++ b/Chart.js @@ -1841,6 +1841,54 @@ } }); + // Recalculate because the size of each scale might have changed slightly due to the margins (label rotation for instance) + totalLeftWidth = xPadding; + totalRightWidth = xPadding; + totalTopHeight = yPadding; + totalBottomHeight = yPadding; + + helpers.each(leftScales, function(scaleInstance) { + totalLeftWidth += scaleInstance.width; + }); + + helpers.each(rightScales, function(scaleInstance) { + totalRightWidth += scaleInstance.width; + }); + + helpers.each(topScales, function(scaleInstance) { + totalTopHeight += scaleInstance.height; + }); + helpers.each(bottomScales, function(scaleInstance) { + totalBottomHeight += scaleInstance.height; + }); + + // Figure out if our chart area changed. This would occur if the dataset scale label rotation + // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do + // without calling `fit` again + var newMaxChartHeight = height - totalTopHeight - totalBottomHeight; + var newMaxChartWidth = width - totalLeftWidth - totalRightWidth; + + if (newMaxChartWidth !== maxChartWidth || newMaxChartHeight !== maxChartHeight) { + helpers.each(leftScales, function(scale) { + scale.height = newMaxChartHeight; + }); + + helpers.each(rightScales, function(scale) { + scale.height = newMaxChartHeight; + }); + + helpers.each(topScales, function(scale) { + scale.width = newMaxChartWidth; + }); + + helpers.each(bottomScales, function(scale) { + scale.width = newMaxChartWidth; + }); + + maxChartHeight = newMaxChartHeight; + maxChartWidth = newMaxChartWidth; + } + // Step 7 // Position the scales var left = xPadding; From e6220f474b8f6755592ea72860cb953db6197fa5 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Mon, 14 Sep 2015 18:50:52 -0400 Subject: [PATCH 5/9] Attempting to make resize better --- samples/bar.html | 21 +++++++++-- src/charts/Chart.Doughnut.js | 1 + src/charts/Chart.PolarArea.js | 1 + src/charts/Chart.Radar.js | 5 +++ src/core/core.controller.js | 22 ++++++------ src/core/core.helpers.js | 68 +++++++++++++++++++++++++++-------- src/core/core.js | 45 ++++++++++++----------- src/core/core.responsive.js | 4 +-- 8 files changed, 116 insertions(+), 51 deletions(-) diff --git a/samples/bar.html b/samples/bar.html index eb8796ac5..7f1d8e7ea 100644 --- a/samples/bar.html +++ b/samples/bar.html @@ -5,10 +5,15 @@ Bar Chart + -
+ @@ -16,6 +21,7 @@ +

Legend

@@ -64,6 +70,13 @@ data: barChartData, options: { responsive: true, + scales: { + xAxes: [{ + // So that bars fill the entire width of the grid + categorySpacing: 0, + spacing: 0 + }] + } } }); @@ -100,7 +113,7 @@ $('#addData').click(function() { if (barChartData.datasets.length > 0) { - barChartData.labels.push('dataset #' + barChartData.labels.length); + barChartData.labels.push('data #' + barChartData.labels.length); for (var index = 0; index < barChartData.datasets.length; ++index) { window.myBar.addData(randomScalingFactor(), index); @@ -123,6 +136,10 @@ }); updateLegend(); }); + + $('#show').click(function() { + document.getElementById('container').style.display = ''; + }); diff --git a/src/charts/Chart.Doughnut.js b/src/charts/Chart.Doughnut.js index ccea714f3..333a0bbeb 100644 --- a/src/charts/Chart.Doughnut.js +++ b/src/charts/Chart.Doughnut.js @@ -6,6 +6,7 @@ var helpers = Chart.helpers; var defaultConfig = { + aspectRatio: 1, legendTemplate: "
    -legend\"><% for (var i = 0; i < data.datasets[0].data.length; i++){%>
  • \"><%if(data.labels && i < data.labels.length){%><%=data.labels[i]%><%}%>
  • <%}%>
", }; diff --git a/src/charts/Chart.PolarArea.js b/src/charts/Chart.PolarArea.js index 7070a0d8f..9dbdf1b39 100644 --- a/src/charts/Chart.PolarArea.js +++ b/src/charts/Chart.PolarArea.js @@ -6,6 +6,7 @@ var helpers = Chart.helpers; var defaultConfig = { + aspectRatio: 1, legendTemplate: "
    -legend\"><% for (var i = 0; i < data.datasets[0].data.length; i++){%>
  • \"><%if(data.labels && i < data.labels.length){%><%=data.labels[i]%><%}%>
  • <%}%>
", }; diff --git a/src/charts/Chart.Radar.js b/src/charts/Chart.Radar.js index f5580783d..2f1f82606 100644 --- a/src/charts/Chart.Radar.js +++ b/src/charts/Chart.Radar.js @@ -5,7 +5,12 @@ var Chart = root.Chart; var helpers = Chart.helpers; + var defaultConfig = { + aspectRatio: 1, + }; + Chart.Radar = function(context, config) { + config.options = helpers.configMerge(defaultConfig, config.options); config.type = 'radar'; return new Chart(context, config); diff --git a/src/core/core.controller.js b/src/core/core.controller.js index 5b611e8ea..b621d6f1e 100644 --- a/src/core/core.controller.js +++ b/src/core/core.controller.js @@ -123,9 +123,11 @@ resize: function resize(silent) { this.stop(); - var canvas = this.chart.canvas, - newWidth = helpers.getMaximumWidth(this.chart.canvas), - newHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : helpers.getMaximumHeight(this.chart.canvas); + var canvas = this.chart.canvas; + var newWidth = helpers.getMaximumWidth(this.chart.canvas); + var newHeight = (this.options.maintainAspectRatio && isNaN(this.chart.aspectRatio) === false && isFinite(this.chart.aspectRatio) && this.chart.aspectRatio !== 0) + ? newWidth / this.chart.aspectRatio + : helpers.getMaximumHeight(this.chart.canvas); canvas.width = this.chart.width = newWidth; canvas.height = this.chart.height = newHeight; @@ -346,19 +348,15 @@ destroy: function destroy() { this.clear(); helpers.unbindEvents(this, this.events); - var canvas = this.chart.canvas; - // Reset canvas height/width attributes starts a fresh with the canvas context + // Reset canvas height/width attributes + var canvas = this.chart.canvas; canvas.width = this.chart.width; canvas.height = this.chart.height; - // < IE9 doesn't support removeProperty - if (canvas.style.removeProperty) { - canvas.style.removeProperty('width'); - canvas.style.removeProperty('height'); - } else { - canvas.style.removeAttribute('width'); - canvas.style.removeAttribute('height'); + // if we scaled the canvas in response to a devicePixelRatio !== 1, we need to undo that transform here + if (this.chart.originalDevicePixelRatio !== undefined) { + canvas.scale(1 / this.chart.originalDevicePixelRatio, 1 / this.chart.originalDevicePixelRatio); } delete Chart.instances[this.id]; diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 1a299079c..b967b30b6 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -691,17 +691,54 @@ removeEvent(chartInstance.chart.canvas, eventName, handler); }); }, + getConstraintWidth = helpers.getConstraintWidth = function(domNode) { // returns Number or undefined if no constraint + var constrainedWidth; + var constrainedWNode = document.defaultView.getComputedStyle(domNode)['max-width']; + var constrainedWContainer = document.defaultView.getComputedStyle(domNode.parentNode)['max-width']; + var hasCWNode = constrainedWNode !== null && constrainedWNode !== "none"; + var hasCWContainer = constrainedWContainer !== null && constrainedWContainer !== "none"; + + if (hasCWNode || hasCWContainer) { + constrainedWidth = Math.min((hasCWNode ? parseInt(constrainedWNode, 10) : Number.POSITIVE_INFINITY), (hasCWContainer ? parseInt(constrainedWContainer, 10) : Number.POSITIVE_INFINITY)); + } + return constrainedWidth; + }, + getConstraintHeight = helpers.getConstraintHeight = function(domNode) { // returns Number or undefined if no constraint + + var constrainedHeight; + var constrainedHNode = document.defaultView.getComputedStyle(domNode)['max-height']; + var constrainedHContainer = document.defaultView.getComputedStyle(domNode.parentNode)['max-height']; + var hasCHNode = constrainedHNode !== null && constrainedHNode !== "none"; + var hasCHContainer = constrainedHContainer !== null && constrainedHContainer !== "none"; + + if (constrainedHNode || constrainedHContainer) { + constrainedHeight = Math.min((hasCHNode ? parseInt(constrainedHNode, 10) : Number.POSITIVE_INFINITY), (hasCHContainer ? parseInt(constrainedHContainer, 10) : Number.POSITIVE_INFINITY)); + } + return constrainedHeight; + }, getMaximumWidth = helpers.getMaximumWidth = function(domNode) { - var container = domNode.parentNode, - padding = parseInt(getStyle(container, 'padding-left')) + parseInt(getStyle(container, 'padding-right')); - // TODO = check cross browser stuff with this. - return container.clientWidth - padding; + var container = domNode.parentNode; + var padding = parseInt(getStyle(container, 'padding-left')) + parseInt(getStyle(container, 'padding-right')); + + var w = container.clientWidth - padding; + var cw = getConstraintWidth(domNode); + if (cw !== undefined) { + w = Math.min(w, cw); + } + + return w; }, getMaximumHeight = helpers.getMaximumHeight = function(domNode) { - var container = domNode.parentNode, - padding = parseInt(getStyle(container, 'padding-bottom')) + parseInt(getStyle(container, 'padding-top')); - // TODO = check cross browser stuff with this. - return container.clientHeight - padding; + var container = domNode.parentNode; + var padding = parseInt(getStyle(container, 'padding-top')) + parseInt(getStyle(container, 'padding-bottom')); + + var h = container.clientHeight - padding; + var ch = getConstraintHeight(domNode); + if (ch !== undefined) { + h = Math.min(h, ch); + } + + return h; }, getStyle = helpers.getStyle = function(el, property) { return el.currentStyle ? @@ -710,16 +747,19 @@ }, getMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support retinaScale = helpers.retinaScale = function(chart) { - var ctx = chart.ctx, - width = chart.canvas.width, - height = chart.canvas.height; + var ctx = chart.ctx; + var width = chart.canvas.width; + var height = chart.canvas.height; - if (window.devicePixelRatio) { - ctx.canvas.style.width = width + "px"; - ctx.canvas.style.height = height + "px"; + if (window.devicePixelRatio !== 1) { ctx.canvas.height = height * window.devicePixelRatio; ctx.canvas.width = width * window.devicePixelRatio; ctx.scale(window.devicePixelRatio, window.devicePixelRatio); + + // Store the device pixel ratio so that we can go backwards in `destroy`. + // The devicePixelRatio changes with zoom, so there are no guarantees that it is the same + // when destroy is called + chart.originalDevicePixelRatio = window.devicePixelRatio; } }, //-- Canvas methods diff --git a/src/core/core.js b/src/core/core.js index 42c214e14..512b4f42e 100755 --- a/src/core/core.js +++ b/src/core/core.js @@ -19,7 +19,6 @@ //Occupy the global variable of Chart, and create a simple base class var Chart = function(context, config) { - var chart = this; this.config = config; // Support a jQuery'd canvas element @@ -32,32 +31,36 @@ context = context.getContext("2d"); } + this.ctx = context; this.canvas = context.canvas; - this.ctx = context; + // Figure out what the size of the chart will be. + // If the canvas has a specified width and height, we use those else + // we look to see if the canvas node has a CSS width and height. + // If there is still no height, fill the parent container + this.width = context.canvas.width || parseInt(Chart.helpers.getStyle(context.canvas, 'width')) || Chart.helpers.getMaximumWidth(context.canvas); + this.height = context.canvas.height || parseInt(Chart.helpers.getStyle(context.canvas, 'height')) || Chart.helpers.getMaximumHeight(context.canvas); - //Variables global to the chart - var computeDimension = function(element, dimension) { - if (element['offset' + dimension]) { - return element['offset' + dimension]; - } else { - return document.defaultView.getComputedStyle(element).getPropertyValue(dimension); - } - }; - - var width = this.width = computeDimension(context.canvas, 'Width') || context.canvas.width; - var height = this.height = computeDimension(context.canvas, 'Height') || context.canvas.height; - - // Firefox requires this to work correctly - context.canvas.width = width; - context.canvas.height = height; - - width = this.width = context.canvas.width; - height = this.height = context.canvas.height; this.aspectRatio = this.width / this.height; - //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. + + if (isNaN(this.aspectRatio) || isFinite(this.aspectRatio) === false) { + // If the canvas has no size, try and figure out what the aspect ratio will be. + // Some charts prefer square canvases (pie, radar, etc). If that is specified, use that + // else use the canvas default ratio of 2 + this.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2; + } + + // High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale. Chart.helpers.retinaScale(this); + // Always bind this so that if the responsive state changes we still work + var _this = this; + Chart.helpers.addResizeListener(context.canvas.parentNode, function() { + if (config.options.responsive) { + _this.controller.resize(); + } + }); + if (config) { this.controller = new Chart.Controller(this); return this.controller; diff --git a/src/core/core.responsive.js b/src/core/core.responsive.js index 7a2eb78c7..2bca2a214 100644 --- a/src/core/core.responsive.js +++ b/src/core/core.responsive.js @@ -9,7 +9,7 @@ // Attach global event to resize each chart instance when the browser resizes - helpers.addEvent(window, "resize", (function() { + /*helpers.addEvent(window, "resize", (function() { // Basic debounce of resize function so it doesn't hurt performance when resizing browser. var timeout; return function() { @@ -24,6 +24,6 @@ }); }, 16); }; - })()); + })());*/ }).call(this); From 52c1c09e16f489dcea774ac14729e4af513e8836 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 18 Sep 2015 18:41:45 -0400 Subject: [PATCH 6/9] Revert "Commit built version of scale algo changes" This reverts commit a36a3f8c09b5424dbf4e140d08a5ceb24d7a5ecb. --- Chart.js | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/Chart.js b/Chart.js index 9e0cef320..35a27e8db 100644 --- a/Chart.js +++ b/Chart.js @@ -1841,54 +1841,6 @@ } }); - // Recalculate because the size of each scale might have changed slightly due to the margins (label rotation for instance) - totalLeftWidth = xPadding; - totalRightWidth = xPadding; - totalTopHeight = yPadding; - totalBottomHeight = yPadding; - - helpers.each(leftScales, function(scaleInstance) { - totalLeftWidth += scaleInstance.width; - }); - - helpers.each(rightScales, function(scaleInstance) { - totalRightWidth += scaleInstance.width; - }); - - helpers.each(topScales, function(scaleInstance) { - totalTopHeight += scaleInstance.height; - }); - helpers.each(bottomScales, function(scaleInstance) { - totalBottomHeight += scaleInstance.height; - }); - - // Figure out if our chart area changed. This would occur if the dataset scale label rotation - // changed due to the application of the margins in step 6. Since we can only get bigger, this is safe to do - // without calling `fit` again - var newMaxChartHeight = height - totalTopHeight - totalBottomHeight; - var newMaxChartWidth = width - totalLeftWidth - totalRightWidth; - - if (newMaxChartWidth !== maxChartWidth || newMaxChartHeight !== maxChartHeight) { - helpers.each(leftScales, function(scale) { - scale.height = newMaxChartHeight; - }); - - helpers.each(rightScales, function(scale) { - scale.height = newMaxChartHeight; - }); - - helpers.each(topScales, function(scale) { - scale.width = newMaxChartWidth; - }); - - helpers.each(bottomScales, function(scale) { - scale.width = newMaxChartWidth; - }); - - maxChartHeight = newMaxChartHeight; - maxChartWidth = newMaxChartWidth; - } - // Step 7 // Position the scales var left = xPadding; From db5066cd23e13e3c34b9db310d4003d5164b17e9 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 18 Sep 2015 18:44:00 -0400 Subject: [PATCH 7/9] Remove core.responsive file. Responsiveness is added during initialization --- src/core/core.responsive.js | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 src/core/core.responsive.js diff --git a/src/core/core.responsive.js b/src/core/core.responsive.js deleted file mode 100644 index 2bca2a214..000000000 --- a/src/core/core.responsive.js +++ /dev/null @@ -1,29 +0,0 @@ -(function() { - - "use strict"; - - //Declare root variable - window in the browser, global on the server - var root = this, - previous = root.Chart, - helpers = Chart.helpers; - - - // Attach global event to resize each chart instance when the browser resizes - /*helpers.addEvent(window, "resize", (function() { - // Basic debounce of resize function so it doesn't hurt performance when resizing browser. - var timeout; - return function() { - clearTimeout(timeout); - timeout = setTimeout(function() { - helpers.each(Chart.instances, function(instance) { - // If the responsive flag is set in the chart instance config - // Cascade the resize event down to the chart. - if (instance.options.responsive) { - instance.resize(); - } - }); - }, 16); - }; - })());*/ - -}).call(this); From 8d476934486182e0f4bd4829997b6927409de8a9 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 18 Sep 2015 18:59:55 -0400 Subject: [PATCH 8/9] Make sure that doughnut and polar area inner & outer radius is >= 0 --- src/controllers/controller.doughnut.js | 4 ++-- src/controllers/controller.polarArea.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/controllers/controller.doughnut.js b/src/controllers/controller.doughnut.js index 2513a0689..d4586b4fc 100644 --- a/src/controllers/controller.doughnut.js +++ b/src/controllers/controller.doughnut.js @@ -86,8 +86,8 @@ update: function(reset) { - this.chart.outerRadius = (helpers.min([this.chart.chart.width, this.chart.chart.height]) / 2) - this.chart.options.elements.arc.borderWidth / 2; - this.chart.innerRadius = this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1; + this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) / 2) - this.chart.options.elements.arc.borderWidth / 2, 0); + this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.data.datasets.length; this.getDataset().total = 0; diff --git a/src/controllers/controller.polarArea.js b/src/controllers/controller.polarArea.js index 4de24af6d..d832f09d1 100644 --- a/src/controllers/controller.polarArea.js +++ b/src/controllers/controller.polarArea.js @@ -87,8 +87,8 @@ this.chart.scale.generateTicks(); this.chart.scale.buildYLabels(); - this.chart.outerRadius = (helpers.min([this.chart.chart.width, this.chart.chart.height]) - this.chart.options.elements.arc.borderWidth / 2) / 2; - this.chart.innerRadius = this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1; + this.chart.outerRadius = Math.max((helpers.min([this.chart.chart.width, this.chart.chart.height]) - this.chart.options.elements.arc.borderWidth / 2) / 2, 0); + this.chart.innerRadius = Math.max(this.chart.options.cutoutPercentage ? (this.chart.outerRadius / 100) * (this.chart.options.cutoutPercentage) : 1, 0); this.chart.radiusLength = (this.chart.outerRadius - this.chart.innerRadius) / this.chart.data.datasets.length; this.getDataset().total = 0; From 97cec8604a9c3091acd0007d8244113c05398412 Mon Sep 17 00:00:00 2001 From: Evert Timberg Date: Fri, 18 Sep 2015 19:22:54 -0400 Subject: [PATCH 9/9] Only store the original device context ratio once --- src/core/core.helpers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 8d6790bf9..02ee89aef 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -758,7 +758,7 @@ // Store the device pixel ratio so that we can go backwards in `destroy`. // The devicePixelRatio changes with zoom, so there are no guarantees that it is the same // when destroy is called - chart.originalDevicePixelRatio = window.devicePixelRatio; + chart.originalDevicePixelRatio = chart.originalDevicePixelRatio || window.devicePixelRatio; } }, //-- Canvas methods