From ba8d23f2ad7e3e4e384fd12b3c8087e5f0e203f4 Mon Sep 17 00:00:00 2001 From: Calvin Fernandez Date: Tue, 16 Aug 2016 18:02:43 -0400 Subject: [PATCH 1/4] closes #858 Add padding field to heatmap that allows users to define space between bricks. --- src/plot_api/plot_api.js | 1 + src/traces/heatmap/attributes.js | 15 ++++- src/traces/heatmap/defaults.js | 2 + src/traces/heatmap/plot.js | 58 +++++++++++++++++- .../image/baselines/heatmap_brick_padding.png | Bin 0 -> 24150 bytes test/image/mocks/heatmap_brick_padding.json | 26 ++++++++ test/jasmine/tests/heatmap_test.js | 58 ++++++++++++++++++ test/jasmine/tests/plot_api_test.js | 20 +++++- 8 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 test/image/baselines/heatmap_brick_padding.png create mode 100644 test/image/mocks/heatmap_brick_padding.json diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index d8c7b07a1cc..7046e3adcc7 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -1620,6 +1620,7 @@ Plotly.restyle = function restyle(gd, astr, val, traces) { // objects need to be made) but not a recalc var replotAttrs = [ 'zmin', 'zmax', 'zauto', + 'xgap', 'ygap', 'marker.cmin', 'marker.cmax', 'marker.cauto', 'line.cmin', 'line.cmax', 'marker.line.cmin', 'marker.line.cmax', diff --git a/src/traces/heatmap/attributes.js b/src/traces/heatmap/attributes.js index 112656e0368..8155a2f8ea2 100644 --- a/src/traces/heatmap/attributes.js +++ b/src/traces/heatmap/attributes.js @@ -76,7 +76,20 @@ module.exports = extendFlat({}, 'in the `z` data are filled in.' ].join(' ') }, - + xgap: { + valType: 'number', + dflt: 0, + min: 0, + role: 'style', + description: 'Sets the horizontal gap (in pixels) between bricks.' + }, + ygap: { + valType: 'number', + dflt: 0, + min: 0, + role: 'style', + description: 'Sets the vertical gap (in pixels) between bricks.' + }, _nestedModules: { 'colorbar': 'Colorbar' } diff --git a/src/traces/heatmap/defaults.js b/src/traces/heatmap/defaults.js index f0fdfb1aafd..33dfdf9b57c 100644 --- a/src/traces/heatmap/defaults.js +++ b/src/traces/heatmap/defaults.js @@ -29,6 +29,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } coerce('text'); + coerce('xgap'); + coerce('ygap'); coerce('zsmooth'); coerce('connectgaps', hasColumns(traceOut) && (traceOut.zsmooth !== false)); diff --git a/src/traces/heatmap/plot.js b/src/traces/heatmap/plot.js index bbaf993b299..d8632d945dc 100644 --- a/src/traces/heatmap/plot.js +++ b/src/traces/heatmap/plot.js @@ -238,6 +238,7 @@ function plotOne(gd, plotinfo, cd) { rcount = 0, gcount = 0, bcount = 0, + brickWithPadding, xb, j, xi, @@ -245,6 +246,47 @@ function plotOne(gd, plotinfo, cd) { row, c; + function applyBrickPadding(trace, x0, x1, y0, y1, xIndex, xLength, yIndex, yLength) { + var padding = { + x0: x0, + x1: x1, + y0: y0, + y1: y1 + }, + xEdgeGap = trace.xgap * 2 / 3, + yEdgeGap = trace.ygap * 2 / 3, + xCenterGap = trace.xgap / 3, + yCenterGap = trace.ygap / 3; + + if(yIndex === yLength - 1) { // top edge brick + padding.y1 = y1 - yEdgeGap; + } + + if(xIndex === xLength - 1) { // right edge brick + padding.x0 = x0 + xEdgeGap; + } + + if(yIndex === 0) { // bottom edge brick + padding.y0 = y0 + yEdgeGap; + } + + if(xIndex === 0) { // left edge brick + padding.x1 = x1 - xEdgeGap; + } + + if(xIndex > 0 && xIndex < xLength - 1) { // brick in the center along x + padding.x0 = x0 + xCenterGap; + padding.x1 = x1 - xCenterGap; + } + + if(yIndex > 0 && yIndex < yLength - 1) { // brick in the center along y + padding.y0 = y0 + yCenterGap; + padding.y1 = y1 - yCenterGap; + } + + return padding; + } + function setColor(v, pixsize) { if(v !== undefined) { var c = s((v - min) / (max - min)); @@ -364,7 +406,21 @@ function plotOne(gd, plotinfo, cd) { v = row[i]; c = setColor(v, (xb[1] - xb[0]) * (yb[1] - yb[0])); context.fillStyle = 'rgba(' + c.join(',') + ')'; - context.fillRect(xb[0], yb[0], (xb[1] - xb[0]), (yb[1] - yb[0])); + + brickWithPadding = applyBrickPadding(trace, + xb[0], + xb[1], + yb[0], + yb[1], + i, + n, + j, + m); + + context.fillRect(brickWithPadding.x0, + brickWithPadding.y0, + (brickWithPadding.x1 - brickWithPadding.x0), + (brickWithPadding.y1 - brickWithPadding.y0)); } } } diff --git a/test/image/baselines/heatmap_brick_padding.png b/test/image/baselines/heatmap_brick_padding.png new file mode 100644 index 0000000000000000000000000000000000000000..d0a398c67e5d747ba0f5d35b6eb3a17114c11831 GIT binary patch literal 24150 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 CD1)s4 literal 0 HcmV?d00001 diff --git a/test/image/mocks/heatmap_brick_padding.json b/test/image/mocks/heatmap_brick_padding.json new file mode 100644 index 00000000000..10cd480c5d6 --- /dev/null +++ b/test/image/mocks/heatmap_brick_padding.json @@ -0,0 +1,26 @@ +{ + "data": [ + { + "z": [ + [ + 1, + 20, + 30 + ], + [ + 20, + 1, + 60 + ], + [ + 30, + 60, + 1 + ] + ], + "xgap": 9, + "ygap": 6, + "type": "heatmap" + } + ] +} diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 1889016a1a6..0150ef4c050 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -89,6 +89,28 @@ describe('heatmap supplyDefaults', function() { expect(traceOut.visible).toBe(false); }); + it('should set paddings to 0 when not defined', function() { + traceIn = { + type: 'heatmap', + z: [[1, 2], [3, 4]] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.xgap).toBe(0); + expect(traceOut.ygap).toBe(0); + }); + + it('should not step on defined paddings', function() { + traceIn = { + xgap: 10, + type: 'heatmap', + z: [[1, 2], [3, 4]] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.xgap).toBe(10); + expect(traceOut.ygap).toBe(0); + }); }); describe('heatmap convertColumnXYZ', function() { @@ -381,7 +403,43 @@ describe('heatmap plot', function() { done(); }); + }); + it('draws canvas with correct margins', function(done) { + var mockWithPadding = require('@mocks/heatmap_brick_padding.json'), + mockWithoutPadding = Lib.extendDeep({}, mockWithPadding), + gd = createGraphDiv(), + getContextStub = { + fillRect: jasmine.createSpy() + }, + originalCreateElement = document.createElement; + + mockWithoutPadding.data[0].xgap = 0; + mockWithoutPadding.data[0].ygap = 0; + + spyOn(document, 'createElement').and.callFake(function(elementType) { + var element = originalCreateElement.call(document, elementType); + if(elementType === 'canvas') { + spyOn(element, 'getContext').and.returnValue(getContextStub); + } + return element; + }); + + var argumentsWithoutPadding = [], + argumentsWithPadding = []; + Plotly.plot(gd, mockWithoutPadding.data, mockWithoutPadding.layout).then(function() { + argumentsWithoutPadding = getContextStub.fillRect.calls.allArgs().slice(0); + expect(argumentsWithoutPadding).toEqual([[0, 180, 177, 90], [177, 180, 177, 90], [354, 180, 177, 90], + [0, 90, 177, 90], [177, 90, 177, 90], [354, 90, 177, 90], + [0, 0, 177, 90], [177, 0, 177, 90], [354, 0, 177, 90]]); + return Plotly.plot(gd, mockWithPadding.data, mockWithPadding.layout); + }).then(function() { + argumentsWithPadding = getContextStub.fillRect.calls.allArgs().slice(getContextStub.fillRect.calls.allArgs().length - 9); + expect(argumentsWithPadding).toEqual([[0, 184, 171, 86], [180, 184, 171, 86], [360, 184, 171, 86], + [0, 92, 171, 86], [180, 92, 171, 86], [360, 92, 171, 86], + [0, 0, 171, 86], [180, 0, 171, 86], [360, 0, 171, 86]]); + done(); + }); }); }); diff --git a/test/jasmine/tests/plot_api_test.js b/test/jasmine/tests/plot_api_test.js index 78fefeb75da..ac938f8358e 100644 --- a/test/jasmine/tests/plot_api_test.js +++ b/test/jasmine/tests/plot_api_test.js @@ -86,7 +86,7 @@ describe('Test plot api', function() { describe('Plotly.restyle', function() { beforeEach(function() { - spyOn(Plotly, 'plot'); + spyOn(PlotlyInternal, 'plot'); spyOn(Plots, 'previousPromises'); spyOn(Scatter, 'arraysToCalcdata'); spyOn(Bar, 'arraysToCalcdata'); @@ -111,7 +111,7 @@ describe('Test plot api', function() { expect(Scatter.arraysToCalcdata).toHaveBeenCalled(); expect(Bar.arraysToCalcdata).not.toHaveBeenCalled(); expect(Plots.style).toHaveBeenCalled(); - expect(Plotly.plot).not.toHaveBeenCalled(); + expect(PlotlyInternal.plot).not.toHaveBeenCalled(); // "docalc" deletes gd.calcdata - make sure this didn't happen expect(gd.calcdata).toBeDefined(); }); @@ -126,10 +126,24 @@ describe('Test plot api', function() { expect(Scatter.arraysToCalcdata).not.toHaveBeenCalled(); expect(Bar.arraysToCalcdata).toHaveBeenCalled(); expect(Plots.style).toHaveBeenCalled(); - expect(Plotly.plot).not.toHaveBeenCalled(); + expect(PlotlyInternal.plot).not.toHaveBeenCalled(); expect(gd.calcdata).toBeDefined(); }); + it('calls plot on xgap and ygap styling', function() { + var gd = { + data: [{z: [[1, 2, 3], [4, 5, 6], [7, 8, 9]], showscale: false, type: 'heatmap'}], + layout: {} + }; + + mockDefaultsAndCalc(gd); + Plotly.restyle(gd, {'xgap': 2}); + expect(PlotlyInternal.plot).toHaveBeenCalled(); + + Plotly.restyle(gd, {'ygap': 2}); + expect(PlotlyInternal.plot.calls.count()).toEqual(2); + }); + it('ignores undefined values', function() { var gd = { data: [{x: [1, 2, 3], y: [1, 2, 3], type: 'scatter'}], From b90d55ab333ed8423e477e3ae28edc2a4e7bbe5a Mon Sep 17 00:00:00 2001 From: Calvin Fernandez Date: Fri, 19 Aug 2016 14:54:27 -0400 Subject: [PATCH 2/4] fix broken tests --- src/traces/histogram2d/attributes.js | 2 ++ src/traces/histogram2d/defaults.js | 2 ++ test/jasmine/tests/heatmap_test.js | 49 ++++++++++++++++++++++---- test/jasmine/tests/histogram2d_test.js | 48 +++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 6 deletions(-) create mode 100644 test/jasmine/tests/histogram2d_test.js diff --git a/src/traces/histogram2d/attributes.js b/src/traces/histogram2d/attributes.js index 37d19b8d2c1..6421274e54b 100644 --- a/src/traces/histogram2d/attributes.js +++ b/src/traces/histogram2d/attributes.js @@ -39,6 +39,8 @@ module.exports = extendFlat({}, nbinsy: histogramAttrs.nbinsy, ybins: histogramAttrs.ybins, + xgap: heatmapAttrs.xgap, + ygap: heatmapAttrs.ygap, zsmooth: heatmapAttrs.zsmooth, _nestedModules: { diff --git a/src/traces/histogram2d/defaults.js b/src/traces/histogram2d/defaults.js index 5b11521aa0a..072f2a9666d 100644 --- a/src/traces/histogram2d/defaults.js +++ b/src/traces/histogram2d/defaults.js @@ -24,6 +24,8 @@ module.exports = function supplyDefaults(traceIn, traceOut, layout) { handleSampleDefaults(traceIn, traceOut, coerce); coerce('zsmooth'); + coerce('xgap'); + coerce('ygap'); colorscaleDefaults( traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'} diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 0150ef4c050..1c24f0ee922 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -429,15 +429,52 @@ describe('heatmap plot', function() { argumentsWithPadding = []; Plotly.plot(gd, mockWithoutPadding.data, mockWithoutPadding.layout).then(function() { argumentsWithoutPadding = getContextStub.fillRect.calls.allArgs().slice(0); - expect(argumentsWithoutPadding).toEqual([[0, 180, 177, 90], [177, 180, 177, 90], [354, 180, 177, 90], - [0, 90, 177, 90], [177, 90, 177, 90], [354, 90, 177, 90], - [0, 0, 177, 90], [177, 0, 177, 90], [354, 0, 177, 90]]); return Plotly.plot(gd, mockWithPadding.data, mockWithPadding.layout); }).then(function() { + var centerXGap = mockWithPadding.data[0].xgap / 3; + var centerYGap = mockWithPadding.data[0].ygap / 3; + var edgeXGap = mockWithPadding.data[0].xgap * 2 / 3; + var edgeYGap = mockWithPadding.data[0].ygap * 2 / 3; + argumentsWithPadding = getContextStub.fillRect.calls.allArgs().slice(getContextStub.fillRect.calls.allArgs().length - 9); - expect(argumentsWithPadding).toEqual([[0, 184, 171, 86], [180, 184, 171, 86], [360, 184, 171, 86], - [0, 92, 171, 86], [180, 92, 171, 86], [360, 92, 171, 86], - [0, 0, 171, 86], [180, 0, 171, 86], [360, 0, 171, 86]]); + expect(argumentsWithPadding).toEqual([ + [argumentsWithoutPadding[0][0], + argumentsWithoutPadding[0][1] + edgeYGap, + argumentsWithoutPadding[0][2] - edgeXGap, + argumentsWithoutPadding[0][3] - edgeYGap], + [argumentsWithoutPadding[1][0] + centerXGap, + argumentsWithoutPadding[1][1] + edgeYGap, + argumentsWithoutPadding[1][2] - edgeXGap, + argumentsWithoutPadding[1][3] - edgeYGap], + [argumentsWithoutPadding[2][0] + edgeXGap, + argumentsWithoutPadding[2][1] + edgeYGap, + argumentsWithoutPadding[2][2] - edgeXGap, + argumentsWithoutPadding[2][3] - edgeYGap], + [argumentsWithoutPadding[3][0], + argumentsWithoutPadding[3][1] + centerYGap, + argumentsWithoutPadding[3][2] - edgeXGap, + argumentsWithoutPadding[3][3] - edgeYGap], + [argumentsWithoutPadding[4][0] + centerXGap, + argumentsWithoutPadding[4][1] + centerYGap, + argumentsWithoutPadding[4][2] - edgeXGap, + argumentsWithoutPadding[4][3] - edgeYGap], + [argumentsWithoutPadding[5][0] + edgeXGap, + argumentsWithoutPadding[5][1] + centerYGap, + argumentsWithoutPadding[5][2] - edgeXGap, + argumentsWithoutPadding[5][3] - edgeYGap], + [argumentsWithoutPadding[6][0], + argumentsWithoutPadding[6][1], + argumentsWithoutPadding[6][2] - edgeXGap, + argumentsWithoutPadding[6][3] - edgeYGap], + [argumentsWithoutPadding[7][0] + centerXGap, + argumentsWithoutPadding[7][1], + argumentsWithoutPadding[7][2] - edgeXGap, + argumentsWithoutPadding[7][3] - edgeYGap], + [argumentsWithoutPadding[8][0] + edgeXGap, + argumentsWithoutPadding[8][1], + argumentsWithoutPadding[8][2] - edgeXGap, + argumentsWithoutPadding[8][3] - edgeYGap + ]]); done(); }); }); diff --git a/test/jasmine/tests/histogram2d_test.js b/test/jasmine/tests/histogram2d_test.js new file mode 100644 index 00000000000..3e7b3aa34ea --- /dev/null +++ b/test/jasmine/tests/histogram2d_test.js @@ -0,0 +1,48 @@ +var supplyDefaults = require('@src/traces/histogram2d/defaults'); + + +describe('Test histogram2d', function() { + 'use strict'; + + describe('supplyDefaults', function() { + var traceIn, + traceOut; + + beforeEach(function() { + traceOut = {}; + }); + + it('should set zsmooth to false when zsmooth is empty', function() { + traceIn = {}; + supplyDefaults(traceIn, traceOut, {}); + expect(traceOut.zsmooth).toBe(false); + }); + + it('doesnt step on zsmooth when zsmooth is set', function() { + traceIn = { + zsmooth: 'fast' + }; + supplyDefaults(traceIn, traceOut, {}); + expect(traceOut.zsmooth).toBe('fast'); + }); + + it('should set xgap and ygap to 0 when xgap and ygap are empty', function() { + traceIn = {}; + supplyDefaults(traceIn, traceOut,{}); + expect(traceOut.xgap).toBe(0); + expect(traceOut.ygap).toBe(0); + }); + + it('shouldnt step on xgap and ygap when xgap and ygap are set', function() { + traceIn = { + xgap: 10, + ygap: 5 + }; + supplyDefaults(traceIn, traceOut, {}); + expect(traceOut.xgap).toBe(10); + expect(traceOut.ygap).toBe(5); + }); + + }); + +}); From 4394a0b526d2dab31137418b31fc823b79437ab4 Mon Sep 17 00:00:00 2001 From: Calvin Fernandez Date: Fri, 19 Aug 2016 15:05:07 -0400 Subject: [PATCH 3/4] fix lint error --- test/jasmine/tests/histogram2d_test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jasmine/tests/histogram2d_test.js b/test/jasmine/tests/histogram2d_test.js index 3e7b3aa34ea..127ada0b966 100644 --- a/test/jasmine/tests/histogram2d_test.js +++ b/test/jasmine/tests/histogram2d_test.js @@ -28,7 +28,7 @@ describe('Test histogram2d', function() { it('should set xgap and ygap to 0 when xgap and ygap are empty', function() { traceIn = {}; - supplyDefaults(traceIn, traceOut,{}); + supplyDefaults(traceIn, traceOut, {}); expect(traceOut.xgap).toBe(0); expect(traceOut.ygap).toBe(0); }); From 94daf84850a2eea7839d8769526674d222f9192a Mon Sep 17 00:00:00 2001 From: Calvin Fernandez Date: Mon, 22 Aug 2016 16:31:10 -0400 Subject: [PATCH 4/4] make gap unsettable when zsmooth is not false --- src/traces/heatmap/defaults.js | 11 ++++++++--- src/traces/histogram2d/defaults.js | 9 ++++++--- test/jasmine/tests/heatmap_test.js | 14 ++++++++++++++ test/jasmine/tests/histogram2d_test.js | 11 +++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/traces/heatmap/defaults.js b/src/traces/heatmap/defaults.js index 33dfdf9b57c..f41624cf57e 100644 --- a/src/traces/heatmap/defaults.js +++ b/src/traces/heatmap/defaults.js @@ -29,9 +29,14 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } coerce('text'); - coerce('xgap'); - coerce('ygap'); - coerce('zsmooth'); + + var zsmooth = coerce('zsmooth'); + if(zsmooth === false) { + // ensure that xgap and ygap are coerced only when zsmooth allows them to have an effect. + coerce('xgap'); + coerce('ygap'); + } + coerce('connectgaps', hasColumns(traceOut) && (traceOut.zsmooth !== false)); colorscaleDefaults(traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'}); diff --git a/src/traces/histogram2d/defaults.js b/src/traces/histogram2d/defaults.js index 072f2a9666d..563c59563d1 100644 --- a/src/traces/histogram2d/defaults.js +++ b/src/traces/histogram2d/defaults.js @@ -23,9 +23,12 @@ module.exports = function supplyDefaults(traceIn, traceOut, layout) { handleSampleDefaults(traceIn, traceOut, coerce); - coerce('zsmooth'); - coerce('xgap'); - coerce('ygap'); + var zsmooth = coerce('zsmooth'); + if(zsmooth === false) { + // ensure that xgap and ygap are coerced only when zsmooth allows them to have an effect. + coerce('xgap'); + coerce('ygap'); + } colorscaleDefaults( traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'} diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 1c24f0ee922..34b828ef6b3 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -111,6 +111,20 @@ describe('heatmap supplyDefaults', function() { expect(traceOut.xgap).toBe(10); expect(traceOut.ygap).toBe(0); }); + + it('should not coerce gap if zsmooth is set', function() { + traceIn = { + xgap: 10, + zsmooth: 'best', + type: 'heatmap', + z: [[1, 2], [3, 4]] + }; + + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.xgap).toBe(undefined); + expect(traceOut.ygap).toBe(undefined); + }); + }); describe('heatmap convertColumnXYZ', function() { diff --git a/test/jasmine/tests/histogram2d_test.js b/test/jasmine/tests/histogram2d_test.js index 127ada0b966..b2dd0ebd28e 100644 --- a/test/jasmine/tests/histogram2d_test.js +++ b/test/jasmine/tests/histogram2d_test.js @@ -43,6 +43,17 @@ describe('Test histogram2d', function() { expect(traceOut.ygap).toBe(5); }); + it('shouldnt coerce gap when zsmooth is set', function() { + traceIn = { + xgap: 10, + ygap: 5, + zsmooth: 'best' + }; + supplyDefaults(traceIn, traceOut, {}); + expect(traceOut.xgap).toBe(undefined); + expect(traceOut.ygap).toBe(undefined); + }); + }); });