webdevpuneet.com

Area Chart — SVG Trend Chart HTML CSS JS Snippet

Area Chart · Charts · Plain HTML, CSS & JS · Live preview

CategoryCharts

Copy & paste

Source Code

<div class="ac-card">
  <div class="ac-head">
    <div>
      <h2 class="ac-title">Monthly active users</h2>
      <div class="ac-value"><span id="acVal">—</span> <span class="ac-month" id="acMonth">hover the chart</span></div>
    </div>
    <div class="ac-peak"><span id="acPeak">0</span> peak</div>
  </div>

  <div class="ac-plot" id="acPlot">
    <svg class="ac-svg" viewBox="0 0 320 170" preserveAspectRatio="none">
      <defs>
        <linearGradient id="acGrad" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#6366f1" stop-opacity="0.34"/>
          <stop offset="100%" stop-color="#6366f1" stop-opacity="0"/>
        </linearGradient>
      </defs>
      <line class="ac-grid" x1="8" y1="22" x2="312" y2="22"/>
      <line class="ac-grid" x1="8" y1="74" x2="312" y2="74"/>
      <line class="ac-grid" x1="8" y1="126" x2="312" y2="126"/>
      <path id="acArea" class="ac-area" d=""/>
      <path id="acLine" class="ac-stroke" d=""/>
      <line id="acVLine" class="ac-vline" x1="0" y1="14" x2="0" y2="140" style="opacity:0"/>
      <circle id="acDot" class="ac-dot" r="4" style="opacity:0"/>
    </svg>
    <div class="ac-xlabels" id="acXlabels"></div>
    <div class="ac-tip" id="acTip"></div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Catmull-Rom smooth curve
smooth derives Bézier control points from each point's neighbours, producing a natural curve that passes through every value.
Auto-scaled axis
render maps values into the plot with 15% padding so the line never touches the edges and small changes stay visible.
SVG gradient area
The area reuses the line path closed to the baseline and fills with an in-markup linearGradient that clips to the curve.
Hover crosshair
A mousemove listener snaps a dot and a dashed vertical line to the nearest point using getBoundingClientRect mapping.
Live value readout
The header value and month update to the hovered point, with a floating tooltip showing the exact figure.
Touch support
A touchmove handler reuses the same nearest-point logic so the crosshair works on phones.
Fluid sizing
preserveAspectRatio="none" stretches the viewBox to the card width; the math is resolution-independent, so no resize code.
Decluttered labels
X-axis labels render every other month, keeping the axis readable on narrow screens.

About this UI Snippet

Area Chart — Smooth Catmull-Rom Curve, Gradient Fill & Hover Crosshair

Screenshot of the Area Chart snippet rendered live

An area chart is the go-to for showing a single metric's trend over time — active users, revenue, temperature — where the filled area under the line emphasises volume and growth. This snippet draws one with an SVG <path> in HTML, CSS, and vanilla JavaScript: a smooth curve through the data points, a gradient area fill, baseline gridlines, and an interactive hover crosshair with a dot, a value readout, and a tooltip.

Smooth curve via Catmull-Rom

Straight line segments between points look jagged; a true smooth curve reads as a polished chart. The smooth function converts the data points into a cubic Bézier path using the Catmull-Rom-to-Bézier formula: for each point it derives two control points from the slope of its neighbours ((p2 - p0) / 6), producing a curve that passes through every data point while flowing naturally between them. This is the same technique charting libraries use for their "smooth"/"natural" line mode, implemented in a dozen lines.

Auto-scaled, gradient-filled area

render computes the data's min and max, adds 15% padding so the line never touches the chart edges, and maps each value into the plot area. The line path is built once with smooth; the area path reuses that exact line and closes it down to the baseline (L X1 BOT L X0 BOT Z), then fills with an SVG linearGradient that fades from translucent to transparent. Using an in-markup SVG gradient (not a CSS background) means the fill clips perfectly to the curved area and renders identically across every framework export.

