droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

HH:MM:SS on y-axis, better way?

Hello all experts

I need some advice/inputs.

What I have is a timestamp (that goes to the x-axis) and two readings:
First reading is “total”.
Second reading is “Out of total”.
The two readings are amount of time and comes from my database in this format: HH:MM:SS and goes to the y-axis.

I want to make a column-chart with the two readings next to each other so it’s easy to compare them.

What I’m doing now is to convert (with PHP, before data is being sent to Highcharts) the HH:MM:SS to HH.MM and this is working fine. But in the tooltip I want it to display the reading as HH:MM.

This is how my data looks like now:

Code: Select all

[ [1496872800000,17.24,1.07], [1496959200000,17.25,1.28], [1497045600000,17.27,5.46], [1497132000000,0.00,0.00] ]
Not sure if I’m doing it right here. Any other way showing HH:MM:SS on the yaxis? Will it takes this data:

Code: Select all

[ [1496872800000,17:24,1:07], [1496959200000,17:25,1:28], [1497045600000,17:27,5:46], [1497132000000,0:00,0:00] ]
This is how it looks now, and the missing data at 11.jun is not a mistake (no data yet):

Image

To sum up:
What I basically is trying to achieve is one of these two:
1: Format the tooltip to show XX:YY instead of XX.YY - Guess this can be done using the Tooltop Formatter.
2: Feed Highcharts with y-axis data in XX:YY format - Can this be done and is this this a more correct way to go than number 1?

Kind Regards
kamil

Re: HH:MM:SS on y-axis, better way?

Hi droiddk,

Here is example that shows how to format tooltip (use tooltip.pointFormat): http://jsfiddle.net/kkulig/9eu33ap2/3/
Please notice that I converted your data to timestamps in order to maintain proportions on y axis.That's a good way to handle that kind of data. If you pass numbers like "17.24" they are treated as floating point numbers (not time).

Best regards!
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

kamil wrote:Hi droiddk,

Here is example that shows how to format tooltip (use tooltip.pointFormat): http://jsfiddle.net/kkulig/9eu33ap2/3/
Please notice that I converted your data to timestamps in order to maintain proportions on y axis.That's a good way to handle that kind of data. If you pass numbers like "17.24" they are treated as floating point numbers (not time).

Best regards!
Hi kamil thanks for your reply.

Your JSFiddle is not working - no graph. :?

I cant figure out how to use timestamps, do you mean milliseconds?

I actually like the floating point numbers on the y-axis, how would the hh:mm:ss look like?

This is how my tooltip is formatted now:

Code: Select all

    tooltip: {
      formatter: function() {
        var number = Highcharts.numberFormat(this.y, 2, '.', '.');
        var number = moment(number, 'H:mm').format('HH:mm');
        return Highcharts.dateFormat('%Y/%m/%d', this.x) + " " + this.series.name + ': ' + number;
      }
    },
Please note I use moment.js for formatting the date. At the moment it is working as I would like, any comments? I have to use numberFormat because if I feed Highcharts with fx 14.30 this.y will give 14.3 and when using that with moment.js it will be converted to 14:03 :/

Best Regards
kamil

Re: HH:MM:SS on y-axis, better way?

Thank you for your reply.

There was a problem with Date.parse() (it worked properly only in Chrome). Here is fixed fiddle: http://jsfiddle.net/kkulig/9eu33ap2/

I used Highcharts.numberFormat() to change dots to colons (it's more elegant way than in previous fiddle).
You are right. I made a mistake in function naming: toTimestamp should be named toMs, because it returns miliseconds. It's fixed now.

Before pushing numbers to y I convert them to miliseconds. If you push them as floating point numbers then range from 60-99 (minutes - number after dot) will be never used. That's what I meant by saying that proportions won't be maintained. For example: there will be a bigger distance between 17.59 and 18.00 than between 17.57 and 17.59.

Do you convert floating point numbers to time data (with moment.js or any other way) before pushing it to y? Could you provide me with code fragment?

Best regards!
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi

Thanks for your reply.

I think it makes more sense doing it like in your example so I will go that way, I really appreciate your inputs!

I have three final (I hope) questions:

1: How to show 01:43 in the tooltip, now it show 1:43? I guess something like this:

Code: Select all

timeUnformatted < 10 ? ("0" + timeUnformatted) : timeUnformatted.toString()


2: How to align the tickmarks and labels on x-axis so they are between the column related to the date? Now they are a little bit to the right.

3: If I want to define the timezone and offset with this:

Code: Select all

        Highcharts.setOptions({
          global: {
            useUTC: false,
            timezoneOffset: 60 * -2
          }
        });
fx... by putting that piece of code in the button of the JSFiddle, then the graph will look odd when I disable/enable some of the series in the legend. And the graph will look odd right away if I place that piece of code in the top :/

Thanks :)

Kind Regards
Last edited by droiddk on Tue Jun 13, 2017 8:13 pm, edited 1 time in total.
kamil

Re: HH:MM:SS on y-axis, better way?

Hi,

All answers below are based on this updated fiddle: http://jsfiddle.net/kkulig/9eu33ap2/

1. Yes, it's correct way to do it. Since we operate on timestamps we can do it even more elegantly with dateFormat function:

Code: Select all

Highcharts.dateFormat("%H:%M", toMs(item[1]))
API reference: http://api.highcharts.com/highcharts/Hi ... dateFormat

2. & 3.
Code:

Code: Select all

        Highcharts.setOptions({
          global: {
            useUTC: false,
            timezoneOffset: 60 * -2
          }
        });
