Показывать только 2 цифры года на оси X Recharts

На моем графике данных Recharts, содержащем строки даты, ось X выглядит довольно запутанной.

введите описание изображения здесь

Можно ли настроить Recharts для маркировки оси только двумя последними цифрами года? Например, 17, 18, 19, 20 без повторения метки для каждого года.

import { ResponsiveContainer, LineChart, Line, CartesianGrid, XAxis, YAxis, Tooltip } from 'recharts';


export function Chart() {

    const d = [
        {date: '2017-02-01', price: 231},
        {date: '2017-04-01', price: 453},
        {date: '2017-16-01', price: 123},
        {date: '2018-01-01', price: 234},
        {date: '2018-04-01', price: 958},
        {date: '2018-11-01', price: 163},
        {date: '2019-03-01', price: 293},
        {date: '2019-10-01', price: 471},
        {date: '2020-07-01', price: 881},
        {date: '2020-09-01', price: 122},
    ]

    return (
        <ResponsiveContainer width="100%" height={400}>
            <LineChart data={d}>
                <Line type="monotone" dataKey="price" stroke="#8884d8" />
                <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
                <XAxis dataKey="date" />
                <YAxis dataKey="price" />
                <Tooltip />
            </LineChart>
        </ResponsiveContainer>
    )
}

Дополнительная проблема: используя подход Баса ван дер Линдена, итоговая диаграмма действительно близка к тому, что нам нужно! Но точки данных не расположены должным образом по оси X.

Это станет более очевидным, если мы воспользуемся массивом d ниже. На полученной диаграмме вы можете видеть, что точки данных за 2018 год занимают гораздо больше места по оси X, чем точки данных за 2017, 2019 и 2020 годы вместе взятые. Будет лучше, если промежуток между метками галочки 17 и 18 будет такой же по длине, как расстояние между метками галочки 18 и 19.

введите описание изображения здесь

    const d = [
        { date: "2017-02-01", price: 231 },
        { date: "2017-04-01", price: 453 },
        { date: "2017-16-01", price: 123 }, 

        { date: "2018-01-01", price: 234 },
        { date: "2018-04-01", price: 958 },
        { date: "2018-11-01", price: 163 },
        { date: "2018-11-02", price: 163 },
        { date: "2018-11-03", price: 163 },
        { date: "2018-11-06", price: 163 },
        { date: "2018-11-05", price: 163 },
        { date: "2018-11-07", price: 163 },
        { date: "2018-11-08", price: 163 },
        { date: "2018-11-09", price: 163 },
        { date: "2018-11-00", price: 163 },
        { date: "2018-11-11", price: 163 },
        { date: "2018-11-12", price: 163 },
        { date: "2018-11-13", price: 163 },
        { date: "2018-11-14", price: 163 },
        { date: "2018-11-15", price: 163 },
        { date: "2018-11-16", price: 163 },
        { date: "2018-11-17", price: 163 },

        { date: "2019-03-01", price: 293 },
        { date: "2019-10-01", price: 471 },
        { date: "2020-07-01", price: 881 },
        { date: "2020-09-01", price: 122 }
      ];

person Nyxynyx    schedule 25.01.2021    source источник


Ответы (1)


Вы можете сделать что-то вроде этого:

export function Chart() {
  const [data, setData] = useState([]);
  const d = [
    { date: "2017-02-01", price: 231 },
    { date: "2017-04-01", price: 453 },
    { date: "2017-16-01", price: 123 },
    { date: "2018-01-01", price: 234 },
    { date: "2018-04-01", price: 958 },
    { date: "2018-11-01", price: 163 },
    { date: "2019-03-01", price: 293 },
    { date: "2019-10-01", price: 471 },
    { date: "2020-07-01", price: 881 },
    { date: "2020-09-01", price: 122 },
  ];

  useEffect(() => {
    const datesAlreadyListed = [];
    for (let i = 0; i < d.length; i++) {
      const year = d[i].date.split("-")[0].substring(2, 4);
      if (!datesAlreadyListed.includes(year)) {
        datesAlreadyListed.push(year);
        d[i].year = year;
      }
    }
    setData(d);
  }, []);

  return (
    <ResponsiveContainer width="100%" height={400}>
      <LineChart data={data}>
        <Line type="monotone" dataKey="price" stroke="#8884d8" />
        <CartesianGrid stroke="#ccc" strokeDasharray="5 5" />
        <XAxis dataKey="year" />
        <YAxis dataKey="price" />
        <Tooltip />
      </LineChart>
    </ResponsiveContainer>
  );
}

Таким образом, описанный выше подход заключается в добавлении свойства year к d внутри useEffect хука. Значение свойства year определяется на основе того, встречалась ли уже дата при циклическом прохождении d.

Если значение года не было раньше, установите для свойства year это значение, чтобы оно отображалось на оси Y.


Пример песочницы

person Bas van der Linden    schedule 25.01.2021
comment
Спасибо, я считаю, что ваше решение очень близко к тому, что мы. Однако интервал между двухзначными обозначениями года на оси размещен неправильно. Обновлен вопрос, чтобы предоставить пример, иллюстрирующий это. Интересно, есть ли у нас решение, которое с этим справится? - person Nyxynyx; 27.01.2021