Skip to content

Commit ea34d6c

Browse files
committed
add hovertemplate to box/violin points
1 parent 609104d commit ea34d6c

File tree

7 files changed

+113
-2
lines changed

7 files changed

+113
-2
lines changed

Diff for: src/traces/box/attributes.js

+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
var scatterAttrs = require('../scatter/attributes');
1212
var barAttrs = require('../bar/attributes');
1313
var colorAttrs = require('../../components/color/attributes');
14+
var hovertemplateAttrs = require('../../components/fx/hovertemplate_attributes');
1415
var extendFlat = require('../../lib/extend').extendFlat;
1516

1617
var scatterMarkerAttrs = scatterAttrs.marker;
@@ -76,6 +77,11 @@ module.exports = {
7677
hovertext: extendFlat({}, scatterAttrs.hovertext, {
7778
description: 'Same as `text`.'
7879
}),
80+
hovertemplate: hovertemplateAttrs({
81+
description: [
82+
'N.B. This only has an effect when hovering on points.'
83+
].join(' ')
84+
}),
7985
whiskerwidth: {
8086
valType: 'number',
8187
min: 0,

Diff for: src/traces/box/defaults.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,10 @@ function handlePointsDefaults(traceIn, traceOut, coerce, opts) {
105105
delete traceOut.marker;
106106
}
107107

108-
coerce('hoveron');
108+
var hoveron = coerce('hoveron');
109+
if(hoveron === 'all' || hoveron.indexOf('points') !== -1) {
110+
coerce('hovertemplate');
111+
}
109112

110113
Lib.coerceSelectionMarkerOpacity(traceOut, coerce);
111114
}

Diff for: src/traces/box/hover.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,15 @@ function hoverOnBoxes(pointData, xval, yval, hovermode) {
176176
if(attr === 'mean' && ('sd' in di) && trace.boxmean === 'sd') {
177177
pointData2[vLetter + 'err'] = di.sd;
178178
}
179+
179180
// only keep name and spikes on the first item (median)
180181
pointData.name = '';
181182
pointData.spikeDistance = undefined;
182183
pointData[spikePosAttr] = undefined;
183184

185+
// no hovertemplate support yet
186+
pointData2.hovertemplate = false;
187+
184188
closeBoxData.push(pointData2);
185189
}
186190

@@ -242,7 +246,8 @@ function hoverOnPoints(pointData, xval, yval) {
242246
x1: xc + rad,
243247
y0: yc - rad,
244248
y1: yc + rad,
245-
spikeDistance: pointData.distance
249+
spikeDistance: pointData.distance,
250+
hovertemplate: trace.hovertemplate
246251
});
247252

248253
var pa;

