Skip to content

Commit a7e2f32

Browse files
committed
extend event data and bin label improvements to histogram2d
1 parent 8d36d81 commit a7e2f32

File tree

4 files changed

+102
-13
lines changed

4 files changed

+102
-13
lines changed

src/traces/heatmap/calc.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ module.exports = function calc(gd, trace) {
4040
y0,
4141
dy,
4242
z,
43-
i;
43+
i,
44+
binned;
4445

4546
// cancel minimum tick spacings (only applies to bars and boxes)
4647
xa._minDtick = 0;
4748
ya._minDtick = 0;
4849

4950
if(isHist) {
50-
var binned = histogram2dCalc(gd, trace);
51+
binned = histogram2dCalc(gd, trace);
5152
x = binned.x;
5253
x0 = binned.x0;
5354
dx = binned.dx;
@@ -128,6 +129,12 @@ module.exports = function calc(gd, trace) {
128129

129130
var cd0 = {x: xArray, y: yArray, z: z, text: trace.text};
130131

132+
if(isHist) {
133+
cd0.xRanges = binned.xRanges;
134+
cd0.yRanges = binned.yRanges;
135+
cd0.pts = binned.pts;
136+
}
137+
131138
// auto-z and autocolorscale if applicable
132139
colorscaleCalc(trace, z, '', 'z');
133140

src/traces/histogram2d/calc.js

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var binFunctions = require('../histogram/bin_functions');
1616
var normFunctions = require('../histogram/norm_functions');
1717
var doAvg = require('../histogram/average');
1818
var cleanBins = require('../histogram/clean_bins');
19+
var getBinSpanLabelRound = require('../histogram/bin_label_vals');
1920

2021

2122
module.exports = function calc(gd, trace) {
@@ -30,7 +31,7 @@ module.exports = function calc(gd, trace) {
3031
var xc2r = function(v) { return xa.c2r(v, 0, xcalendar); };
3132
var yc2r = function(v) { return ya.c2r(v, 0, ycalendar); };
3233

33-
var i, n, m;
34+
var i, j, n, m;
3435

3536
var serieslen = Math.min(x.length, y.length);
3637
if(x.length > serieslen) x.splice(serieslen, x.length - serieslen);
@@ -46,10 +47,13 @@ module.exports = function calc(gd, trace) {
4647
var zerocol = [];
4748
var nonuniformBinsX = (typeof(trace.xbins.size) === 'string');
4849
var nonuniformBinsY = (typeof(trace.ybins.size) === 'string');
49-
var xbins = nonuniformBinsX ? [] : trace.xbins;
50-
var ybins = nonuniformBinsY ? [] : trace.ybins;
50+
var xEdges = [];
51+
var yEdges = [];
52+
var xbins = nonuniformBinsX ? xEdges : trace.xbins;
53+
var ybins = nonuniformBinsY ? yEdges : trace.ybins;
5154
var total = 0;
5255
var counts = [];
56+
var inputPoints = [];
5357
var norm = trace.histnorm;
5458
var func = trace.histfunc;
5559
var densitynorm = (norm.indexOf('density') !== -1);
@@ -83,10 +87,10 @@ module.exports = function calc(gd, trace) {
8387

8488
for(i = binStart; i < binEnd; i = Axes.tickIncrement(i, binSpec.size, false, xcalendar)) {
8589
onecol.push(sizeinit);
86-
if(nonuniformBinsX) xbins.push(i);
90+
xEdges.push(i);
8791
if(doavg) zerocol.push(0);
8892
}
89-
if(nonuniformBinsX) xbins.push(i);
93+
xEdges.push(i);
9094

9195
var nx = onecol.length;
9296
var x0c = xr2c(trace.xbins.start);
@@ -100,10 +104,13 @@ module.exports = function calc(gd, trace) {
100104

101105
for(i = binStart; i < binEnd; i = Axes.tickIncrement(i, binSpec.size, false, ycalendar)) {
102106
z.push(onecol.slice());
103-
if(nonuniformBinsY) ybins.push(i);
107+
yEdges.push(i);
108+
var ipCol = new Array(nx);
109+
for(j = 0; j < nx; j++) ipCol[j] = [];
110+
inputPoints.push(ipCol);
104111
if(doavg) counts.push(zerocol.slice());
105112
}
106-
if(nonuniformBinsY) ybins.push(i);
113+
yEdges.push(i);
107114

108115
var ny = z.length;
109116
var y0c = yr2c(trace.ybins.start);
@@ -121,11 +128,36 @@ module.exports = function calc(gd, trace) {
121128
if(!nonuniformBinsY && ya.type === 'date') ybins = binsToCalc(yr2c, ybins);
122129

123130
// put data into bins
131+
var uniqueValsPerX = true;
132+
var uniqueValsPerY = true;
133+
var xVals = new Array(nx);
134+
var yVals = new Array(ny);
135+
var xGapLow = Infinity;
136+
var xGapHigh = Infinity;
137+
var yGapLow = Infinity;
138+
var yGapHigh = Infinity;
124139
for(i = 0; i < serieslen; i++) {
125-
n = Lib.findBin(x[i], xbins);
126-
m = Lib.findBin(y[i], ybins);
140+
var xi = x[i];
141+
var yi = y[i];
142+
n = Lib.findBin(xi, xbins);
143+
m = Lib.findBin(yi, ybins);
127144
if(n >= 0 && n < nx && m >= 0 && m < ny) {
128145
total += binfunc(n, i, z[m], rawCounterData, counts[m]);
146+
inputPoints[m][n].push(i);
147+
148+
if(uniqueValsPerX) {
149+
if(xVals[n] === undefined) xVals[n] = xi;
150+
else if(xVals[n] !== xi) uniqueValsPerX = false;
151+
}
152+
if(uniqueValsPerY) {
153+
if(yVals[n] === undefined) yVals[n] = yi;
154+
else if(yVals[n] !== yi) uniqueValsPerY = false;
155+
}
156+
157+
xGapLow = Math.min(xGapLow, xi - xEdges[n]);
158+
xGapHigh = Math.min(xGapHigh, xEdges[n + 1] - xi);
159+
yGapLow = Math.min(yGapLow, yi - yEdges[m]);
160+
yGapHigh = Math.min(yGapHigh, yEdges[m + 1] - yi);
129161
}
130162
}
131163
// normalize, if needed
@@ -138,12 +170,15 @@ module.exports = function calc(gd, trace) {
138170

139171
return {
140172
x: x,
173+
xRanges: getRanges(xEdges, uniqueValsPerX && xVals, xGapLow, xGapHigh, xa, xcalendar),
141174
x0: x0,
142175
dx: dx,
143176
y: y,
177+
yRanges: getRanges(yEdges, uniqueValsPerY && yVals, yGapLow, yGapHigh, ya, ycalendar),
144178
y0: y0,
145179
dy: dy,
146-
z: z
180+
z: z,
181+
pts: inputPoints
147182
};
148183
};
149184

@@ -195,3 +230,17 @@ function binsToCalc(r2c, bins) {
195230
size: bins.size
196231
};
197232
}
233+
234+
function getRanges(edges, uniqueVals, gapLow, gapHigh, ax, calendar) {
235+
var i;
236+
var len = edges.length - 1;
237+
var out = new Array(len);
238+
if(uniqueVals) {
239+
for(i = 0; i < len; i++) out[i] = [uniqueVals[i], uniqueVals[i]];
240+
}
241+
else {
242+
var roundFn = getBinSpanLabelRound(gapLow, gapHigh, edges, ax, calendar);
243+
for(i = 0; i < len; i++) out[i] = [roundFn(edges[i]), roundFn(edges[i + 1], true)];
244+
}
245+
return out;
246+
}

src/traces/histogram2d/hover.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* Copyright 2012-2017, 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 heatmapHover = require('../heatmap/hover');
13+
14+
module.exports = function hoverPoints(pointData, xval, yval, hovermode, contour) {
15+
var pts = heatmapHover(pointData, xval, yval, hovermode, contour);
16+
17+
if(!pts) return;
18+
19+
pointData = pts[0];
20+
var indices = pointData.index;
21+
var ny = indices[0];
22+
var nx = indices[1];
23+
var cd0 = pointData.cd[0];
24+
25+
pointData.xLabelVal0 = cd0.xRanges[nx][0];
26+
pointData.xLabelVal1 = cd0.xRanges[nx][1];
27+
pointData.yLabelVal0 = cd0.yRanges[ny][0];
28+
pointData.yLabelVal1 = cd0.yRanges[ny][1];
29+
pointData.pts = cd0.pts[ny][nx];
30+
31+
return pts;
32+
};

src/traces/histogram2d/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ Histogram2D.calc = require('../heatmap/calc');
1717
Histogram2D.plot = require('../heatmap/plot');
1818
Histogram2D.colorbar = require('../heatmap/colorbar');
1919
Histogram2D.style = require('../heatmap/style');
20-
Histogram2D.hoverPoints = require('../heatmap/hover');
20+
Histogram2D.hoverPoints = require('./hover');
21+
Histogram2D.eventData = require('../histogram/event_data');
2122

2223
Histogram2D.moduleType = 'trace';
2324
Histogram2D.name = 'histogram2d';

0 commit comments

Comments
 (0)