Skip to main content
The charts page renders a filled area chart of historical USD prices for a selected cryptocurrency. Users can switch between multiple assets and time windows without leaving the page.

Component overview

The AreaChartFillByValue component in src/components/cryptoGrafics.jsx handles both data fetching and rendering. It is used in two contexts:

Standalone charts page

Rendered at /grafics. The user can freely switch between Bitcoin, Ethereum, Tether, BNB, and Solana using the asset selector buttons.

Favorites page

Rendered once per favorited coin with cryptoId locked to that coin. The asset selector buttons are hidden when cryptoId is provided as a prop.

Props

props.cryptoId
string
CoinGecko coin identifier to pin the chart to a specific asset (e.g. "bitcoin"). When omitted, the user can pick the asset from the selector buttons. Defaults to "bitcoin" when not supplied.

Selectable assets

When cryptoId is not provided the following assets are available in the selector:
IDDisplay name
bitcoinBitcoin
ethereumEthereum
tetherTether
binancecoinBNB
solanaSolana

Time windows

Four time-range buttons are always visible regardless of the asset selection:
Buttondays valueLabel format
24H1Hour (2-digit)
7D7Month + day (short)
30D30Month + day (short)
1Y365Month + day (short)
The default time window on first render is 7 days.

Data loading

Chart data is fetched via keepHistory(cryptoId, days) whenever either activeCrypto or days changes:
cryptoGrafics.jsx
useEffect(() => {
  async function loadChartData() {
    setLoading(true);
    const history = await keepHistory(activeCrypto, days);
    const mockSeries = history.prices;

    const formattedData = mockSeries.map(([timestamp, price]) => ({
      time: new Date(timestamp).toLocaleDateString("en-US", {
        month: days === 1 ? undefined : "short",
        day: "numeric",
        hour: days === 1 ? "2-digit" : undefined,
      }),
      price: price,
    }));

    setChartData(formattedData);
    setLoading(false);
  }

  loadChartData();
}, [activeCrypto, days]);
keepHistory calls the CoinGecko market chart endpoint:
GET https://api.coingecko.com/api/v3/coins/{id}/market_chart
  ?vs_currency=usd
  &days={days}
Each unique (cryptoId, days) combination is cached independently in localStorage under the key history_{cryptoId}_{days} for 5 minutes.

Chart rendering

The chart is built with the Recharts library using AreaChart with a ResponsiveContainer:
cryptoGrafics.jsx
<ResponsiveContainer width="100%" height="100%">
  <AreaChart
    data={chartData}
    margin={{ top: 10, right: 0, left: 0, bottom: 0 }}
  >
    <CartesianGrid strokeDasharray="3 3" />
    <XAxis dataKey="time" />
    <YAxis width="auto" />
    <Tooltip
      formatter={(value) =>
        `$${value.toLocaleString("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2,
        })}`
      }
    />
    <Gradient />
    <Area
      type="monotone"
      dataKey="price"
      stroke="#000"
      fill="url(#splitColor)"
    />
  </AreaChart>
</ResponsiveContainer>
The area fill uses a vertical green gradient defined by the internal Gradient component, which renders an SVG <linearGradient id="splitColor">: Tailwind’s #10b981 (green-500) at 80% opacity at the top, fading to 10% opacity at the bottom. The gradient is referenced via fill="url(#splitColor)" on the <Area> element.
The chart container is responsive and adjusts its height based on the viewport: 300 px on mobile, 360 px on small screens, and 420 px on medium and larger screens.

Build docs developers (and LLMs) love