skip to Main Content

I am trying to display the values from this object on a React Chart.js line chart:
The times are formatted as hours, minutes, and seconds.

  {
    "totaltime": "10:55:41",
    "date": "2018-01-01T00:00:00"
  },
  {
    "totaltime": "339:40:53",
    "date": "2019-01-01T00:00:00"
  },
  {
    "totaltime": "227:25:42",
    "date": "2020-01-01T00:00:00"
  },
  {
    "totaltime": "286:40:01",
    "date": "2021-01-01T00:00:00"
  },
]

I then use this function to add the time values to the line chart component:

function getChartData(documents, label, color) {

  return {
    labels: documents.map((document) => document.date),
    datasets: [
      {
        label: label,
        data: documents.map((document) => document.totaltime),
        backgroundColor: color,
        borderColor: color,
        borderWidth: 1,
      },
    ],
  };
}

However only the dates display and no data appears on the X-axis. If I change the values from date objects to seconds, they display perfectly but I want users to see the data in hours and minutes instead of seconds.

I have tried sending the data as seconds and then formatting the output to hours and minutes with the date-fns library using the Chart.js options, but the values never changed and stayed as seconds.

2

Answers


  1. Chosen as BEST ANSWER

    Solution to get the time values without replacing your date labels after using Remesh's answer

    Send the formattedDate labels to the line chart component:

      const chartData = {
        labels: [],
        datasets: [
          {
            label: label,
            data: [],
            backgroundColor: color,
            borderColor: color,
            borderWidth: 1,
            value: formattedDates
          },
        ],
      };
    

    access it in the line component and change the tick values using a callback:

      return (
        <div>
          <Line 
            data={data}
            type="line"
            height={300} // set the height of the chart
            width={1300} // set the width of the char
            options= {{
              scales: {
                  x: {
                      ticks: {
                          // add dates to x axis
                          callback: function(index) {
                              return data.datasets[0].value[index];
                          }
                      }
                  }
              }
            }}
          />
        </div>
      );
    }
    

  2. Here’s an updated version of your getChartData function that handles the conversion and formatting:

    function formatTime(totalTime) {
      const hours = Math.floor(totalTime / 3600);
      const minutes = Math.floor((totalTime % 3600) / 60);
      const seconds = totalTime % 60;
    
      return `${hours.toString().padStart(2, '0')}:${minutes
        .toString()
        .padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
    }
    
    function getChartData(documents, label, color) {
      const chartData = {
        labels: [],
        datasets: [
          {
            label: label,
            data: [],
            backgroundColor: color,
            borderColor: color,
            borderWidth: 1,
          },
        ],
      };
    
      documents.forEach((document) => {
        const timeComponents = document.totaltime.split(':');
        const hours = parseInt(timeComponents[0]);
        const minutes = parseInt(timeComponents[1]);
        const seconds = parseInt(timeComponents[2]);
    
        // Calculate the total time in seconds
        const totalTimeInSeconds = hours * 3600 + minutes * 60 + seconds;
    
        // Format the time as hours:minutes:seconds
        const formattedTime = formatTime(totalTimeInSeconds);
    
        chartData.labels.push(formattedTime);
        chartData.datasets[0].data.push(totalTimeInSeconds);
      });
    
      return chartData;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search