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

Floating bar charts #4120

Closed
mahead opened this issue Apr 6, 2017 · 30 comments
Closed

Floating bar charts #4120

mahead opened this issue Apr 6, 2017 · 30 comments

Comments

@mahead
Copy link

mahead commented Apr 6, 2017

I'm using Chart.js for plotting temperatures. Each plotted measure point is average of n measurements per hour/day/week/month/year. So I'm collecting data each minute, but plot only averages per different time periods. However, I would like to add also minimums and maximums per each measurement, because that would be a lot more useful than plotting just averages. Unfortunately I didn't find any kind support for plotting floating bars (or just plain vertical lines); all the bars are always started from zero.

I have attached similar kind of graph that I have in my mind (only addition to that is, that I want to plot also the average as continuous line too).
screenshot_20170406_220303

@etimberg
Copy link
Member

etimberg commented Apr 6, 2017

I think this is different enough from a regular bar chart that it involves a new chart type. I think you could create an extension that derives from a bar chart and the overrides the updateElement method so that the base property of the bar model is set to the value you want.

I think this would made a good extension to Chart.js but I think it's too specific to include in the main library.

@mahead
Copy link
Author

mahead commented Apr 7, 2017

Thanks for the comment and the tip! At the updateElement there is a line base: reset ? scaleBase : me.calculateBarBase(me.index, index),; do you meant that if I simply set desired value to the base variable instead of calling calculateBarBase(), I get the results I'm looking for? So all I have to do, is create an extension, implement updateElement method there with one extra parameter and then use the parameter value instead of calculateBarBase()?

(Sorry for asking stupid question; while I'm familiar with programming, I haven't done anything with javascript.)

@etimberg
Copy link
Member

etimberg commented Apr 7, 2017

It's almost that simple, yes 😄

However, one thing to keep in mind is that the base value is a raw pixel coordinate. To translate from a data coordinate to a pixel coordinate you need to use the axis to translate the value. In calculateBarBase that's done here so you should be able to do something very similar for your case.

Hope this helps!

@simonbrunel
Copy link
Member

@mahead In case you are working around the bar implementation, note that it has been fully refactored in #4044!

@mahead
Copy link
Author

mahead commented Apr 7, 2017

Thanks a lot for your help! I ended up modifying the Bar graph directly, because all the code was there already and basically all I had to do was to fake the bar class to think I was always having stacked bars. And add support for plotting range instead on single value. There are still couple of bugs left (bars don't affect the y-axle scale at all for some reason, tool tips always show NaN as a range, bottom border line missing on bars), but overall I'm very happy that I was able to modify the code for supporting my own purposes. :)

Here is live example with hour-by-hour humidity data (both outside & inside).
screenshot_20170408_010655

I'm happy to share the modifications if someone is interested, but I don't think there is much general use for those as it's probably not very often useful to have multiple bars on same x-axle point etc. And of course current implementation is mostly useless because it overwrites original bar functionality.

@etimberg
Copy link
Member

etimberg commented Apr 7, 2017

@mahead glad that was easy to do :)

I think for the tooltip issue you can get around it by changing the tooltip callback (though I'm not sure why the data would be NaN).

For the axes, I assume you are referring to the limits? Those should be updated for the data in each dataset but that won't work too well for ranges.

@mahead
Copy link
Author

mahead commented Apr 7, 2017

@etimberg I took a look at the tooltip, but didn't understand where the actual value is set. I believe the issue happens because I have modified the data format, this way:
{ type: 'bar', data: [{min: 60, max: 80},{min: 48, max: 84},{min: 40, max: 82},{min: 64, max: 88},{min: 60, max: 90},{min: 80, max: 86}], label: 'Piha min/max', backgroundColor: 'rgba(75, 192, 192, .2)', borderColor: 'rgba(75, 192, 192, .2)', borderWidth: 1, }
Because of this, I modified all the references to Dataset.Data[] => Dataset.Data[].Max at controller.bar.js . To make tooltips work, should something be fixed at another file? This is how it looks currently:
image

Regarding axes, you assume correctly. If I disable all the regular lines so that only these range bars are left, the scale is changed from -1...1, even though actual data values are greater:
image
But this is really not an issue, because other data lines help the scale to be correct. That tooltip would be only actual thing I would like to fix, since it's useful to hover mouse over the bar to check what the exact range is.

@etimberg
Copy link
Member

etimberg commented Apr 8, 2017

Changing the data format would do it. The default label is generated by https://github.com/chartjs/Chart.js/blob/master/src/core/core.tooltip.js#L72-L80

You can just override that in your config

options: {
  tooltips: {
    callbacks: {
      label: function(tooltipItem, data) {
        var label = data.datasets[tooltipItem.datasetIndex].label || '';

        if (label) {
          label += ': ';
        }
        label += data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index].max.toString();
        return label;
      }
    }
  }
}

@mahead
Copy link
Author

mahead commented Apr 8, 2017

@etimberg Thank you again, that indeed did the trick. 👍 (Though I also added the min value to the tooltip.)

When I originally noticed Chart.js doesn't support range bars, I tried to find alternative charting libraries. None of them pleased me (or they were commercial and prices were $300+), so I came back hoping you could implement the feature some day. I must say I'm more than happy that you could point me to do it by myself, and what I looked the code, it looked very clean and well structured; at least before my modifications. Keep up the good work!

@etimberg
Copy link
Member

etimberg commented Apr 9, 2017

Thanks @mahead! 😄 I think your chart would make a nice extension. If you publish it as it's own type eventually I'm happy to link to it from the docs

