javascriptjscharts

Handling empty data in Jscharting


I have this Jscharting script which loads data from a csv file. It works great, but unfortunately it doesn't load at all if there is any empty data in the source. How would you add handling empty data into following script?

JSC.fetch( 
  './js/data.csv'
).then(function(response) { 
  response.text().then(function(t) {
       
var jsonData = JSC.csv2Json(t,{coerce:function(d){
  return {
    Date: d.date,
    s1: parseFloat(d.s1),
    s2: parseFloat(d.s2),
  }

}});

var s1Points = JSC.nest()
  .key('Date')
  .rollup('s1')
  .points(jsonData);

var s2Points = JSC.nest()
  .key('Date')
  .rollup('s2')
  .points(jsonData);       

var chart = JSC.chart('chartDiv', { 
  debug: true, 
  type: 'line', 
  legend_visible: false, 
  defaultCultureName: "hu-SK",
  xAxis: { 
    crosshair_enabled: true, 
    scale: { 
      type: 'time',
      time: {
              parser: 'YYYY-MM-DD',
              }
    },
    formatString: 'd',
  },
  yAxis: { 
    orientation: 'opposite', 
    formatString: 'c'
  }, 
  defaultSeries: { 
    firstPoint_label_text: '<b>%seriesName</b>', 
    defaultPoint_marker: { 
      type: 'circle', 
      
      fill: 'white', 
      outline: { width: 2, color: 'currentColor' } 
    } 
  }, 
  series: [ 
    { 
      name: 's1', 
      points: s1Points 
    }, 
    { 
      name: 's2', 
      points: s2Points 
    }
  ] 
});
});
});

I tried simple thing as:

s1: (parseFloat(d.s1) || '0'),
s2: (parseFloat(d.s2) || '0'),

...but the result is quite unreadable:

enter image description here

I would like to have in this case break the continuous line instead of zero value, if it's possible.


Solution

  • I think you need to use parseFloat(d.s1) || null.
    And, on series, set emptyPointMode to default, ignore, or treatAsZero.

    Demo JsFiddle

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width,initial-scale=1.0">
      <title>Empty point mode</title>
    </head>
    
    <body>
      <script src="https://code.jscharting.com/latest/jscharting.js"></script>
      <div id="chartDiv" style="width: 100%; height: 400px;"></div>
      <script>
        function showData(t) {
          var jsonData = JSC.csv2Json(t, {
            coerce: function (d) {
              return {
                Date: d.date,
                s1: (parseFloat(d.s1) || null),
                s2: (parseFloat(d.s2) || null),
                s3: (parseFloat(d.s3) || null),
              }
    
            }
          });
    
          var s1Points = JSC.nest()
            .key('Date')
            .rollup('s1')
            .points(jsonData);
    
          var s2Points = JSC.nest()
            .key('Date')
            .rollup('s2')
            .points(jsonData);
          var s3Points = JSC.nest()
            .key('Date')
            .rollup('s3')
            .points(jsonData);
    
          var chart = JSC.chart('chartDiv', {
            debug: true,
            type: 'line',
            legend_visible: true,
            title: {
              position: 'top',
              padding: 7,
              fill: ['orange', 'orange', 0],
              opacity: 0.4,
              boxVisible: true,
              label: {
                text: 'emptyPointMode: default / ignore / treatAsZero',
                align: 'left'
              }
            },
            legend: {
              position: 'inside right top',
              defaultEntry_value: '%value'
            },
            defaultCultureName: "hu-SK",
            xAxis: {
              crosshair_enabled: true,
              scale: {
                type: 'time',
                time: {
                  parser: 'YYYY-MM-DD',
                }
              },
              formatString: 'dd',
            },
            yAxis: {
              orientation: 'opposite',
              formatString: 'c'
            },
            defaultSeries: {
              firstPoint_label_text: '<b>%seriesName</b>',
              defaultPoint_marker: {
                type: 'circle',
    
                fill: 'white',
                outline: { width: 2, color: 'currentColor' }
              }
            },
            series: [
              {
                name: 'default',
                points: s1Points,
                emptyPointMode: 'default'
              },
              {
                name: 'ignore',
                points: s2Points,
                emptyPointMode: 'ignore'
              },
              {
                name: 'treatAsZero',
                points: s3Points,
                emptyPointMode: 'treatAsZero'
              }
            ]
          });
        }
    
        const data = `date,s1,s2,s3
    2022-01-1,22.2,33,15
    2022-01-2,25.2,30,17
    2022-01-3,30.1.2,35,13
    2022-01-4,20.2,25,15
    2022-01-5,,,
    2022-01-6,22.2,30,15
    2022-01-7,23.2,31,15,
    2022-01-8,23.2,31.5,16
        `;
        showData(data);
    
      </script>
    </body>
    
    </html>

    In above demo 5th day has no data.
    The demo may not run on Stackoverflow. Use the JsFiddle link.