折线图:对齐多个数据集的x轴(时间戳)

Line chart: align x axis (timestamps) for multiple data sets

本文关键字:时间戳 数据集 对齐 折线图      更新时间:2023-09-26

我的头撞上了这堵砖墙。我有一个随时间跟踪三个数据点的数据集。这些数据点可以相互独立地改变。我试图在折线图中展示这些变化的历史,但我还没有找到如何为三者制作一个公共的x轴。

数据返回如下:

{
    "Default": {
        "Values": [
            999,
            799,
            999
        ],
        "Timestamps": [
            "2015-03-01T03:31:16+00:00",
            "2015-03-01T07:21:43+00:00",
            "2015-03-01T14:02:22+00:00"
        ]
    },
    "Current": {
        "Values": [
            399,
            849
        ],
        "Timestamps": [
            "2015-03-01T01:15:22+00:00",
            "2015-03-01T21:30:43+00:00"
        ]
    },
    "CurrentPremium": {
        "Values": [
            500,
            345,
            200,
            500
        ],
        "Timestamps": [
            "2015-02-01T14:24:00+00:00",
            "2015-03-01T00:13:28+00:00",
            "2015-03-01T09:56:43+00:00",
            "2015-03-01T12:00:04+00:00"
        ]
    }
}

返回的值指示此值何时从以前的值更改。

我正在使用chartjs中的折线图来可视化数据。为此,我需要提供一个与行的数据点匹配的通用标签列表,所以我需要以某种方式对齐这三个数据集,但我不知道如何实现这一点。

我会使用像lodash这样的库(使实用程序更快)将数据预处理到所有时间戳的平面列表中,然后对于每个数据集,如果该数据集没有来自所有时间戳合并平面列表的时间戳,则会为每个数据集生成一个记录为null的匹配值列表。

我还在我的chart js分支中添加了一个选项,它在这里很有用,可以将稀疏数据填充到仍然连接的行中,这样就不会留下难以看到的浮点。

var datasets = {
  "Default": {
    "Values": [
      999,
      799,
      999
    ],
    "Timestamps": [
      "2015-03-01T03:31:16+00:00",
      "2015-03-01T07:21:43+00:00",
      "2015-03-01T14:02:22+00:00"
    ]
  },
  "Current": {
    "Values": [
      399,
      849
    ],
    "Timestamps": [
      "2015-03-01T01:15:22+00:00",
      "2015-03-01T21:30:43+00:00"
    ]
  },
  "CurrentPremium": {
    "Values": [
      500,
      345,
      200,
      500
    ],
    "Timestamps": [
      "2015-02-01T14:24:00+00:00",
      "2015-03-01T00:13:28+00:00",
      "2015-03-01T09:56:43+00:00",
      "2015-03-01T12:00:04+00:00"
    ]
  }
};
//merge and sort all timestamps in to one array (used lodash here just to make things easy
var timestamps = _.chain(datasets).pluck("Timestamps").reduce(function(previous, current, index) {
  return previous.concat(current)
}).unique().sortBy(function(timestamp) {
  return new Date(timestamp)
}).value();
//set up base chart data with colours
var chartDatasets = [{
  fillColor: "rgba(220,120,120,0.2)",
  strokeColor: "rgba(220,120,120,1)",
  pointColor: "rgba(120,120,120,1)",
  pointStrokeColor: "#fff",
  pointHighlightFill: "#fff",
  pointHighlightStroke: "rgba(220,220,220,1)",
}, {
  fillColor: "rgba(20,120,120,0.2)",
  strokeColor: "rgba(20,120,120,1)",
  pointColor: "rgba(20,120,120,1)",
  pointStrokeColor: "#fff",
  pointHighlightFill: "#fff",
  pointHighlightStroke: "rgba(220,220,220,1)",
}, {
  fillColor: "rgba(120,120,120,0.2)",
  strokeColor: "rgba(120,120,120,1)",
  pointColor: "rgba(120,120,120,1)",
  pointStrokeColor: "#fff",
  pointHighlightFill: "#fff",
  pointHighlightStroke: "rgba(220,220,220,1)",
}]
//go through each dataset from server,
//for each dataset go through it's time stamps,
//go through the merged timestamps and if the timestamp is prresent in the dataset record the value other wise record null so we
//end up with a flat list of data that matches the flat time stamps
var datasetsIndex = 0;
_.forEach(datasets, function(dataset, key) {
  var data = [];
  _.forEach(timestamps, function(timestamp) {
    var dataToPush = null;
    _.forEach(dataset.Timestamps, function(datasetTimestamp, datasetTimestampIndex) {
      if (datasetTimestamp === timestamp) {
        dataToPush = dataset.Values[datasetTimestampIndex];
      }
    });
    data.push(dataToPush);
  });
  chartDatasets[datasetsIndex].label = key;
  chartDatasets[datasetsIndex].data = data;
  datasetsIndex++;
});
var chartData = {
  labels: timestamps,
  datasets: chartDatasets
};
var chart = new Chart(document.getElementById("chart").getContext("2d")).Line(chartData, {
  populateSparseData: true
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.3.1/lodash.js"></script>
<script src="http://quincewebdesign.com/cdn/Chart.js"></script>
<canvas id="chart" width="400" height="400"></canvas>