javascriptdojoxpagesdojox.charting

Better time ticks and axis labels in a dojo graph


My goal is to display a graph that shows the memory used by a web application over time, during a maximum of 6 hours, sliding, and refresh the screen regularly. That part works, but the possibilities for the X-axis are poor: either the standard scale and standard ticks, or silly time labels displayed by labelFunc(), with ticks at user-unfriendly positions.

Tick labels generated using labelFunc

I'd like to show proper times in the image, like 12:40:00 12:50:00 etc., but there seems to be no way to achieve that. Dojo seems to describe what ticks are, what their distance should be and when a label is printed.

As I see it, there could be two ways to solve my problem:

  1. I provide the labels array and dojo adds the ticks where I say they have to be.
  2. Or, dojo gets two new properties (per axis): startDate and endDate, so it can simply calculate the ticks itself.

The algorithm to calculate values and time strings isn't that difficult, I managed to do that:

labels:[{"value":21,"text":"12:20:00 PM"},{"value":121,"text":"12:30:00 PM"},{"value":221,"text":"12:40:00 PM"},{"value":321,"text":"12:50:00 PM"},{"value":421,"text":"1:00:00 PM"},{"value":521,"text":"1:10:00 PM"},{"value":621,"text":"1:20:00 PM"}]

Unfortunately, dojo doesn't follow suit, it just skips the values in the labels array when it decides it has to place a label and the corresponding value isn't in the array. It would be great if one could define that the array is leading.

Does anyone know of a flexible way to display user-friendly ticks and times on a dojox chart axis??

Thanks!


Solution

  • The solution was indeed, as Paul said, to add min and max, but I also had to set the tick steps, so I get relevant ticks positioned more or less logically.

    <xc:yn_ui_charts charttheme="BlueDusk" tooltips_enabled="false" charttype="Lines" width="1200" height="400" axisXMax="#{javascript:new Date().getTime()/1000}"
        axisXMin="#{javascript:SystemData.getLogStartDate().getTime()/1000}">
        <xc:this.dataSeries>
            <xp:value>#{javascript:SystemData.getUsageDataXY()}</xp:value>
        </xc:this.dataSeries>
        <xc:this.axisXLabelScript><![CDATA[var date= new Date(+xvalue*1000); return date.toLocaleTimeString();]]></xc:this.axisXLabelScript>
        <xc:this.axisXTickSteps><![CDATA[#{javascript:getTickSteps()}]]></xc:this.axisXTickSteps>
        <xc:this.axisXTicks><![CDATA[#{javascript:[true, true, true]}]]></xc:this.axisXTicks>
    </xc:yn_ui_charts>
    

    As you can see, I based my code on the yn_ui_charts Control originally developed by Julian Buss. I added a few parameters in order to simplify tick settings etc., and I create a simple function that defines the tick steps for me depending on the number of seconds in the image.

    function getTickSteps() {
        var limits= [1, 10, 20, 30, 60, 120, 300, 600, 1200, 1800, 3600, 7200, 10800, 21600];
        var start= Math.floor(SystemData.getDiskLogStartDate().getTime()/1000);
        var end= Math.floor(new java.util.Date().getTime()/1000);
        var seconds= end-start;
        var ticks= 10;
        var span= Math.floor(seconds/ticks);
        for(var l= limits.length-1; l>=0; l--)
            if(span>limits[l])
                break;
        var steps= [];
        if(l<limits.length-1)
            steps.push(limits[l+1]);
        if(l>=0)
            steps.push(limits[l]);
        if(l>0)
            steps.push(limits[l-1]);
        return steps;
    }
    

    An output sample:

    enter image description here

    QED