Skip to content

Commit 9921522

Browse files
committed
Replace xshift and yshift with x0shift and y0shift
1 parent fdcaa0c commit 9921522

File tree

12 files changed

+238
-114
lines changed

12 files changed

+238
-114
lines changed

src/components/selections/attributes.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,26 +54,48 @@ module.exports = overrideAll(templatedArray('selection', {
5454
description: 'Sets the selection\'s end y position.'
5555
},
5656

57-
xshift: {
57+
x0shift: {
5858
valType: 'number',
5959
dflt: 0,
60-
min: -0.5,
61-
max: 0.5,
60+
min: -1,
61+
max: 1,
62+
editType: 'calc',
63+
description: [
64+
'Only relevant if xref is a (multi-)category axes. Shifts x0 by a fraction of the',
65+
'reference unit.'
66+
].join(' ')
67+
},
68+
x1shift: {
69+
valType: 'number',
70+
dflt: 0,
71+
min: -1,
72+
max: 1,
6273
editType: 'calc',
6374
description: [
64-
'Only relevant if xref is a (multi-)category axes. Shifts x0 and x1 by a fraction of',
65-
'the reference unit.'
75+
'Only relevant if xref is a (multi-)category axes. Shifts x1 by a fraction of the',
76+
'reference unit.'
6677
].join(' ')
6778
},
68-
yshift: {
79+
y0shift: {
6980
valType: 'number',
7081
dflt: 0,
71-
min: -0.5,
72-
max: 0.5,
82+
min: -1,
83+
max: 1,
84+
editType: 'calc',
85+
description: [
86+
'Only relevant if yref is a (multi-)category axes. Shifts y0 by a fraction of the',
87+
'reference unit.'
88+
].join(' ')
89+
},
90+
y1shift: {
91+
valType: 'number',
92+
dflt: 0,
93+
min: -1,
94+
max: 1,
7395
editType: 'calc',
7496
description: [
75-
'Only relevant if yref is a (multi-)category axes. Shifts y0 and y1 by a fraction of',
76-
'the reference unit.'
97+
'Only relevant if yref is a (multi-)category axes. Shifts y1 by a fraction of the',
98+
'reference unit.'
7799
].join(' ')
78100
},
79101

src/components/selections/defaults.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ function handleSelectionDefaults(selectionIn, selectionOut, fullLayout) {
4949
coerce('line.color');
5050
coerce('line.width');
5151
coerce('line.dash');
52-
coerce('xshift');
53-
coerce('yshift');
52+
coerce('x0shift');
53+
coerce('x1shift');
54+
coerce('y0shift');
55+
coerce('y1shift');
5456

5557
// positioning
5658
var axLetters = ['x', 'y'];

src/components/shapes/attributes.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -169,15 +169,26 @@ module.exports = templatedArray('shape', {
169169
'See `type` and `xsizemode` for more info.'
170170
].join(' ')
171171
},
172-
xshift: {
172+
x0shift: {
173173
valType: 'number',
174174
dflt: 0,
175-
min: -0.5,
176-
max: 0.5,
175+
min: -1,
176+
max: 1,
177+
editType: 'calc',
178+
description: [
179+
'Only relevant if xref is a (multi-)category axes. Shifts x0 by a fraction of the',
180+
'reference unit.'
181+
].join(' ')
182+
},
183+
x1shift: {
184+
valType: 'number',
185+
dflt: 0,
186+
min: -1,
187+
max: 1,
177188
editType: 'calc',
178189
description: [
179-
'Only relevant if xref is a (multi-)category axes. Shifts x0 and x1 by a fraction of',
180-
'the reference unit.'
190+
'Only relevant if xref is a (multi-)category axes. Shifts x1 by a fraction of the',
191+
'reference unit.'
181192
].join(' ')
182193
},
183194
yref: extendFlat({}, annAttrs.yref, {
@@ -230,15 +241,26 @@ module.exports = templatedArray('shape', {
230241
'See `type` and `ysizemode` for more info.'
231242
].join(' ')
232243
},
233-
yshift: {
244+
y0shift: {
234245
valType: 'number',
235246
dflt: 0,
236-
min: -0.5,
237-
max: 0.5,
247+
min: -1,
248+
max: 1,
249+
editType: 'calc',
250+
description: [
251+
'Only relevant if yref is a (multi-)category axes. Shifts y0 by a fraction of the',
252+
'reference unit.'
253+
].join(' ')
254+
},
255+
y1shift: {
256+
valType: 'number',
257+
dflt: 0,
258+
min: -1,
259+
max: 1,
238260
editType: 'calc',
239261
description: [
240-
'Only relevant if yref is a (multi-)category axes. Shifts y0 and y1 by a fraction of',
241-
'the reference unit.'
262+
'Only relevant if yref is a (multi-)category axes. Shifts y1 by a fraction of the',
263+
'reference unit.'
242264
].join(' ')
243265
},
244266
path: {

src/components/shapes/calc_autorange.js

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,18 @@ module.exports = function calcAutorange(gd) {
2323

2424
// paper and axis domain referenced shapes don't affect autorange
2525
if(shape.xref !== 'paper' && xRefType !== 'domain') {
26-
var vx0 = shape.xsizemode === 'pixel' ? shape.xanchor : shape.x0;
27-
var vx1 = shape.xsizemode === 'pixel' ? shape.xanchor : shape.x1;
2826
ax = Axes.getFromId(gd, shape.xref);
2927

30-
bounds = shapeBounds(ax, vx0, vx1, shape.path, shape.xshift, constants.paramIsX);
28+
bounds = shapeBounds(ax, shape, constants.paramIsX);
3129
if(bounds) {
3230
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcXPaddingOptions(shape));
3331
}
3432
}
3533

3634
if(shape.yref !== 'paper' && yRefType !== 'domain') {
37-
var vy0 = shape.ysizemode === 'pixel' ? shape.yanchor : shape.y0;
38-
var vy1 = shape.ysizemode === 'pixel' ? shape.yanchor : shape.y1;
3935
ax = Axes.getFromId(gd, shape.yref);
4036

41-
bounds = shapeBounds(ax, vy0, vy1, shape.path, shape.yshift, constants.paramIsY);
37+
bounds = shapeBounds(ax, shape, constants.paramIsY);
4238
if(bounds) {
4339
shape._extremes[ax._id] = Axes.findExtremes(ax, bounds, calcYPaddingOptions(shape));
4440
}
@@ -77,20 +73,35 @@ function calcPaddingOptions(lineWidth, sizeMode, v0, v1, path, isYAxis) {
7773
}
7874
}
7975

80-
function shapeBounds(ax, v0, v1, path, shift, paramsToUse) {
81-
var convertVal;
82-
if(ax.type === 'category' || ax.type === 'multicategory') {
83-
convertVal = function(v) { return ax.r2c(v) + shift; };
76+
function shapeBounds(ax, shape, paramsToUse) {
77+
var dim = ax._id.charAt(0) === 'x' ? 'x' : 'y';
78+
var isCategory = ax.type === 'category' || ax.type === 'multicategory';
79+
var v0;
80+
var v1;
81+
var shiftStart = 0;
82+
var shiftEnd = 0;
83+
84+
var convertVal = isCategory ? ax.r2c : ax.d2c;
85+
86+
var isSizeModeScale = shape[dim + 'sizemode'] === 'scale';
87+
if(isSizeModeScale) {
88+
v0 = shape[dim + '0'];
89+
v1 = shape[dim + '1'];
90+
if(isCategory) {
91+
shiftStart = shape[dim + '0shift'];
92+
shiftEnd = shape[dim + '1shift'];
93+
}
8494
} else {
85-
convertVal = ax.d2c;
95+
v0 = shape[dim + 'anchor'];
96+
v1 = shape[dim + 'anchor'];
8697
}
8798

88-
if(v0 !== undefined) return [convertVal(v0), convertVal(v1)];
89-
if(!path) return;
99+
if(v0 !== undefined) return [convertVal(v0) + shiftStart, convertVal(v1) + shiftEnd];
100+
if(!shape.path) return;
90101

91102
var min = Infinity;
92103
var max = -Infinity;
93-
var segments = path.match(constants.segmentRE);
104+
var segments = shape.path.match(constants.segmentRE);
94105
var i;
95106
var segment;
96107
var drawnParam;

src/components/shapes/defaults.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ function handleShapeDefaults(shapeIn, shapeOut, fullLayout) {
7575
var pos2r;
7676
var r2pos;
7777

78-
coerce('xshift');
79-
coerce('yshift');
78+
coerce('x0shift');
79+
coerce('x1shift');
80+
coerce('y0shift');
81+
coerce('y1shift');
8082

8183
// xref, yref
8284
var axRef = Axes.coerceRef(shapeIn, shapeOut, gdMock, axLetter, undefined,

src/components/shapes/display_labels.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,25 @@ module.exports = function drawLabel(gd, index, options, shapeGroup) {
8888
// and convert them to pixel coordinates
8989
// Setup conversion functions
9090
var xa = Axes.getFromId(gd, options.xref);
91+
var xShiftStart = options.x0shift;
92+
var xShiftEnd = options.x1shift;
9193
var xRefType = Axes.getRefType(options.xref);
92-
var xShift = options.xshift;
9394
var ya = Axes.getFromId(gd, options.yref);
95+
var yShiftStart = options.y0shift;
96+
var yShiftEnd = options.y1shift;
9497
var yRefType = Axes.getRefType(options.yref);
95-
var yShift = options.yshift;
96-
var x2p = helpers.getDataToPixel(gd, xa, xShift, false, xRefType);
97-
var y2p = helpers.getDataToPixel(gd, ya, yShift, true, yRefType);
98-
shapex0 = x2p(options.x0);
99-
shapex1 = x2p(options.x1);
100-
shapey0 = y2p(options.y0);
101-
shapey1 = y2p(options.y1);
98+
var x2p = function(v, shift) {
99+
var dataToPixel = helpers.getDataToPixel(gd, xa, shift, false, xRefType);
100+
return dataToPixel(v);
101+
};
102+
var y2p = function(v, shift) {
103+
var dataToPixel = helpers.getDataToPixel(gd, ya, shift, true, yRefType);
104+
return dataToPixel(v);
105+
};
106+
shapex0 = x2p(options.x0, xShiftStart);
107+
shapex1 = x2p(options.x1, xShiftEnd);
108+
shapey0 = y2p(options.y0, yShiftStart);
109+
shapey1 = y2p(options.y1, yShiftEnd);
102110
}
103111

104112
// Handle `auto` angle

src/components/shapes/draw.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,20 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer, editHe
225225
// setup conversion functions
226226
var xa = Axes.getFromId(gd, shapeOptions.xref);
227227
var xRefType = Axes.getRefType(shapeOptions.xref);
228-
var xShift = shapeOptions.xshift;
229228
var ya = Axes.getFromId(gd, shapeOptions.yref);
230229
var yRefType = Axes.getRefType(shapeOptions.yref);
231-
var yShift = shapeOptions.yshift;
232-
var x2p = helpers.getDataToPixel(gd, xa, xShift, false, xRefType);
233-
var y2p = helpers.getDataToPixel(gd, ya, yShift, true, yRefType);
230+
var shiftXStart = shapeOptions.x0shift;
231+
var shiftXEnd = shapeOptions.x1shift;
232+
var shiftYStart = shapeOptions.y0shift;
233+
var shiftYEnd = shapeOptions.y1shift;
234+
var x2p = function(v, shift) {
235+
var dataToPixel = helpers.getDataToPixel(gd, xa, shift, false, xRefType);
236+
return dataToPixel(v);
237+
};
238+
var y2p = function(v, shift) {
239+
var dataToPixel = helpers.getDataToPixel(gd, ya, shift, true, yRefType);
240+
return dataToPixel(v);
241+
};
234242
var p2x = helpers.getPixelToData(gd, xa, false, xRefType);
235243
var p2y = helpers.getPixelToData(gd, ya, true, yRefType);
236244

@@ -281,8 +289,8 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer, editHe
281289
g.append('circle')
282290
.attr({
283291
'data-line-point': 'start-point',
284-
cx: xPixelSized ? x2p(shapeOptions.xanchor) + shapeOptions.x0 : x2p(shapeOptions.x0),
285-
cy: yPixelSized ? y2p(shapeOptions.yanchor) - shapeOptions.y0 : y2p(shapeOptions.y0),
292+
cx: xPixelSized ? x2p(shapeOptions.xanchor) + shapeOptions.x0 : x2p(shapeOptions.x0, shiftXStart),
293+
cy: yPixelSized ? y2p(shapeOptions.yanchor) - shapeOptions.y0 : y2p(shapeOptions.y0, shiftYStart),
286294
r: circleRadius
287295
})
288296
.style(circleStyle)
@@ -291,8 +299,8 @@ function setupDragElement(gd, shapePath, shapeOptions, index, shapeLayer, editHe
291299
g.append('circle')
292300
.attr({
293301
'data-line-point': 'end-point',
294-
cx: xPixelSized ? x2p(shapeOptions.xanchor) + shapeOptions.x1 : x2p(shapeOptions.x1),
295-
cy: yPixelSized ? y2p(shapeOptions.yanchor) - shapeOptions.y1 : y2p(shapeOptions.y1),
302+
cx: xPixelSized ? x2p(shapeOptions.xanchor) + shapeOptions.x1 : x2p(shapeOptions.x1, shiftXEnd),
303+
cy: yPixelSized ? y2p(shapeOptions.yanchor) - shapeOptions.y1 : y2p(shapeOptions.y1, shiftYEnd),
296304
r: circleRadius
297305
})
298306
.style(circleStyle)

src/components/shapes/helpers.js

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ exports.getDataToPixel = function(gd, axis, shift, isVertical, refType) {
6969
var shiftPixels = 0;
7070
if(axis.type === 'category' || axis.type === 'multicategory') {
7171
if(isVertical) {
72-
shiftPixels = -1 * ((gs.h - axis.r2p(d2r(0.5, true))) * shift);
72+
shiftPixels = ((axis.r2p(1) - axis.r2p(0)) * shift);
7373
} else {
74-
shiftPixels = axis.r2p(d2r(0.5, true)) * shift;
74+
shiftPixels = axis.r2p(0.5) * shift;
7575
}
7676
}
77-
return axis._offset + axis.r2p(d2r(v, true)) + (shiftPixels || 0);
77+
return axis._offset + axis.r2p(d2r(v, true)) + shiftPixels;
7878
};
7979

8080
if(axis.type === 'date') dataToPixel = exports.decodeDate(dataToPixel);
@@ -187,8 +187,10 @@ exports.getPathString = function(gd, options) {
187187
var ya = Axes.getFromId(gd, options.yref);
188188
var gs = gd._fullLayout._size;
189189
var x2r, x2p, y2r, y2p;
190-
var shiftUnitX = 0;
191-
var shiftUnitY = 0;
190+
var xShiftStart = 0;
191+
var xShiftEnd = 0;
192+
var yShiftStart = 0;
193+
var yShiftEnd = 0;
192194
var x0, x1, y0, y1;
193195

194196
if(xa) {
@@ -198,7 +200,9 @@ exports.getPathString = function(gd, options) {
198200
x2r = exports.shapePositionToRange(xa);
199201
x2p = function(v) { return xa._offset + xa.r2p(x2r(v, true)); };
200202
if(xa.type === 'category' || xa.type === 'multicategory') {
201-
shiftUnitX = xa.r2p(x2r(0.5, true));
203+
var shiftUnitX = xa.r2p(0.5);
204+
xShiftStart = shiftUnitX * options.x0shift;
205+
xShiftEnd = shiftUnitX * options.x1shift;
202206
}
203207
}
204208
} else {
@@ -212,7 +216,9 @@ exports.getPathString = function(gd, options) {
212216
y2r = exports.shapePositionToRange(ya);
213217
y2p = function(v) { return ya._offset + ya.r2p(y2r(v, true)); };
214218
if(ya.type === 'category' || ya.type === 'multicategory') {
215-
shiftUnitY = gs.h - ya.r2p(y2r(0.5, true));
219+
var shiftUnitY = ya.r2p(0) - ya.r2p(1);
220+
yShiftStart = shiftUnitY * options.y0shift;
221+
yShiftEnd = shiftUnitY * options.y1shift;
216222
}
217223
}
218224
} else {
@@ -226,20 +232,20 @@ exports.getPathString = function(gd, options) {
226232
}
227233
if(options.xsizemode === 'pixel') {
228234
var xAnchorPos = x2p(options.xanchor);
229-
x0 = xAnchorPos + options.x0 + shiftUnitX * options.xshift;
230-
x1 = xAnchorPos + options.x1 + shiftUnitX * options.xshift;
235+
x0 = xAnchorPos + options.x0 + xShiftStart;
236+
x1 = xAnchorPos + options.x1 + xShiftEnd;
231237
} else {
232-
x0 = x2p(options.x0) + shiftUnitX * options.xshift;
233-
x1 = x2p(options.x1) + shiftUnitX * options.xshift;
238+
x0 = x2p(options.x0) + xShiftStart;
239+
x1 = x2p(options.x1) + xShiftEnd;
234240
}
235241

236242
if(options.ysizemode === 'pixel') {
237243
var yAnchorPos = y2p(options.yanchor);
238-
y0 = yAnchorPos - options.y0 - shiftUnitY * options.yshift;
239-
y1 = yAnchorPos - options.y1 - shiftUnitY * options.yshift;
244+
y0 = yAnchorPos - options.y0 - yShiftStart;
245+
y1 = yAnchorPos - options.y1 - yShiftEnd;
240246
} else {
241-
y0 = y2p(options.y0) - shiftUnitY * options.yshift;
242-
y1 = y2p(options.y1) - shiftUnitY * options.yshift;
247+
y0 = y2p(options.y0) - yShiftStart;
248+
y1 = y2p(options.y1) - yShiftEnd;
243249
}
244250

245251
if(type === 'line') return 'M' + x0 + ',' + y0 + 'L' + x1 + ',' + y1;

0 commit comments

Comments
 (0)