Search code examples
javascriptjqueryflotutc

UTC Woes, Flot X Axis Time Wrong


So I've read through most search results, and the archives at the discussion group for flot... not sure what I can do here as I don't think I fully appreciate the problem...

I currently have unix timestamped data that I'm displaying on both daily and weekly snapshot graphs. Daily graph options shown...

            $.ajax({
                url: "/whats/encode_daily_graph.php?itemid=<?php echo $_GET['item']?>",
                method: 'GET',
                dataType: 'json',
                success: onOutboundReceived
            });
            function onOutboundReceived(series) {
                var length = series.length;
                var finalData = series;
                var options = {
                    lines: { show: true },
                    legend: { show : false },
                    points: { show: true, hoverable:true },
                    grid: { hoverable: true, clickable: true },
                    xaxis: { mode : "time", timeformat : "%H:%M" },
                    yaxis: { minTickSize: "1", tickDecimals : "0" }
                };
                $.plot($(".graph_daily"), finalData, options);
            }

So a lot threads (as well as the docs) mention that I should "pretend the data is UTC". Well in my case, since my data is all logged PST (UTC-8), I should just add 8*3600*1000 to my data that I'm passing into the graph, right? For some reason neither subtracting nor adding this offset does anything I expect - the scales change to something completely unreasonable. So I'm probably misunderstanding the entire question at hand.

Could anyone provide any insight into this matter? Thanks for your time!

EDIT : Here's what the AJAX url fetches back for one graph.

[{"label":"24 Hour Overview","data":[[1343283113000,"111"],[1343286597000,"111"], [1343290220000,"111"],[1343293802000,"111"],[1343297377000,"111"],[1343300843000,"111"], [1343304504000,"111"],[1343308105000,"111"],[1343311724000,"111"],[1343315331000,"111"],[1343322489000,"111"],[1343326080000,"111"],[1343329669000,"111"],[1343333296000,"111"],[1343336882000,"111"],[1343340493000,"111"],[1343344094000,"111"],[1343347683000,"111"],[1343351299000,"111"],[1343355015000,"111"],[1343358535000,"112"],[1343362132000,"112"],[1343365704000,"112"]],"color":"#FFAA42"}]

Here's what it looks like on graph. Note I have a tooltip that uses Javascript's Date to construct a Date object so I can easily grab the hour and minutes of the json data, and this doesn't match the axis. https://i.sstatic.net/k32IM.png

How the tooltip is rendered :

            var previousPoint = null;
            $(".graph_daily").bind("plothover", function (event,pos,item){
                if (item) {
                    if (previousPoint != item.dataIndex) {
                        previousPoint = item.dataIndex;

                        $("#graph_info").remove();
                        var x = item.datapoint[0].toFixed(2), y = item.datapoint[1].toFixed(2);
                        var date = new Date(item.datapoint[0]);
                        var hour = date.getHours();
                        var min = date.getMinutes();
                        var msg = hour + ":" + min + ", " + y;
                        if (min < 10) msg = hour + ":" + "0" +  min + ", " + y;
                        showToolTip(item.pageX, item.pageY, msg);
                    }
                }
                else{
                    $("#graph_info").remove();
                    previousPoint = null;
                }
            });

Solution

  • All you need to do is change your tooltip code to correctly add the timezone offset:

           var x = item.datapoint[0],
               y = item.datapoint[1].toFixed(2);
           var date = new Date(x + (7 * 60 * 60 * 1000));
    

    After that your graph axes and tooltips line up correctly for me. You may find that making your graph work for people in other timezones is slightly more complicated - you would want to move your raw JSON data to UTC (i.e. if it's recorded in PDT, add that before sending to the browser). Then when you go to create the tooltip, instead of offsetting by 7*60*60*1000, you would offset by this:

            var userTZ = new Date();//user = the viewers browser
            userTZ = userTZ.getTimezoneOffset()*60*1000;
            var dt = new Date(x+userTZ);
    

    Here it is working as in the simpler example: http://jsfiddle.net/ryleyb/4uuPZ/