Skip to content

Commit 3cb7e7e

Browse files
authoredOct 25, 2016
Merge pull request #1075 from n-riesco/pr-20161017-issue-80-bar-base-offset-width
Implement attributes base, offset and width in bar traces (issue 80)
2 parents 1fd52c3 + cc69e8f commit 3cb7e7e

18 files changed

+1493
-301
lines changed
 

‎src/lib/coerce.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ exports.valObjects = {
228228
any: {
229229
description: 'Any type.',
230230
requiredOpts: [],
231-
otherOpts: ['dflt', 'values'],
231+
otherOpts: ['dflt', 'values', 'arrayOk'],
232232
coerceFunction: function(v, propOut, dflt) {
233233
if(v === undefined) propOut.set(dflt);
234234
else propOut.set(v);

‎src/plot_api/plot_api.js

+1
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ function _restyle(gd, aobj, _traces) {
12671267
'x', 'y', 'z',
12681268
'a', 'b', 'c',
12691269
'open', 'high', 'low', 'close',
1270+
'base', 'width', 'offset',
12701271
'xtype', 'x0', 'dx', 'ytype', 'y0', 'dy', 'xaxis', 'yaxis',
12711272
'line.width',
12721273
'connectgaps', 'transpose', 'zsmooth',

‎src/traces/bar/attributes.js

+38
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,44 @@ module.exports = {
4848
].join(' ')
4949
},
5050

51+
base: {
52+
valType: 'any',
53+
dflt: null,
54+
arrayOk: true,
55+
role: 'info',
56+
description: [
57+
'Sets where the bar base is drawn (in position axis units).',
58+
'In *stack* or *relative* barmode,',
59+
'traces that set *base* will be excluded',
60+
'and drawn in *overlay* mode instead.'
61+
].join(' ')
62+
},
63+
64+
offset: {
65+
valType: 'number',
66+
dflt: null,
67+
arrayOk: true,
68+
role: 'info',
69+
description: [
70+
'Shifts the position where the bar is drawn',
71+
'(in position axis units).',
72+
'In *group* barmode,',
73+
'traces that set *offset* will be excluded',
74+
'and drawn in *overlay* mode instead.'
75+
].join(' ')
76+
},
77+
78+
width: {
79+
valType: 'number',
80+
dflt: null,
81+
min: 0,
82+
arrayOk: true,
83+
role: 'info',
84+
description: [
85+
'Sets the bar width (in position axis units).'
86+
].join(' ')
87+
},
88+
5189
marker: marker,
5290

5391
r: scatterAttrs.r,

‎src/traces/bar/calc.js

+33-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ module.exports = function calc(gd, trace) {
2525
var xa = Axes.getFromId(gd, trace.xaxis || 'x'),
2626
ya = Axes.getFromId(gd, trace.yaxis || 'y'),
2727
orientation = trace.orientation || ((trace.x && !trace.y) ? 'h' : 'v'),
28-
pos, size, i;
28+
sa, pos, size, i;
2929

3030
if(orientation === 'h') {
31+
sa = xa;
3132
size = xa.makeCalcdata(trace, 'x');
3233
pos = ya.makeCalcdata(trace, 'y');
3334
}
3435
else {
36+
sa = ya;
3537
size = ya.makeCalcdata(trace, 'y');
3638
pos = xa.makeCalcdata(trace, 'x');
3739
}
@@ -40,14 +42,43 @@ module.exports = function calc(gd, trace) {
4042
var serieslen = Math.min(pos.length, size.length),
4143
cd = [];
4244

45+
// set position
4346
for(i = 0; i < serieslen; i++) {
4447

4548
// add bars with non-numeric sizes to calcdata
4649
// so that ensure that traces with gaps are
4750
// plotted in the correct order
4851

4952
if(isNumeric(pos[i])) {
50-
cd.push({p: pos[i], s: size[i], b: 0});
53+
cd.push({p: pos[i]});
54+
}
55+
}
56+
57+
// set base
58+
var base = trace.base,
59+
b;
60+
61+
if(Array.isArray(base)) {
62+
for(i = 0; i < Math.min(base.length, cd.length); i++) {
63+
b = sa.d2c(base[i]);
64+
cd[i].b = (isNumeric(b)) ? b : 0;
65+
}
66+
for(; i < cd.length; i++) {
67+
cd[i].b = 0;
68+
}
69+
}
70+
else {
71+
b = sa.d2c(base);
72+
b = (isNumeric(b)) ? b : 0;
73+
for(i = 0; i < cd.length; i++) {
74+
cd[i].b = b;
75+
}
76+
}
77+
78+
// set size
79+
for(i = 0; i < cd.length; i++) {
80+
if(isNumeric(size[i])) {
81+
cd[i].s = size[i];
5182
}
5283
}
5384

‎src/traces/bar/defaults.js

+3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3030
}
3131

3232
coerce('orientation', (traceOut.x && !traceOut.y) ? 'h' : 'v');
33+
coerce('base');
34+
coerce('offset');
35+
coerce('width');
3336
coerce('text');
3437

3538
handleStyleDefaults(traceIn, traceOut, coerce, defaultColor, layout);

‎src/traces/bar/hover.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
2121
xa = pointData.xa,
2222
ya = pointData.ya,
2323
barDelta = (hovermode === 'closest') ?
24-
t.barwidth / 2 : t.dbar * (1 - xa._gd._fullLayout.bargap) / 2,
24+
t.barwidth / 2 :
25+
t.bargroupwidth,
2526
barPos;
2627

2728
if(hovermode !== 'closest') barPos = function(di) { return di.p; };

‎src/traces/bar/plot.js

+19-10
Original file line numberDiff line numberDiff line change
@@ -34,30 +34,39 @@ module.exports = function plot(gd, plotinfo, cdbar) {
3434
.attr('class', 'points')
3535
.each(function(d) {
3636
var t = d[0].t,
37-
trace = d[0].trace;
37+
trace = d[0].trace,
38+
poffset = t.poffset,
39+
poffsetIsArray = Array.isArray(poffset),
40+
barwidth = t.barwidth,
41+
barwidthIsArray = Array.isArray(barwidth);
3842

3943
arraysToCalcdata(d);
4044

4145
d3.select(this).selectAll('path')
4246
.data(Lib.identity)
4347
.enter().append('path')
44-
.each(function(di) {
48+
.each(function(di, i) {
4549
// now display the bar
4650
// clipped xf/yf (2nd arg true): non-positive
4751
// log values go off-screen by plotwidth
4852
// so you see them continue if you drag the plot
53+
var p0 = di.p + ((poffsetIsArray) ? poffset[i] : poffset),
54+
p1 = p0 + ((barwidthIsArray) ? barwidth[i] : barwidth),
55+
s0 = di.b,
56+
s1 = s0 + di.s;
57+
4958
var x0, x1, y0, y1;
5059
if(trace.orientation === 'h') {
51-
y0 = ya.c2p(t.poffset + di.p, true);
52-
y1 = ya.c2p(t.poffset + di.p + t.barwidth, true);
53-
x0 = xa.c2p(di.b, true);
54-
x1 = xa.c2p(di.s + di.b, true);
60+
y0 = ya.c2p(p0, true);
61+
y1 = ya.c2p(p1, true);
62+
x0 = xa.c2p(s0, true);
63+
x1 = xa.c2p(s1, true);
5564
}
5665
else {
57-
x0 = xa.c2p(t.poffset + di.p, true);
58-
x1 = xa.c2p(t.poffset + di.p + t.barwidth, true);
59-
y1 = ya.c2p(di.s + di.b, true);
60-
y0 = ya.c2p(di.b, true);
66+
x0 = xa.c2p(p0, true);
67+
x1 = xa.c2p(p1, true);
68+
y0 = ya.c2p(s0, true);
69+
y1 = ya.c2p(s1, true);
6170
}
6271

6372
if(!isNumeric(x0) || !isNumeric(x1) ||

0 commit comments

Comments
 (0)
Please sign in to comment.