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

Waterfall charts #3531

Merged
merged 78 commits into from
Mar 28, 2019
Merged
Show file tree
Hide file tree
Changes from 58 commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
8f89564
started waterfall
archmoj Feb 4, 2019
5678653
rm traceIs waterfall as it described as bar
archmoj Feb 11, 2019
cfe8eb2
isFall > isSum as we may use rise and fall for positive and negative …
archmoj Feb 11, 2019
dbc98b5
separated calc for waterfall - pass 1
archmoj Feb 11, 2019
acc3640
removed barnorm stack and base
archmoj Feb 11, 2019
9537ee8
removed more useless mocks
archmoj Feb 11, 2019
6be0a4a
easier to use api
archmoj Feb 11, 2019
d6a69f2
new baselines
archmoj Feb 12, 2019
34b6a0a
handle undefined cases in extract instructions
archmoj Feb 12, 2019
aa58571
new baselines
archmoj Feb 12, 2019
6a4666a
auto compute color array based on vals when array left empty
archmoj Feb 12, 2019
3fb3597
new baselines
archmoj Feb 12, 2019
dc1b420
defualt to remove instructions from ax text
archmoj Feb 12, 2019
f8507ce
only accept valid tokens
archmoj Feb 12, 2019
a875ac7
new baselines
archmoj Feb 12, 2019
69956a0
only run waterfalls on CI for now
archmoj Feb 12, 2019
82dfd18
use operators instead of instr and token
archmoj Feb 12, 2019
87ad17c
handle initial values
archmoj Feb 12, 2019
b0fdced
correct baselines cases without an initial value
archmoj Feb 12, 2019
4c4c8e5
refactor plot using isHorizontal and else fixup
archmoj Feb 13, 2019
c052205
describe connectors
archmoj Feb 13, 2019
fb28e30
draw connector at the end of each bar
archmoj Feb 13, 2019
ea4863f
extend connectors using dtick
archmoj Feb 13, 2019
af60c1f
fixed shape and dist between connectors
archmoj Feb 13, 2019
1827ee6
new baselines
archmoj Feb 13, 2019
89e66bb
revised includes
archmoj Feb 13, 2019
4383a71
providing a separate array for the operators
archmoj Feb 13, 2019
2454e6c
removed last connector
archmoj Feb 13, 2019
3533448
new baselines without last connector
archmoj Feb 13, 2019
cd16944
Merge branch 'master' into waterfall-new-trace_dev1
archmoj Mar 1, 2019
f9b36cb
consider alignment and offset group across matching axes in waterfall
archmoj Mar 1, 2019
3386803
removed few unused parameters from bar cross_trace_calc
archmoj Mar 5, 2019
d1c8c48
inherit from bars - pass 1
archmoj Mar 6, 2019
cd81dcd
rm triangles
archmoj Mar 6, 2019
e7602e2
removed operator - used null magic number and added initialized attri…
archmoj Mar 6, 2019
d1bbae6
removed errorbar support
archmoj Mar 6, 2019
59ee151
removed errorbars
archmoj Mar 8, 2019
d8d54cd
support non-array base - waterfall tests
archmoj Mar 13, 2019
c1ed50f
revised connector line shapes
archmoj Mar 14, 2019
346c637
revised connectors - hover showing initial - multicategory example
archmoj Mar 14, 2019
fed3c97
Revision based on Etienne review - pass 1
archmoj Mar 18, 2019
aa8abe4
fixup attributes width offset connector lines plot and test
archmoj Mar 20, 2019
a05352f
arrayOk width and offset back - apply offset arrays in connector draw
archmoj Mar 20, 2019
20d1cbc
added totals container and fixed hover colors
archmoj Mar 21, 2019
692c6d4
fix hover color in test
archmoj Mar 21, 2019
c0b1017
waterfallmode
archmoj Mar 26, 2019
9533558
waterfallgap
archmoj Mar 26, 2019
2480892
waterfallgroupgap
archmoj Mar 26, 2019
f3f7d84
fixup waterfall mode gap groupgap
archmoj Mar 26, 2019
7e41079
rename inner node in <g.lines> -> <g.line>
etpinard Mar 26, 2019
84e3a27
fix `cliponaxis:false` for waterfall traces
etpinard Mar 26, 2019
00070ba
always drawn waterfall trace below bar/histogram
etpinard Mar 26, 2019
dcab107
fixup waterfall/bar mode/gap/groupgap interplay
etpinard Mar 26, 2019
d52116b
revised waterfall marker logic
archmoj Mar 27, 2019
6d37db9
drop steps connector mode
archmoj Mar 27, 2019
fb0d7a9
added connector visible drop false mode
archmoj Mar 27, 2019
9e941ba
tweak bar endpoints to adjust with connector in mode between
archmoj Mar 27, 2019
2a25753
dont coerce connector if visible false
archmoj Mar 27, 2019
1825027
turn connector.(color|dash|width) into -> connector.line.(color|dash|…
archmoj Mar 27, 2019
4a044e4
make restyle connector visible (true|false) work
archmoj Mar 27, 2019
c53bcce
fixup restyle connector visible remove nodes
archmoj Mar 27, 2019
3b984ff
added connector restyle visible true false
archmoj Mar 27, 2019
6b3eeab
no need to loop over all the traces when waterfallmode is not group
archmoj Mar 27, 2019
ce0a56a
make waterfall NOT a 'bar' category
etpinard Mar 27, 2019
412bf9d
revamp waterfall marker style logic
etpinard Mar 27, 2019
a55777f
:hocho: [un]selected style container for waterfall (for now)
etpinard Mar 27, 2019
dee39dc
do not show hover label when size===0
etpinard Mar 27, 2019
a138ebd
adapt waterfall legend to new *marker* styles ...
etpinard Mar 27, 2019
7019a12
fixup (from :hocho: 'bar' category commit)
etpinard Mar 27, 2019
8bbc863
fixup waterfall mocks and baselines
etpinard Mar 27, 2019
b6fdaed
fixup mock list
etpinard Mar 27, 2019
cb8f1ec
adapt failing waterfall jasmine tests
archmoj Mar 27, 2019
1447b40
fixup waterfall bar path query
etpinard Mar 27, 2019
4eb5daf
add a flaky flag for one test
archmoj Mar 28, 2019
f3a071e
waterfall marker description - set default to between mode - added sp…
archmoj Mar 28, 2019
1721ab7
fix waterfall connectors - not to draw lines between null amounts - u…
archmoj Mar 28, 2019
7655664
Merge remote-tracking branch 'origin/master' into waterfall-new-trace
archmoj Mar 28, 2019
1d275f5
set a noCI flag for the select test
archmoj Mar 28, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Plotly.register([
require('./contour'),
require('./scatterternary'),
require('./violin'),
require('./waterfall'),

require('./scatter3d'),
require('./surface'),
Expand Down
11 changes: 11 additions & 0 deletions lib/waterfall.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Copyright 2012-2019, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

module.exports = require('../src/traces/waterfall');
18 changes: 16 additions & 2 deletions src/components/drawing/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,9 @@ drawing.hideOutsideRangePoints = function(traceGroups, subplot) {
var trace = d[0].trace;
var xcalendar = trace.xcalendar;
var ycalendar = trace.ycalendar;
var selector = trace.type === 'bar' ? '.bartext' : '.point,.textpoint';
var selector = trace.type === 'bar' ? '.bartext' :
trace.type === 'waterfall' ? '.bartext,.line' :
'.point,.textpoint';

traceGroups.selectAll(selector).each(function(d) {
drawing.hideOutsideRangePoint(d, d3.select(this), xa, ya, xcalendar, ycalendar);
Expand Down Expand Up @@ -360,8 +362,21 @@ drawing.pointStyle = function(s, trace, gd) {
});
};

drawing.waterfallStyle = function(d, trace) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This thing doesn't do any drawing now. Can we move that to waterfall/calc.js?

var marker = trace.marker;
if(marker) return marker;
if(!d.isSum) {
if(d.rawS > 0) return trace.increasing;
return trace.decreasing; // Note here by default we return RED for zero and null
}
return trace.totals;
};

drawing.singlePointStyle = function(d, sel, trace, fns, gd) {
var marker = trace.marker;
if(trace.type === 'waterfall') {
marker = this.waterfallStyle(d, trace);
}
var markerLine = marker.line;

sel.style('opacity',
Expand Down Expand Up @@ -497,7 +512,6 @@ drawing.makePointStyleFns = function(trace) {
if(trace.selectedpoints) {
Lib.extendFlat(out, drawing.makeSelectedPointStyleFns(trace));
}

return out;
};

Expand Down
42 changes: 42 additions & 0 deletions src/components/legend/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ module.exports = function style(s, gd) {
.enter().append('g')
.classed('legendpoints', true);
})
.each(styleWaterfalls)
.each(styleBars)
.each(styleBoxes)
.each(stylePies)
Expand Down Expand Up @@ -241,8 +242,49 @@ module.exports = function style(s, gd) {
txt.selectAll('text').call(Drawing.textPointStyle, tMod, gd);
}

function styleWaterfalls(d) {
Copy link
Contributor

@etpinard etpinard Mar 26, 2019

Choose a reason for hiding this comment

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

image

Could we not show the "totals" part in the legend symbol when the trace only shows increasing/decreasing bars?

var trace = d[0].trace;
if(trace.type !== 'waterfall') return d;

var barpath = d3.select(this).select('g.legendpoints')
.selectAll('path.legendbar')
.data(Registry.traceIs(trace, 'bar') ? [d, d, d] : []);
barpath.enter().append('path').classed('legendbar', true)
.attr('d', function(_, i) {
return (
(i === 0) ? 'M-6,-6V6H0Z' :
(i === 1) ? 'M6,6V-6H0Z' : 'M6,6H0L-6,-6H-0Z'
);
})
.attr('transform', 'translate(20,0)');
barpath.exit().remove();

barpath.each(function(d, i) {

var container = trace.marker || trace[
(i % 3 === 0) ? 'increasing' :
(i % 3 === 1) ? 'decreasing' : 'totals'
];

var line = container.line || {};

var p = d3.select(this);
var d0 = d[0];
var w = (d0.mlw + 1 || line.width + 1) - 1;

p.style('stroke-width', w + 'px')
.call(Color.fill, container.color);

if(w) {
p.call(Color.stroke, container.color);
}
});
}

function styleBars(d) {
var trace = d[0].trace;
if(trace.type === 'waterfall') return d;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need this line? In other words, why is styleBars ever calls via waterfall traces?


var marker = trace.marker || {};
var markerLine = marker.line || {};

Expand Down
2 changes: 1 addition & 1 deletion src/plot_api/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ exports.cleanData = function(data) {
// the axes it's eventually going to be used with
if('bardir' in trace) {
if(trace.bardir === 'h' && (Registry.traceIs(trace, 'bar') ||
trace.type.substr(0, 9) === 'histogram')) {
trace.type.substr(0, 9) === 'histogram')) {
trace.orientation = 'h';
exports.swapXYData(trace);
}
Expand Down
2 changes: 1 addition & 1 deletion src/plots/cartesian/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ module.exports = {
traceLayerClasses: [
'heatmaplayer',
'contourcarpetlayer', 'contourlayer',
'barlayer',
'waterfalllayer', 'barlayer',
'carpetlayer',
'violinlayer',
'boxlayer',
Expand Down
4 changes: 2 additions & 2 deletions src/plots/cartesian/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
);

// layers that allow `cliponaxis: false`
if(className !== 'scatterlayer' && className !== 'barlayer') {
if(className !== 'scatterlayer' && className !== 'barlayer' && className !== 'waterfalllayer') {
Drawing.setClipUrl(sel, plotinfo.layerClipId, gd);
}
});
Expand All @@ -277,7 +277,7 @@ function plotOne(gd, plotinfo, cdSubplot, transitionOpts, makeOnCompleteCallback
if(!gd._context.staticPlot) {
if(plotinfo._hasClipOnAxisFalse) {
plotinfo.clipOnAxisFalseTraces = plotinfo.plot
.selectAll('.scatterlayer, .barlayer')
.selectAll('.scatterlayer, .barlayer, .waterfalllayer')
.selectAll('.trace');
}

Expand Down
2 changes: 0 additions & 2 deletions src/traces/bar/arrays_to_calcdata.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var mergeArray = require('../../lib').mergeArray;


// arrayOk attributes, merge them into calcdata array
module.exports = function arraysToCalcdata(cd, trace) {
for(var i = 0; i < cd.length; i++) cd[i].i = i;
Expand Down
3 changes: 2 additions & 1 deletion src/traces/bar/cross_trace_calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function crossTraceCalc(gd, plotinfo) {
var fullTrace = fullTraces[i];
if(
fullTrace.visible === true &&
Registry.traceIs(fullTrace, 'bar') &&
(Registry.traceIs(fullTrace, 'bar') && fullTrace.type !== 'waterfall') &&
fullTrace.xaxis === xa._id &&
fullTrace.yaxis === ya._id
) {
Expand Down Expand Up @@ -237,6 +237,7 @@ function setOffsetAndWidth(gd, pa, sieve) {
var fullLayout = gd._fullLayout;
var bargap = fullLayout.bargap;
var bargroupgap = fullLayout.bargroupgap || 0;

var minDiff = sieve.minDiff;
var calcTraces = sieve.traces;

Expand Down
70 changes: 38 additions & 32 deletions src/traces/bar/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var Color = require('../../components/color');
var Registry = require('../../registry');

var handleXYDefaults = require('../scatter/xy_defaults');
var handleStyleDefaults = require('../bar/style_defaults');
var handleStyleDefaults = require('./style_defaults');
var getAxisGroup = require('../../plots/cartesian/axis_ids').getAxisGroup;
var attributes = require('./attributes');

Expand All @@ -22,8 +22,6 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
return Lib.coerce(traceIn, traceOut, attributes, attr, dflt);
}

var coerceFont = Lib.coerceFont;

var len = handleXYDefaults(traceIn, traceOut, layout, coerce);
if(!len) {
traceOut.visible = false;
Expand All @@ -39,34 +37,7 @@ function supplyDefaults(traceIn, traceOut, defaultColor, layout) {
coerce('hovertext');
coerce('hovertemplate');

var textPosition = coerce('textposition');

var hasBoth = Array.isArray(textPosition) || textPosition === 'auto';
var hasInside = hasBoth || textPosition === 'inside';
var hasOutside = hasBoth || textPosition === 'outside';

if(hasInside || hasOutside) {
var textFont = coerceFont(coerce, 'textfont', layout.font);

// Note that coercing `insidetextfont` is always needed –
// even if `textposition` is `outside` for each trace – since
// an outside label can become an inside one, for example because
// of a bar being stacked on top of it.
var insideTextFontDefault = Lib.extendFlat({}, textFont);
var isTraceTextfontColorSet = traceIn.textfont && traceIn.textfont.color;
var isColorInheritedFromLayoutFont = !isTraceTextfontColorSet;
if(isColorInheritedFromLayoutFont) {
delete insideTextFontDefault.color;
}
coerceFont(coerce, 'insidetextfont', insideTextFontDefault);

if(hasOutside) coerceFont(coerce, 'outsidetextfont', textFont);

coerce('constraintext');
coerce('selected.textfont.color');
coerce('unselected.textfont.color');
coerce('cliponaxis');
}
handleText(traceIn, traceOut, layout, coerce);

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

Expand Down Expand Up @@ -138,8 +109,43 @@ function crossTraceDefaults(fullData, fullLayout) {
}
}

function handleText(traceIn, traceOut, layout, coerce) {

var textPosition = coerce('textposition');

var hasBoth = Array.isArray(textPosition) || textPosition === 'auto';
var hasInside = hasBoth || textPosition === 'inside';
var hasOutside = hasBoth || textPosition === 'outside';

if(hasInside || hasOutside) {
var coerceFont = Lib.coerceFont;

var textFont = coerceFont(coerce, 'textfont', layout.font);

// Note that coercing `insidetextfont` is always needed –
// even if `textposition` is `outside` for each trace – since
// an outside label can become an inside one, for example because
// of a bar being stacked on top of it.
var insideTextFontDefault = Lib.extendFlat({}, textFont);
var isTraceTextfontColorSet = traceIn.textfont && traceIn.textfont.color;
var isColorInheritedFromLayoutFont = !isTraceTextfontColorSet;
if(isColorInheritedFromLayoutFont) {
delete insideTextFontDefault.color;
}
coerceFont(coerce, 'insidetextfont', insideTextFontDefault);

if(hasOutside) coerceFont(coerce, 'outsidetextfont', textFont);

coerce('constraintext');
coerce('selected.textfont.color');
coerce('unselected.textfont.color');
coerce('cliponaxis');
}
}

module.exports = {
supplyDefaults: supplyDefaults,
crossTraceDefaults: crossTraceDefaults,
handleGroupingDefaults: handleGroupingDefaults
handleGroupingDefaults: handleGroupingDefaults,
handleText: handleText
};
6 changes: 3 additions & 3 deletions src/traces/bar/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,9 @@ function hoverPoints(pointData, xval, yval, hovermode) {
}

function getTraceColor(trace, di) {
var mc = di.mcc || trace.marker.color;
var mlc = di.mlcc || trace.marker.line.color;
var mlw = di.mlw || trace.marker.line.width;
var mc = (di.mc !== undefined) ? di.mc : trace.marker.color;
var mlc = (di.mlc !== undefined) ? di.mlc : trace.marker.line.color;
var mlw = (di.mlw !== undefined) ? di.mlw : trace.marker.line.width;

if(Color.opacity(mc)) return mc;
else if(Color.opacity(mlc) && mlw) return mlc;
Expand Down
Loading