-
Notifications
You must be signed in to change notification settings - Fork 22.9k
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
stack layout does not support a mix of positive and negative bars #2265
Comments
I made a copy of d3.layout.stack and implemented my suggestion locally. It worked nicely. I can now show stacked bars with positive and negative bars in the same stack. I just need to supply "offset" and "out" functions that maintain y0 as a [positiveBase, negativeBase]. .offset(function(data) {
var j = -1;
var len = data[0].length;
var y0 = [];
while (++j < len) {
// baseline for positive and negative bars respectively.
y0[j] = [0, 0];
}
return y0;
})
.out(function(d, y0, change, y) {
// update either the positive or negative baseline depending on the sign of the bar segment.
var posOrNeg = (change >= 0) ? 0 : 1;
y0[posOrNeg] += change;
d.y0 = y0.slice();
d.y = y;
}); I hope this small change can be incorporated into a future version of D3. |
Thank you for this @barrybecker4, it would be great if this was included any time soon. |
Got same problem. Thank you @barrybecker4 for the idea. var buildOut = function(dataSeriesCount) {
var currentXOffsets = [];
var current_xIndex = 0;
return function(d, y0, y){
if(current_xIndex++ % dataSeriesCount === 0){
currentXOffsets = [0, 0];
}
if(y >= 0) {
d.y0 = currentXOffsets[1];
d.y = y;
currentXOffsets[1] += y;
} else {
d.y0 = currentXOffsets[0] + y;
d.y = -y;
currentXOffsets[0] += y;
}
}
} And then just call The point is to store positive and negative values in a closure: currentXOffsets. No backward incopatibilities. |
+1 |
Sounds useful, although presumably this only makes sense with the “zero” offset? When there’s a non-zero baseline then you don’t really have a place to put negative values. |
Thanks @novtor on that improved solution. It's much better to do it that way instead of trying to modify the layout code as I did originally. In my case, I always use a 0 offset, but maybe this could work if currentXOffsets is initialized in a way that matches the offset function. |
Thanks. Where to make this call d3.layout.stack().out(buildOut(seriesCount)). I have 2 series(cash_in, cash_out and I was attempting to show a stacked chart, with positive for cash_in and negative for cash_out). Thanks in Advance if you could help.
|
@seedhisadak , just follow an example of d3 layout stack (like here http://bl.ocks.org/mbostock/1134768) and then to create the layout, do |
@novtor That helps. Thank you very much |
@novtor Thanks a lot for your help. it works. |
The d3.stack layout was rewritten for 4.0, so closing this issue. |
The stack layout rewrite doesn't specifically "solve" this issue, right? It just changes the optimal solution(s)? I've been working to convert a stacked bar chart of mixed positive and negative values from D3 3.x to 4.0, and it seems like some custom adjustment still needs to be made, either to the returned array from |
It is possible to use d3.stack with positive and negative values, so in that sense it is already supported and this issue is closed. But moreover the code now resides in d3-shape, so a discussion about what new features may be useful in improving the design (I do not claim that the current design is optimal—things can always be improved) should happen over there rather than here. If you have a specific suggestion for improving the design of d3.stack please open a new issue over in the d3-shape repo; otherwise I do not have any concrete changes planned in this area for d3.stack. |
This may be my lack of understanding and not an actual limitation, but it seems that the stack layout only supports showing stacked bars when the bars are all positive (or all negative). I would like to show a stacked bar chart where bar segments with positive height extend above the x axis, and those with negative segments extend below the x axis.
The reason I don't think this is possible with the current stack layout is because it involves maintaining a baseline for positive and negative bars separately (not just y0). If each series had only positive or negative bars, then the current layout would work, but I want to allow for any of the series to have a mix of positive and negative values.
I think this limitation could be removed with just a small change in the stack layout code.
If the signature of the out function was
function out(d, y0, change, y)
instead of
function out(d, y0, y)
and
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
was changed to
out.call(stack, series[i][j], o, points[i - 1][j][1], points[i][j][1]);
then I could store [positiveBase, negativeBase] in y0 instead of just a single scalar, and maintain separate y0 values for positive stacks and negative stacks. Is that correct? Would this be a good change. I realize that there would be backwards compatibility issues.
The text was updated successfully, but these errors were encountered: