Search code examples
javascriptplotchartszingchart

Defining 'step' attribute in Zingchart renders the graph unusable


Scenario:

I am able to get a status graph with Zingchart, using a stacked hbar and plotting data intervals where the status of an element doesn't change: Zingchart graph OK

However, I would like to have more resolution in the axis that provides the time.

Problem:

I am not able to increase the number of ticks in the y-axis (this is an stacked hbar graph, so the usual x-axis is actually the y-axis).

If I introduce step:"1hour", in the scaleY field I get back to epoch 0 and this is what I obtain:

Zingchart graph definitely not OK

Question:

What am I doing wrong? I would like either:

  • To have more time references in the axis of the time.
  • Or (and this may be another question) to be able to know on mouse over (in the tooltip?) at what time I am. Since I am plotting time increments I lost the actual time on where the change of status happens. Is there a direct way to do this in this particular situation? Or do I have to carry another data-customValue for the actual date of the start / end of the interval?

In the code, I jump from epoch 0 to the time I start having data, and define minValue to plot as the first epoch I have data minus one second. This is the working code (no step attribute defined):

<!DOCTYPE html>
<html>

<head>
  <script src="/home/eballes/Work/backup/zingchart_test/zingchart_2.3.3/zingchart.min.js"></script>
  <script>
    zingchart.MODULESDIR = "/home/eballes/Work/backup/zingchart_test/zingchart_2.3.3/modules/";
  </script>
  <style></style>
</head>

<body>
  <div id='myChart'></div>
  <script>
var myConfig = {
    type: "hbar",
    utc:true,
    title: {
      text: 'Status'
    },
    scaleY:{
      transform:{
        type:'date',
        all:"%d/%M/%Y\n%H:%i:%s",
      },
      minValue:1456693864000, 
      zooming:true,
      label:{
        "text": "Time",
      },
      tick:{
          "line-color":"black",
          "line-width":"2px",
          "size":8,
      },
      maxItems:10,
      itemsOverlap:true,
      item:{
        "font-size":10
      },
    },
    scaleX:{
      label:{
        "text": "Item",
      },
    },
    plot:{
      stacked:true,
      exact:false,
      barWidth:10,
      rules:[
        {
          rule:'%data-customValue == 0',
          alpha:0, // Transparent
        },
        {
          rule:'%data-customValue == 1',
          backgroundColor:'#0000FF' // Dark Blue
        },
        {
          rule:'%data-customValue == 2',
          backgroundColor:'#00FFFF' // Light Blue
        },
        {
          rule:'%data-customValue == 3',
          backgroundColor:'#FF7F50' // Orange
        },
        {
          rule:'%data-customValue == 4',
          backgroundColor:'#FFFF00' // Yellow
        },
        {
          rule:'%data-customValue == 5',
          backgroundColor:'#EE82EE' // Purple
        },
        {
          rule:'%data-customValue == 6',
          backgroundColor:'#00FF00' // Green
        },
        {
          rule:'%data-customValue == 7',
          backgroundColor:'#FF0000' // Red
        },
      ]
    },
    tooltip:{
        jsRule:"CustomFn.formatTooltip()",
    },
    series : [
        {
            values : [
            [1,1456693864000],
            [2,1456693864000], 
            .... // From 1 to 36
            [36,1456693864000], 
            ],
            'data-customValue':[0,0,0,0,0,0,
                                0,0,0,0,0,0,
                                0,0,0,0,0,0,
                                0,0,0,0,0,0,
                                0,0,0,0,0,0,
                                0,0,0,0,0,0],
        },
                {
            values : [
[11, 32000], [12, 10270000], [14, 5033000], [18, 79000], [20, 43000], [24, 76000], [26, 4043000], [8, 33000], [9, 63000], 
            ],
            'data-customValue':[2, 6, 6, 0, 1, 2, 6, 1, 0, ],
        },
        {
            values : [
[14, 3000], [19, 20000], [26, 1000], [8, 86000], [9, 13000], 
            ],
            'data-customValue':[2, 2, 2, 0, 1, ],
        },
// All intervals

    ]
};

CustomFn = {};
CustomFn.formatTooltip = function(p){
  var hours = Math.floor(p.value / 3600000);
  var minutes = Math.floor((p.value % 3600000) / 60000);
  var seconds = (p.value % 60000)/1000;
  var tooltipText = "Item: " + p.scaletext + "\nDuration: ";

  var hoursText = (hours == 0) ? "" : (hours + "h ");
  var minutesText = (minutes == 0) ? "" : (minutes + "m");
  var secondsText = (seconds == 0) ? "" : (seconds + "s");

  tooltipText = tooltipText + hoursText + minutesText + secondsText + "\n";
  tooltipText = tooltipText + "Value: " + p['data-customValue'];

  var alpha = 70;

  // We don't want any tooltip for the time-jump
  if (hours > 300000) {
    tooltipText = "";
    alpha = 0;
  }

  return {
    text : tooltipText,
    backgroundColor : "#222",
    alpha: alpha,
  }
};

zingchart.render({
    id : 'myChart',
    data : myConfig,
    height: 670,
    width: '100%'
});
  </script>
</body>

</html>

This is the link to the Plunker with the whole example, not working. If you remove the line step:"1hour", it will work.

Funny enough, step:20 works fine. But I would prefer to have my steps in a normal way, like hourly.


Note: Just to provide some more context, this question is the continuation of this other previous question.


Solution

  • Full Disclosure, I'm a member of the ZingChart team.

    The first problem being

    step:'1hour'
    

    That string value is being interpreted by our library as the value 0. This is because the string '1hour' does not match any of our keywords nor does it evaluate to a Number type. We are not simply using parseInt so it does not evaluate to 1.

    If you want an hourly step you would do the step count in milliseconds. This is documented in our scales page.

    step:3600000
    

    For display the scale value we do have a tokens list which allows you to add values from your scale to your tooltip. In your customFn.formatTooltip you would add this line.

      ...
      tooltipText = tooltipText + "Value: " + p['data-customValue'];
      tooltipText += '<br> %vv'
    

    The %vv is in our tokens list and will grab the transformed value off the y-axis. If you did %vt it would give you the millisecond value.