From 0cf2a7f0dbf3fffdeeef5de9c5167f57174ba3bc Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 27 Nov 2020 16:23:29 +0100 Subject: [PATCH 01/14] add mock for reversed image that uses source --- .../mocks/image_source_axis_reverse.json | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/image/mocks/image_source_axis_reverse.json diff --git a/test/image/mocks/image_source_axis_reverse.json b/test/image/mocks/image_source_axis_reverse.json new file mode 100644 index 00000000000..3b986de69f8 --- /dev/null +++ b/test/image/mocks/image_source_axis_reverse.json @@ -0,0 +1,20 @@ +{"data": [ + {"colormodel": "rgba", "type": "image", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, + {"colormodel": "rgba", "type": "image", "xaxis": "x2", "yaxis": "y2", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, + {"colormodel": "rgba", "type": "image", "xaxis": "x3", "yaxis": "y3", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, + {"colormodel": "rgba", "type": "image", "xaxis": "x4", "yaxis": "y4", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="} + ], + "layout": { + "grid": {"rows": 2, "columns": 2, "pattern": "independent"}, + "width": 600, "height": 600, + "margin": {"t": 35, "l": 35, "b": 35, "r": 35}, + "xaxis2": {"autorange": "reversed"}, + "yaxis3": {"autorange": true}, + "yaxis4": {"autorange": true}, + "xaxis4": {"autorange": "reversed"} + } +} From fb8d99508d458ce9974b2fc63345e4898579b372 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 27 Nov 2020 16:23:59 +0100 Subject: [PATCH 02/14] Reverse images as needed with css --- src/traces/image/plot.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index c5a85c3af8f..cba68a76d7a 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -15,12 +15,6 @@ var constants = require('./constants'); var unsupportedBrowsers = Lib.isIOS() || Lib.isSafari() || Lib.isIE(); -function compatibleAxis(ax) { - return ax.type === 'linear' && - // y axis must be reversed but x axis mustn't be - ((ax.range[1] > ax.range[0]) === (ax._id.charAt(0) === 'x')); -} - module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { var xa = plotinfo.xaxis; var ya = plotinfo.yaxis; @@ -31,7 +25,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { var plotGroup = d3.select(this); var cd0 = cd[0]; var trace = cd0.trace; - var fastImage = supportsPixelatedImage && !trace._hasZ && trace._hasSource && compatibleAxis(xa) && compatibleAxis(ya); + var fastImage = supportsPixelatedImage && !trace._hasZ && trace._hasSource && xa.type === 'linear' && ya.type === 'linear'; trace._fastImage = fastImage; var z = cd0.z; @@ -144,8 +138,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { // Pixelated image rendering // http://phrogz.net/tmp/canvas_image_zoom.html // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering - image3 - .attr('style', 'image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated;'); + var initialStyle = 'image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated;'; var p = new Promise(function(resolve) { if(trace._hasZ) { @@ -181,13 +174,21 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { } }) .then(function() { - var href, canvas; + var href, canvas, localStyle; + localStyle = initialStyle; if(trace._hasZ) { canvas = drawMagnifiedPixelsOnCanvas(function(i, j) {return z[j][i];}); href = canvas.toDataURL('image/png'); } else if(trace._hasSource) { if(fastImage) { href = trace.source; + // Flip the SVG image as needed + var axis_scale = [(xa.range[0] < xa.range[1]) ? 1 : -1, (ya.range[0] < ya.range[1]) ? -1 : 1]; + var trans = ''; + trans += 'translate(' + (left + imageWidth / 2) + 'px,' + (top + imageHeight / 2) + 'px)'; + trans += 'scale(' + axis_scale[0] + ',' + axis_scale[1] + ')'; + trans += 'translate(' + (-left - imageWidth / 2) + 'px,' + (-top - imageHeight / 2) + 'px)'; + localStyle += 'transform:' + trans + ';'; } else { var context = trace._canvas.el.getContext('2d'); var data = context.getImageData(0, 0, w, h).data; @@ -209,7 +210,8 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { height: imageHeight, width: imageWidth, x: left, - y: top + y: top, + style: localStyle }); }); From 189243f08dfeea15c98812154173a1120bd12485 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Fri, 27 Nov 2020 16:43:16 +0100 Subject: [PATCH 03/14] formatting --- src/traces/image/plot.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index cba68a76d7a..2a664468e9b 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -182,11 +182,11 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { } else if(trace._hasSource) { if(fastImage) { href = trace.source; - // Flip the SVG image as needed - var axis_scale = [(xa.range[0] < xa.range[1]) ? 1 : -1, (ya.range[0] < ya.range[1]) ? -1 : 1]; + // Flip the SVG image as needed (around the proper center location) + var axisScale = [(xa.range[0] < xa.range[1]) ? 1 : -1, (ya.range[0] < ya.range[1]) ? -1 : 1]; var trans = ''; trans += 'translate(' + (left + imageWidth / 2) + 'px,' + (top + imageHeight / 2) + 'px)'; - trans += 'scale(' + axis_scale[0] + ',' + axis_scale[1] + ')'; + trans += 'scale(' + axisScale[0] + ',' + axisScale[1] + ')'; trans += 'translate(' + (-left - imageWidth / 2) + 'px,' + (-top - imageHeight / 2) + 'px)'; localStyle += 'transform:' + trans + ';'; } else { From 24c7699e36f560cf5f59cbfc072534e66dbc5cd5 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 29 Nov 2020 23:06:39 +0100 Subject: [PATCH 04/14] remove jasmine tests that are no longer valid --- test/jasmine/tests/image_test.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index 879f3eb47d7..f243ef167bd 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -423,9 +423,7 @@ describe('image plot', function() { [ ['yaxis.type', 'log'], - ['xaxis.type', 'log'], - ['xaxis.range', [50, 0]], - ['yaxis.range', [0, 50]] + ['xaxis.type', 'log'] ].forEach(function(attr) { it('does not renders pixelated image when the axes are not compatible', function(done) { var mock = require('@mocks/image_astronaut_source.json'); From 0f0ca1f2e51fc84d9be11b64bb92d5467b062f46 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Sun, 29 Nov 2020 23:27:38 +0100 Subject: [PATCH 05/14] Add jasmine test to validate that hover tool shows correct color regardless of axis direction --- test/jasmine/tests/image_test.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index f243ef167bd..3fdc2a1a956 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -667,5 +667,30 @@ describe('image hover:', function() { .then(done); }); }); + + [ + ['auto', 'auto'], + ['auto', 'reversed'], + ['reversed', 'auto'], + ['reversed', 'reversed'] + ].forEach(function(test) { + it('should show correct hover info regardless of axis directions ' + test, function(done) { + var mockCopy = Lib.extendDeep({}, mock); + mockCopy.layout.xaxis.autorange = test[0]; + mockCopy.layout.yaxis.autorange = test[1]; + mockCopy.data[0].colormodel = 'rgba'; + mockCopy.data[0].hovertemplate = '%{color}'; + Plotly.newPlot(gd, mockCopy) + .then(function() {_hover(205, 125);}) + .then(function() { + assertHoverLabelContent({ + nums: '[202, 148, 125, 255]', + name: '' + }, 'variable `z` should be correct!'); + }) + .catch(failTest) + .then(done); + }); + }); }); }); From 24705321420bf748daaaa751f6d2c7577947990c Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 00:05:45 +0100 Subject: [PATCH 06/14] Use strTranslate for cleaner code --- src/traces/image/plot.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index 2a664468e9b..45064de721e 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -10,6 +10,7 @@ var d3 = require('d3'); var Lib = require('../../lib'); +var strTranslate = Lib.strTranslate; var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); var constants = require('./constants'); @@ -185,9 +186,9 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { // Flip the SVG image as needed (around the proper center location) var axisScale = [(xa.range[0] < xa.range[1]) ? 1 : -1, (ya.range[0] < ya.range[1]) ? -1 : 1]; var trans = ''; - trans += 'translate(' + (left + imageWidth / 2) + 'px,' + (top + imageHeight / 2) + 'px)'; + trans += strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px'); trans += 'scale(' + axisScale[0] + ',' + axisScale[1] + ')'; - trans += 'translate(' + (-left - imageWidth / 2) + 'px,' + (-top - imageHeight / 2) + 'px)'; + trans += strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px'); localStyle += 'transform:' + trans + ';'; } else { var context = trace._canvas.el.getContext('2d'); From 7895727a61f9282917a17a9ce15c5195e6e62b7e Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 10:23:52 +0100 Subject: [PATCH 07/14] Bit of suggested code refactoring --- src/traces/image/plot.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index 45064de721e..0af3f1778e7 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -184,12 +184,14 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { if(fastImage) { href = trace.source; // Flip the SVG image as needed (around the proper center location) - var axisScale = [(xa.range[0] < xa.range[1]) ? 1 : -1, (ya.range[0] < ya.range[1]) ? -1 : 1]; - var trans = ''; - trans += strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px'); - trans += 'scale(' + axisScale[0] + ',' + axisScale[1] + ')'; - trans += strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px'); - localStyle += 'transform:' + trans + ';'; + var axisScale = [ + (xa.range[0] < xa.range[1]) ? 1 : -1, + (ya.range[0] < ya.range[1]) ? -1 : 1 + ]; + localStyle += 'transform:' + + strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px') + + 'scale(' + axisScale[0] + ',' + axisScale[1] + ')' + + strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px') + ';'; } else { var context = trace._canvas.el.getContext('2d'); var data = context.getImageData(0, 0, w, h).data; From 4d98780f4b353667a699b35858adcf7b0f211e36 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 10:41:02 +0100 Subject: [PATCH 08/14] fix test --- test/jasmine/tests/image_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index 3fdc2a1a956..d922cee452b 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -679,7 +679,7 @@ describe('image hover:', function() { mockCopy.layout.xaxis.autorange = test[0]; mockCopy.layout.yaxis.autorange = test[1]; mockCopy.data[0].colormodel = 'rgba'; - mockCopy.data[0].hovertemplate = '%{color}'; + mockCopy.data[0].hovertemplate = '%{z}'; Plotly.newPlot(gd, mockCopy) .then(function() {_hover(205, 125);}) .then(function() { From a19b05b8253b371a17dbc5632f5b5db6bcbe34a5 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 11:03:33 +0100 Subject: [PATCH 09/14] remove mock --- .../mocks/image_source_axis_reverse.json | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 test/image/mocks/image_source_axis_reverse.json diff --git a/test/image/mocks/image_source_axis_reverse.json b/test/image/mocks/image_source_axis_reverse.json deleted file mode 100644 index 3b986de69f8..00000000000 --- a/test/image/mocks/image_source_axis_reverse.json +++ /dev/null @@ -1,20 +0,0 @@ -{"data": [ - {"colormodel": "rgba", "type": "image", - "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, - {"colormodel": "rgba", "type": "image", "xaxis": "x2", "yaxis": "y2", - "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, - {"colormodel": "rgba", "type": "image", "xaxis": "x3", "yaxis": "y3", - "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="}, - {"colormodel": "rgba", "type": "image", "xaxis": "x4", "yaxis": "y4", - "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg=="} - ], - "layout": { - "grid": {"rows": 2, "columns": 2, "pattern": "independent"}, - "width": 600, "height": 600, - "margin": {"t": 35, "l": 35, "b": 35, "r": 35}, - "xaxis2": {"autorange": "reversed"}, - "yaxis3": {"autorange": true}, - "yaxis4": {"autorange": true}, - "xaxis4": {"autorange": "reversed"} - } -} From 8ebfa7116a39e1bf796c657871d45c30a99b58ca Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 13:43:41 +0100 Subject: [PATCH 10/14] improve test code --- test/jasmine/tests/image_test.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index d922cee452b..89befb48f96 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -669,15 +669,15 @@ describe('image hover:', function() { }); [ - ['auto', 'auto'], - ['auto', 'reversed'], - ['reversed', 'auto'], - ['reversed', 'reversed'] + [[0, 512], [0, 512]], + [[0, 512], [512, 0]], // the default image layout + [[512, 0], [0, 512]], + [[512, 0], [512, 0]] ].forEach(function(test) { it('should show correct hover info regardless of axis directions ' + test, function(done) { var mockCopy = Lib.extendDeep({}, mock); - mockCopy.layout.xaxis.autorange = test[0]; - mockCopy.layout.yaxis.autorange = test[1]; + mockCopy.layout.xaxis.range = test[0]; + mockCopy.layout.yaxis.range = test[1]; mockCopy.data[0].colormodel = 'rgba'; mockCopy.data[0].hovertemplate = '%{z}'; Plotly.newPlot(gd, mockCopy) From db00dea517e84b7d244c1592b78e378a2416cfef Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 14:52:54 +0100 Subject: [PATCH 11/14] also put autorange tests in --- test/jasmine/tests/image_test.js | 33 ++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index 89befb48f96..37be60c1e30 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -669,10 +669,35 @@ describe('image hover:', function() { }); [ - [[0, 512], [0, 512]], - [[0, 512], [512, 0]], // the default image layout - [[512, 0], [0, 512]], - [[512, 0], [512, 0]] + [true, true], + [true, 'reversed'], // the default image layout + ['reversed', true], + ['reversed', 'reversed'] + ].forEach(function(test) { + it('should show correct hover info regardless of axis directions ' + test, function(done) { + var mockCopy = Lib.extendDeep({}, mock); + mockCopy.layout.xaxis.autorange = test[0]; + mockCopy.layout.yaxis.autorange = test[1]; + mockCopy.data[0].colormodel = 'rgba'; + mockCopy.data[0].hovertemplate = '%{z}'; + Plotly.newPlot(gd, mockCopy) + .then(function() {_hover(205, 125);}) + .then(function() { + assertHoverLabelContent({ + nums: '[202, 148, 125, 255]', + name: '' + }, 'variable `z` should be correct!'); + }) + .catch(failTest) + .then(done); + }); + }); + + [ + [[-0.5, 511.5], [-0.5, 511.5]], + [[-0.5, 511.5], [511.5, -0.5]], // the default image layout + [[511.5, -0.5], [-0.5, 511.5]], + [[511.5, -0.5], [511.5, -0.5]] ].forEach(function(test) { it('should show correct hover info regardless of axis directions ' + test, function(done) { var mockCopy = Lib.extendDeep({}, mock); From d4eadbd6e037ca4372e52bc37c66e492f5aa6af9 Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 30 Nov 2020 09:34:48 -0500 Subject: [PATCH 12/14] correct style --- src/traces/image/plot.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index 0af3f1778e7..37bd9665cfe 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -139,7 +139,19 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { // Pixelated image rendering // http://phrogz.net/tmp/canvas_image_zoom.html // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering - var initialStyle = 'image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated;'; + var style = 'image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated;'; + if(fastImage) { + // Flip the SVG image as needed (around the proper center location) + var axisScale = [ + (xa.range[0] < xa.range[1]) ? 1 : -1, + (ya.range[0] < ya.range[1]) ? -1 : 1 + ]; + style += 'transform:' + + strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px') + + 'scale(' + axisScale[0] + ',' + axisScale[1] + ')' + + strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px') + ';'; + } + image3.attr('style', style); var p = new Promise(function(resolve) { if(trace._hasZ) { @@ -175,23 +187,13 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { } }) .then(function() { - var href, canvas, localStyle; - localStyle = initialStyle; + var href, canvas; if(trace._hasZ) { canvas = drawMagnifiedPixelsOnCanvas(function(i, j) {return z[j][i];}); href = canvas.toDataURL('image/png'); } else if(trace._hasSource) { if(fastImage) { href = trace.source; - // Flip the SVG image as needed (around the proper center location) - var axisScale = [ - (xa.range[0] < xa.range[1]) ? 1 : -1, - (ya.range[0] < ya.range[1]) ? -1 : 1 - ]; - localStyle += 'transform:' + - strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px') + - 'scale(' + axisScale[0] + ',' + axisScale[1] + ')' + - strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px') + ';'; } else { var context = trace._canvas.el.getContext('2d'); var data = context.getImageData(0, 0, w, h).data; @@ -213,8 +215,7 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { height: imageHeight, width: imageWidth, x: left, - y: top, - style: localStyle + y: top }); }); From e351d9b521400ad9b5b739d317ff8ae152c886f2 Mon Sep 17 00:00:00 2001 From: Almar Klein Date: Mon, 30 Nov 2020 16:42:22 +0100 Subject: [PATCH 13/14] simplify transform --- src/traces/image/plot.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index 37bd9665cfe..9fbe9d063d7 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -10,7 +10,6 @@ var d3 = require('d3'); var Lib = require('../../lib'); -var strTranslate = Lib.strTranslate; var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); var constants = require('./constants'); @@ -147,9 +146,9 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { (ya.range[0] < ya.range[1]) ? -1 : 1 ]; style += 'transform:' + - strTranslate(left + imageWidth / 2 + 'px', top + imageHeight / 2 + 'px') + + 'translate(50%,50%)' + 'scale(' + axisScale[0] + ',' + axisScale[1] + ')' + - strTranslate(-left - imageWidth / 2 + 'px', -top - imageHeight / 2 + 'px') + ';'; + 'translate(-50%,-50%)' + ';'; } image3.attr('style', style); From 632532fdc085d8aa9d8bde806a52f5b12521b526 Mon Sep 17 00:00:00 2001 From: archmoj Date: Mon, 30 Nov 2020 14:10:00 -0500 Subject: [PATCH 14/14] fix transform, use linear ranges, fix tests, add mock --- src/traces/image/plot.js | 23 ++++--- .../baselines/image_source_axis_reverse.png | Bin 0 -> 29450 bytes .../mocks/image_source_axis_reverse.json | 60 ++++++++++++++++++ test/jasmine/tests/image_test.js | 37 +++-------- test/jasmine/tests/mock_test.js | 2 + 5 files changed, 86 insertions(+), 36 deletions(-) create mode 100644 test/image/baselines/image_source_axis_reverse.png create mode 100644 test/image/mocks/image_source_axis_reverse.json diff --git a/src/traces/image/plot.js b/src/traces/image/plot.js index 9fbe9d063d7..60bc5a6cc2d 100644 --- a/src/traces/image/plot.js +++ b/src/traces/image/plot.js @@ -10,6 +10,7 @@ var d3 = require('d3'); var Lib = require('../../lib'); +var strTranslate = Lib.strTranslate; var xmlnsNamespaces = require('../../constants/xmlns_namespaces'); var constants = require('./constants'); @@ -140,15 +141,19 @@ module.exports = function plot(gd, plotinfo, cdimage, imageLayer) { // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering var style = 'image-rendering: optimizeSpeed; image-rendering: -moz-crisp-edges; image-rendering: -o-crisp-edges; image-rendering: -webkit-optimize-contrast; image-rendering: optimize-contrast; image-rendering: crisp-edges; image-rendering: pixelated;'; if(fastImage) { - // Flip the SVG image as needed (around the proper center location) - var axisScale = [ - (xa.range[0] < xa.range[1]) ? 1 : -1, - (ya.range[0] < ya.range[1]) ? -1 : 1 - ]; - style += 'transform:' + - 'translate(50%,50%)' + - 'scale(' + axisScale[0] + ',' + axisScale[1] + ')' + - 'translate(-50%,-50%)' + ';'; + var xRange = Lib.simpleMap(xa.range, xa.r2l); + var yRange = Lib.simpleMap(ya.range, ya.r2l); + + var flipX = xRange[1] < xRange[0]; + var flipY = yRange[1] > yRange[0]; + if(flipX || flipY) { + var tx = left + imageWidth / 2; + var ty = top + imageHeight / 2; + style += 'transform:' + + strTranslate(tx + 'px', ty + 'px') + + 'scale(' + (flipX ? -1 : 1) + ',' + (flipY ? -1 : 1) + ')' + + strTranslate(-tx + 'px', -ty + 'px') + ';'; + } } image3.attr('style', style); diff --git a/test/image/baselines/image_source_axis_reverse.png b/test/image/baselines/image_source_axis_reverse.png new file mode 100644 index 0000000000000000000000000000000000000000..4c7120a508f7454b5718f1e6ae717d30c652a8ad GIT binary patch literal 29450 zcmeEuXH-;M)~#YG1*lNuoJv4)5|AKBmLNzjM4&)&6c7+eTA(5#NY0>=bCEMx2qIa@ z86*l4BxiWLOntk*+v9!jjW^!-e)NxfyYH#u)Y<#&z1LiG&AFc6Qd7KuPmO=-)Ts+f zH{>)=ox(w2|AC$ZSL!TcMo*n$Jf$Qjt^L4gsTMDStgjM%B)l;S)r&pPe9ollQ`zbB z0;8kn_3jd#1O)iMVq}(nrSa|&GyvL4^px<7+%2LDdZFyfjFgYNtm14_Ziq3!{24D% zo`#(cWj}v1OjEt=l08{7e_uy0QA|B=wo0VQz;pHCxM5${P^qn6|K7%Y7Xb}~@ziPP z^;0-Rj~-bXcp2DnC zUT%{9a|!Z7^7q|OK_ploAwAAVO#S)6Qz&_cUw;Z7fS%+!TH>6t)9<@oKZSWq_~XHT z+&u)35kY?@?ds2G1(zNnKjZ$n)uU$cq#=(rX@5T$(RK9KGk;wE~*uUoaKX3aq^nbg^Co7SOQocrW?XmE0 z0|n9Rvu!Hn4r8fzn}g{^;(sjuONz*Y?PUSiMQzdhUte8u7)2-q)3TS^^eN{Py=4L$ z<}%&`9)xXwZs-LX;g7p()3Y-z;R0qKi9F%9-Ko#Bl@vqhOPz#ldT%w6%+Q^NH(Ru| zwyx*jQdYikY6TA#d3AEM(#5&!+Rn#!kI$r;w?!41HsKG|cof&F%iE_&oekHhzj`t58}=FGNvs zF^p^VRkrf})C=AvE5|4JWZG*G7IoxEnZ28tHyH9Za-$io63tU|?~6>B$ofKf~r?$fP4jivhQ(a zExRB}r%FlEY05u>Q?FB5SImAc?q;<8Se2_=qs{L3FY-6(`H+t`S0{|)gzas1D#xO` zXAc9*H`-$bo%c7bvozC`#e}8oN9-Wq1`F?M);`=Sx%TY7{VqI2!c;M%pkfLiugAN^ z1+zF@n$w;rUjA{403Uy;pwYS~oosf6qJH-YJVagUs3hiSZeZZ}=wP;$vp{v=PKJGT zSJE|3@E&fCY-iZM@0jL(wOA5!UV%sKyE`3?7y^2=07Bc9*-a8i{A#^+|oYP&ZSFjD1t}oPG#Fn)~6&$-Hodpv&30juUkPR-YKH`*UMYE?jP+ zejtYkM8D8!f;S*5;%^Ji!M=R`oRTK{>|%G7tF4M>OBjpu_etr6fr8{fNmN?Hj0zEI zmZ0DN2{Qt_*pSV^bOPS{_hYYlmT|WQUAez9st*u6L96h(G^Cx{v&z$Wf{?8T{Xq4s<)(rUc_vja3LDq_b88nvS; z#KMfAR%QtSaW2~XbaPGLDB48!paShMR>i`5)r^G^fw=_1;6L^JfTyd(2S>2H(JQ(O z%MDvo*|LIg>NwNRE1bgMryGOs-BUz|O$H-bPPa|p!Ul=fDIzYG%MIEf-jK0&`GJ5L znoZCiBZ{zLrofX!D=YJDO~Z0~hazWgKyof^UKLI{g(6c;22cK_6RJx*3d_BO^q>s{ zkx*No7L^8(j|n`5om3AnsiK;$kAslx8cYb~Tax}v2+8X@q|cG;jIg&LbY^LIPzNAA z0tK@gz!UI5RPb7#@j=>fGXt4nTxT!I^nxc6;!r;W<5G8G)uBYCH9kSIOYadqMed!_ z(YS<4dn6YS2YyOn)|wGD%ifuaFN=<-zz&81+>qflN1z;<^c7SCgyG&yi3@UQiKbX> z6KE7M1$fF?SxVIG8EyGcXcP`HlMRTb)R7sFp-~xE!#U1lG^b?H5wE?VvS_bI*_Vki zn%9}-Zl1zurmSBf!mN{8YCZuYx&v+%K?rV0c#BM)8G(PpKNEy>8||cX%!s5Z)oeb9 z%5wsYCTgAOJZAlL_S+i}mDA6Ogib?LUbgmJhqP%WD3LuyvOE1}a{e6GMq}1uZ*2Ha;gwb6XzPO${<5bNIL5DUjt~BUsj% zGP@yW^=n%ZS8RH3)UCaAB*p8mbeV4)^~b$PdzssytV9Z5#BtniRZC-phzr7L<1O}i zPfi)#-U6^m%XsEW#q>q}N@w%Wdm+?9t>eA7ORP+GVrhmRpTSL4PnLX6IpnK|){gPQ zQ@(_deOlt&J5shRLR>bx(Iw^Hc*osPtzlZgoLK@DiRR2aXUA zOYw)2aQQ7P4HY}jC%S)t>W0u?Gh3f&(acbzQ|S(ffuZq8SV=>#xh=)`IRo&ybh8WE z|DI6F&e6**O=a?9C|ol|;X+Gmt8?Bi2G@~G2V>J`W4C|<%`BU44pFIeo=uf`f`7V{ zvDAjQUtN>4VeJ*~-+JY8 zc?z30F~?lirjDEFDz{}0m-)`fI3e3%O#s4jxo*Y_=Vg)$E|S&9hVlraiX0~-Iqw!* zbSM|<&_;2b?jhsZQgj)uIN{O3RBaDqvXYc<(?th(BGl8rQxo1jm^#}QWVJk6*(1r! z^{+roJ4=&Ad_B^^plUly`>OAE%=tbOBmDlsLf`v&g5ec8ucI|zRpxhSr#{?TB&$?p z*YR$#k)Yrb)V7?n>?<&y(5-QrR?siC(E+1QyWI$Hn5;S*0`)WLg3GK{HWNg}a>o4~ zG~2lVMa$8{s^0Htq94dnB5~cb#O~6=;>z8{?tf*>Gbk^kjN;N~#wDbW@HyJg5eC+HC?0$-5LTD^@ z#ksUlVgy|1`tuD9Hp$=YJ-K@S>n-c?n#!jn;iEbchj<)32nUj37w5XU%!=2O$@~Xb z!pA#KuaQiY`p$^C`*bFU6QZ>tZJxVpD0BL;&Bea9<4>GkFZg(Q)zejDr@UuRM^n0D zZda8k$}~9e_FJv+gWC!1ToZiTbZN)mdX1a$E~JepLCUu-l1nhT`B3?a<2Nf21$0Sj zO^7VI#xk27hUvbg%)@GgZvR~Ewp_$J8B-odBW!2IK+&IPAX16yVWh@5A3qYbmPL2J z-bf#8yn(M9$i?FUFbl4ZVJtK%ID9|@8Z{s%SS*kYvMJy(|eEJ(;J?R}1&60w#S8QldWTippJS8k85~o zGF*M!?XazMpi{lH;uHNdmhU|K|e0TC`EX58}CV(rN_f1{&@mXhbP9aeU&j| zez^5*m)yIGUU^AFqr#~E?(qPkhZA9x6AfP}f&jn&w+qWg8>+jQDdP≺7XcHz7ks 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 G5dQ*BreuHs literal 0 HcmV?d00001 diff --git a/test/image/mocks/image_source_axis_reverse.json b/test/image/mocks/image_source_axis_reverse.json new file mode 100644 index 00000000000..edd7b578c5a --- /dev/null +++ b/test/image/mocks/image_source_axis_reverse.json @@ -0,0 +1,60 @@ +{ + "data": [ + { + "colormodel": "rgba", + "type": "image", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg==" + }, + { + "colormodel": "rgba", + "type": "image", + "xaxis": "x2", + "yaxis": "y2", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg==" + }, + { + "colormodel": "rgba", + "type": "image", + "xaxis": "x3", + "yaxis": "y3", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg==" + }, + { + "colormodel": "rgba", + "type": "image", + "xaxis": "x4", + "yaxis": "y4", + "source": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAADmklEQVR4nO2XUWhTVxjHfyfdmKMN1oelK9QSLUVY2RWHrEKtLw66KQX30Ifpg0qxz31wb8O0UNjL1I3h09iDAy000D0Z0DJhEdslBXN7SwZBJmmbErKwNuU2UXDes4d4r700bib33KflD+Ge8+We78sv3/fdcy401VRTTTXVVFMIvxwnEhG5c97fP+lbLPARZHz8qBwY+AAA0zTp69MA/4B8cTo+flRq2n4MY42dMMFgEICRkZ+Uxw2odgigafudq2majn3nWLV8ATGMNdf44cPfd9lVyxeQwcF3MIw1gsEgY2OLzM9fYmDgPebnLzlQquVLj1y//pFcWan+R1eujLm+KxYTHDr0o/K4b6l2GI2efPnY3eTUqSMUiwmgBQDD+ANNC6sOCSgurUxmVAKUSpfp6tpHLJYiFksBL4AXaFr45Vy9lGUkkxmVhpEll9ukra1q6+raB+D68d3d76oK6ZKSjGQyozIWS5HLbVIujwCQyz0jHL4LVIHsT3f3r0xNfS3/zV8jUlpaNsT6eoS2tq/Q9TnSaZOZmRAzMyFKpcvo+hz5fEE5jGcQOxt2GeXzBQC2t6fY3p5y3bu+HnFsqmE8gdh9AThlZGtr67kzDoU6CIU6nPnGxioXLnzD0NCXLC7+rQTGE4jd3MePJ9H1OQBu3PjW2SO2tp6TTvfQ2dnhWjc9PSvs++2rVyl7aun6XTY2Vl22dLqHw4erp97Ozg6WlnqIRqfFqzVqIMADiL3x7cyGrb1733bGds8ArvK6f/+HRkPXVMNHhWj0pMzlNkkmw46tvT1NofAUTXtfPnnyrKbvgwf3yImJpPIznufSOns2C8Dt22EKhafMzq6KfL7XKpfZ1cStrUEeP/YasbY8Hd6KxS/kvXvfkc3eQdO+Z3j4kTh27BMrELCoVCpYlvUqkBBIKWltrb5cLSz8ojQrnpzZEOHwaYaHHwkAISSVSgWAlpYWDCMZMIxkwLIshBAIoXxTBzyA3Lr1p8xm7zA4+DnnzoUEwNWrnzkpEEKQSi04/peXFwMA5XKZoSGT8+c/tHZ7bVwNgcTjJQfixIl2AXDt2qeWlILe3iKAC8LW0lIicOZMdXzggNrDY90g8XhJPnjwswsCqiVlmn8hhETXf3ut38nJhC9vpXU5fR2ErWy2ws2by//pc2WlXE/YN9Ibg9gQ4fDpmhCgvlx8UTxekvF4qeYjJxLptyYmPq6reS9e7Kt7zf9C/wDLc4opp/2WUgAAAABJRU5ErkJggg==" + } + ], + "layout": { + "grid": { + "rows": 2, + "columns": 2, + "pattern": "independent" + }, + "width": 600, + "height": 600, + "margin": { + "t": 35, + "l": 35, + "b": 35, + "r": 35 + }, + "xaxis2": { + "autorange": "reversed" + }, + "yaxis3": { + "range": [ + "8", + "32" + ] + }, + "yaxis4": { + "autorange": true + }, + "xaxis4": { + "autorange": "reversed" + } + } +} diff --git a/test/jasmine/tests/image_test.js b/test/jasmine/tests/image_test.js index 37be60c1e30..903cde4ee59 100644 --- a/test/jasmine/tests/image_test.js +++ b/test/jasmine/tests/image_test.js @@ -679,39 +679,22 @@ describe('image hover:', function() { mockCopy.layout.xaxis.autorange = test[0]; mockCopy.layout.yaxis.autorange = test[1]; mockCopy.data[0].colormodel = 'rgba'; - mockCopy.data[0].hovertemplate = '%{z}'; + mockCopy.data[0].hovertemplate = 'x:%{x}, y:%{y}, z:%{z}'; Plotly.newPlot(gd, mockCopy) - .then(function() {_hover(205, 125);}) .then(function() { - assertHoverLabelContent({ - nums: '[202, 148, 125, 255]', - name: '' - }, 'variable `z` should be correct!'); - }) - .catch(failTest) - .then(done); - }); - }); + var x = 205; + var y = 125; - [ - [[-0.5, 511.5], [-0.5, 511.5]], - [[-0.5, 511.5], [511.5, -0.5]], // the default image layout - [[511.5, -0.5], [-0.5, 511.5]], - [[511.5, -0.5], [511.5, -0.5]] - ].forEach(function(test) { - it('should show correct hover info regardless of axis directions ' + test, function(done) { - var mockCopy = Lib.extendDeep({}, mock); - mockCopy.layout.xaxis.range = test[0]; - mockCopy.layout.yaxis.range = test[1]; - mockCopy.data[0].colormodel = 'rgba'; - mockCopy.data[0].hovertemplate = '%{z}'; - Plotly.newPlot(gd, mockCopy) - .then(function() {_hover(205, 125);}) + // adjust considering css + if(test[0] === 'reversed') x = 512 - x; + if(test[1] !== 'reversed') y = 512 - y; + _hover(x, y); + }) .then(function() { assertHoverLabelContent({ - nums: '[202, 148, 125, 255]', + nums: 'x:205, y:125, z:[202, 148, 125, 255]', name: '' - }, 'variable `z` should be correct!'); + }, 'positions should be correct!'); }) .catch(failTest) .then(done); diff --git a/test/jasmine/tests/mock_test.js b/test/jasmine/tests/mock_test.js index 7cd61e5b034..8aaa8b97456 100644 --- a/test/jasmine/tests/mock_test.js +++ b/test/jasmine/tests/mock_test.js @@ -648,6 +648,7 @@ var list = [ 'image_colormodel', 'image_non_numeric', 'image_opacity', + 'image_source_axis_reverse', 'image_with_gaps', 'image_with_heatmap', 'image_zmin_zmax', @@ -1721,6 +1722,7 @@ figs['image_cat'] = require('@mocks/image_cat'); figs['image_colormodel'] = require('@mocks/image_colormodel'); figs['image_non_numeric'] = require('@mocks/image_non_numeric'); figs['image_opacity'] = require('@mocks/image_opacity'); +figs['image_source_axis_reverse'] = require('@mocks/image_source_axis_reverse'); figs['image_with_gaps'] = require('@mocks/image_with_gaps'); figs['image_with_heatmap'] = require('@mocks/image_with_heatmap'); figs['image_zmin_zmax'] = require('@mocks/image_zmin_zmax');