0
votes

I have run my head into a brick wall with this one. I have a data set that tracks three data points over time. These data points can change independently of each other. I am trying to show the history of these changes in a line chart but I have yet to find out how to make a common x axis for the three.

The data is returned like this:

{
    "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"
        ]
    }
}

The returned values indicate when this value changed from its previous value.

I am using a linechart from chartjs to visualize the data. For that I need to supply a common list of labels that match the data points for the lines so I need to align these three data sets somehow but I can't figure out how to achieve this.

1
was the below answer what you were looking for?Quince

1 Answers

0
votes

I would use a library like lodash (to make utility things quicker) to pre process the data into a flat list of all timestamps and then for each dataset a matching list of values recording null if that data set does not have a timestamp from the merged flat list of all timestamps.

I have also added an option to my fork of chart js which would be useful here which would be to then populate sparse data to the lines still connect and you are not left with floating points that can be hard to see.

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>