SolanaUISolanaUI

Price Chart

An area chart for displaying token price history with axes, grid lines, and tooltips

SOL Price

January 2026

import { PriceChart } from "@/components/sol/price-chart";

export function PriceChartDemo() {
  return (
    <PriceChart
      title="SOL Price"
      description="January 2026"
      series={[
        { time: "2026-01-01", value: 148.32 },
        { time: "2026-01-02", value: 149.10 },
        { time: "2026-01-03", value: 147.85 },
        { time: "2026-01-04", value: 148.90 },
        { time: "2026-01-05", value: 150.20 },
        { time: "2026-01-06", value: 151.45 },
        { time: "2026-01-07", value: 150.80 },
        { time: "2026-01-08", value: 152.30 },
        { time: "2026-01-09", value: 151.60 },
        { time: "2026-01-10", value: 153.15 },
        { time: "2026-01-11", value: 152.40 },
        { time: "2026-01-12", value: 154.20 },
        { time: "2026-01-13", value: 153.80 },
        { time: "2026-01-14", value: 155.10 },
        { time: "2026-01-15", value: 154.60 },
        { time: "2026-01-16", value: 156.30 },
        { time: "2026-01-17", value: 155.80 },
        { time: "2026-01-18", value: 157.20 },
        { time: "2026-01-19", value: 156.50 },
        { time: "2026-01-20", value: 158.10 },
        { time: "2026-01-21", value: 157.40 },
        { time: "2026-01-22", value: 158.90 },
        { time: "2026-01-23", value: 159.30 },
        { time: "2026-01-24", value: 158.60 },
        { time: "2026-01-25", value: 160.10 },
        { time: "2026-01-26", value: 159.80 },
        { time: "2026-01-27", value: 161.20 },
        { time: "2026-01-28", value: 160.50 },
        { time: "2026-01-29", value: 161.80 },
        { time: "2026-01-30", value: 163.10 },
        { time: "2026-01-31", value: 162.56 },
      ]}
    />
  );
}

Installation

pnpm dlx shadcn@latest add @solanaui/price-chart
npx shadcn@latest add @solanaui/price-chart
yarn dlx shadcn@latest add @solanaui/price-chart

Usage

<PriceChart
  title="SOL Price"
  description="January 2026"
  series={[
    { time: "2026-01-01", value: 148.32 },
    { time: "2026-01-15", value: 155.40 },
    { time: "2026-01-31", value: 162.56 },
  ]}
/>

Without Title

<PriceChart
  series={[
    { time: "2026-01-01", value: 148.32 },
    { time: "2026-01-15", value: 155.40 },
    { time: "2026-01-31", value: 162.56 },
  ]}
/>

Source Code

"use client";import React from "react";import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from "recharts";import {  type ChartConfig,  ChartContainer,  ChartTooltip,  ChartTooltipContent,} from "@/components/ui/chart";import { cn } from "@/lib/utils";interface PriceChartProps {  title?: string;  description?: string;  series: {    time: string;    value: number;  }[];  className?: string;}const POSITIVE_COLOR = "hsl(160 84% 39%)";const NEGATIVE_COLOR = "hsl(0 84% 67%)";const chartConfig = {  value: {    label: "Value",  },} satisfies ChartConfig;const PriceChart = ({  title,  description,  series,  className,}: PriceChartProps) => {  const gradientId = React.useId();  if (!series.length) return null;  const firstValue = series[0].value;  const lastValue = series[series.length - 1].value;  const isPositive = lastValue >= firstValue;  const chartColor = isPositive ? POSITIVE_COLOR : NEGATIVE_COLOR;  const minValue = Math.min(...series.map((s) => s.value));  const maxValue = Math.max(...series.map((s) => s.value));  const padding = (maxValue - minValue) * 0.1;  return (    <div      className={cn(        "flex min-h-0 flex-1 flex-col gap-4 rounded-lg border bg-card p-4",        className,      )}    >      {(title || description) && (        <div className="flex flex-col gap-0.5">          {title && (            <h3 className="text-base font-semibold tracking-tight">{title}</h3>          )}          {description && (            <p className="text-sm text-muted-foreground">{description}</p>          )}        </div>      )}      <ChartContainer config={chartConfig} className="min-h-0 flex-1 w-full">        <AreaChart accessibilityLayer data={series}>          <defs>            <linearGradient id={gradientId} x1="0" y1="0" x2="0" y2="1">              <stop offset="0%" stopColor={chartColor} stopOpacity={0.2} />              <stop offset="100%" stopColor={chartColor} stopOpacity={0} />            </linearGradient>          </defs>          <CartesianGrid            vertical={false}            strokeDasharray="3 3"            stroke="var(--border)"          />          <XAxis            dataKey="time"            tickLine={false}            axisLine={false}            tickMargin={8}            tickFormatter={(value: string) => {              const date = new Date(value);              return date.toLocaleDateString("en-US", {                month: "short",                day: "numeric",              });            }}          />          <YAxis            domain={[minValue - padding, maxValue + padding]}            tickLine={false}            axisLine={false}            tickMargin={8}            tickFormatter={(value: number) =>              value >= 1                ? `$${value.toLocaleString(undefined, { maximumFractionDigits: 0 })}`                : `$${value.toFixed(6)}`            }            width={60}          />          <ChartTooltip            content={              <ChartTooltipContent                labelFormatter={(value: string) => {                  return new Date(value).toLocaleDateString("en-US", {                    month: "short",                    day: "numeric",                    year: "numeric",                  });                }}                formatter={(value) => {                  const num = Number(value);                  const formatted =                    num >= 1                      ? `$${num.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`                      : `$${num.toFixed(8)}`;                  return (                    <span className="font-mono text-foreground">                      {formatted}                    </span>                  );                }}              />            }          />          <Area            dataKey="value"            type="monotone"            stroke={chartColor}            strokeWidth={2}            fill={`url(#${gradientId})`}            dot={false}          />        </AreaChart>      </ChartContainer>    </div>  );};export type { PriceChartProps };export { PriceChart };