Line Chart Widget — Free HTML CSS JS SVG Snippet

Line Chart Widget · Charts · Plain HTML, CSS & JS · Live preview

Share & Support

What's included

Features

SVG line chart: M/L path built from normalised (x,y) coordinate pairs
Gradient area fill: linearGradient in SVG defs, transparent fade-out bottom
Mousemove tooltip: getBoundingClientRect coordinate conversion, closest-point finder
Tracking dot: SVG circle moves to nearest data point on hover
Period tabs: 3 datasets, renderChart() regenerates all SVG paths on tab click
Y gridlines: 3 horizontal SVG lines at 25%/50%/75% height
Peak and average footer: computed from data array on each render
No chart library — pure SVG, CSS, and vanilla JavaScript

About this UI Snippet

Line Chart Widget — SVG Line & Area Chart with Mousemove Tooltip and Period Tab Switcher

Screenshot of the Line Chart Widget snippet rendered live

If you need a revenue or metric line chart for a dashboard without importing a charting library, this snippet builds a complete SVG line chart from scratch: a normalised SVG polyline path, a gradient area fill, a mousemove tooltip with a tracking dot, a period tab switcher (7d / 30d / 90d), and a footer with peak and average statistics — all in plain HTML, CSS, and vanilla JavaScript.

How the SVG path is generated

The chart function takes the data array and normalises each value to an SVG coordinate. The X position is evenly distributed: x = pad + (i / (n-1)) * (svgW - pad*2). The Y position inverts the scale: y = svgH - pad - ((val - min) / (max - min)) * (svgH - pad*2) — subtracting from svgH because SVG Y increases downward. These (x,y) points form an array of coordinate pairs. The SVG path D attribute is built by joining M (moveto) for the first point and L (lineto) for each subsequent point.

The gradient area fill

