Lelouch
Lelouch

Reputation: 21

X axis by Month in Recharts

I want X Axis to display only the months and I can add content on different days within a month.

I tried using ticks but it just removed the X Axys I'm using ticksFormatter but when there is a different day in the same month it duplicates the X Axys caption and goes something like "June July August August September October Novemeber", and what I wanted was for it to be just "June July August September October Novemeber"

Something like that:

Example

<ResponsiveContainer width="95%" height={360}>
<LineChart data={data.data}>
<CartesianGrid strokeDasharray="1 5" stroke="#2A2A2C" vertical={false} />
<XAxis dataKey="name" axisLine={false} tickLine={false} tickFormatter={date => moment(date, "YYYY-MM-DD HH:mm:ss").format("MMMM")}/>
<YAxis axisLine={false} tickLine={false} tick={{ stroke: '#000', strokeWidth: 1 }} tickMargin="10" />
<Tooltip labelFormatter={date => moment(date, "YYYY-MM-DD HH:mm:ss").format("DD-MM-YYYY")} />
<Legend verticalAlign="top" align="right" height={36} iconType="circle" formatter={text => <span style={{ color: "#000" }}>{text}</span>} />
{data.ref.map((entry, index) => (
<Line type="linear" dataKey={entry.name} strokeWidth={5} stroke={entry.color} dot={{ strokeWidth: 4, r: 5 }} />))}
</LineChart>
</ResponsiveContainer>

Here is my JSON

"lineChart": {
        "title": "Pedidos (× R$ 1M)",
        "ref": [{
                "name": "Aprovados",
                "color": "#BF2542"
            },
            {
                "name": "Incluídos",
                "color": "#7DA43D"
            }
        ],
        "data": [{
                "name": "2021-06-20 00:20:16",
                "Aprovados": 31,
                "Incluídos": 23
            },
            {
                "name": "2021-07-20 00:20:16",
                "Aprovados": 41,
                "Incluídos": 13
            },
            {
                "name": "2021-08-20 00:20:16",
                "Aprovados": 21,
                "Incluídos": 43
            },
            {
                "name": "2021-08-22 00:20:16",
                "Aprovados": 23,
                "Incluídos": 23
            },
            {
                "name": "2021-09-20 00:20:16",
                "Aprovados": 71,
                "Incluídos": 63
            },
            {
                "name": "2021-10-20 00:20:16",
                "Aprovados": 21,
                "Incluídos": 43
            },
            {
                "name": "2021-11-20 00:20:16",
                "Aprovados": 41,
                "Incluídos": 13
            }
        ]
    }

Upvotes: 2

Views: 3280

Answers (2)

Pal
Pal

Reputation: 1

 const formatMonth = (date) => {
    return new Date(date).toLocaleString("default", { month: "short" });
  };

  const final_data = [];
  let prevMonth = "";

  data.forEach((item, index) => {
    const currentMonth = formatMonth(item.month);
    if (currentMonth !== prevMonth) {
      final_data.push({
        ...item,
        show: currentMonth,
      });
      prevMonth = currentMonth;
    } else {
      final_data.push({
        ...item,
        show: "",
      });
    }
  });
<XAxis dataKey="show" tick={customTick} tickLine={false} />

Upvotes: 0

KingDom
KingDom

Reputation: 21

If you save the months already used in state and then use a callback function which checks if the month is already on the x axis, this will stop the values from repeating.

const [xValues, setXValues] = useState([])

const formatDate = (date) => {
    if (xValues.includes(date.getMonth())) {
        setXValues([...xValues, date.getMonth()])
        return moment(date, "YYYY-MM-DD HH:mm:ss").format("MMMM")
    } return ''
}

<XAxis dataKey="name" axisLine={false} tickLine={false} tickFormatter={date => formatDate(new Date(date))}/>

Upvotes: 2

Related Questions