Search code examples
chartschart.js

How to create a chart where some labels don't have a value in ChartJS?


I want to create a chart in ChartJS that shows progress over time. In my database I only have the values and dates for the dates that the progress has changed. So something like this:

    "progress": {
        "07.02.2020": 0,
        "29.02.2020": 1,
        "07.04.2020": 2,
        "07.05.2020": 3,
        "07.07.2020": 4,
        "07.08.2020": 5,
        "07.09.2020": 6,
        "07.11.2020": 7,
        "07.12.2020": 8,
        "07.01.2021": 9,
        "07.02.2022": 10,
        "30.02.2022": 11
    }

I used this script to add labels for every date between 07.02.2020 and 30.02.2022:

function addDatesToChart(startDate, endDate) {
    const currentDate = new Date(startDate.getTime());
    console.log(currentDate);
    while (currentDate <= endDate) {
        chartData3.labels.push(new Date(currentDate).toLocaleDateString("et-EE", {year: "numeric", month: "2-digit", day: "2-digit"}));
        currentDate.setDate(currentDate.getDate() + 1);
    }
}

Then I used this script to add the progress values to the chart and fill in the gaps with the value from the last progress entry:

let lastGivenProgress = 0;
let lastGivenProgressIndex = 0;
for (let i = 0; i < chartData.labels.length; i++) {
    if (!(Object.keys(progress).includes(chartData.labels[i]))) {
        chartData.datasets[0].data.push(lastGivenProgress);
    }
    else {
        chartData.datasets[0].data.push(Object.values(data)[lastGivenProgressIndex++]);
        lastGivenProgress = Object.values(progress)[lastGivenProgressIndex];
    }
}

The problem is that I'd like the line to have tension, but I can't use that if all the labels have a value and so the line comes out jagged:

chart

I wonder if there is a way to just add the values at certain indexes and leave other labels empty so that the line gets drawn between the points where progress has changed? So something like the red line in this image (sorry for my horrible drawing):

Expected chart

Maybe you have another suggestion, a different approach that I haven't thought of?


Solution

  • have you tried using the spanGaps option ? If you don't set any Y value, except where progresses were made, there should be gaps between your points. Using this, according to chartjs documentation, it should draw lines between points with data, such as:

    var ctx = document.getElementById('myCanva').getContext('2d');
    
    var config = {
      type:'line',
      data:{
        labels:[0,1,2,3,4,5,6,7,8,9],
        datasets:[{
          data:[1,2,5,null,9,null,null,15,null,20],
          label:'A'
        }]
      },
      options:{
        spanGaps:false,
      }
    } 
    
    var myChart = new Chart(ctx, config)
    
    
    function spanGapsBtn(){
      config.options.spanGaps = !config.options.spanGaps
      myChart.update()
    }
    <script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.min.js"></script>
    <canvas id="myCanva"></canvas>
    <button onClick = "spanGapsBtn()">Enable/Disable span Gaps</button>