Flotr2 bug with bar graph dates

325 views Asked by At

I have a flotr2 graph that is supposed to display some data in it:

Edit: Chrome users: Please note, this jsfiddle does not seem to work me in chrome, not sure why

http://jsfiddle.net/1jgb2k6r/7/

My problem is that my bars aren't center-aligned over the date they represent.

$(function () {
    (function color_gradients(container) {
        var myData = [];

        myData.push([new Date('1/1/2014').getTime(), Math.ceil(Math.random() * 10)]);
        myData.push([new Date('1/8/2014').getTime(), Math.ceil(Math.random() * 10)]);
        myData.push([new Date('1/15/2014').getTime(), Math.ceil(Math.random() * 10)]);
        myData.push([new Date('1/22/2014').getTime(), Math.ceil(Math.random() * 10)]);
        var
        bars = {
            data: myData,
            bars: {
                show: true,
                barWidth: 0.8,
                lineWidth: 20,
            }
        };

        graph = Flotr.draw(
        container, [bars], {
            yaxis: {
                min: 0,
                max: 11
            },
            xaxis: {
                mode: 'time',
                timeMode: 'local',
                min: (new Date('1/1/2014').getTime() - (7 * 24 * 60 * 60 * 1000)),
                max: (new Date('1/22/2014').getTime() + (7 * 24 * 60 * 60 * 1000))
            }
        });
    })(document.getElementById("editor-render-0"));
});

Is there a way in flot to realign these bars?

1

There are 1 answers

0
C Bauer On BEST ANSWER

Always in the eleventh hour I post my question, and always in the eleventh hour I find the solution.

http://jsfiddle.net/1jgb2k6r/10/

Basically, the flot line of graphing libraries have an integral bug in their datetime calculations. They all suffer severe floating point rounding errors in relation to time axis on the graph which causes the bars to shimmy over to the left of their intended plot locations.

Here is an example of a getTimeScale function that returns a date as a week number from epoch time (starting at ~2200 from 1/1/2014):

function getTimeScale(date){
    return (new Date(date).getTime() / 1000 / 60 / 60 / 24 / 7);
}

This function, applied to date arguments in the data series, returns a normalized number not on the order of the hundreds of thousands:

$(function () {
    (function color_gradients(container) {
        var myData = [];


        myData.push([getTimeScale('1/1/2014'),Math.ceil(Math.random() * 10)]);
        myData.push([getTimeScale('1/8/2014'),Math.ceil(Math.random() * 10)]);
        myData.push([getTimeScale('1/15/2014'), Math.ceil(Math.random() * 10)]);
        myData.push([getTimeScale('1/22/2014'), Math.ceil(Math.random() * 10)]);

        var bars = {
            data: myData,
            bars: {
                show: true,
                barWidth: 0.8,
                lineWidth: 1,
            }
        };

        graph = Flotr.draw(
        container, [bars], {
            yaxis: {
                min: 0,
                max: 11
            },
            xaxis: {
                ticks: ticks,
                min: (getTimeScale('1/1/2014') - 1),
                max: (getTimeScale('1/22/2014') + 1)
            }
        });
    })(document.getElementById("editor-render-0"));
});

In order to display the ticks as a datetime again, you have to specify the ticks explicitly:

var ticks = [];

ticks.push([getTimeScale('1/1/2014'), '1/1/2014']);
ticks.push([getTimeScale('1/8/2014'),  '1/8/2014']);
ticks.push([getTimeScale('1/15/2014'), '1/15/2014']);
ticks.push([getTimeScale('1/22/2014'), '1/22/2014']);

graph = Flotr.draw(
    container, [bars], {
        yaxis: {
            min: 0,
            max: 11
        },
        xaxis: {
            ticks: ticks,
            min: (getTimeScale('1/1/2014') - 1), //gives a little padding room on the graph
            max: (getTimeScale('1/22/2014') + 1) //gives a little padding room on the graph
        }
});