Skip to content

Commit 1e923c9

Browse files
committed
break up heatmap index:
- the supply-defaults, calc, plot, style and hoverPoints steps each get a file of their own. - helpers convertColumnXYZ, hasColumns and maxRowLength are now modules required into module files.
1 parent 53343bd commit 1e923c9

File tree

10 files changed

+1177
-1038
lines changed

10 files changed

+1177
-1038
lines changed

src/traces/heatmap/calc.js

Lines changed: 431 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var Lib = require('../../lib');
13+
14+
15+
module.exports = function convertColumnXYZ(trace, xa, ya) {
16+
var xCol = trace.x.slice(),
17+
yCol = trace.y.slice(),
18+
zCol = trace.z,
19+
textCol = trace.text,
20+
colLen = Math.min(xCol.length, yCol.length, zCol.length),
21+
hasColumnText = (textCol!==undefined && !Array.isArray(textCol[0]));
22+
23+
var i;
24+
25+
if(colLen < xCol.length) xCol = xCol.slice(0, colLen);
26+
if(colLen < yCol.length) yCol = yCol.slice(0, colLen);
27+
28+
for(i = 0; i < colLen; i++) {
29+
xCol[i] = xa.d2c(xCol[i]);
30+
yCol[i] = ya.d2c(yCol[i]);
31+
}
32+
33+
var xColdv = Lib.distinctVals(xCol),
34+
x = xColdv.vals,
35+
yColdv = Lib.distinctVals(yCol),
36+
y = yColdv.vals,
37+
z = Lib.init2dArray(y.length, x.length);
38+
39+
var ix, iy, text;
40+
41+
if(hasColumnText) text = Lib.init2dArray(y.length, x.length);
42+
43+
for(i = 0; i < colLen; i++) {
44+
ix = Lib.findBin(xCol[i] + xColdv.minDiff / 2, x);
45+
iy = Lib.findBin(yCol[i] + yColdv.minDiff / 2, y);
46+
47+
z[iy][ix] = zCol[i];
48+
if(hasColumnText) text[iy][ix] = textCol[i];
49+
}
50+
51+
trace.x = x;
52+
trace.y = y;
53+
trace.z = z;
54+
if(hasColumnText) trace.text = text;
55+
};
56+
57+

src/traces/heatmap/defaults.js

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var isNumeric = require('fast-isnumeric');
13+
14+
var Plotly = require('../../plotly');
15+
var Plots = require('../../plots/plots');
16+
var Lib = require('../../lib');
17+
var Colorscale = require('../../components/colorscale');
18+
19+
var attributes = require('./attributes');
20+
var hasColumns = require('./has_columns');
21+
22+
23+
module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
24+
var isContour = Plots.traceIs(traceOut, 'contour');
25+
26+
function coerce(attr, dflt) {
27+
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
28+
}
29+
30+
if(!isContour) coerce('zsmooth');
31+
32+
if(Plots.traceIs(traceOut, 'histogram')) {
33+
// x, y, z, marker.color, and x0, dx, y0, dy are coerced
34+
// in Histogram.supplyDefaults
35+
// (along with histogram-specific attributes)
36+
Plotly.Histogram.supplyDefaults(traceIn, traceOut);
37+
if(traceOut.visible === false) return;
38+
}
39+
else {
40+
var len = handleXYZDefaults(traceIn, traceOut, coerce);
41+
if(!len) {
42+
traceOut.visible = false;
43+
return;
44+
}
45+
46+
coerce('text');
47+
48+
var _hasColumns = hasColumns(traceOut);
49+
50+
if(!_hasColumns) coerce('transpose');
51+
coerce('connectgaps', _hasColumns &&
52+
(isContour || traceOut.zsmooth !== false));
53+
}
54+
55+
if(!isContour || (traceOut.contours || {}).coloring!=='none') {
56+
Colorscale.handleDefaults(
57+
traceIn, traceOut, layout, coerce, {prefix: '', cLetter: 'z'}
58+
);
59+
}
60+
};
61+
62+
function handleXYZDefaults(traceIn, traceOut, coerce) {
63+
var z = coerce('z');
64+
var x, y;
65+
66+
if(z===undefined || !z.length) return 0;
67+
68+
if(hasColumns(traceIn)) {
69+
x = coerce('x');
70+
y = coerce('y');
71+
72+
// column z must be accompanied by 'x' and 'y' arrays
73+
if(!x || !y) return 0;
74+
}
75+
else {
76+
x = coordDefaults('x', coerce);
77+
y = coordDefaults('y', coerce);
78+
79+
// TODO put z validation elsewhere
80+
if(!isValidZ(z)) return 0;
81+
}
82+
83+
return traceOut.z.length;
84+
}
85+
86+
function coordDefaults(coordStr, coerce) {
87+
var coord = coerce(coordStr),
88+
coordType = coord ?
89+
coerce(coordStr + 'type', 'array') :
90+
'scaled';
91+
92+
if(coordType === 'scaled') {
93+
coerce(coordStr + '0');
94+
coerce('d' + coordStr);
95+
}
96+
97+
return coord;
98+
}
99+
100+
function isValidZ(z) {
101+
var allRowsAreArrays = true,
102+
oneRowIsFilled = false,
103+
hasOneNumber = false,
104+
zi;
105+
106+
/*
107+
* Without this step:
108+
*
109+
* hasOneNumber = false breaks contour but not heatmap
110+
* allRowsAreArrays = false breaks contour but not heatmap
111+
* oneRowIsFilled = false breaks both
112+
*/
113+
114+
for(var i = 0; i < z.length; i++) {
115+
zi = z[i];
116+
if(!Array.isArray(zi)) {
117+
allRowsAreArrays = false;
118+
break;
119+
}
120+
if(zi.length > 0) oneRowIsFilled = true;
121+
for(var j = 0; j < zi.length; j++) {
122+
if(isNumeric(zi[j])) {
123+
hasOneNumber = true;
124+
break;
125+
}
126+
}
127+
}
128+
129+
return (allRowsAreArrays && oneRowIsFilled && hasOneNumber);
130+
}

