Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 536ba6f

Browse filesBrowse files
authored
Merge pull request plotly#2280 from plotly/ghost-fill
fix ghost fill-tonext when either trace is emptied out
2 parents defb8aa + fb8357a commit 536ba6f
Copy full SHA for 536ba6f

File tree

3 files changed

+79
-21
lines changed
Filter options

3 files changed

+79
-21
lines changed

‎src/traces/scatter/link_traces.js

Copy file name to clipboardExpand all lines: src/traces/scatter/link_traces.js
+3-4Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,11 @@
99
'use strict';
1010

1111
module.exports = function linkTraces(gd, plotinfo, cdscatter) {
12-
var cd, trace;
12+
var trace, i;
1313
var prevtrace = null;
1414

15-
for(var i = 0; i < cdscatter.length; ++i) {
16-
cd = cdscatter[i];
17-
trace = cd[0].trace;
15+
for(i = 0; i < cdscatter.length; ++i) {
16+
trace = cdscatter[i][0].trace;
1817

1918
// Note: The check which ensures all cdscatter here are for the same axis and
2019
// are either cartesian or scatterternary has been removed. This code assumes

‎src/traces/scatter/plot.js

Copy file name to clipboardExpand all lines: src/traces/scatter/plot.js
+32-17Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,10 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
323323

324324
Drawing.setClipUrl(lineJoin, plotinfo.layerClipId);
325325

326+
function clearFill(selection) {
327+
transition(selection).attr('d', 'M0,0Z');
328+
}
329+
326330
if(segments.length) {
327331
if(ownFillEl3) {
328332
if(pt0 && pt1) {
@@ -348,30 +352,41 @@ function plotOne(gd, idx, plotinfo, cdscatter, cdscatterAll, element, transition
348352
}
349353
}
350354
}
351-
else if(trace.fill.substr(0, 6) === 'tonext' && fullpath && prevRevpath) {
352-
// fill to next: full trace path, plus the previous path reversed
353-
if(trace.fill === 'tonext') {
354-
// tonext: for use by concentric shapes, like manually constructed
355-
// contours, we just add the two paths closed on themselves.
356-
// This makes strange results if one path is *not* entirely
357-
// inside the other, but then that is a strange usage.
358-
transition(tonext).attr('d', fullpath + 'Z' + prevRevpath + 'Z')
359-
.call(Drawing.singleFillStyle);
355+
else if(tonext) {
356+
if(trace.fill.substr(0, 6) === 'tonext' && fullpath && prevRevpath) {
357+
// fill to next: full trace path, plus the previous path reversed
358+
if(trace.fill === 'tonext') {
359+
// tonext: for use by concentric shapes, like manually constructed
360+
// contours, we just add the two paths closed on themselves.
361+
// This makes strange results if one path is *not* entirely
362+
// inside the other, but then that is a strange usage.
363+
transition(tonext).attr('d', fullpath + 'Z' + prevRevpath + 'Z')
364+
.call(Drawing.singleFillStyle);
365+
}
366+
else {
367+
// tonextx/y: for now just connect endpoints with lines. This is
368+
// the correct behavior if the endpoints are at the same value of
369+
// y/x, but if they *aren't*, we should ideally do more complicated
370+
// things depending on whether the new endpoint projects onto the
371+
// existing curve or off the end of it
372+
transition(tonext).attr('d', fullpath + 'L' + prevRevpath.substr(1) + 'Z')
373+
.call(Drawing.singleFillStyle);
374+
}
375+
trace._polygons = trace._polygons.concat(prevPolygons);
360376
}
361377
else {
362-
// tonextx/y: for now just connect endpoints with lines. This is
363-
// the correct behavior if the endpoints are at the same value of
364-
// y/x, but if they *aren't*, we should ideally do more complicated
365-
// things depending on whether the new endpoint projects onto the
366-
// existing curve or off the end of it
367-
transition(tonext).attr('d', fullpath + 'L' + prevRevpath.substr(1) + 'Z')
368-
.call(Drawing.singleFillStyle);
378+
clearFill(tonext);
379+
trace._polygons = null;
369380
}
370-
trace._polygons = trace._polygons.concat(prevPolygons);
371381
}
372382
trace._prevRevpath = revpath;
373383
trace._prevPolygons = thisPolygons;
374384
}
385+
else {
386+
if(ownFillEl3) clearFill(ownFillEl3);
387+
else if(tonext) clearFill(tonext);
388+
trace._polygons = trace._prevRevpath = trace._prevPolygons = null;
389+
}
375390

376391

377392
function visFilter(d) {

‎test/jasmine/tests/scatter_test.js

Copy file name to clipboardExpand all lines: test/jasmine/tests/scatter_test.js
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,50 @@ describe('end-to-end scatter tests', function() {
713713
expect(fill()).toEqual('rgb(0, 0, 255)');
714714
}).catch(fail).then(done);
715715
});
716+
717+
it('clears fills tonext when either trace is emptied out', function(done) {
718+
var trace0 = {y: [1, 3, 5, 7]};
719+
var trace1 = {y: [1, 2, 3, 4], line: {width: 0}, mode: 'lines'};
720+
var trace2 = {y: [3, 4, 5, 6], fill: 'tonexty', mode: 'none'};
721+
722+
function checkFill(visible, msg) {
723+
var fillSelection = d3.select(gd).selectAll('.scatterlayer .js-fill');
724+
expect(fillSelection.size()).toBe(1, msg);
725+
expect(fillSelection.attr('d')).negateIf(visible).toBe('M0,0Z', msg);
726+
}
727+
728+
Plotly.newPlot(gd, [trace0, trace1, trace2], {}, {scrollZoom: true})
729+
.then(function() {
730+
checkFill(true, 'initial');
731+
732+
return Plotly.restyle(gd, {y: [[null, null, null, null]]}, [1]);
733+
})
734+
.then(function() {
735+
checkFill(false, 'null out trace 1');
736+
737+
return Plotly.restyle(gd, {y: [[1, 2, 3, 4]]}, [1]);
738+
})
739+
.then(function() {
740+
checkFill(true, 'restore trace 1');
741+
742+
return Plotly.restyle(gd, {y: [[null, null, null, null]]}, [2]);
743+
})
744+
.then(function() {
745+
checkFill(false, 'null out trace 2');
746+
747+
return Plotly.restyle(gd, {y: [[1, 2, 3, 4]]}, [2]);
748+
})
749+
.then(function() {
750+
checkFill(true, 'restore trace 2');
751+
752+
return Plotly.restyle(gd, {y: [[null, null, null, null], [null, null, null, null]]}, [1, 2]);
753+
})
754+
.then(function() {
755+
checkFill(false, 'null out both traces');
756+
})
757+
.catch(fail)
758+
.then(done);
759+
});
716760
});
717761

718762
describe('scatter hoverPoints', function() {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.