From 64f1c4dfd7425931fcd1bd9949157c0ba6958656 Mon Sep 17 00:00:00 2001 From: Jeff VanDyke Date: Wed, 20 Sep 2017 18:17:03 -0400 Subject: [PATCH] Added pixelRatio option to override canvas upscaling. Resolves #876, test included. (#877) * Added pixelRatio option, using where appropriate. Falls back to old behavior if not specified. Added to options reference, Added to Dygraph.prototype.resizeElements_, Added to rangeSelector.prototype.updateVisibility. * Fixed bug in range-selector pixelRatio implementation, tests pass * added test for the pixelRatio option, properly run. First fails without change, then passes after change. * Added pull request suggestions Fix typo in docs, documented a float type, Simplified method of reading option. * Added note about pixelRatio affecting resolution --- auto_tests/tests/hidpi.js | 31 +++++++++++++++++++++++++++++++ src/dygraph-options-reference.js | 6 ++++++ src/dygraph.js | 6 ++++-- src/plugins/range-selector.js | 9 +++++---- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/auto_tests/tests/hidpi.js b/auto_tests/tests/hidpi.js index 1dd131c..ceb3a49 100644 --- a/auto_tests/tests/hidpi.js +++ b/auto_tests/tests/hidpi.js @@ -45,5 +45,36 @@ it('testDoesntCreateScrollbars', function() { assert.equal(sw, document.body.scrollWidth); }); +it('should be influenced by options.pixelRatio', function () { + var graph = document.getElementById("graph"); + + // make sure devicePixelRatio is still setup to not 1. + assert(devicePixelRatio > 1.5, 'devicePixelRatio is not much greater than 1.'); + + var data = "X,Y\n" + + "0,-1\n" + + "1,0\n" + + "2,1\n" + + "3,0\n"; + + // first try a default one + var g1 = new Dygraph(graph, data, {}); + var area1 = g1.getArea(); + + var g2 = new Dygraph(graph, data, { pixelRatio: 1 }); + var area2 = g2.getArea(); + + var g3 = new Dygraph(graph, data, { pixelRatio: 3 }); + var area3 = g3.getArea(); + + assert.deepEqual(area1, area2, 'areas 1 and 2 are not the same'); + assert.deepEqual(area2, area3, 'areas 2 and 3 are not the same'); + + assert.notEqual(g1.canvas_.width, g2.canvas_.width, + 'Expected, for devicePixelRatio != 1, ' + + 'that setting options.pixelRatio would change the canvas width'); + assert.equal(g2.canvas_.width * 3, g3.canvas_.width, + 'Expected that pixelRatio of 3 vs 1 would triple the canvas width.'); +}); }); diff --git a/src/dygraph-options-reference.js b/src/dygraph-options-reference.js index 3bf2a56..9cffd5e 100644 --- a/src/dygraph-options-reference.js +++ b/src/dygraph-options-reference.js @@ -299,6 +299,12 @@ OPTIONS_REFERENCE = // "type": "integer", "description": "Width, in pixels, of the chart. If the container div has been explicitly sized, this will be ignored." }, + "pixelRatio": { + "default": "(devicePixelRatio / context.backingStoreRatio)", + "labels": ["Overall display"], + "type": "float", + "description": "Overrides the pixel ratio scaling factor for the canvas's 2d context. Ordinarily, this is set to the devicePixelRatio / (context.backingStoreRatio || 1), so on mobile devices, where the devicePixelRatio can be somewhere around 3, performance can be improved by overriding this value to something less precise, like 1, at the expense of resolution." + }, "interactionModel": { "default": "...", "labels": ["Interactive Elements"], diff --git a/src/dygraph.js b/src/dygraph.js index ba44739..531191f 100644 --- a/src/dygraph.js +++ b/src/dygraph.js @@ -861,7 +861,9 @@ Dygraph.prototype.resizeElements_ = function() { this.graphDiv.style.width = this.width_ + "px"; this.graphDiv.style.height = this.height_ + "px"; - var canvasScale = utils.getContextPixelRatio(this.canvas_ctx_); + var pixelRatioOption = this.getNumericOption('pixelRatio') + + var canvasScale = pixelRatioOption || utils.getContextPixelRatio(this.canvas_ctx_); this.canvas_.width = this.width_ * canvasScale; this.canvas_.height = this.height_ * canvasScale; this.canvas_.style.width = this.width_ + "px"; // for IE @@ -870,7 +872,7 @@ Dygraph.prototype.resizeElements_ = function() { this.canvas_ctx_.scale(canvasScale, canvasScale); } - var hiddenScale = utils.getContextPixelRatio(this.hidden_ctx_); + var hiddenScale = pixelRatioOption || utils.getContextPixelRatio(this.hidden_ctx_); this.hidden_.width = this.width_ * hiddenScale; this.hidden_.height = this.height_ * hiddenScale; this.hidden_.style.width = this.width_ + "px"; // for IE diff --git a/src/plugins/range-selector.js b/src/plugins/range-selector.js index 7f91dc8..c1f70f9 100644 --- a/src/plugins/range-selector.js +++ b/src/plugins/range-selector.js @@ -161,8 +161,8 @@ rangeSelector.prototype.updateVisibility_ = function() { * Resizes the range selector. */ rangeSelector.prototype.resize_ = function() { - function setElementRect(canvas, context, rect) { - var canvasScale = utils.getContextPixelRatio(context); + function setElementRect(canvas, context, rect, pixelRatioOption) { + var canvasScale = pixelRatioOption || utils.getContextPixelRatio(context); canvas.style.top = rect.y + 'px'; canvas.style.left = rect.x + 'px'; @@ -189,8 +189,9 @@ rangeSelector.prototype.resize_ = function() { h: this.getOption_('rangeSelectorHeight') }; - setElementRect(this.bgcanvas_, this.bgcanvas_ctx_, this.canvasRect_); - setElementRect(this.fgcanvas_, this.fgcanvas_ctx_, this.canvasRect_); + var pixelRatioOption = this.dygraph_.getNumericOption('pixelRatio'); + setElementRect(this.bgcanvas_, this.bgcanvas_ctx_, this.canvasRect_, pixelRatioOption); + setElementRect(this.fgcanvas_, this.fgcanvas_ctx_, this.canvasRect_, pixelRatioOption); }; /** -- 2.7.4