Maarten Deen
Maarten Deen

Reputation: 83

Chart.js combined line and bar chart with differing data points

I want to use chart.js to plot the daily generation of my solar panels combined with the month total in one chart, much like in the image below. Both graphs alone are easy to produce, but all examples I find for a combined chart have the same amount of datapoints for both charts. I have 12 for the bar chart and 365 or 366 for the line chart. Is it possible to make this?

Solar production

Upvotes: 2

Views: 2259

Answers (2)

Jürgen Fink
Jürgen Fink

Reputation: 3545

Using timeseries as x-Axis, applying additional trick:

Try following:

  1. set x-axis type to timeseries:
    for each x-Axis scales: {'daily-x-axis': { type: 'timeseries' ...
    for x-Axis type 'time' or 'timeseries' to work, you need additional libraries (like moment.js and its adapter)
  2. Trick: for monthly totals in your data, use first day of month as x value, like x: "2021-01-01" etc ...
  3. style your bars and labels/ticks, adding backgroundColor: 'rgba(0,0,255,0.5)', x- and y-Axis label colors, color of ticks, etc ...

let dailyGeneration = [{x: '2021-01-01', y: 1},{x: '2021-01-02', y: 3},{x: '2021-01-03', y: 2},{x: '2021-01-04', y: 5},{x: '2021-01-05', y: 8},{x: '2021-01-06', y: 2},{x: '2021-01-07', y: 11},{x: '2021-01-08', y: 10},{x: '2021-01-09', y: 7},{x: '2021-01-10', y: 6},{x: '2021-01-11', y: 1.5},{x: '2021-01-12', y: 3},{x: '2021-01-13', y: 4},{x: '2021-01-14', y: 6},{x: '2021-01-15', y: 0.5},{x: '2021-01-16', y: 3},{x: '2021-01-17', y: 9},{x: '2021-01-18', y: 8},{x: '2021-01-19', y: 7},{x: '2021-01-20', y: 6},{x: '2021-01-21', y: 6},{x: '2021-01-22', y: 4},{x: '2021-01-23', y: 3},{x: '2021-01-24', y: 1},{x: '2021-01-25', y: 1},{x: '2021-01-26', y: 2},{x: '2021-01-27', y: 5},{x: '2021-01-28', y: 8},{x: '2021-01-29', y: 7},{x: '2021-01-30', y: 12},{x: '2021-01-31', y: 2},
{x: '2021-02-01', y: 1},{x: '2021-02-02', y: 3},{x: '2021-02-03', y: 2},{x: '2021-02-04', y: 5},{x: '2021-02-05', y: 8},{x: '2021-02-06', y: 2},{x: '2021-02-07', y: 11},{x: '2021-02-08', y: 10},{x: '2021-02-09', y: 7},{x: '2021-02-10', y: 6},{x: '2021-02-11', y: 1.5},{x: '2021-02-12', y: 3},{x: '2021-02-13', y: 4},{x: '2021-02-14', y: 6},{x: '2021-02-15', y: 0.5},{x: '2021-02-16', y: 3},{x: '2021-02-17', y: 9},{x: '2021-02-18', y: 8},{x: '2021-02-19', y: 7},{x: '2021-02-20', y: 6},{x: '2021-02-21', y: 6},{x: '2021-02-22', y: 4},{x: '2021-02-23', y: 3},{x: '2021-02-24', y: 1},{x: '2021-02-25', y: 1},{x: '2021-02-26', y: 2},{x: '2021-02-27', y: 5},{x: '2021-02-28', y: 8}];

let montlyTotals = [{x: '2021-01-01', y: 98},{x: '2021-02-01', y: 120}];

let yourData = {
  datasets: [{
    type: 'line',
    label: 'Daily Generation',
    data: dailyGeneration,
    borderColor: 'rgba(0,0,255,1)',
    xAxisID: 'daily-x-axis',
    yAxisID: 'daily-y-axis',
  },
  {
    type: 'bar',
    label: 'Monthly Totals',
    data: montlyTotals,
    borderColor: 'rgba(0,255,0,0.5)',
    backgroundColor: 'rgba(0,255,0,0.5)',
    xAxisID: 'monthly-x-axis',
    yAxisID: 'monthly-y-axis',
  }]
};

let yourOptions = {
  scales: {
    // x-Axis by their IDs
    'daily-x-axis': { // <-- v3.x now object "{", not array "[{" anymore
      type: 'timeseries', // <-- try "time" and "timeseries" to see difference
      time: {
        unit: 'day', // <-- set to 'day'
        displayFormats: {
          day: 'MMM DD, YYYY',
          month: 'MMM'
        },
        tooltipFormat: 'dddd, MMM DD, YYYY'
      },
      ticks: {
        minRotation: 80, // avoiding overlapping of x-Axis ticks
        maxRotation: 90,
        color: "blue"
      },
      position: 'bottom'
    },
    'monthly-x-axis': {
      type: 'timeseries', // <-- try "time" and "timeseries" to see difference
      time: {
        unit: 'month', // <-- set to 'month'
        displayFormats: {
          day: 'MMM DD, YYYY',
          month: 'MMM'
        },
        tooltipFormat: 'MMM, YYYY'
      },
      ticks: {
        color: "green"
      },
      position: 'bottom'
    },
    // y-Axis by their IDs
    'daily-y-axis': {
      position: 'left',
      title: {
        display: true,
        text: 'kWh / day',
        color: "blue"
      },
      ticks: {
        color: "blue"
      }
    },
    'monthly-y-axis': {
      position: 'right',
      title: {
        display: true,
        text: 'total kWh / month',
        color: "green"
      },
      ticks: {
        color: "green"
      }
    }
  }
};

const ctx = document.getElementById('chartJSContainer').getContext('2d');

const myChart = new Chart(ctx, {
  data: yourData,
  options: yourOptions
});
<!-- get the latest version of Chart.js, now at v3.5.1 -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<!-- for x-Axis type 'time' or 'timeseries' to work, you need additional libraries -->
<!-- (like moment.js and its adapter) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment"></script>

<canvas id="chartJSContainer" width="600" height="400"></canvas>

Upvotes: 4

LeeLenalee
LeeLenalee

Reputation: 31431

Yes, just use object notation:

var options = {
  type: 'line',
  data: {
    datasets: [{
        label: '# of Votes',
        data: [{
          x: new Date('09-08-2021 12:04'),
          y: 10
        }, {
          x: new Date('09-08-2021 12:08'),
          y: 15
        }, {
          x: new Date('09-08-2021 12:12'),
          y: 5
        }, {
          x: new Date('09-08-2021 12:30'),
          y: 8
        }],
        borderColor: 'pink'
      },
      {
        type: 'bar',
        label: '# of Points',
        data: [{
          x: new Date('09-08-2021 12:04'),
          y: 4
        }, {
          x: new Date('09-08-2021 12:08'),
          y: 6
        }, {
          x: new Date('09-08-2021 12:12'),
          y: 12
        }, {
          x: new Date('09-08-2021 12:30'),
          y: 18
        }, {
          x: new Date('09-08-2021 12:022'),
          y: 10
        }, {
          x: new Date('09-08-2021 12:38'),
          y: 15
        }, {
          x: new Date('09-08-2021 12:52'),
          y: 5
        }, {
          x: new Date('09-08-2021 12:59'),
          y: 8
        }],
        backgroundColor: 'orange'
      }
    ]
  },
  options: {
    scales: {
      x: {
        type: 'time',
      }
    }
  }
}

var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
  <canvas id="chartJSContainer" width="600" height="400"></canvas>
</body>

Upvotes: -1

Related Questions