Diff for: src/traces/violin/attributes.js

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ module.exports = {
147147
marker: boxAttrs.marker,
148148
text: boxAttrs.text,
149149
hovertext: boxAttrs.hovertext,
150+
hovertemplate: boxAttrs.hovertemplate,
150151

151152
box: {
152153
visible: {

Diff for: src/traces/violin/hover.js

+3
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, hoverLay
7171
closeBoxData[0].spikeDistance = undefined;
7272
closeBoxData[0][spikePosAttr] = undefined;
7373

74+
// no hovertemplate support yet
75+
kdePointData.hovertemplate = false;
76+
7477
closeData.push(kdePointData);
7578

7679
violinLineAttrs = {stroke: pointData.color};

Diff for: test/jasmine/tests/box_test.js

+47
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,40 @@ describe('Test boxes supplyDefaults', function() {
152152
expect(traceOut.text).toBeDefined();
153153
});
154154

155+
describe('should not coerce hovertemplate when *hoveron* does not contains *points* flag', function() {
156+
var ht = '--- %{y}';
157+
158+
it('- case hoveron:points', function() {
159+
traceIn = {
160+
y: [1, 1, 2],
161+
hoveron: 'points',
162+
hovertemplate: ht
163+
};
164+
supplyDefaults(traceIn, traceOut, defaultColor, {});
165+
expect(traceOut.hovertemplate).toBe(ht);
166+
});
167+
168+
it('- case hoveron:points+boxes', function() {
169+
traceIn = {
170+
y: [1, 1, 2],
171+
hoveron: 'points+boxes',
172+
hovertemplate: ht
173+
};
174+
supplyDefaults(traceIn, traceOut, defaultColor, {});
175+
expect(traceOut.hovertemplate).toBe(ht);
176+
});
177+
178+
it('- case hoveron:boxes', function() {
179+
traceIn = {
180+
y: [1, 1, 2],
181+
hoveron: 'boxes',
182+
hovertemplate: ht
183+
};
184+
supplyDefaults(traceIn, traceOut, defaultColor, {});
185+
expect(traceOut.hovertemplate).toBe(undefined);
186+
});
187+
});
188+
155189
it('should not include alignementgroup/offsetgroup when boxmode is not *group*', function() {
156190
var gd = {
157191
data: [{type: 'box', y: [1], alignmentgroup: 'a', offsetgroup: '1'}],
@@ -391,6 +425,19 @@ describe('Test box hover:', function() {
391425
pos: [202, 335],
392426
nums: '(2, 13.1)',
393427
name: ''
428+
}, {
429+
desc: 'with hovertemplate for points',
430+
patch: function(fig) {
431+
fig.data.forEach(function(trace) {
432+
trace.boxpoints = 'all';
433+
trace.hoveron = 'points';
434+
trace.hovertemplate = '%{y}<extra>pt #%{pointNumber}</extra>';
435+
});
436+
fig.layout.hovermode = 'closest';
437+
return fig;
438+
},
439+
nums: '0.6',
440+
name: 'pt #0'
394441
}].forEach(function(specs) {
395442
it('should generate correct hover labels ' + specs.desc, function(done) {
396443
run(specs).catch(failTest).then(done);

Diff for: test/jasmine/tests/violin_test.js

+46
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,38 @@ describe('Test violin defaults', function() {
160160
expect(traceOut.scalegroup).toBe('');
161161
});
162162

163+
it('should not coerce hovertemplate when *hoveron* does not contains *points* flag', function() {
164+
var ht = '--- %{y} ---';
165+
166+
_supply({
167+
y: [1, 2, 1],
168+
hoveron: 'points',
169+
hovertemplate: ht
170+
});
171+
expect(traceOut.hovertemplate).toBe(ht, 'hoveron:points');
172+
173+
_supply({
174+
y: [1, 2, 1],
175+
hoveron: 'kde',
176+
hovertemplate: ht
177+
});
178+
expect(traceOut.hovertemplate).toBe(undefined, 'hoveron:kde');
179+
180+
_supply({
181+
y: [1, 2, 1],
182+
hoveron: 'all',
183+
hovertemplate: ht
184+
});
185+
expect(traceOut.hovertemplate).toBe(ht, 'hoveron:all');
186+
187+
_supply({
188+
y: [1, 2, 1],
189+
hoveron: 'violins+points',
190+
hovertemplate: ht
191+
});
192+
expect(traceOut.hovertemplate).toBe(ht, 'hoveron:violins+points');
193+
});
194+
163195
it('should not include alignementgroup/offsetgroup when violinmode is not *group*', function() {
164196
var gd = {
165197
data: [{type: 'violin', y: [1], alignmentgroup: 'a', offsetgroup: '1'}],
@@ -591,6 +623,20 @@ describe('Test violin hover:', function() {
591623
pos: [417, 309],
592624
nums: '(14, 2)',
593625
name: ''
626+
}, {
627+
desc: 'with hovertemplate for points',
628+
patch: function(fig) {
629+
fig.data.forEach(function(trace) {
630+
trace.points = 'all';
631+
trace.hoveron = 'points';
632+
trace.hovertemplate = 'Sample pt %{pointNumber}: %{y:.3f}<extra></extra>';
633+
});
634+
fig.layout.hovermode = 'closest';
635+
return fig;
636+
},
637+
pos: [220, 200],
638+
nums: 'Sample pt 3: 0.900',
639+
name: ''
594640
}]
595641
.forEach(function(specs) {
596642
it('should generate correct hover labels ' + specs.desc, function(done) {

0 commit comments

Comments
 (0)