plotgraphchart.jsintervals

chartjs 4.4 : not able to plot 2 time series in 1 graph


I have an issue with plotting 2 lines in 1 graph using chartjs: I get 2 graphs with 1 line in stead of 1 graph with 2 lines, and I think I made a very simpe error, but I can't find it. I have spend hours on it.

When I align the timestamps (with the same intervals), all works fine. But the timestamps have different intervals.

Here is the code:

<html>
<div>
  <canvas id="myChart"></canvas>
</div>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<script>

new Chart("myChart", {
    type: 'line',
    data: {
        datasets: [{
            data: [{x:'2021-11-06 23:39:30',y:1900},{x:'2022-11-07 01:00:28',y:2000},{x:'2023-11-08 09:00:28',y:1800}],
            borderColor: "red",
            label:"John",
            fill: false
        },{
            data: [{x:'2021-11-06 21:39:30',y:1800},{x:'2022-11-07 00:10:28',y:1650},{x:'2023-11-08 12:00:28',y:1900}],
            borderColor: "blue",
            label:"Laura",
            fill: false         
        }],
    },

    options: {
        scales: {
            x: {    
            },
            y: {
                min: 1000,      
                max: 2400, 
            }
        }
    }   
});
</script>
</html>

This is what I get

2 graphs

This is what I want:

Desired graph


Solution

  • Well the easy / fast solution for me would be to use the "date-module / adapter", since your x- values are dates. Just add the needed libs and set the type for x to for example time, and your string x-values should be all converted to correct "datetimes" and be displayed on the same axis / points. (first config in the demo below)

    A short demo:

    the demo also includes an alternative solution the x - values are stripped from the time part and than match with the help of the labels properties. The later is not very "nice" from a technical standpoint, but it works and doesn't need some fancy library. (It was just included, as an alternative solution/approach )

    const config = {
      type: 'line',
      data: {
        datasets: [
          {
            data: [
              { x: '2021-11-06 23:39:30', y: 1900 },
              { x: '2022-11-07 01:00:28', y: 2000 },
              { x: '2023-11-08 09:00:28', y: 1800 },
            ],
            borderColor: 'red',
            label: 'John',
            fill: false,
          },
          {
            data: [
              { x: '2021-11-06 21:39:30', y: 1800 },
              { x: '2022-11-07 00:10:28', y: 1650 },
              { x: '2023-11-08 12:00:28', y: 1900 },
            ],
            borderColor: 'blue',
            label: 'Laura',
            fill: false,
          },
        ],
      },
    
      options: {
        scales: {
          x: { type: 'time' },
          y: {
            min: 1000,
            max: 2400,
          },
        },
      },
    };
    
    var data1 = [
      { x: '2021-11-06 23:39:30', y: 1900 },
      { x: '2022-11-07 01:00:28', y: 2000 },
      { x: '2023-11-08 09:00:28', y: 1800 },
    ].map( entry => {
      entry.x = entry.x.split(' ')[0]
      return entry;
    });
    
    var data2 =  [
      { x: '2021-11-06 21:39:30', y: 1800 },
      { x: '2022-11-07 00:10:28', y: 1650 },
      { x: '2023-11-08 12:00:28', y: 1900 },
    ].map( entry => {
      entry.x = entry.x.split(' ')[0]
      return entry;
    });
    
    var labels = Array.from(new Set(data1.concat(data2).map( entry => entry.x).sort()))
    
    const config2 = {
      type: 'line',
      data: {
      labels: labels,
        datasets: [
          {
            data: data1,
            borderColor: 'red',
            label: 'John',
                     parsing: {
            yAxisKey: 'y'
          }
          },
          {
            data: data2,
            borderColor: 'blue',
            label: 'Laura',
             parsing: {
            yAxisKey: 'y'
          }
          },
        ],
      },
      options: {
        scales: {
            y: {
            min: 1000,
            max: 2400,
          },
        },
      },
    };
    
    var myChart = new Chart(document.getElementById('chart'), config);
    
    var myChart2 = new Chart(document.getElementById('chart2'), config2);
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/moment@^2"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-moment@^1"></script>
    
    <div class="chart" style="height:184px; width:350px;">
        <canvas  id="chart" ></canvas>
    </div>
    
    <div class="chart" style="height:184px; width:350px;">
        <canvas  id="chart2" ></canvas>
    </div>

    Info: Just for clarity, the chartjs lib doesn't recognize string-datetime values without an external library / adapter (link to documentation)