Chartjs-Chartjs – Fill dates between given labels

0👍

It would probably be easier to do this on the backend serving up the data; but this code works if you want to do it in JavaScript on the frontend.

My method was to use a defined self-executing function which returns an array containing two arrays.

The first array is called finalLabels and contains all date strings between, and including, the dates provided in the original labels.

Which gives us ['Aug 23', 'Aug 24', 'Aug 25', 'Aug 26', 'Aug 27', 'Aug 28', 'Aug 29', 'Aug 30', 'Aug 31', 'Sep 01', 'Sep 02']

The second returned array is called finalDatas and contains all of the original data values at the same index of the original label; and a value of zero where the value wasn’t previously defined.

Which gives us: [2750, 0, 0, 1100, 0, 0, 0, 0, 3080, 0, 4320]

Working Codepen: https://codepen.io/vpolston/pen/NWMgwOw

My account doesn’t have ability to embed pictures, but this is what you end up with: image of final chart created.

JS

const labels = ['Aug 23','Aug 26','Aug 31','Sep 02'];
const data = [2750.00,1100.00,3080.00,4320.00];

const datasets = (function () {
  
  const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul","Aug", "Sep", "Oct", "Nov", "Dec"];
  
  /* define start and end date from labels and create date objects */
  const startDateString = labels[0];
  const endDateString = labels[labels.length - 1];
  const startDateObj = new Date(startDateString);
  const endDateObj = new Date(endDateString);
  
  /* create empty dates array to hold dates within range */
  let dates = [];
  
  /* 
  create currentDateObj var to increment in while loop 
  loop through, add currentDateObj to array, increment until false
  */
  let currentDateObj = new Date(startDateString);
  while( currentDateObj <= endDateObj ){
    
    /* format date to match the provided label and push to dates array */
    let dateString = currentDateObj.toDateString();
    let month = months[currentDateObj.getMonth()];
    let day = currentDateObj.getDate();
    
    if( day < 10 ){
      day = '0' + day
    };
    
    let date = month + ' ' + day; 
    dates.push(date);
    
    /* increment CurrentDateObj */
    currentDateObj.setDate(currentDateObj.getDate() + 1);
    
  };
  
  /* 
  use counter to loop through original datas
  */
  let valueExistsCounter = 0;
  
  let finalLabels = [];
  let finalDatas = [];
  
  for( const [index, date] of dates.entries() ){

    if( labels.includes(date) ){
      
      /* if date was provided in labels get the data value */
      finalLabels.push(date);
      finalDatas.push(data[valueExistsCounter]);
      
      valueExistsCounter += 1

    } else {
      
      /* set date value to 0 */
      finalLabels.push(date);
      finalDatas.push(0);
      
    }
    
  };
  
  return [finalLabels, finalDatas]

}());

const finalLabels = datasets[0];
const finalDatas = datasets[1];

/* now we can build the chart */
const ctx = document.getElementById('myChart').getContext('2d');

const myChart = new Chart(ctx, {
  type: 'line',
  data: {
    labels: finalLabels,
    datasets: [{
      label: 'Sales',
      'fill': true,
      borderColor: '#ccc',
      backgroundColor: 'rgba(204,204,204,0.5)',
      tension: 0.2,
      data: finalDatas
    }]
  },
  options: {
    scales: {
      x: {
        grid: {
          color: 'rgba(204,204,204,0.1)'
        }
      },
      y: {
        grid: {
          color: 'rgba(204,204,204,0.1)'
        }
      }
    }
  }
});

HTML


<!-- Canvas -->
<div class="chartContainer">
  <canvas id="myChart"></canvas>
</div>

<!-- include Chart.js 3.9.1  -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.js" integrity="sha512-d6nObkPJgV791iTGuBoVC9Aa2iecqzJRE0Jiqvk85BhLHAPhWqkuBiQb1xz2jvuHNqHLYoN3ymPfpiB1o+Zgpw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

CSS

body {
  background-color: #0d1117;
}

.chartContainer {
  width: 800px;
  height: 400px;
}

I think that covers it? If that was helpful please mark answered.

Leave a comment