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

时间:2015-03-01 13:45:28

标签: javascript chart.js

我用这个把头撞到了一堵砖墙上。我有一个跟踪三个数据点的数据集。这些数据点可以彼此独立地改变。我试图在折线图中显示这些变化的历史,但我还没有找到如何为三者创建一个共同的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的线图来可视化数据。为此,我需要提供一个与行数据点匹配的标签列表,因此我需要以某种方式对齐这三个数据集,但我无法弄清楚如何实现这一点。

1 个答案:

答案 0 :(得分:0)

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

我还在我的图表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>
&#13;
&#13;
&#13;