@benmccann
Copy link
Contributor

@mahead would you be able to share your implementation? I'm curious if you had to build new axes types or just a new controller?

@mahead
Copy link
Author

mahead commented Apr 22, 2017

@benmccann Sure, I could share the implementation. However, in it's current form it's an ugly hack that replaces the default bar graph. So, while it's very useful for me, there is no way it could be considered as general solution. So for now I'm not willing to contribute it anywhere, since I think I should make it properly first (and because of lack of time, I can't give any estimates).

Basically, as I see it, it's new type of controller. It is very similar to current stacked bar graph, just so that the base is taken from configured coordinates. I also changed the bar width to constant, because I don't want to place bars next to each other on single x point, but stack them and let them overlap. So far only issue I have, is that y-axle don't scale based on this modified bar type values. But it doesn't bother me, because I can use predefined values for my axles.

@benmccann
Copy link
Contributor

I've created a candlestick chart - https://github.com/chartjs/chartjs-chart-financial. You could probably create a floating bar chart using the candlestick chart by setting the high & low within the open & close.

@antoinecorne
Copy link

antoinecorne commented Apr 25, 2017

@mahead Hello, I'm currently working on a similar feature but for a horizontal bar chart instead. I managed to shift all bars with a constant value but would like to fill a specific one directly through the datasets (like your example). Could you tell me where do I have to look to do this? Thanks.

@eirikb
Copy link

eirikb commented May 8, 2017

Does this vaguely relate to #3574 ? I'm looking for a solution similar to what @antoinecorne is mentioning, I want a normal horizontal bar chart, but I want to set where each bar starts and ends. I don't need all the date-stuff in 3574.
What you have made @mahead looks great, basically exactly what I want, just vertically. It would be great to see your solution, even though you call it a hack.

@WasinTh
Copy link

WasinTh commented May 11, 2017

Hi. I've modify the Bar Chart to support the floated bar by adding "minData" parameter into the bar chart itself. You can have a look HERE
There are still problem with lower border of the floated bar.

@eirikb
Copy link

eirikb commented May 11, 2017

@WasinTh Didn't know about minData, haven't seen it in documentation either. I think this might be exactly what I'm looking for. Thanks!

@WasinTh
Copy link

WasinTh commented May 11, 2017

@eirikb It's not in the official release of ChartJS. I just modified their code and recompile it. If the community accept my approach, I'm willing to request pull on this modification.

@eirikb
Copy link

eirikb commented May 11, 2017

@WasinTh Ah I was a bit quick on the trigger. I didn't see any custom code in the fiddle, but now I noticed that the external resource is actually pointing to your version. Nevertheless, I think minData would suite me just fine, so I think it's a good idea.

@mahead
Copy link
Author

mahead commented May 14, 2017

@antoinecorne, @eirikb; It seems that I don't have time to properly implement my modifications, so I'm throwing it all here. Please feel free to take a look and take any ideas I might have had there. (I also added the Chart.js-master.zip that I had taken, so it's easier to diff only my modifications.)

chart.js.tar.zip
Chart.js-master.zip

@lex111
Copy link

lex111 commented May 31, 2017

And how can I set the minimum value for each data element?

For example:

data: [
   {min: 60}, // or simply 60 - when starts from zero
   {min: 48}
]

Those. It is possible for each dataset to specify from which value it should be shown (in the case of a stacked bar chart, so that the value does not start from zero). Is this possible?

@mahead
Copy link
Author

mahead commented May 31, 2017

@lex111 If you are using Chart.js version that I tweaked, you can define datasets this way:

data: [ { min:-13.5, max:7.6}, {min: -4.0, max:19.0 } ]

That will create two bars with ranges of -13,5 ... 7,6 and -4,0 ... 19,0.

@lex111
Copy link

lex111 commented May 31, 2017

@mahead Tried, but does not work incorrectly with stacked groups bar charts. All data must be represented by the object (eg { min:-13.5, max:7.6})? Can you show the demo, please?

@mahead
Copy link
Author

mahead commented May 31, 2017

@lex111 Sure, here is demopage.html as zipped attachment. You need to have Chart.bundle.min.js in same directory with the html file, then it will work (obviously you will need my version of the Chart.bundle.min.js, see earlier attachment).

Sorry for the Finnish language, I grabbed the file directly from the live environment.

demopage.zip

@sclaflin
Copy link

sclaflin commented Sep 1, 2017

I fiddled around a bit to and created a new chart type derived from bar based on version 2.6.0.

http://jsfiddle.net/3fepvcte/

I hope this helps!

@Meenu-Hexaware
Copy link

Meenu-Hexaware commented Oct 14, 2017

Can someone plz suggest me, how to plot xaxis values with dates [like 13/10/2017 format] in Bar chart

@benmccann
Copy link
Contributor

@Meenu-Hexaware you need to use the time scale. If you have more questions about this, let's please discuss elsewhere as the question is a bit off-topic on this thread

@xmyzincx
Copy link

xmyzincx commented Dec 21, 2017

@sclaflin Thanks a lot. It indeed helped a lot!!! Although there were some issues with tooltips but I fixed it anyway ;) I used it on version 2.7.1.

@hameddhib-dydu
Copy link

@sclaflin Thanks a lot for this exeple, but how can i adapt it for horizantal bar chart.

@simonbrunel
Copy link
Member

simonbrunel commented May 21, 2019

Implemented in #6056 and will be released in v2.9.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests