-
Notifications
You must be signed in to change notification settings - Fork 11.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
Group stacked bar charts (#2643) #3563
Conversation
@@ -49,6 +49,7 @@ borderSkipped | `String or Array<String>` | Which edge to skip drawing the borde | |||
hoverBackgroundColor | `Color or Array<Color>` | Bar background color when hovered | |||
hoverBorderColor | `Color or Array<Color>` | Bar border color when hovered | |||
hoverBorderWidth | `Number or Array<Number>` | Border width of bar when hovered | |||
stack | `String` | For grouping stacked bars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is String
the best type for this? Would a number make more sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think String
is the best, because it serves as the name of the stack. For instance, here's chadcodes' image from the related issue
Also a number would imply an order (confusing if Dataset1 and 2 are in stack 2
and Dataset 3 is in stack 1
)
On a slightly related note - do you think stack
is a generic enough property name, or would something like group
(or cluster
) be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that's a good call then. You're right that the numbers could imply an order to the stacks.
I think stack
is ok. Maybe @simonbrunel has some thoughts on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking group
first, but finally stack
might be better. Can we explicitly document this dataset.stack
as an ID and not a name to avoid any confusion with label/text/title?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking group first, but finally stack might be better.
After I chose stack
, I was worried that it would be very bar specific (just in case we want to use the same property for grouping datasets for other chart types) + we are calling it grouped stacked bars. But I'll go with whatever you suggest (I've being going back and forth between them that they both seem logical - I'll have good things to say about stack
once we've changed to group
:-))
Can we explicitly document this dataset.stack as an ID and not a name to avoid any confusion with label/text/title?
You mean call it stackID (like we do with axisIDs) and point to options (in future) for name, styling? Or do you mean just change For grouping stacked bars
to ID for grouping stacked bars
? Should be simple enough either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean simply change the documentation: identifier to group bars in stack(s)
(or similar) but keep the property name simple: stack
. About the stack vs group
, group
would make sense if this concept could be implemented for every types of chart, which I'm not sure it's possible, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok done!
About the stack vs group , group would make sense if this concept could be implemented for every types of chart, which I'm not sure it's possible, right?
I was thinking about folks who extend Chart.js to add other chart types (outside of the core library). If we call this stack
, they may be tempted to add / use a new property that's better suited to their chart type.
A convoluted example would be a grouped scatter plot (with pie charts instead of dots). stack
feels out of place, group
might be ok.
}, | ||
|
||
// Get the number of datasets that display bars. We use this to correctly calculate the bar width | ||
// Correctly calculate the bar width accounting for stacks and the fact that not all bars are visible | ||
getBarCount: function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be a good idea to have a unit test that tests this new functionality by creating a chart with multiple stacks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. I haven't worked with karma yet. Will read up a bit and add tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added unit test. Cheers!
if (xScale.options.barThickness) { | ||
return xScale.options.barThickness; | ||
} | ||
return xScale.options.stacked ? ruler.categoryWidth : ruler.barWidth; | ||
return (xScale.options.stacked && meta.stack === undefined) ? ruler.categoryWidth : ruler.barWidth; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be a good idea to always return bar width here and then have it correctly calculate for the stacks in getRuler
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The && meta.stack === undefined
retains the existing behaviour for (non-grouped) stacked bar widths - which is currently independent of barPercentage (and depends only on categoryPercentage).
I think it would be consistent to have non grouped stacked bar widths proportional to categoryPercentage AND barPercentage. If it's ok to change to make this change, I can remove meta.stack === undefined
from getBarCount
and remove the entire (xScale.options.stacked && meta.stack === undefined) ? ruler.categoryWidth :
part from here (i.e. just use ruler.barWidth which I believe is already correctly calculated)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the ungrouped stacked bar (or stacked with a single group) should use the bar width. I think it's safe to go ahead and make those changes. This will likely cause some test changes as well if we are testing the bar width at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done and changed unit tests.
I also changed the controller method names - getBarCount
to getStackCount
and getBarIndex
to getStackIndex
. The ruler property barCount
is now stackCount
. Related unit tests changed too.
@@ -33,16 +33,16 @@ module.exports = function(Chart) { | |||
|
|||
helpers.each(datasets, function(dataset, datasetIndex) { | |||
var meta = chart.getDatasetMeta(datasetIndex); | |||
if (valuesPerType[meta.type] === undefined) { | |||
valuesPerType[meta.type] = { | |||
if (valuesPerType[meta.type + meta.stack] === undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if there is a way to not have the stack leak into here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm... its somewhat similar to meta.type in that it's just another property to group datasets. Maybe a common meta property that factors in both type and (an optional stack) would be better? Might be too big a change though.
Can't think of anything nicer :-(
hey guys, when will be this branch merged? |
I didn't get time to review the whole code (will do asap) but I feel that the A rough idea would be to make the (deprecated code hidden)
|
@simonbrunel - the stack name feels a lot similar to the xAxisID and yAxisID properties on the dataset. And it would probably be a bit easier to manipulate the datasets in one place vs. changing them in both the IMO stack (i.e. the group name) is more data than option (data being something you can't omit without losing information, and option being something you can omit if you're ok with the defaults). |
@potatopeelings, after a second thought, I agree with you that it's more convenient to keep the |
@simonbrunel - sounds good! I'll add in something in scale |
@etimberg what do you think about this Actually, there are many cases to think about: (a) datasets: [{}, {}, {}, {}]
(b) datasets: [{ stack: 'foo' }, { stack: 'foo' }, {}, {}]
(c) datasets: [{ stack: 'foo' }, { stack: 'foo' }, { stack: 'bar' }, { stack: 'bar' }]
scale.stacked: undefined
(a) 4 stacks: [0][1][2][3]
(b) 3 stacks: [0,1][2][3]
(c) 2 stacks: [0,1][2,3]
scale.stacked: true
(a) 1 stack: [0,1,2,3]
(b,c) 2 stacks: [0,1][2,3]
scale.stacked: false
(a,b,c) 4 stacks: [0][1][2][3] Does it make sense? if so, would be great to have unit tests for all of these cases. |
@simonbrunel I think I agree with that behaviour. I think it's pretty unlikely that |
@simonbrunel - Done! @etimberg - The default config doesn't define BTW, there seems to be an existing (i.e. before groups) problem with stacks and logarithmic scales. I have raised an issue for it (#3585) . Just thought I'd mention it in case you notice something funny there when reviewing this PR. |
What's the final decision on the option name: I like |
I prefer If we want to group for tooltips or highlighting, I think think something more specific would be better (
That said, I don't mind |
@simonbrunel is this good to go? |
If everyone agree to use |
I'm good with |
@potatopeelings can you fix the merge conflict? then I'll merge this |
@etimberg - sure |
Excited for this merge ... waiting on bated breath here. :) |
@etimberg - I will need a few more days to get this sorted out (nothing to do with the code - my monitor just gave out :-(). Sorry! I should have done it straightaway instead of putting it off for the weekend. |
@potatopeelings thanks for letting me know |
Excited for this merge :-) |
All done! The (new and existing) codeclimate issues are because of the similarity in code between bar and horizontalBar (only the axes differ in these functions). These can be fixed by parameterizing the axes (but anyway, it would be cleaner to do that in a separate PR) Monitor is still wonky though - it gives out every 15 minutes instead of 1 now, so 2017 is better than 2016 :-) |
Thanks @potatopeelings |
@potatopeelings is it possible to add labels to stacks like in this fiddle (uses v2.1 and I think was a previous fiddle of yours)? http://jsfiddle.net/ryanwinchester/vw1wc464/1/ I tried editing it to use 2.5 but that didn't work for me. (@etimberg ) |
@simonbrunel understood. Thanks! |
@simonbrunel i still have this bug with the current version, do we know why? |
@JohnCoding94 can you build a jsfiddle that demonstrates your issue with 2.7.1? |
@simonbrunel i am using react-chartjs-2, i'll try to post that, thanks. |
Sounds good, also have a look to that comment to make sure you use the correct stacked options. |
Here is my options JSON: {
maintainAspectRatio: false,
legend: {
display: false,
position: 'left'
},
title: {
display: true,
text: '2018',
},
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}; Do you see something wrong with that syntax? |
It looks ok and should stack in both directions, what result do you get then? |
The same as @vaseker when he upgraded from the 2.4.0 to the 2.5.0. |
Any update on this one? https://jsfiddle.net/e8n4xd4z/9385/ Apparently 2.4.0 was the latest version this thing worked. See above comment by @vaseker |
Group stacked bar charts (chartjs#2643)
Code changes, documentation update and sample for #2643.
JSFiddle: https://jsfiddle.net/Lvj2qnrp/1/
(same as samples/bar/bar-stacked-group.html)