Chart.js: Floating bar charts

Created on 6 Apr 2017  路  30Comments  路  Source: chartjs/Chart.js

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

enhancement

Most helpful comment

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!

All 30 comments

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.

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.)

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!

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

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.

@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.

@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.

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;
      }
    }
  }
}

@etimberg Thank you again, that indeed did the trick. :+1: (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!

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

@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?

@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.

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.

@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.

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.

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.

@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!

@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.

@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.

@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

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?

@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.

@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?

@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

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!

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

@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

@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.

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

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

gouthamrv picture gouthamrv  路  3Comments

HeinPauwelyn picture HeinPauwelyn  路  3Comments

nanospeck picture nanospeck  路  3Comments

benmccann picture benmccann  路  3Comments

adriantombu picture adriantombu  路  3Comments