Skip to content

Commit 2ebc1a9

Browse files
committed
add backoff to line
1 parent 9e14777 commit 2ebc1a9

18 files changed

+491
-23
lines changed

src/traces/scatter/attributes.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,14 +292,26 @@ module.exports = {
292292
].join(' ')
293293
},
294294
dash: extendFlat({}, dash, {editType: 'style'}),
295+
backoff: { // TODO: do we want to have a similar option for the start of the line? If so what the name should be?
296+
valType: 'number',
297+
min: 0,
298+
dflt: 0,
299+
arrayOk: true,
300+
editType: 'plot',
301+
description: [
302+
'Sets the line back off from the end point of the nth line segment (in px).',
303+
'This option is useful e.g. to avoid overlap with arrowhead markers.',
304+
].join(' ')
305+
},
295306
simplify: {
296307
valType: 'boolean',
297-
dflt: true,
298308
editType: 'plot',
299309
description: [
300310
'Simplifies lines by removing nearly-collinear points. When transitioning',
301311
'lines, it may be desirable to disable this so that the number of points',
302-
'along the resulting SVG path is unaffected.'
312+
'along the resulting SVG path is unaffected.',
313+
'Defaults to *false* when `backoff` is set,',
314+
'otherwise defaults to *true*.'
303315
].join(' ')
304316
},
305317
editType: 'plot'

src/traces/scatter/defaults.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
3939
coerce('mode', defaultMode);
4040

4141
if(subTypes.hasLines(traceOut)) {
42-
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
42+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
4343
handleLineShapeDefaults(traceIn, traceOut, coerce);
4444
coerce('connectgaps');
45-
coerce('line.simplify');
45+
coerce('line.simplify', traceOut.backoff ? false : true);
4646
}
4747

4848
if(subTypes.hasMarkers(traceOut)) {

src/traces/scatter/line_defaults.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ var hasColorscale = require('../../components/colorscale/helpers').hasColorscale
55
var colorscaleDefaults = require('../../components/colorscale/defaults');
66

77
module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout, coerce, opts) {
8+
if(!opts) opts = {};
9+
810
var markerColor = (traceIn.marker || {}).color;
911

1012
coerce('line.color', defaultColor);
@@ -17,5 +19,7 @@ module.exports = function lineDefaults(traceIn, traceOut, defaultColor, layout,
1719
}
1820

1921
coerce('line.width');
20-
if(!(opts || {}).noDash) coerce('line.dash');
22+
23+
if(!opts.noDash) coerce('line.dash');
24+
if(opts.backoff) coerce('line.backoff');
2125
};

src/traces/scatter/line_points.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ module.exports = function linePoints(d, opts) {
1818
var yLog = ya.type === 'log';
1919
var xLen = xa._length;
2020
var yLen = ya._length;
21+
var backoff = opts.backoff;
2122
var connectGaps = opts.connectGaps;
2223
var baseTolerance = opts.baseTolerance;
2324
var shape = opts.shape;
@@ -446,5 +447,52 @@ module.exports = function linePoints(d, opts) {
446447
segments.push(pts.slice(0, pti));
447448
}
448449

450+
if(backoff) {
451+
var newSegments = [];
452+
var arrayBackoff = Lib.isArrayOrTypedArray(backoff);
453+
var lastShapeChar = shape.slice(shape.length - 1);
454+
i = -1;
455+
for(var j = 0; j < segments.length; j++) {
456+
i++;
457+
for(var k = 0; k < segments[j].length - 1; k++) {
458+
var start = segments[j][k];
459+
var end = segments[j][k + 1];
460+
461+
var x1 = start[0];
462+
var y1 = start[1];
463+
464+
var x2 = end[0];
465+
var y2 = end[1];
466+
467+
var dx = x2 - x1;
468+
var dy = y2 - y1;
469+
470+
var t = Math.atan2(dy, dx);
471+
if(lastShapeChar === 'h') {
472+
t = dx < 0 ? Math.PI : 0;
473+
} else if(lastShapeChar === 'v') {
474+
t = dy > 0 ? Math.PI / 2 : -Math.PI / 2;
475+
}
476+
477+
var b = arrayBackoff ? backoff[i] : backoff;
478+
479+
var x = x2 - b * Math.cos(t);
480+
var y = y2 - b * Math.sin(t);
481+
482+
if(
483+
((x <= x2 && x >= x1) || (x >= x2 && x <= x1)) &&
484+
((y <= y2 && y >= y1) || (y >= y2 && y <= y1))
485+
) {
486+
if(!newSegments[j]) newSegments[j] = [];
487+
488+
newSegments[j].push(start);
489+
newSegments[j].push([x, y]);
490+
}
491+
}
492+
}
493+
494+
return newSegments;
495+
}
496+
449497
return segments;
450498
};

src/traces/scatter/plot.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
212212
connectGaps: trace.connectgaps,
213213
baseTolerance: Math.max(line.width || 1, 3) / 4,
214214
shape: line.shape,
215+
backoff: line.backoff,
215216
simplify: line.simplify,
216217
fill: trace.fill
217218
});

src/traces/scattercarpet/attributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ module.exports = {
6161
color: scatterLineAttrs.color,
6262
width: scatterLineAttrs.width,
6363
dash: scatterLineAttrs.dash,
64+
backoff: scatterLineAttrs.backoff,
6465
shape: extendFlat({}, scatterLineAttrs.shape,
6566
{values: ['linear', 'spline']}),
6667
smoothing: scatterLineAttrs.smoothing,

src/traces/scattercarpet/defaults.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
4242
coerce('mode', defaultMode);
4343

4444
if(subTypes.hasLines(traceOut)) {
45-
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
45+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
4646
handleLineShapeDefaults(traceIn, traceOut, coerce);
4747
coerce('connectgaps');
4848
}

src/traces/scatterpolar/attributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ module.exports = {
8282
color: lineAttrs.color,
8383
width: lineAttrs.width,
8484
dash: lineAttrs.dash,
85+
backoff: lineAttrs.backoff,
8586
shape: extendFlat({}, lineAttrs.shape, {
8687
values: ['linear', 'spline']
8788
}),

src/traces/scatterpolar/defaults.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
3030
if(traceOut.hoveron !== 'fills') coerce('hovertemplate');
3131

3232
if(subTypes.hasLines(traceOut)) {
33-
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce);
33+
handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce, {backoff: true});
3434
handleLineShapeDefaults(traceIn, traceOut, coerce);
3535
coerce('connectgaps');
3636
}

src/traces/scattersmith/attributes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ module.exports = {
3838
color: lineAttrs.color,
3939
width: lineAttrs.width,
4040
dash: lineAttrs.dash,
41+
backoff: lineAttrs.backoff,
4142
shape: extendFlat({}, lineAttrs.shape, {
4243
values: ['linear', 'spline']
4344
}),

0 commit comments

Comments
 (0)