Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ternary (and scatter) fill #462

Merged
merged 11 commits into from
Apr 22, 2016
2 changes: 1 addition & 1 deletion src/traces/scatter/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ module.exports = {
},
fill: {
valType: 'enumerated',
values: ['none', 'tozeroy', 'tozerox', 'tonexty', 'tonextx'],
values: ['none', 'tozeroy', 'tozerox', 'tonexty', 'tonextx', 'toself', 'tonext'],
dflt: 'none',
role: 'style',
description: [
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be a good time to add more info the description field.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 added. It takes a lot to describe this behavior...

Expand Down
67 changes: 51 additions & 16 deletions src/traces/scatter/plot.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,25 @@ module.exports = function plot(gd, plotinfo, cdscatter) {

// BUILD LINES AND FILLS
var prevpath = '',
tozero, tonext, nexttonext;
ownFillEl3, ownFillDir, tonext, nexttonext;

scattertraces.each(function(d) {
var trace = d[0].trace,
line = trace.line,
tr = d3.select(this);
if(trace.visible !== true) return;

ownFillDir = trace.fill.charAt(trace.fill.length - 1);
if(ownFillDir !== 'x' && ownFillDir !== 'y') ownFillDir = '';

d[0].node3 = tr; // store node for tweaking by selectPoints

arraysToCalcdata(d);

if(!subTypes.hasLines(trace) && trace.fill === 'none') return;

var thispath,
thisrevpath,
// fullpath is all paths for this curve, joined together straight
// across gaps, for filling
fullpath = '',
Expand All @@ -67,12 +71,12 @@ module.exports = function plot(gd, plotinfo, cdscatter) {
// make the fill-to-zero path now, so it shows behind the line
// fill to next puts the fill associated with one trace
// grouped with the previous
if(trace.fill.substr(0, 6) === 'tozero' ||
if(trace.fill.substr(0, 6) === 'tozero' || trace.fill === 'toself' ||
(trace.fill.substr(0, 2) === 'to' && !prevpath)) {
tozero = tr.append('path')
ownFillEl3 = tr.append('path')
.classed('js-fill', true);
}
else tozero = null;
else ownFillEl3 = null;

// make the fill-to-next path now for the NEXT trace, so it shows
// behind both lines.
Expand Down Expand Up @@ -102,7 +106,7 @@ module.exports = function plot(gd, plotinfo, cdscatter) {

revpathfn = function(pts) {
// note: this is destructive (reverses pts in place) so can't use pts after this
return 'L' + revpathbase(pts.reverse()).substr(1);
return revpathbase(pts.reverse());
};

var segments = linePoints(d, {
Expand All @@ -121,27 +125,58 @@ module.exports = function plot(gd, plotinfo, cdscatter) {
for(var i = 0; i < segments.length; i++) {
var pts = segments[i];
thispath = pathfn(pts);
fullpath += fullpath ? ('L' + thispath.substr(1)) : thispath;
revpath = revpathfn(pts) + revpath;
thisrevpath = revpathfn(pts);
if(!fullpath) {
fullpath = thispath;
revpath = thisrevpath;
}
else if(ownFillDir) {
fullpath += 'L' + thispath.substr(1);
revpath = thisrevpath + ('L' + revpath.substr(1));
}
else {
fullpath += 'Z' + thispath;
revpath = thisrevpath + 'Z' + revpath;
}
if(subTypes.hasLines(trace) && pts.length > 1) {
tr.append('path').classed('js-line', true).attr('d', thispath);
}
}
if(tozero) {
if(ownFillEl3) {
if(pt0 && pt1) {
if(trace.fill.charAt(trace.fill.length - 1) === 'y') {
pt0[1] = pt1[1] = ya.c2p(0, true);
if(ownFillDir) {
if(ownFillDir === 'y') {
pt0[1] = pt1[1] = ya.c2p(0, true);
}
else if(ownFillDir === 'x') {
pt0[0] = pt1[0] = xa.c2p(0, true);
}

// fill to zero: full trace path, plus extension of
// the endpoints to the appropriate axis
ownFillEl3.attr('d', fullpath + 'L' + pt1 + 'L' + pt0 + 'Z');
}
else pt0[0] = pt1[0] = xa.c2p(0, true);

// fill to zero: full trace path, plus extension of
// the endpoints to the appropriate axis
tozero.attr('d', fullpath + 'L' + pt1 + 'L' + pt0 + 'Z');
// fill to self: just join the path to itself
else ownFillEl3.attr('d', fullpath + 'Z');
}
}
else if(trace.fill.substr(0, 6) === 'tonext' && fullpath && prevpath) {
// fill to next: full trace path, plus the previous path reversed
tonext.attr('d', fullpath + prevpath + 'Z');
if(trace.fill === 'tonext') {
// tonext: for use by concentric shapes, like manually constructed
// contours, we just add the two paths closed on themselves.
// This makes strange results if one path is *not* entirely
// inside the other, but then that is a strange usage.
tonext.attr('d', fullpath + 'Z' + prevpath + 'Z');
}
else {
// tonextx/y: for now just connect endpoints with lines. This is
// the correct behavior if the endpoints are at the same value of
// y/x, but if they *aren't*, we should ideally do more complicated
// things depending on whether the new endpoint projects onto the
// existing curve or off the end of it
tonext.attr('d', fullpath + 'L' + prevpath.substr(1) + 'Z');
}
}
prevpath = revpath;
}
Expand Down
4 changes: 4 additions & 0 deletions src/traces/scatterternary/attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ module.exports = {
smoothing: scatterLineAttrs.smoothing
},
connectgaps: scatterAttrs.connectgaps,
fill: extendFlat({}, scatterAttrs.fill, {
values: ['none', 'toself', 'tonext']
}),
fillcolor: scatterAttrs.fillcolor,
marker: {
symbol: scatterMarkerAttrs.symbol,
opacity: scatterMarkerAttrs.opacity,
Expand Down
10 changes: 7 additions & 3 deletions src/traces/scatterternary/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ var handleMarkerDefaults = require('../scatter/marker_defaults');
var handleLineDefaults = require('../scatter/line_defaults');
var handleLineShapeDefaults = require('../scatter/line_shape_defaults');
var handleTextDefaults = require('../scatter/text_defaults');
var handleFillColorDefaults = require('../scatter/fillcolor_defaults');

var attributes = require('./attributes');

Expand Down Expand Up @@ -84,8 +85,11 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
coerce('marker.maxdisplayed');
}

coerce('hoverinfo', (layout._dataLength === 1) ? 'a+b+c+text' : undefined);
coerce('fill');
if(traceOut.fill !== 'none') {
handleFillColorDefaults(traceIn, traceOut, defaultColor, coerce);
if(!subTypes.hasLines(traceOut)) handleLineShapeDefaults(traceIn, traceOut, coerce);
}

// until 'fill' and 'fillcolor' are supported
traceOut.fill = 'none';
coerce('hoverinfo', (layout._dataLength === 1) ? 'a+b+c+text' : undefined);
};