Skip to content

Commit 28c2770

Browse files
committed
add support for custom hover label in gl2d
1 parent 6bbfa65 commit 28c2770

File tree

5 files changed

+125
-13
lines changed

5 files changed

+125
-13
lines changed

src/plots/gl2d/scene2d.js

+24-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
'use strict';
1111

12+
var Lib = require('../../lib');
1213
var Registry = require('../../registry');
1314
var Axes = require('../../plots/cartesian/axes');
1415
var Fx = require('../../components/fx');
@@ -633,6 +634,9 @@ proto.draw = function() {
633634
if(parts.indexOf('name') === -1) selection.name = undefined;
634635
}
635636

637+
var trace = this.fullData[selection.trace.index] || {};
638+
var ptNumber = selection.pointIndex;
639+
636640
Fx.loneHover({
637641
x: selection.screenCoord[0],
638642
y: selection.screenCoord[1],
@@ -641,7 +645,11 @@ proto.draw = function() {
641645
zLabel: selection.traceCoord[2],
642646
text: selection.textLabel,
643647
name: selection.name,
644-
color: selection.color
648+
color: this.castHoverOption(trace, ptNumber, 'bgcolor') || selection.color,
649+
borderColor: this.castHoverOption(trace, ptNumber, 'bordercolor'),
650+
fontFamily: this.castHoverOption(trace, ptNumber, 'font.family'),
651+
fontSize: this.castHoverOption(trace, ptNumber, 'font.size'),
652+
fontColor: this.castHoverOption(trace, ptNumber, 'font.color')
645653
}, {
646654
container: this.svgContainer
647655
});
@@ -667,3 +675,18 @@ proto.hoverFormatter = function(axisName, val) {
667675
var axis = this[axisName];
668676
return Axes.tickText(axis, axis.c2l(val), 'hover').text;
669677
};
678+
679+
proto.castHoverOption = function(trace, ptNumber, attr) {
680+
var labelOpts = trace.hoverlabel || {};
681+
var val = Lib.nestedProperty(labelOpts, attr).get();
682+
683+
if(Array.isArray(val)) {
684+
if(Array.isArray(ptNumber) && Array.isArray(val[ptNumber[0]])) {
685+
return val[ptNumber[0]][ptNumber[1]];
686+
} else {
687+
return val[ptNumber];
688+
}
689+
} else {
690+
return val;
691+
}
692+
};

src/traces/contourgl/convert.js

+1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ proto.handlePick = function(pickResult) {
8585
proto.update = function(fullTrace, calcTrace) {
8686
var calcPt = calcTrace[0];
8787

88+
this.index = fullTrace.index;
8889
this.name = fullTrace.name;
8990
this.hoverinfo = fullTrace.hoverinfo;
9091

src/traces/heatmapgl/convert.js

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ proto.handlePick = function(pickResult) {
7171
proto.update = function(fullTrace, calcTrace) {
7272
var calcPt = calcTrace[0];
7373

74+
this.index = fullTrace.index;
7475
this.name = fullTrace.name;
7576
this.hoverinfo = fullTrace.hoverinfo;
7677

src/traces/pointcloud/convert.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ function Pointcloud(scene, uid) {
4848
var proto = Pointcloud.prototype;
4949

5050
proto.handlePick = function(pickResult) {
51-
5251
var index = this.idToIndex[pickResult.pointId];
5352

5453
// prefer the readout from XY, if present
@@ -69,7 +68,7 @@ proto.handlePick = function(pickResult) {
6968
};
7069

7170
proto.update = function(options) {
72-
71+
this.index = options.index;
7372
this.textLabels = options.text;
7473
this.name = options.name;
7574
this.hoverinfo = options.hoverinfo;

test/jasmine/tests/gl2d_click_test.js

+98-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
var Plotly = require('@lib/index');
22
var Lib = require('@src/lib');
33

4+
var d3 = require('d3');
45
var createGraphDiv = require('../assets/create_graph_div');
56
var destroyGraphDiv = require('../assets/destroy_graph_div');
67
var customMatchers = require('../assets/custom_matchers');
@@ -27,7 +28,7 @@ var mock3 = {
2728
[10, 10.625, 12.5, 15.625, 20],
2829
[5.625, 6.25, 8.125, 11.25, 15.625],
2930
[2.5, 3.125, 5, 8.125, 12.5],
30-
[0.625, 1.25, 3.125, 6.25, 10.625],
31+
[0.625, 1.25, 3.125, 20, 10.625],
3132
[0, 0.625, 2.5, 5.625, 10]
3233
],
3334
colorscale: 'Jet',
@@ -128,6 +129,22 @@ describe('Test hover and click interactions', function() {
128129
expect(pt.pointNumber).toEqual(expected.pointNumber, 'point number');
129130
}
130131

132+
function assertHoverLabelStyle(sel, expected) {
133+
if(sel.node() === null) {
134+
expect(expected.noHoverLabel).toBe(true);
135+
return;
136+
}
137+
138+
var path = sel.select('path');
139+
expect(path.style('fill')).toEqual(expected.bgColor, 'bgcolor');
140+
expect(path.style('stroke')).toEqual(expected.borderColor, 'bordercolor');
141+
142+
var text = sel.select('text.nums');
143+
expect(parseInt(text.style('font-size'))).toEqual(expected.fontSize, 'font.size');
144+
expect(text.style('font-family').split(',')[0]).toEqual(expected.fontFamily, 'font.family');
145+
expect(text.style('fill')).toEqual(expected.fontColor, 'font.color');
146+
}
147+
131148
// returns basic hover/click/unhover runner for one xy position
132149
function makeRunner(pos, expected, opts) {
133150
opts = opts || {};
@@ -144,6 +161,7 @@ describe('Test hover and click interactions', function() {
144161
.then(_hover)
145162
.then(function(eventData) {
146163
assertEventData(eventData, expected);
164+
assertHoverLabelStyle(d3.select('g.hovertext'), expected);
147165
})
148166
.then(_click)
149167
.then(function(eventData) {
@@ -171,11 +189,28 @@ describe('Test hover and click interactions', function() {
171189

172190
it('should output correct event data for scattergl', function(done) {
173191
var _mock = Lib.extendDeep({}, mock1);
192+
193+
_mock.layout.hoverlabel = {
194+
font: {
195+
size: 20,
196+
color: 'yellow'
197+
}
198+
};
199+
_mock.data[0].hoverlabel = {
200+
bgcolor: 'blue',
201+
bordercolor: _mock.data[0].x.map(function(_, i) { return i % 2 ? 'red' : 'green'; })
202+
};
203+
174204
var run = makeRunner([655, 317], {
175205
x: 15.772,
176206
y: 0.387,
177207
curveNumber: 0,
178-
pointNumber: 33
208+
pointNumber: 33,
209+
bgColor: 'rgb(0, 0, 255)',
210+
borderColor: 'rgb(255, 0, 0)',
211+
fontSize: 20,
212+
fontFamily: 'Arial',
213+
fontColor: 'rgb(255, 255, 0)'
179214
});
180215

181216
Plotly.plot(gd, _mock)
@@ -192,7 +227,8 @@ describe('Test hover and click interactions', function() {
192227
x: 15.772,
193228
y: 0.387,
194229
curveNumber: 0,
195-
pointNumber: 33
230+
pointNumber: 33,
231+
noHoverLabel: true
196232
});
197233

198234
Plotly.plot(gd, _mock)
@@ -204,11 +240,21 @@ describe('Test hover and click interactions', function() {
204240
it('should output correct event data for pointcloud', function(done) {
205241
var _mock = Lib.extendDeep({}, mock2);
206242

243+
_mock.layout.hoverlabel = { font: {size: 8} };
244+
_mock.data[2].hoverlabel = {
245+
bgcolor: ['red', 'green', 'blue']
246+
};
247+
207248
var run = makeRunner([540, 150], {
208249
x: 4.5,
209250
y: 9,
210251
curveNumber: 2,
211-
pointNumber: 1
252+
pointNumber: 1,
253+
bgColor: 'rgb(0, 128, 0)',
254+
borderColor: 'rgb(255, 255, 255)',
255+
fontSize: 8,
256+
fontFamily: 'Arial',
257+
fontColor: 'rgb(255, 255, 255)'
212258
});
213259

214260
Plotly.plot(gd, _mock)
@@ -221,11 +267,24 @@ describe('Test hover and click interactions', function() {
221267
var _mock = Lib.extendDeep({}, mock3);
222268
_mock.data[0].type = 'heatmapgl';
223269

270+
_mock.data[0].hoverlabel = {
271+
font: { size: _mock.data[0].z }
272+
};
273+
274+
_mock.layout.hoverlabel = {
275+
font: { family: 'Roboto' }
276+
};
277+
224278
var run = makeRunner([540, 150], {
225279
x: 3,
226280
y: 3,
227281
curveNumber: 0,
228-
pointNumber: [3, 3]
282+
pointNumber: [3, 3],
283+
bgColor: 'rgb(68, 68, 68)',
284+
borderColor: 'rgb(255, 255, 255)',
285+
fontSize: 20,
286+
fontFamily: 'Roboto',
287+
fontColor: 'rgb(255, 255, 255)'
229288
}, {
230289
noUnHover: true
231290
});
@@ -243,15 +302,25 @@ describe('Test hover and click interactions', function() {
243302
x: 8,
244303
y: 18,
245304
curveNumber: 2,
246-
pointNumber: 0
305+
pointNumber: 0,
306+
bgColor: 'rgb(44, 160, 44)',
307+
borderColor: 'rgb(255, 255, 255)',
308+
fontSize: 13,
309+
fontFamily: 'Arial',
310+
fontColor: 'rgb(255, 255, 255)'
247311
});
248312

249313
// after the restyle, autorange changes the y range
250314
var run2 = makeRunner([435, 106], {
251315
x: 8,
252316
y: 18,
253317
curveNumber: 2,
254-
pointNumber: 0
318+
pointNumber: 0,
319+
bgColor: 'rgb(255, 127, 14)',
320+
borderColor: 'rgb(68, 68, 68)',
321+
fontSize: 13,
322+
fontFamily: 'Arial',
323+
fontColor: 'rgb(68, 68, 68)'
255324
});
256325

257326
Plotly.plot(gd, _mock)
@@ -274,7 +343,12 @@ describe('Test hover and click interactions', function() {
274343
x: 8,
275344
y: 18,
276345
curveNumber: 2,
277-
pointNumber: 0
346+
pointNumber: 0,
347+
bgColor: 'rgb(44, 160, 44)',
348+
borderColor: 'rgb(255, 255, 255)',
349+
fontSize: 13,
350+
fontFamily: 'Arial',
351+
fontColor: 'rgb(255, 255, 255)'
278352
});
279353

280354
// after the restyle, autorange changes the x AND y ranges
@@ -285,7 +359,12 @@ describe('Test hover and click interactions', function() {
285359
x: 8,
286360
y: 18,
287361
curveNumber: 2,
288-
pointNumber: 0
362+
pointNumber: 0,
363+
bgColor: 'rgb(255, 127, 14)',
364+
borderColor: 'rgb(68, 68, 68)',
365+
fontSize: 13,
366+
fontFamily: 'Arial',
367+
fontColor: 'rgb(68, 68, 68)'
289368
});
290369

291370
Plotly.plot(gd, _mock)
@@ -301,11 +380,20 @@ describe('Test hover and click interactions', function() {
301380
it('should output correct event data contourgl', function(done) {
302381
var _mock = Lib.extendDeep({}, mock3);
303382

383+
_mock.data[0].hoverlabel = {
384+
font: { size: _mock.data[0].z }
385+
};
386+
304387
var run = makeRunner([540, 150], {
305388
x: 3,
306389
y: 3,
307390
curveNumber: 0,
308-
pointNumber: [3, 3]
391+
pointNumber: [3, 3],
392+
bgColor: 'rgb(68, 68, 68)',
393+
borderColor: 'rgb(255, 255, 255)',
394+
fontSize: 20,
395+
fontFamily: 'Arial',
396+
fontColor: 'rgb(255, 255, 255)'
309397
}, {
310398
noUnHover: true
311399
});

0 commit comments

Comments
 (0)