AmCharts - Compare dataSets with missing values

2019-07-29 14:27发布

问题:

I'm using AmCharts to display two datasets which represent number of downloads per two file types: pdf and xls. The chart is similar to the one available at https://www.amcharts.com/demos/multiple-data-sets/, but I set recalculateToPercents option to 'never' to always display actual downloads count for compared series. I'm using hourly period.

The problem I encounter is that in situations when there are no downloads in specific hour for first file type (the main dataSet), the value for second file type is not displayed either, even when there are more than 0 downloads of the second file type.

Is it possible for amCharts to display values of compared series for dates that are not present in the main dataSet?

回答1:

Use this mini-plugin, which if syncDataTimestamps: true is in your chart config is set, will pre-process your data and will add missing "empty" data points to main data set so that all data points from all data sets are shown, even if their timestamps do not overlap:

/**
 * amCharts plugin: sync timestamps of the data sets
 * ---------------
 * Will work only if syncDataTimestamps is set to true in chart config
 */
AmCharts.addInitHandler(function(chart) {

  // check if plugin is enabled
  if (chart.syncDataTimestamps !== true)
    return;

  // go thorugh all data sets and collect all the different timestamps
  var dates = {};
  for (var i = 0; i < chart.dataSets.length; i++) {
    var ds = chart.dataSets[i];
    for (var x = 0; x < ds.dataProvider.length; x++) {
      var date = ds.dataProvider[x][ds.categoryField];
      if (dates[date.getTime()] === undefined)
        dates[date.getTime()] = {};
      dates[date.getTime()][i] = ds.dataProvider[x];
    }
  }

  // iterate through data sets again and fill in the blanks
  for (var i = 0; i < chart.dataSets.length; i++) {
    var ds = chart.dataSets[i];
    var dp = [];
    for (var ts in dates) {
      if (!dates.hasOwnProperty(ts))
        continue;
      var row = dates[ts];
      if (row[i] === undefined) {
        row[i] = {};
        var d = new Date();
        d.setTime(ts);
        row[i][ds.categoryField] = d;
      }
      dp.push(row[i]);
    }
    dp.sort(function(a,b){
      return new Date(a[ds.categoryField]) - new Date(b[ds.categoryField]);
    });
    ds.dataProvider = dp;
  }

}, ["stock"]);

This is taken from this amCharts demo.