src/traces/heatmap/has_columns.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
module.exports = function(trace) {
13+
return !Array.isArray(trace.z[0]);
14+
};

src/traces/heatmap/hover.js

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Copyright 2012-2015, Plotly, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
10+
'use strict';
11+
12+
var Plotly = require('../../plotly');
13+
var Lib = require('../../lib');
14+
15+
16+
module.exports = function hoverPoints(pointData, xval, yval, hovermode, contour) {
17+
// never let a heatmap override another type as closest point
18+
if(pointData.distance < Plotly.Fx.MAXDIST) return;
19+
20+
var cd0 = pointData.cd[0],
21+
trace = cd0.trace,
22+
xa = pointData.xa,
23+
ya = pointData.ya,
24+
x = cd0.x,
25+
y = cd0.y,
26+
z = cd0.z,
27+
zmask = cd0.zmask,
28+
x2 = x,
29+
y2 = y,
30+
xl,
31+
yl,
32+
nx,
33+
ny;
34+
if(pointData.index!==false) {
35+
try {
36+
nx = Math.round(pointData.index[1]);
37+
ny = Math.round(pointData.index[0]);
38+
}
39+
catch(e) {
40+
console.log('Error hovering on heatmap, ' +
41+
'pointNumber must be [row,col], found:', pointData.index);
42+
return;
43+
}
44+
if(nx<0 || nx>=z[0].length || ny<0 || ny>z.length) {
45+
return;
46+
}
47+
}
48+
else if(Plotly.Fx.inbox(xval-x[0], xval-x[x.length-1])>Plotly.Fx.MAXDIST ||
49+
Plotly.Fx.inbox(yval-y[0], yval-y[y.length-1])>Plotly.Fx.MAXDIST) {
50+
return;
51+
}
52+
else {
53+
if(contour) {
54+
x2 = [2*x[0]-x[1]];
55+
for(var i2=1; i2<x.length; i2++) {
56+
x2.push((x[i2]+x[i2-1])/2);
57+
}
58+
x2.push([2*x[x.length-1]-x[x.length-2]]);
59+
60+
y2 = [2*y[0]-y[1]];
61+
for(i2=1; i2<y.length; i2++) {
62+
y2.push((y[i2]+y[i2-1])/2);
63+
}
64+
y2.push([2*y[y.length-1]-y[y.length-2]]);
65+
}
66+
nx = Math.max(0,Math.min(x2.length-2, Lib.findBin(xval,x2)));
67+
ny = Math.max(0,Math.min(y2.length-2, Lib.findBin(yval,y2)));
68+
}
69+
var x0 = xa.c2p(x[nx]),
70+
x1 = xa.c2p(x[nx+1]),
71+
y0 = ya.c2p(y[ny]),
72+
y1 = ya.c2p(y[ny+1]);
73+
if(contour) {
74+
x1=x0;
75+
xl=x[nx];
76+
y1=y0;
77+
yl=y[ny];
78+
}
79+
else {
80+
xl = (x[nx]+x[nx+1])/2;
81+
yl = (y[ny]+y[ny+1])/2;
82+
if(trace.zsmooth) {
83+
x0=x1=(x0+x1)/2;
84+
y0=y1=(y0+y1)/2;
85+
}
86+
}
87+
88+
var zVal = z[ny][nx];
89+
if(zmask && !zmask[ny][nx]) zVal = undefined;
90+
91+
var text;
92+
if(Array.isArray(trace.text) && Array.isArray(trace.text[ny])) {
93+
text = trace.text[ny][nx];
94+
}
95+
96+
return [Lib.extendFlat(pointData, {
97+
index: [ny, nx],
98+
// never let a 2D override 1D type as closest point
99+
distance: Plotly.Fx.MAXDIST+10,
100+
x0: x0,
101+
x1: x1,
102+
y0: y0,
103+
y1: y1,
104+
xLabelVal: xl,
105+
yLabelVal: yl,
106+
zLabelVal: zVal,
107+
text: text
108+
})];
109+
};

0 commit comments

Comments
 (0)