applies timezoneOffset to all axes. In this example x and y axes are 'datetime' type, so we also change offset for y values. That's why series are not aligned properly. Workaround for this is to define offset variable and then change x values manually:

Code: Select all

data.forEach((item) => (item[0] -= timezoneOffset * 60 * 1000));
This solves the problem from your second question.

Let us know if you have any further questions.

Best regards!
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi kamil

Thank you very much, I will have a look at it when I'm home but I guess it all makes sense, thanks to your fine answers.

Are you part of the Highchart team? Very qualified answers!

Kind Regards
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi kamil

Just a follow up.

Everything seems to be fine! Thanks.

But, I found one thing.

When a time like this: 17:30:40 is fed to the labels using this code:

Code: Select all

label: Highcharts.dateFormat("%M", toMs(item[1]))
then the label will show 17:03 :?

I just tried another route and instead of using the toMs-function I convert the hh:mm:ss to miliseconds with PHP before sending it to Highcharts and with this route the labels shows as they should.

Before when parsing the data to the data-arrays we did this:

Code: Select all

 y: toMs(item[1]),

And because that the data is now already miliseconds I have changed it to

Code: Select all

 y: item[1]
So I guess the error is in the toMs-function :)

Kind Regards
kamil

Re: HH:MM:SS on y-axis, better way?

Hi,

toMs() function is just for example purposes. It's not a generic util function. The assumption is that it takes as an argument float number in format "XX.XX" or "X.XX"; where "X" is a digit. This function doesn't even check if arguments are proper - it's easy to cause an error within it ;)

I'm glad everything is fine now.
Best regards!
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi

I just took it for good since it came from you, that toMs() :D

But no need to all that work in Javascript, MySQL can return seconds from HH:MM:SS when using the TIME_TO_SEC() function, much easier :lol:

I think I'm there, thank you very much for very very constructive help!

Kind Regards
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi Kamil and ohers

I'm back :)

So the yearly DST-shift happened this night and it caused some trouble.
I decided to use the "new" timezone-option and now all my spline-charts looks all right:

Code: Select all

Highcharts.setOptions({
  global: {
    timezone: 'Europe/Copenhagen'
  }
});   
But, my column-chart as we discussed above now looks like this:
Image

I guess it is because

Code: Select all

 timezone: 'Europe/Copenhagen' 
is working on both the y-axis and x-axis. How to avoid this when I have a chart (the column-chart) with datetime on the y-axis?
Top-priority is to keep 'timezone: 'Europe/Copenhagen' since this works great with all my spline-charts on the same website.

Example here: http://jsfiddle.net/droiddk/3krzLdq8/

EDIT: I also just realised that timezone: 'Europe/Copenhagen' is adding one hour to my column-values :/

I'm in a sort of dilemma here: I can easily make my spline-charts work with the irritating DST-change, but this will affect my column-chart, and I can make my column-chart work fine but that will make my spline-charts work badly with with DST-change. All because spline-chart and column-chart are on the same website (share the same global Highcharts settings) and column-chart uses datetime on the y-axis.

I would love the ability to disable 'timezone: 'Europe/Copenhagen' on the y-axis.

I really need some input here :/

Kind Regards
kamil

Re: HH:MM:SS on y-axis, better way?

Hi,

Before I wrote:
kamil wrote:

Code: Select all

        Highcharts.setOptions({
          global: {
            useUTC: false,
            timezoneOffset: 60 * -2
          }
        });
applies timezoneOffset to all axes. In this example x and y axes are 'datetime' type, so we also change offset for y values. That's why series are not aligned properly. Workaround for this is to define offset variable and then change x values manually:

Code: Select all

data.forEach((item) => (item[0] -= timezoneOffset * 60 * 1000));
If you apply the global time zone offset it'll always cause this unwanted space on the y axis. That's way I suggested setting the time zone offset manually and only for the desired axis.

One way of solving this issue is to set time offset manually on every chart - but it becomes problematic and not elegant when there're many charts.

I think that you should change the type of the yAxis to default linear type. Then use categories array to set proper labels (['00:00', '02:00', ...]) and convert datetime strings to numeric values using the following formula (because there're 60 mintues within an hour and not 100):

Code: Select all

H - hours from string
M - minutes from string
N - numeric value

N = H + (M * 5/3) / 100
The last step is to convert the number value in tooltip formatter back to the datetime format (so that values like 17.78 are not presented to the user). You can use the following formula for this:

Code: Select all

I - integer part of the number
D - decimal part of the number
DT - the number presented to the user

DT = I + (D * 3/5) / 100
If you have any further questions feel free to ask.

Best regards!

API references:
https://api.highcharts.com/highcharts/yAxis.categories
https://api.highcharts.com/highcharts/tooltip.formatter
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Hi Kamil

Thank you so much for your answer.
I think it sounds like the right thing to do using linear type instead.

EDIT: I tried going another route and came up with this: http://jsfiddle.net/droiddk/nadowtt7/ Seems to do the job, agree ? :D The new graph looks exactly ("down to the very last pixel") like the old graph but the new graph works with the timezone-option.

Kind Regards
Last edited by droiddk on Sat Nov 04, 2017 4:49 pm, edited 1 time in total.
kamil

Re: HH:MM:SS on y-axis, better way?

It looks good :) I'm glad everything is working fine now.
droiddk
Posts: 63
Joined: Wed Apr 13, 2016 2:30 pm

Re: HH:MM:SS on y-axis, better way?

Thanks. And again, thank you very much for your kind support, world class :)

Kind Regards
Droid

Return to “Highcharts Usage”