Hover crosshair and readout

A mousemove listener on the plot maps the cursor's horizontal position to the nearest data index using getBoundingClientRect (so it works regardless of the chart's CSS size versus its viewBox). It then positions a marker dot on that point, draws a dashed vertical crosshair line, updates the big value/month readout in the header, and floats a small tooltip above the point. Leaving the chart hides them and resets the readout. A touchmove handler maps the same logic for mobile.

Responsive by default

preserveAspectRatio="none" lets the 320×170 viewBox stretch to the card width, and the coordinate mapping in render is resolution-independent, so the chart is fluid with no resize handling. The x-axis labels render every other month to avoid crowding on narrow screens.

Swap the DATA array for your figures and it redraws. Pair this with a realtime line chart for live streams, a stacked bar chart for composition, or a sparkline chart for compact trends.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA "Monthly active users" card appears with a smooth gradient-filled area curve across twelve months and a peak readout.
  2. 2
    Hover the chartA dot snaps to the nearest month, a dashed vertical line marks it, and the header shows that month's value.
  3. 3
    Read the tooltipA small tooltip floats above the hovered point with the exact value, tracking your cursor across the months.
  4. 4
    Move along the curveAs you sweep across, the crosshair and readout update to the nearest data point in real time.
  5. 5
    On mobileDrag a finger across the chart — the same crosshair and readout follow your touch.
  6. 6
    Plug in your dataReplace the DATA array with your { m, v } points; the curve auto-scales to the min/max with padding.

Real-world uses

Common Use Cases

Growth and usage trends
Monthly active users, signups, or sessions over time. Pair with a metric card grid for headline stats.
Revenue and finance charts
MRR, sales, or balance over months with the area emphasising cumulative volume.
Analytics dashboards
A trend panel beside a stacked bar chart for composition and a funnel chart for conversion.
Monitoring and metrics
Slower-moving metrics (daily averages) where a smooth area reads better than a live ticker; for live data use a realtime line chart.
Weather and sensor history
Temperature or reading history with a gradient area and hover values for each point.
Report and email embeds
A clean, dependency-free trend chart for static reports; compact variants pair with a sparkline chart.
Related: Cohort Retention Heatmap
See the Cohort Retention Heatmap for a related charts pattern worth pairing with this one.
Related: Parallel Coordinates Chart
See the Parallel Coordinates Chart for a related charts pattern worth pairing with this one.
Related: Ridgeline Plot Chart
See the Ridgeline Plot Chart for a related charts pattern worth pairing with this one.
Related: Horizon Chart
See the Horizon Chart for a related charts pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Replace the DATA array with your { m, v } points (any length) and call render. It recomputes the min/max with padding and remaps every point, so the curve, area, gridlines, and peak adapt automatically. For non-monthly data, just change the label field and the x-axis renderer.

Render a second line and area from another data array with its own gradient and colour, layering the paths in the SVG. Add both values to the hover tooltip. For comparison readability, give the second series a distinct hue and a slightly lower area opacity so the overlap stays legible.

Catmull-Rom produces a smooth curve that still passes through every actual data point, so values are not visually distorted — unlike a basis spline, which only approximates the points. Straight segments are accurate but jagged. Catmull-Rom is the sweet spot most dashboards use for "smooth" lines, and it is cheap to compute.

Give the SVG role="img" with an aria-label summarising the trend, and expose the underlying data as an off-screen or toggleable data table for screen-reader users. The hover readout is mouse-only, so also ensure the key figures (latest, peak) appear as real text in the header, which they do here.

In React, compute the path strings with useMemo from your data and render them in JSX; track the hovered index in useState for the crosshair, updating it in an onMouseMove. In Vue, use a computed for the paths and a ref for hover. In Angular, compute in the component and bind [attr.d]. The Catmull-Rom function and gradient port unchanged.