Search code examples
reactjsrecharts

How to use UTC date string as recharts axis and distribute it evenly


My source of data looks like this:

const data = [
    { dataora: "2019-10-20T04:00:00Z", valore: -0.04 },
    { dataora: "2019-10-20T05:00:00Z", valore: -0.03 },
    { dataora: "2019-10-20T06:00:00Z", valore: -0.03 },
    { dataora: "2019-10-20T07:00:00Z", valore: -0.03 },
    { dataora: "2019-10-21T10:00:00Z", valore: -0.04 },
    { dataora: "2019-10-21T23:00:00Z", valore: -0.04 },
    { dataora: "2019-10-22T00:00:00Z", valore: -0.04 }
  ];

My recharts component looks like this:

<LineChart width={600} height={300} data={data}>
  <Line type="monotone" dataKey="valore" stroke="black" strokeWidth={2} dot={false} />
  <CartesianGrid stroke="#ccc" />
  <XAxis
    dataKey={'dataora'}
    tickFormatter={dateFormatter}
  />
  <YAxis />
</LineChart>

dateFormatter looks like this:

const dateFormatter = date => {
  // return moment(date).unix();
  return moment(date).format('DD/MM/YY HH:mm');
};

Usually I have a data entry every other hour, but 2019-10-21 has only two values for the whole day, now I'd like to show also the missing hours in my graph. In other data entries I may get different time gap so I can't set the tick interval manually.. I just need the date field to be distributed evenly on the XAxis.

I tried to change the tickFormatter to return the date in Unix epoch seconds and use the below props..

scale="time" type="number" domain={[dateFormatter(data[0].dataora), dateFormatter(data[1].dataora)]}

but the XAxis dissapeared along with the data line. Is there any way to "fill in" those date blanks?

A codesandbox


Solution

  • [answering myself here]

    It turns out that I had to process the input data beforehand since recharts does not have anything that allows me to teach him how to read my input data. So I converted my date field to epoch.

    data.forEach(d => {
      d.dataora = moment(d.dataora).valueOf(); // date -> epoch
    });
    

    And then I can use the date field type as a number and set the domain etc.

    <XAxis 
      dataKey={'dataora'}
      domain={[data[0].dataora, data[data.length - 1].dataora]}
      scale="time"
      type="number"
      tickFormatter={DateFormatter} />
    

    I'm not really happy with this solution because it requires me to actually process all the data before rendering the chart. I haven't tried it with large size data (thousands of entries or more) yet but I'm not optimistic.