Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chart.js: different dataset size

I need to display what I think is a pretty common use case: A line chart showing e.g. daily and hourly averages covering one week.

One dataset has obviously 7 data points, the other has 168.

I have not been able to find an example or a documented option that would allow for this. Sure - I can configure almost anything regarding the look&feel, but when it comes to the data size, both datasets are expected to have as many data points as there are labels.

I would like to have labels only for the dataset with the less datapoints (in this example: daily avg), and the other (168 data points) would simply draw a thin line and should not add aynthing else to the chart (no vertical bars etc.)

Is this possible with Chart.js?

like image 744
Perlator Avatar asked Apr 03 '17 19:04

Perlator


1 Answers

What you are describing is actually possible with chart.js as long as at least 1 of your datasets can be expressed using the alternate scatter chart dataset. Let me walk you through an example where I show the daily avg as bars and the hourly avg as a line (aka, a mixed chart type).

First, configure a bar chart with labels for each day of the week and provide the daily average values for the data as your first dataset.

Next, create another dataset, but set it's type property to 'line'. Since we are wanting to use a different X axis and a different set of labels, you must express your data using the {x: 0, y: 2} notation. This will allow you to circumvent the scale from using the labels defined above.

Finally, in your options.scales config, define 2 xAxes scales and associate your 2nd dataset to the 2nd X axis scale (also set it's display property to false so you don't see any of the 2nd scale).

You end up with a chart configuration that looks like this.

var ctx = document.getElementById("canvas").getContext("2d");
var myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
    datasets: [{
      type: 'bar',
      label: 'Daily Avg',
      backgroundColor: chartColors.red,
      data: dailyAvgData,
      borderColor: 'white',
      borderWidth: 2
    }, {
      type: 'line',
      label: 'Hourly Avg',
      borderColor: chartColors.green,
      backgroundColor: chartColors.green,
      borderWidth: 1,
      fill: false,
      pointRadius: 0,
      xAxisID: 'x-axis-2',
      data: hourlyAvgData
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Chart.js - Combo Chart With Multiple Scales (X Axis)'
    },
    tooltips: {
      mode: 'nearest',
      intersect: true
    },
    scales: {
      xAxes: [{}, {
        id: 'x-axis-2',
        type: 'linear',
        position: 'bottom',
        display: false,
      }],
      yAxes: [{
        ticks: {
          min: 0,
          max: 50
        }
      }]
    }
  }
});

You can see it in action at this codepen.

Here is another example but instead of using a combo chart (daily is bars, hourly is line), both plots are lines. The approach is exactly the same except the chart type is changed from bar to line.

Note, in this version I have adjusted the daily avg line over by one so that the points are plotted at the "end of the day". The previous example was showing the daily avg at the start of each day (which is technically not correct).

Here is an example codepen that demonstrates the line version of the chart.

like image 176
jordanwillis Avatar answered Oct 21 '22 06:10

jordanwillis