Don't increase canvas css size during a retina scale. Reset the canvas style exactly as it was set before during destroy. Ensure coordinates are translated over correctly into model coordinates. Fixed a bug during destroy when unscaling the canvas

This commit is contained in:
Evert Timberg
2015-09-22 19:22:55 -04:00
parent cd0b95d383
commit 4a093196b8
3 changed files with 22 additions and 7 deletions

View File

@@ -258,7 +258,7 @@
// @return : An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw
getElementAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e);
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
@@ -274,7 +274,7 @@
},
getElementsAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e);
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
@@ -289,7 +289,7 @@
},
getDatasetAtEvent: function(e) {
var eventPosition = helpers.getRelativePosition(e);
var eventPosition = helpers.getRelativePosition(e, this.chart);
var elementsArray = [];
for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; datasetIndex++) {
@@ -321,9 +321,13 @@
// 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);
this.chart.ctx.scale(1 / this.chart.originalDevicePixelRatio, 1 / this.chart.originalDevicePixelRatio);
}
// Reset to the old style since it may have been changed by the device pixel ratio changes
canvas.style.width = this.chart.originalCanvasStyleWidth;
canvas.style.height = this.chart.originalCanvasStyleHeight;
delete Chart.instances[this.id];
},

View File

@@ -635,7 +635,7 @@
};
})(),
//-- DOM methods
getRelativePosition = helpers.getRelativePosition = function(evt) {
getRelativePosition = helpers.getRelativePosition = function(evt, chart) {
var mouseX, mouseY;
var e = evt.originalEvent || evt,
canvas = evt.currentTarget || evt.srcElement,
@@ -653,8 +653,11 @@
// Scale mouse coordinates into canvas coordinates
// by following the pattern laid out by 'jerryj' in the comments of
// http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
mouseX = Math.round((mouseX - boundingRect.left) / (boundingRect.right - boundingRect.left) * canvas.width);
mouseY = Math.round((mouseY - boundingRect.top) / (boundingRect.bottom - boundingRect.top) * canvas.height);
// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However
// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here
mouseX = Math.round((mouseX - boundingRect.left) / (boundingRect.right - boundingRect.left) * canvas.width / chart.currentDevicePixelRatio);
mouseY = Math.round((mouseY - boundingRect.top) / (boundingRect.bottom - boundingRect.top) * canvas.height / chart.currentDevicePixelRatio);
return {
x: mouseX,
@@ -755,12 +758,16 @@
var ctx = chart.ctx;
var width = chart.canvas.width;
var height = chart.canvas.height;
chart.currentDevicePixelRatio = window.devicePixelRatio || 1;
if (window.devicePixelRatio !== 1) {
ctx.canvas.height = height * window.devicePixelRatio;
ctx.canvas.width = width * window.devicePixelRatio;
ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
ctx.canvas.style.width = width + 'px';
ctx.canvas.style.height = height + 'px';
// 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

View File

@@ -50,6 +50,10 @@
this.aspectRatio = config.aspectRatio !== undefined ? config.aspectRatio : 2;
}
// Store the original style of the element so we can set it back
this.originalCanvasStyleWidth = context.canvas.style.width;
this.originalCanvasStyleHeight = context.canvas.style.height;
// High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
Chart.helpers.retinaScale(this);