Horizontal Scrollable Graph in Recharts

Chaeeun Lee·2025년 3월 20일
0

There is no built-in API for a scrollable feature in Recharts.

Fortunately, there are solutions for bar charts (click here), but they don't work for area charts perfectly.

However, I found the solution!

The keys to making a scrollable chart with a sticky Y-axis are:

  1. Create two AreaCharts—one for the fixed Y-axis (let’s call this the "fixed part") and another for the scrollable X-axis (let’s call this the "scrollable part").
  2. Set the width of the X-axis to 0 in the scrollable part and the width of the Y-axis to 0 in the fixed part.
  3. Make the AreaChart transparent in the fixed part.

Exaple code below :

<div className="flex px-16">
  {/* Fixed Y-Axis Chart */}
  <div>
    <AreaChart data={priceData} width={30} height={200} margin={{ top: 10, left: 0, right: 0, bottom: 0 }}>
      <XAxis dataKey="date" width={0} />
      <YAxis
        tickLine={false}
        axisLine={false}
        tickFormatter={(value) => Math.floor(value / 10000)}
        domain={minMax}
        tick={{ fill: '#bbb', fontSize: 12 }}
        width={30}
      />

      <Area dataKey="sales" fill="transparent" stroke="transparent" />
    </AreaChart>
  </div>

  {/* Scrollable Area Chart */}
  <div className="flex overflow-x--scroll">
    <div style={{ width: 600 }}>
      <AreaChart data={priceData} width={600} height={200} margin={{ top: 10, left: 0, right: 0, bottom: 0 }}>
        <XAxis
          dataKey="date"
          dy={10}
          tickLine={false}
          axisLine={false}
          padding={{ left: 20, right: 20 }}
          tick={{ fill: '#bbb', fontSize: 12 }}
          domain={minMax}
        />
        <YAxis
          tickLine={false}
          axisLine={false}
          tickFormatter={(value) => Math.floor(value / 10000)}
          domain={minMax}
          tick={{ fill: '#bbb', fontSize: 12 }}
          width={0}
        />

        <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#A8E1D1" />

        <defs>
          <linearGradient id="color" x1="0" y1="0" x2="0" y2="1">
            <stop offset="5%" stopColor="#A8E1D1" stopOpacity={0.9} />
            <stop offset="95%" stopColor="#A8E1D1" stopOpacity={0.1} />
          </linearGradient>
        </defs>

        <Area
          dataKey="sales"
          type="linear"
          stroke={'#11856A'}
          strokeWidth={2}
          fill={'url(#color)'}
          dot={{
            stroke: '#11856A',
            strokeWidth: 3,
            fill: 'white',
            opacity: '1',
            fillOpacity: '1',
            r: 4.5,
            onClick: (event) => {
              setActiveDotIndex((prev) => event.index);
            },
          }}
        >
          <LabelList dataKey="sales" content={customizedLabel} />
        </Area>
      </AreaChart>
    </div>
  </div>
</div>;
profile
나는야 뚝딱이 개발자야

0개의 댓글