A linearGradient element in the SVG defs fades from indigo at 18% opacity to transparent. The area path starts at the line path, then closes back along the bottom edge of the chart (L to the last x at svgH, then L to the first x at svgH, then Z). The fill is set to url(#areaGrad).

The mousemove tooltip

On mousemove over the SVG, the mouse X position is converted from pixel coordinates to SVG coordinates using getBoundingClientRect(). The closest data point is found by comparing each point X to the converted mouse X. The tracking dot is moved to that point, and the tooltip div is positioned using percentage-based left/top derived from the SVG coordinate divided by svgW and svgH.

Period tab switcher

Three datasets (7 days, 30 days, 90 days) are stored as separate arrays. Clicking a period tab calls renderChart(idx) which regenerates all SVG paths, updates the header total and change, and refills the X axis labels and footer stats.

No library required

This pattern replaces Chart.js or Recharts for simple single-series line charts. The full implementation is under 100 lines of JavaScript.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You do not need to reverse the coordinate math in your head to follow it. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain precisely why the Y formula subtracts from svgH before scaling, and how the area path's closing "L...L...Z" segment reuses the same points array as the line path to build the gradient fill. The same assistant can help optimize it, for instance asking whether recomputing the full pts array and rewriting the tooltip's onmousemove handler on every renderChart() call is wasteful compared to caching points per dataset, or whether the closest-point search should use binary search once the x-values are known to be sorted. It is also useful for extending the widget: ask it to add a second overlaid line for a comparison metric, support pinch-zoom on the date range, or animate the path's d attribute smoothly between period switches instead of relying on the CSS transition on d. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a "line chart widget" card in plain HTML, CSS, and JavaScript using raw SVG paths — no charting library, no canvas.

Requirements:
- An SVG with a fixed viewBox (e.g. 0 to 420 by 0 to 120) containing a linearGradient definition, a filled area path, a stroked line path, a circle that tracks the current hover point, and a few static horizontal gridlines.
- Given an array of numeric values, compute each point's x as padding plus (index / (count - 1)) times the usable width, and its y as the chart height minus padding minus the value normalized between the data's min and max times the usable height — remembering that SVG y grows downward so the value-to-y mapping must be inverted.
- Build the line path's d attribute by joining an "M" moveto for the first point and "L" lineto commands for every subsequent point, formatted to one decimal place.
- Build the area path by reusing the exact same line path string, then appending a line down to the chart's bottom edge at the last point's x, another line across to the bottom edge at the first point's x, and a closing Z, so the area is always in sync with the line.
- Implement at least two switchable time-period datasets (e.g. 7 days and 30 days) as separate arrays, and a tab-click handler that regenerates the line, area, x-axis labels, and header stats (peak and average) for whichever dataset is active, without reloading the page.
- On mousemove over the SVG, convert the cursor's pixel position to the SVG's internal coordinate space using getBoundingClientRect(), find the closest data point by comparing x-distances, move the tracking circle and a positioned tooltip div to that point, and show the corresponding date label and formatted value. Reset the tracking circle to the last point and hide the tooltip on mouseleave.

Step by step

How to Use

  1. 1
    Hover over the chartMove the cursor across the chart area to see the tracking dot and tooltip update. The tooltip shows the date label and value for the nearest data point.
  2. 2
    Click the period tabsSwitch between 7d, 30d, and 90d. Each tab loads a different dataset, regenerates the SVG path, and updates the header total, change percentage, and footer stats.
  3. 3
    Replace the data arraysIn the JS panel, update the vals arrays in each dataset object. The chart automatically normalises any range of values to fit the 120px SVG height.
  4. 4
    Change the chart colourReplace #6366f1 in the CSS and SVG attributes with your brand hex. Update both the stroke colour on the line path and the stop-color in the linearGradient.
  5. 5
    Change the metric labelUpdate "Revenue" in the .card-title and the total/change strings in each dataset object. Add more stat-pair entries in the footer for additional metrics like Min or Total.
  6. 6
    Export in your formatClick "HTML" for a standalone file, "JSX" for a React component using useState for period and useMemo for chart path calculation, or "Tailwind" for a Tailwind CSS version.

Real-world uses

Common Use Cases

SaaS revenue and MRR dashboard widgets
Show monthly recurring revenue, daily active users, or conversion rate trends in a card widget. The period tab switcher (7d/30d/90d) is the standard pattern for metric time series on SaaS dashboards — exactly the same interaction users expect from Stripe, Mixpanel, and Amplitude. For a compact inline variant, drop in a sparkline chart instead.
Analytics overview and traffic chart widgets
Adapt for page views, sessions, or API call counts. Update the card title and datasets. The normalised SVG approach handles any numeric range without configuration — whether values are in the hundreds or millions.
E-commerce sales and order volume tracking
Show daily order counts or GMV over 7, 30, or 90 days, or switch to a realtime line chart for live streaming data. Add a second SVG line in a different colour (e.g. green) to compare two metrics on the same chart — duplicate the line and area paths with different data arrays.
Learn SVG path generation and coordinate normalisation
The chart builds its path entirely from coordinate math — no third-party library needed. Studying this snippet teaches how SVG viewBox coordinates work, how to normalise arbitrary data ranges to pixel heights, and how to map mouse position to data point index.
Executive and management dashboard summary cards
The card layout with large metric value, change percentage, chart, and footer stats is the standard executive dashboard summary pattern. Pair with the Stats Card snippet for KPI rows above a more detailed line chart.
Replace Chart.js for simple single-series line charts
Chart.js adds ~60KB of JavaScript for a use case this snippet handles in under 100 lines. For dashboards with 2-3 simple metric charts, this zero-dependency SVG approach avoids the bundle size overhead with identical visual output — mix it with a donut chart for part-to-whole breakdowns.

Got questions?

Frequently Asked Questions

Each data value is converted to an (x,y) SVG coordinate. X is evenly distributed: x = pad + (index / (n-1)) * (svgWidth - pad*2). Y is normalised and inverted: y = svgHeight - pad - ((value - min) / (max - min)) * (svgHeight - pad*2). Subtracting from svgHeight inverts the scale because SVG Y increases downward. These points are joined into an SVG path D string: "M x0,y0 L x1,y1 L x2,y2 ...".

The mousemove handler reads e.clientX and the chart SVG's getBoundingClientRect() to compute xRel — the cursor position in SVG coordinate units. It then iterates all point X coordinates and tracks the index with the minimum absolute distance to xRel. That index selects the tooltip label, value, and dot position. The dot and tooltip update on every mousemove event.

Add a second path element to the SVG with a different stroke colour: <path id="line2" fill="none" stroke="#10b981" stroke-width="2"/>. In renderChart(), compute pts2 from the second data array using the same coordinate math. Set document.getElementById("line2").setAttribute("d", lineD2). Add a second legend dot in the footer with the new colour.

Click "JSX" to download. Manage activePeriod with useState. Compute pts with useMemo from the active dataset — recalculate only when activePeriod or data changes. Set the SVG path d attribute via a state variable that updates when pts change. For the tooltip, use useState for hover position and onMouseMove on the SVG element.