From c7bf990c02545f863a4edaf478cbc8230684e3a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:49:15 -0400 Subject: [PATCH 1/8] lint in heatmap calc --- src/traces/heatmap/calc.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index c10b549fa98..4dc2b75f8e8 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -178,23 +178,28 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { var len = arrayIn.length; // given vals are brick centers - // hopefully length==numbricks, but use this method even if too few are supplied + // hopefully length === numbricks, but use this method even if too few are supplied // and extend it linearly based on the last two points if(len <= numbricks) { // contour plots only want the centers if(isContour || isGL2D) arrayOut = arrayIn.slice(0, numbricks); - else if(numbricks === 1) arrayOut = [arrayIn[0] - 0.5, arrayIn[0] + 0.5]; + else if(numbricks === 1) { + arrayOut = [arrayIn[0] - 0.5, arrayIn[0] + 0.5]; + } else { arrayOut = [1.5 * arrayIn[0] - 0.5 * arrayIn[1]]; + for(i = 1; i < len; i++) { arrayOut.push((arrayIn[i - 1] + arrayIn[i]) * 0.5); } + arrayOut.push(1.5 * arrayIn[len - 1] - 0.5 * arrayIn[len - 2]); } if(len < numbricks) { var lastPt = arrayOut[arrayOut.length - 1], delta = lastPt - arrayOut[arrayOut.length - 2]; + for(i = len; i < numbricks; i++) { lastPt += delta; arrayOut.push(lastPt); @@ -202,7 +207,7 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { } } else { - // hopefully length==numbricks+1, but do something regardless: + // hopefully length === numbricks+1, but do something regardless: // given vals are brick boundaries return isContour ? arrayIn.slice(0, numbricks) : // we must be strict for contours @@ -219,6 +224,7 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { arrayOut.push(v0 + dv * i); } } + return arrayOut; } From 485bae519aa72bc8daa525f2abeac1d3ad7c6ed3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:53:32 -0400 Subject: [PATCH 2/8] flatten heatmap and contour test suite --- test/jasmine/tests/contour_test.js | 245 ++++++++++--------- test/jasmine/tests/heatmap_test.js | 362 ++++++++++++++--------------- 2 files changed, 302 insertions(+), 305 deletions(-) diff --git a/test/jasmine/tests/contour_test.js b/test/jasmine/tests/contour_test.js index 1b7b36e2186..280527be1cb 100644 --- a/test/jasmine/tests/contour_test.js +++ b/test/jasmine/tests/contour_test.js @@ -3,133 +3,132 @@ var Contour = require('@src/traces/contour'); var makeColorMap = require('@src/traces/contour/make_color_map'); var colorScales = require('@src/components/colorscale/scales'); +describe('contour defaults', function() { + 'use strict'; + + var traceIn, + traceOut; + + var defaultColor = '#444', + layout = { + font: Plots.layoutAttributes.font + }; + + var supplyDefaults = Contour.supplyDefaults; + + beforeEach(function() { + traceOut = {}; + }); -describe('Test contour', function() { + it('should set autocontour to false when contours is supplied', function() { + traceIn = { + type: 'contour', + z: [[10, 10.625, 12.5, 15.625], + [5.625, 6.25, 8.125, 11.25], + [2.5, 3.125, 5.0, 8.125], + [0.625, 1.25, 3.125, 6.25]], + contours: { + start: 4, + end: 14, + size: 0.5 + } + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.autocontour).toBe(false); + + traceIn = { + type: 'contour', + z: [[10, 10.625, 12.5, 15.625], + [5.625, 6.25, 8.125, 11.25], + [2.5, 3.125, 5.0, 8.125], + [0.625, 1.25, 3.125, 6.25]] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.autocontour).toBe(true); + }); +}); + +describe('contour makeColorMap', function() { 'use strict'; - describe('supplyDefaults', function() { - var traceIn, - traceOut; - - var defaultColor = '#444', - layout = { - font: Plots.layoutAttributes.font - }; - - var supplyDefaults = Contour.supplyDefaults; - - beforeEach(function() { - traceOut = {}; - }); - - it('should set autocontour to false when contours is supplied', function() { - traceIn = { - type: 'contour', - z: [[10, 10.625, 12.5, 15.625], - [5.625, 6.25, 8.125, 11.25], - [2.5, 3.125, 5.0, 8.125], - [0.625, 1.25, 3.125, 6.25]], - contours: { - start: 4, - end: 14, - size: 0.5 - } - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.autocontour).toBe(false); - - traceIn = { - type: 'contour', - z: [[10, 10.625, 12.5, 15.625], - [5.625, 6.25, 8.125, 11.25], - [2.5, 3.125, 5.0, 8.125], - [0.625, 1.25, 3.125, 6.25]] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.autocontour).toBe(true); - }); + it('should make correct color map function (\'fill\' coloring case)', function() { + var trace = { + contours: { + coloring: 'fill', + start: -1.5, + size: 0.5, + end: 2.005 + }, + colorscale: [[ + 0, 'rgb(12,51,131)' + ], [ + 0.25, 'rgb(10,136,186)' + ], [ + 0.5, 'rgb(242,211,56)' + ], [ + 0.75, 'rgb(242,143,56)' + ], [ + 1, 'rgb(217,30,30)' + ]] + }; + + var colorMap = makeColorMap(trace); + + expect(colorMap.domain()).toEqual( + [-1.75, -0.75, 0.25, 1.25, 2.25] + ); + + expect(colorMap.range()).toEqual([ + 'rgb(12,51,131)', 'rgb(10,136,186)', 'rgb(242,211,56)', + 'rgb(242,143,56)', 'rgb(217,30,30)' + ]); + }); + + it('should make correct color map function (\'heatmap\' coloring case)', function() { + var trace = { + contours: { + coloring: 'heatmap', + start: 1.5, + size: 0.5, + end: 5.505 + }, + colorscale: colorScales.RdBu, + zmin: 1, + zmax: 6 + }; + + var colorMap = makeColorMap(trace); + + expect(colorMap.domain()).toEqual( + [1, 2.75, 3.5, 4, 4.5, 6] + ); + + expect(colorMap.range()).toEqual([ + 'rgb(5,10,172)', 'rgb(106,137,247)', 'rgb(190,190,190)', + 'rgb(220,170,132)', 'rgb(230,145,90)', 'rgb(178,10,28)' + ]); }); - describe('makeColorMap', function() { - it('should make correct color map function (\'fill\' coloring case)', function() { - var trace = { - contours: { - coloring: 'fill', - start: -1.5, - size: 0.5, - end: 2.005 - }, - colorscale: [[ - 0, 'rgb(12,51,131)' - ], [ - 0.25, 'rgb(10,136,186)' - ], [ - 0.5, 'rgb(242,211,56)' - ], [ - 0.75, 'rgb(242,143,56)' - ], [ - 1, 'rgb(217,30,30)' - ]] - }; - - var colorMap = makeColorMap(trace); - - expect(colorMap.domain()).toEqual( - [-1.75, -0.75, 0.25, 1.25, 2.25] - ); - - expect(colorMap.range()).toEqual([ - 'rgb(12,51,131)', 'rgb(10,136,186)', 'rgb(242,211,56)', - 'rgb(242,143,56)', 'rgb(217,30,30)' - ]); - }); - - it('should make correct color map function (\'heatmap\' coloring case)', function() { - var trace = { - contours: { - coloring: 'heatmap', - start: 1.5, - size: 0.5, - end: 5.505 - }, - colorscale: colorScales.RdBu, - zmin: 1, - zmax: 6 - }; - - var colorMap = makeColorMap(trace); - - expect(colorMap.domain()).toEqual( - [1, 2.75, 3.5, 4, 4.5, 6] - ); - - expect(colorMap.range()).toEqual([ - 'rgb(5,10,172)', 'rgb(106,137,247)', 'rgb(190,190,190)', - 'rgb(220,170,132)', 'rgb(230,145,90)', 'rgb(178,10,28)' - ]); - }); - - it('should make correct color map function (\'lines\' coloring case)', function() { - var trace = { - contours: { - coloring: 'lines', - start: 1.5, - size: 0.5, - end: 5.505 - }, - colorscale: colorScales.RdBu - }; - - var colorMap = makeColorMap(trace); - - expect(colorMap.domain()).toEqual( - [1.5, 2.9, 3.5, 3.9, 4.3, 5.5] - ); - - expect(colorMap.range()).toEqual([ - 'rgb(5,10,172)', 'rgb(106,137,247)', 'rgb(190,190,190)', - 'rgb(220,170,132)', 'rgb(230,145,90)', 'rgb(178,10,28)' - ]); - }); + it('should make correct color map function (\'lines\' coloring case)', function() { + var trace = { + contours: { + coloring: 'lines', + start: 1.5, + size: 0.5, + end: 5.505 + }, + colorscale: colorScales.RdBu + }; + + var colorMap = makeColorMap(trace); + + expect(colorMap.domain()).toEqual( + [1.5, 2.9, 3.5, 3.9, 4.3, 5.5] + ); + + expect(colorMap.range()).toEqual([ + 'rgb(5,10,172)', 'rgb(106,137,247)', 'rgb(190,190,190)', + 'rgb(220,170,132)', 'rgb(230,145,90)', 'rgb(178,10,28)' + ]); }); }); diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 17340fda0cd..2b2df917aa3 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -3,194 +3,192 @@ var Heatmap = require('@src/traces/heatmap'); var Plots = require('@src/plots/plots'); -describe('Test heatmap', function() { +describe('heatmap supplyDefaults', function() { 'use strict'; - describe('supplyDefaults', function() { - var traceIn, - traceOut; - - var defaultColor = '#444', - layout = { - font: Plots.layoutAttributes.font - }; - - var supplyDefaults = Heatmap.supplyDefaults; - - beforeEach(function() { - traceOut = {}; - }); - - it('should set visible to false when z is empty', function() { - traceIn = { - z: [] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - z: [[]] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - z: [[], [], []] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - - traceIn = { - type: 'heatmap', - z: [[1, 2], []] - }; - traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); - - traceIn = { - type: 'heatmap', - z: [[], [1, 2], [1, 2, 3]] - }; - traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); - expect(traceOut.visible).toBe(true); - expect(traceOut.visible).toBe(true); - }); - - it('should set visible to false when z is non-numeric', function() { - traceIn = { - type: 'heatmap', - z: [['a', 'b'], ['c', 'd']] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); - - it('should set visible to false when z isn\'t column not a 2d array', function() { - traceIn = { - x: [1, 1, 1, 2, 2], - y: [1, 2, 3, 1, 2], - z: [1, ['this is considered a column'], 1, 2, 3] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).not.toBe(false); - - traceIn = { - x: [1, 1, 1, 2, 2], - y: [1, 2, 3, 1, 2], - z: [[0], ['this is not considered a column'], 1, ['nor 2d']] - }; - supplyDefaults(traceIn, traceOut, defaultColor, layout); - expect(traceOut.visible).toBe(false); - }); + var traceIn, + traceOut; + var defaultColor = '#444', + layout = { + font: Plots.layoutAttributes.font + }; + + var supplyDefaults = Heatmap.supplyDefaults; + + beforeEach(function() { + traceOut = {}; + }); + + it('should set visible to false when z is empty', function() { + traceIn = { + z: [] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + + traceIn = { + z: [[]] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + + traceIn = { + z: [[], [], []] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + + traceIn = { + type: 'heatmap', + z: [[1, 2], []] + }; + traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); + + traceIn = { + type: 'heatmap', + z: [[], [1, 2], [1, 2, 3]] + }; + traceOut = Plots.supplyDataDefaults(traceIn, 0, layout); + expect(traceOut.visible).toBe(true); + expect(traceOut.visible).toBe(true); }); - describe('convertColumnXYZ', function() { - var trace; - - function makeMockAxis() { - return { - d2c: function(v) { return v; } - }; - } - - var xa = makeMockAxis(), - ya = makeMockAxis(); - - it('should convert x/y/z columns to z(x,y)', function() { - trace = { - x: [1, 1, 1, 2, 2, 2], - y: [1, 2, 3, 1, 2, 3], - z: [1, 2, 3, 4, 5, 6] - }; - - convertColumnXYZ(trace, xa, ya); - expect(trace.x).toEqual([1, 2]); - expect(trace.y).toEqual([1, 2, 3]); - expect(trace.z).toEqual([[1, 4], [2, 5], [3, 6]]); - }); - - it('should convert x/y/z columns to z(x,y) with uneven dimensions', function() { - trace = { - x: [1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3], - y: [1, 2, 1, 2, 3], - z: [1, 2, 4, 5, 6] - }; - - convertColumnXYZ(trace, xa, ya); - expect(trace.x).toEqual([1, 2]); - expect(trace.y).toEqual([1, 2, 3]); - expect(trace.z).toEqual([[1, 4], [2, 5], [, 6]]); - }); - - it('should convert x/y/z columns to z(x,y) with missing values', function() { - trace = { - x: [1, 1, 2, 2, 2], - y: [1, 2, 1, 2, 3], - z: [1, null, 4, 5, 6] - }; - - convertColumnXYZ(trace, xa, ya); - expect(trace.x).toEqual([1, 2]); - expect(trace.y).toEqual([1, 2, 3]); - expect(trace.z).toEqual([[1, 4], [null, 5], [, 6]]); - }); - - it('should convert x/y/z/text columns to z(x,y) and text(x,y)', function() { - trace = { - x: [1, 1, 1, 2, 2, 2], - y: [1, 2, 3, 1, 2, 3], - z: [1, 2, 3, 4, 5, 6], - text: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] - }; - - convertColumnXYZ(trace, xa, ya); - expect(trace.text).toEqual([['a', 'd'], ['b', 'e'], ['c', 'f']]); - }); - - it('should convert x/y/z columns to z(x,y) with out-of-order data', function() { - /*eslint no-sparse-arrays: 0*/ - - trace = { - x: [ - 50076, -42372, -19260, 3852, 26964, -65484, -42372, -19260, - 3852, 26964, -88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188, - -65484, -42372, -19260, 3852, 26964, 50076, -42372, -19260, 3852, 26964, - -88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188, -88596, -65484, - -42372, -19260, 3852, 26964, 50076, 73188 - ], - y: [ - 51851.8, 77841.4, 77841.4, 77841.4, 77841.4, 51851.8, 51851.8, 51851.8, - 51851.8, 51851.8, -26117, -26117, -26117, -26117, -26117, -26117, -26117, -26117, - -52106.6, -52106.6, -52106.6, -52106.6, -52106.6, -52106.6, -78096.2, -78096.2, - -78096.2, -78096.2, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, - 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2 - ], - z: [ - 4.361856, 4.234497, 4.321701, 4.450315, 4.416136, 4.210373, - 4.32009, 4.246728, 4.293992, 4.316364, 3.908434, 4.433257, 4.364234, 4.308714, 4.275516, - 4.126979, 4.296483, 4.320471, 4.339848, 4.39907, 4.345006, 4.315032, 4.295618, 4.262052, - 4.154291, 4.404264, 4.33847, 4.270931, 4.032226, 4.381492, 4.328922, 4.24046, 4.349151, - 4.202861, 4.256402, 4.28972, 3.956225, 4.337909, 4.31226, 4.259435, 4.146854, 4.235799, - 4.238752, 4.299876 - ] - }; - - convertColumnXYZ(trace, xa, ya); - expect(trace.x).toEqual( - [-88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188]); - expect(trace.y).toEqual( - [-78096.2, -52106.6, -26117, -127.4, 25862.2, 51851.8, 77841.4]); - expect(trace.z).toEqual([ - [,, 4.154291, 4.404264, 4.33847, 4.270931,,, ], - [, 4.339848, 4.39907, 4.345006, 4.315032, 4.295618, 4.262052,, ], - [3.908434, 4.433257, 4.364234, 4.308714, 4.275516, 4.126979, 4.296483, 4.320471], - [4.032226, 4.381492, 4.328922, 4.24046, 4.349151, 4.202861, 4.256402, 4.28972], - [3.956225, 4.337909, 4.31226, 4.259435, 4.146854, 4.235799, 4.238752, 4.299876], - [, 4.210373, 4.32009, 4.246728, 4.293992, 4.316364, 4.361856,, ], - [,, 4.234497, 4.321701, 4.450315, 4.416136,,, ] - ]); - }); + it('should set visible to false when z is non-numeric', function() { + traceIn = { + type: 'heatmap', + z: [['a', 'b'], ['c', 'd']] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); + }); + it('should set visible to false when z isn\'t column not a 2d array', function() { + traceIn = { + x: [1, 1, 1, 2, 2], + y: [1, 2, 3, 1, 2], + z: [1, ['this is considered a column'], 1, 2, 3] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).not.toBe(false); + + traceIn = { + x: [1, 1, 1, 2, 2], + y: [1, 2, 3, 1, 2], + z: [[0], ['this is not considered a column'], 1, ['nor 2d']] + }; + supplyDefaults(traceIn, traceOut, defaultColor, layout); + expect(traceOut.visible).toBe(false); }); }); + +describe('heatmap convertColumnXYZ', function() { + 'use strict'; + + var trace; + + function makeMockAxis() { + return { + d2c: function(v) { return v; } + }; + } + + var xa = makeMockAxis(), + ya = makeMockAxis(); + + it('should convert x/y/z columns to z(x,y)', function() { + trace = { + x: [1, 1, 1, 2, 2, 2], + y: [1, 2, 3, 1, 2, 3], + z: [1, 2, 3, 4, 5, 6] + }; + + convertColumnXYZ(trace, xa, ya); + expect(trace.x).toEqual([1, 2]); + expect(trace.y).toEqual([1, 2, 3]); + expect(trace.z).toEqual([[1, 4], [2, 5], [3, 6]]); + }); + + it('should convert x/y/z columns to z(x,y) with uneven dimensions', function() { + trace = { + x: [1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3], + y: [1, 2, 1, 2, 3], + z: [1, 2, 4, 5, 6] + }; + + convertColumnXYZ(trace, xa, ya); + expect(trace.x).toEqual([1, 2]); + expect(trace.y).toEqual([1, 2, 3]); + expect(trace.z).toEqual([[1, 4], [2, 5], [, 6]]); + }); + + it('should convert x/y/z columns to z(x,y) with missing values', function() { + trace = { + x: [1, 1, 2, 2, 2], + y: [1, 2, 1, 2, 3], + z: [1, null, 4, 5, 6] + }; + + convertColumnXYZ(trace, xa, ya); + expect(trace.x).toEqual([1, 2]); + expect(trace.y).toEqual([1, 2, 3]); + expect(trace.z).toEqual([[1, 4], [null, 5], [, 6]]); + }); + + it('should convert x/y/z/text columns to z(x,y) and text(x,y)', function() { + trace = { + x: [1, 1, 1, 2, 2, 2], + y: [1, 2, 3, 1, 2, 3], + z: [1, 2, 3, 4, 5, 6], + text: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] + }; + + convertColumnXYZ(trace, xa, ya); + expect(trace.text).toEqual([['a', 'd'], ['b', 'e'], ['c', 'f']]); + }); + + it('should convert x/y/z columns to z(x,y) with out-of-order data', function() { + /*eslint no-sparse-arrays: 0*/ + + trace = { + x: [ + 50076, -42372, -19260, 3852, 26964, -65484, -42372, -19260, + 3852, 26964, -88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188, + -65484, -42372, -19260, 3852, 26964, 50076, -42372, -19260, 3852, 26964, + -88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188, -88596, -65484, + -42372, -19260, 3852, 26964, 50076, 73188 + ], + y: [ + 51851.8, 77841.4, 77841.4, 77841.4, 77841.4, 51851.8, 51851.8, 51851.8, + 51851.8, 51851.8, -26117, -26117, -26117, -26117, -26117, -26117, -26117, -26117, + -52106.6, -52106.6, -52106.6, -52106.6, -52106.6, -52106.6, -78096.2, -78096.2, + -78096.2, -78096.2, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, -127.4, + 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2, 25862.2 + ], + z: [ + 4.361856, 4.234497, 4.321701, 4.450315, 4.416136, 4.210373, + 4.32009, 4.246728, 4.293992, 4.316364, 3.908434, 4.433257, 4.364234, 4.308714, 4.275516, + 4.126979, 4.296483, 4.320471, 4.339848, 4.39907, 4.345006, 4.315032, 4.295618, 4.262052, + 4.154291, 4.404264, 4.33847, 4.270931, 4.032226, 4.381492, 4.328922, 4.24046, 4.349151, + 4.202861, 4.256402, 4.28972, 3.956225, 4.337909, 4.31226, 4.259435, 4.146854, 4.235799, + 4.238752, 4.299876 + ] + }; + + convertColumnXYZ(trace, xa, ya); + expect(trace.x).toEqual( + [-88596, -65484, -42372, -19260, 3852, 26964, 50076, 73188]); + expect(trace.y).toEqual( + [-78096.2, -52106.6, -26117, -127.4, 25862.2, 51851.8, 77841.4]); + expect(trace.z).toEqual([ + [,, 4.154291, 4.404264, 4.33847, 4.270931,,, ], + [, 4.339848, 4.39907, 4.345006, 4.315032, 4.295618, 4.262052,, ], + [3.908434, 4.433257, 4.364234, 4.308714, 4.275516, 4.126979, 4.296483, 4.320471], + [4.032226, 4.381492, 4.328922, 4.24046, 4.349151, 4.202861, 4.256402, 4.28972], + [3.956225, 4.337909, 4.31226, 4.259435, 4.146854, 4.235799, 4.238752, 4.299876], + [, 4.210373, 4.32009, 4.246728, 4.293992, 4.316364, 4.361856,, ], + [,, 4.234497, 4.321701, 4.450315, 4.416136,,, ] + ]); + }); +}); From 4d8eeb45b66c5b451e369eff0f2999bddd061cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:54:44 -0400 Subject: [PATCH 3/8] fix toBeCloseArray, - so that it handle case where expected and actual array length differs. --- test/jasmine/assets/custom_matchers.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/jasmine/assets/custom_matchers.js b/test/jasmine/assets/custom_matchers.js index 1e5c52a4678..a132a07708e 100644 --- a/test/jasmine/assets/custom_matchers.js +++ b/test/jasmine/assets/custom_matchers.js @@ -12,7 +12,10 @@ module.exports = { return Math.abs(expected[i] - element) < precision; }); - var passed = tested.indexOf(false) < 0; + var passed = ( + expected.length === actual.length && + tested.indexOf(false) < 0 + ); return { pass: passed, From da10b23afd38eb20c5867d291ee5db9e8018e6f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:55:03 -0400 Subject: [PATCH 4/8] add toCloseTo2DArray custom matcher --- test/jasmine/assets/custom_matchers.js | 60 ++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/test/jasmine/assets/custom_matchers.js b/test/jasmine/assets/custom_matchers.js index a132a07708e..3524a522a2a 100644 --- a/test/jasmine/assets/custom_matchers.js +++ b/test/jasmine/assets/custom_matchers.js @@ -4,9 +4,7 @@ module.exports = { toBeCloseToArray: function() { return { compare: function(actual, expected, precision) { - if(precision !== 0) { - precision = Math.pow(10, -precision) / 2 || 0.005; - } + precision = coercePosition(precision); var tested = actual.map(function(element, i) { return Math.abs(expected[i] - element) < precision; @@ -23,5 +21,59 @@ module.exports = { }; } }; - } + }, + + // toBeCloseTo... but for 2D arrays + toBeCloseTo2DArray: function() { + return { + compare: function(actual, expected, precision) { + precision = coercePosition(precision); + + var passed = true; + + if(expected.length !== actual.length) passed = false; + else { + for(var i = 0; i < expected.length; ++i) { + if(expected[i].length !== actual[i].length) { + passed = false; + break; + } + + for(var j = 0; j < expected[i].length; ++j) { + var isClose = Math.abs(expected[i][j] - actual[i][j]) < precision; + + if(!isClose) { + passed = false; + break; + } + } + } + } + + var message = [ + 'Expected', + arrayToStr(actual.map(arrayToStr)), + 'to be close to', + arrayToStr(expected.map(arrayToStr)) + ].join(' '); + + return { + pass: passed, + message: message + }; + } + }; + }, }; + +function coercePosition(precision) { + if(precision !== 0) { + precision = Math.pow(10, -precision) / 2 || 0.005; + } + + return precision; +} + +function arrayToStr(array) { + return '[ ' + array.join(', ') + ' ]'; +} From b913a5bd44cda9f28b4cea5a076cd24820b6d3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:56:37 -0400 Subject: [PATCH 5/8] make x/y of length 0 or 1 generate correct bricks [fixes #605] --- src/traces/heatmap/calc.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index 4dc2b75f8e8..0db91545f73 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -173,7 +173,9 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { dv, i; - if(Array.isArray(arrayIn) && !isHist && (ax.type !== 'category')) { + var isArrayOfTwoItemsOrMore = Array.isArray(arrayIn) && arrayIn.length > 1; + + if(isArrayOfTwoItemsOrMore && !isHist && (ax.type !== 'category')) { arrayIn = arrayIn.map(ax.d2c); var len = arrayIn.length; @@ -216,7 +218,9 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { } else { dv = dvIn || 1; - if(v0In === undefined) v0 = 0; + + if(Array.isArray(arrayIn) && arrayIn.length === 1) v0 = arrayIn[0]; + else if(v0In === undefined) v0 = v0In; else if(isHist || ax.type === 'category') v0 = v0In; else v0 = ax.d2c(v0In); From cb108dce908377af6fe6816219e664eb3eb9e38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 15:56:48 -0400 Subject: [PATCH 6/8] add calc test for heatmap and contour --- test/jasmine/tests/contour_test.js | 108 ++++++++++++++++++++++++++++ test/jasmine/tests/heatmap_test.js | 109 ++++++++++++++++++++++++++++- 2 files changed, 216 insertions(+), 1 deletion(-) diff --git a/test/jasmine/tests/contour_test.js b/test/jasmine/tests/contour_test.js index 280527be1cb..bd58247a384 100644 --- a/test/jasmine/tests/contour_test.js +++ b/test/jasmine/tests/contour_test.js @@ -1,8 +1,13 @@ var Plots = require('@src/plots/plots'); +var Lib = require('@src/lib'); + var Contour = require('@src/traces/contour'); var makeColorMap = require('@src/traces/contour/make_color_map'); var colorScales = require('@src/components/colorscale/scales'); +var customMatchers = require('../assets/custom_matchers'); + + describe('contour defaults', function() { 'use strict'; @@ -132,3 +137,106 @@ describe('contour makeColorMap', function() { ]); }); }); + +describe('contour calc', function() { + 'use strict'; + + beforeAll(function() { + jasmine.addMatchers(customMatchers); + }); + + function _calc(trace) { + var base = { type: 'contour' }, + trace = Lib.extendFlat({}, base, trace), + gd = { data: [trace] }; + + Plots.supplyDefaults(gd); + var fullTrace = gd._fullData[0]; + + return Contour.calc(gd, fullTrace)[0]; + } + + it('should fill in bricks if x/y not given', function() { + var out = _calc({ + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([0, 1, 2]); + expect(out.y).toBeCloseToArray([0, 1]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should fill in bricks with x0/dx + y0/dy', function() { + var out = _calc({ + z: [[1, 2, 3], [3, 1, 2]], + x0: 10, + dx: 0.5, + y0: -2, + dy: -2 + }); + + expect(out.x).toBeCloseToArray([10, 10.5, 11]); + expect(out.y).toBeCloseToArray([-2, -4]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should convert x/y coordinates into bricks', function() { + var out = _calc({ + x: [1, 2, 3], + y: [2, 6], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([1, 2, 3]); + expect(out.y).toBeCloseToArray([2, 6]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should trim brick-link /y coordinates', function() { + var out = _calc({ + x: [1, 2, 3, 4], + y: [2, 6, 10], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([1, 2, 3]); + expect(out.y).toBeCloseToArray([2, 6]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should handle 1-xy + 1-brick case', function() { + var out = _calc({ + x: [2], + y: [3], + z: [[1]] + }); + + expect(out.x).toBeCloseToArray([2]); + expect(out.y).toBeCloseToArray([3]); + expect(out.z).toBeCloseTo2DArray([[1]]); + }); + + it('should handle 1-xy + multi-brick case', function() { + var out = _calc({ + x: [2], + y: [3], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([2, 3, 4]); + expect(out.y).toBeCloseToArray([3, 4]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should handle 0-xy + multi-brick case', function() { + var out = _calc({ + x: [], + y: [], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([0, 1, 2]); + expect(out.y).toBeCloseToArray([0, 1]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); +}); diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 2b2df917aa3..9a883221a86 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -1,6 +1,10 @@ +var Plots = require('@src/plots/plots'); +var Lib = require('@src/lib'); + var convertColumnXYZ = require('@src/traces/heatmap/convert_column_xyz'); var Heatmap = require('@src/traces/heatmap'); -var Plots = require('@src/plots/plots'); + +var customMatchers = require('../assets/custom_matchers'); describe('heatmap supplyDefaults', function() { @@ -192,3 +196,106 @@ describe('heatmap convertColumnXYZ', function() { ]); }); }); + +describe('heatmap calc', function() { + 'use strict'; + + beforeAll(function() { + jasmine.addMatchers(customMatchers); + }); + + function _calc(trace) { + var base = { type: 'heatmap' }, + trace = Lib.extendFlat({}, base, trace), + gd = { data: [trace] }; + + Plots.supplyDefaults(gd); + var fullTrace = gd._fullData[0]; + + return Heatmap.calc(gd, fullTrace)[0]; + } + + it('should fill in bricks if x/y not given', function() { + var out = _calc({ + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should fill in bricks with x0/dx + y0/dy', function() { + var out = _calc({ + z: [[1, 2, 3], [3, 1, 2]], + x0: 10, + dx: 0.5, + y0: -2, + dy: -2 + }); + + expect(out.x).toBeCloseToArray([9.75, 10.25, 10.75, 11.25]); + expect(out.y).toBeCloseToArray([-1, -3, -5]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should convert x/y coordinates into bricks', function() { + var out = _calc({ + x: [1, 2, 3], + y: [2, 6], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([0.5, 1.5, 2.5, 3.5]); + expect(out.y).toBeCloseToArray([0, 4, 8]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should respect brick-link /y coordinates', function() { + var out = _calc({ + x: [1, 2, 3, 4], + y: [2, 6, 10], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([1, 2, 3, 4]); + expect(out.y).toBeCloseToArray([2, 6, 10]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should handle 1-xy + 1-brick case', function() { + var out = _calc({ + x: [2], + y: [3], + z: [[1]] + }); + + expect(out.x).toBeCloseToArray([1.5, 2.5]); + expect(out.y).toBeCloseToArray([2.5, 3.5]); + expect(out.z).toBeCloseTo2DArray([[1]]); + }); + + it('should handle 1-xy + multi-brick case', function() { + var out = _calc({ + x: [2], + y: [3], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([1.5, 2.5, 3.5, 4.5]); + expect(out.y).toBeCloseToArray([2.5, 3.5, 4.5, 5.5]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); + + it('should handle 0-xy + multi-brick case', function() { + var out = _calc({ + x: [], + y: [], + z: [[1, 2, 3], [3, 1, 2]] + }); + + expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5, 3.5]); + expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); + }); +}); From 35cd1613aa13e47486dafaac346dd59c77ade5e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Wed, 15 Jun 2016 16:11:27 -0400 Subject: [PATCH 7/8] fixups --- test/jasmine/assets/custom_matchers.js | 2 +- test/jasmine/tests/contour_test.js | 4 ++-- test/jasmine/tests/heatmap_test.js | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/jasmine/assets/custom_matchers.js b/test/jasmine/assets/custom_matchers.js index 3524a522a2a..fc1e710bd19 100644 --- a/test/jasmine/assets/custom_matchers.js +++ b/test/jasmine/assets/custom_matchers.js @@ -63,7 +63,7 @@ module.exports = { }; } }; - }, + } }; function coercePosition(precision) { diff --git a/test/jasmine/tests/contour_test.js b/test/jasmine/tests/contour_test.js index bd58247a384..0cc1fd0c1be 100644 --- a/test/jasmine/tests/contour_test.js +++ b/test/jasmine/tests/contour_test.js @@ -145,9 +145,9 @@ describe('contour calc', function() { jasmine.addMatchers(customMatchers); }); - function _calc(trace) { + function _calc(opts) { var base = { type: 'contour' }, - trace = Lib.extendFlat({}, base, trace), + trace = Lib.extendFlat({}, base, opts), gd = { data: [trace] }; Plots.supplyDefaults(gd); diff --git a/test/jasmine/tests/heatmap_test.js b/test/jasmine/tests/heatmap_test.js index 9a883221a86..dae549a81b0 100644 --- a/test/jasmine/tests/heatmap_test.js +++ b/test/jasmine/tests/heatmap_test.js @@ -204,9 +204,9 @@ describe('heatmap calc', function() { jasmine.addMatchers(customMatchers); }); - function _calc(trace) { + function _calc(opts) { var base = { type: 'heatmap' }, - trace = Lib.extendFlat({}, base, trace), + trace = Lib.extendFlat({}, base, opts), gd = { data: [trace] }; Plots.supplyDefaults(gd); @@ -221,7 +221,7 @@ describe('heatmap calc', function() { }); expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); - expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5]); expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); }); @@ -283,7 +283,7 @@ describe('heatmap calc', function() { }); expect(out.x).toBeCloseToArray([1.5, 2.5, 3.5, 4.5]); - expect(out.y).toBeCloseToArray([2.5, 3.5, 4.5, 5.5]); + expect(out.y).toBeCloseToArray([2.5, 3.5, 4.5]); expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); }); @@ -294,8 +294,8 @@ describe('heatmap calc', function() { z: [[1, 2, 3], [3, 1, 2]] }); - expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5, 3.5]); - expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.x).toBeCloseToArray([-0.5, 0.5, 1.5, 2.5]); + expect(out.y).toBeCloseToArray([-0.5, 0.5, 1.5]); expect(out.z).toBeCloseTo2DArray([[1, 2, 3], [3, 1, 2]]); }); }); From f9b5ebda12b47918c88dd754cb452c7f2eb67616 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Mon, 20 Jun 2016 13:53:48 -0400 Subject: [PATCH 8/8] makeBoundArray: fix case where v0In is undefined --- src/traces/heatmap/calc.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/traces/heatmap/calc.js b/src/traces/heatmap/calc.js index 0db91545f73..e8611ccc82e 100644 --- a/src/traces/heatmap/calc.js +++ b/src/traces/heatmap/calc.js @@ -220,7 +220,7 @@ function makeBoundArray(trace, arrayIn, v0In, dvIn, numbricks, ax) { dv = dvIn || 1; if(Array.isArray(arrayIn) && arrayIn.length === 1) v0 = arrayIn[0]; - else if(v0In === undefined) v0 = v0In; + else if(v0In === undefined) v0 = 0; else if(isHist || ax.type === 'category') v0 = v0In; else v0 = ax.d2c(v0In);