ECharts Funnel Conversion Chart — Free Stage-by-Stage Snippet

ECharts Funnel Conversion Chart · Dashboards · Plain HTML, CSS & JS · Live preview

What's included

Features

Stage-over-stage rates
Percentages relative to the previous step, not the top.
Sequential order preserved
sort: none keeps the real process order intact.
Dual-line segment labels
Count and rate shown together inside each segment.
Readable tail segment
minSize keeps the smallest stage from vanishing.
Precomputed rate array
Percentage math lives outside the chart option.
Consistent color ramp
A single-hue gradient across all five stages.
Custom tooltip formatter
Repeats count and rate on hover for confirmation.
Responsive canvas
ResizeObserver keeps the funnel sized to its container.

About this UI Snippet

ECharts Funnel Conversion Chart — Stage-to-Stage Rates, Not Percent-of-Total

Screenshot of the ECharts Funnel Conversion Chart snippet rendered live

Most funnel charts show each stage as a percentage of the very top — which tells you the chart looks good overall but hides exactly where users are leaking out fastest. This snippet computes and displays each stage's conversion *relative to the stage directly above it*, which is the number a growth or product team actually needs to find the weakest step.

sort: 'none' is a deliberate override

ECharts' funnel series defaults to sorting data by value, largest first — sensible for a generic funnel, wrong here. The stages are already in their real, sequential order (viewed, added to cart, checkout, payment, completed), and re-sorting by size would scramble that sequence into something that no longer represents an actual user journey. sort: 'none' keeps the array order as the funnel's visual order.

The rate is computed once, outside the chart option

Before building option, a small .map pass walks the stages array and computes each one's rate against stages[i - 1].value (100% for the first stage, since there's no prior one). That precomputed withRates array is what both the segment labels and the tooltip formatter read from — the chart itself never does percentage math, it only renders values it's handed.

Labels carry both the count and the rate

Each segment's inline label combines the raw count and the stage-over-stage percentage on two lines ('\n' inside the formatter's returned string) — useful because a raw count alone doesn't show *where* the funnel is leaking, and a percentage alone doesn't show *how many people* that represents.

minSize keeps the bottom segment visible

With five stages spanning 10,000 down to 1,450, a funnel sized purely by proportion would shrink the final segment to a sliver too thin to read its label. minSize: '18%' floors every segment's width so the smallest stage stays legible, at the cost of the shape being only approximately proportional at the tail — a fair trade for a chart people need to actually read.

Reusing it

Replace the five checkout stages with any sequential process — onboarding steps, application review stages, a sales pipeline — and the stage-over-stage rate computation, labels, and tooltip keep working unchanged since they only depend on the stages array being in real sequence order.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to work out funnel percentage math from scratch. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how the stage-over-stage rate is precomputed outside the chart option and why that's a more actionable metric than percent-of-total for finding the weakest step in a process. The same assistant can help optimize it — ask whether minSize: '18%' distorts the visual proportionality too much for a funnel with a very long tail, and whether there's a cleaner way to encode both count and rate in the label without a manual newline character. It's also useful for extending the effect: ask it to add a comparison funnel for a previous time period rendered side by side, a click handler that drills into the users who dropped off at a specific stage, or a horizontal orientation instead of vertical. 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 funnel conversion chart for a sequential process (such as an e-commerce checkout) using Apache ECharts (load echarts from a CDN, no other library), in plain HTML, CSS, and JavaScript.

Requirements:
- Model the funnel as an ordered list of stages, each with a name and a numeric count of users who reached that stage, listed in their real sequential order from first to last (not sorted by value).
- Before building the chart, precompute each stage's conversion rate relative to the immediately preceding stage (not relative to the very first stage) — the first stage should show 100%, and every later stage's rate should be its count divided by the previous stage's count.
- Configure the funnel chart to preserve the given sequential order rather than automatically re-sorting segments by size, and set a minimum segment size so that even the smallest stage near the bottom of the funnel remains wide enough to hold a readable label instead of shrinking to an unreadable sliver.
- Show each segment's raw user count and its precomputed stage-over-stage percentage together as a two-line label rendered inside that segment.
- Show a tooltip on hover that repeats the stage name, raw count, and stage-over-stage percentage.
- Use a color ramp across the segments (for example a single hue getting progressively lighter from top to bottom) so the stages are visually distinguishable while still reading as one continuous funnel.
- Keep the chart instance responsive to its container being resized by calling the chart's resize method whenever the container's size changes.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="efn-wrap">
  <div class="efn-card">
    <div class="efn-title">Checkout Funnel</div>
    <div class="efn-sub">Percentages are relative to the stage above, not the top of the funnel</div>
    <div class="efn-chart" id="efnChart"></div>
  </div>
</div>

Step by step

How to Use

  1. 1
    Add the ECharts CDNLoad echarts.min.js before the snippet's JS runs.
  2. 2
    Paste HTML, CSS, and JSA five-stage checkout funnel renders top to bottom.
  3. 3
    Read each segment labelIt shows the raw count and the rate from the prior stage.
  4. 4
    Hover a segmentThe tooltip repeats the count and stage-over-stage rate.
  5. 5
    Find the biggest leakThe lowest per-stage percentage is the weakest step.
  6. 6
    Compare to percent-of-totalNotice how different that view would look versus stage-over-stage.

Real-world uses

Common Use Cases

E-commerce checkout analysis
Find the exact step where carts are abandoned.
Onboarding flow reviews
Apply the same stage-over-stage math to signup steps.
Sales pipeline dashboards
Lead to opportunity to closed-won, one stage at a time.
Hiring pipeline tracking
Applied to interviewed to offered to hired.
Growth team reporting
Pair with a Sankey user flow to see where drop-offs actually go.
Learning ECharts
A clear reference for the funnel series and label formatting.
Related: ECharts Sankey User Flow Diagram
See the ECharts Sankey User Flow Diagram for a related charts pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

Percent-of-total tells you a stage's size compared to the very top of the funnel, which can look deceptively stable even while a specific step is leaking badly. Percent-of-previous-stage isolates exactly how much each individual transition loses, which is the number a team needs to identify which specific step to fix first.

ECharts' funnel chart defaults to sorting segments by value from largest to smallest, which is appropriate when the categories have no inherent order. Here the stages represent a real sequential process (viewed, added to cart, checkout, payment, completed), so sorting by size would scramble that sequence — sort: 'none' preserves the array's given order as the funnel's visual order.

The series sets minSize: '18%', which floors every segment's rendered width at 18% of the funnel's total width regardless of its actual proportional value. Without it, a segment representing 1,450 out of a 10,000-value scale would render as a sliver too narrow to hold its label — the trade-off is that segment widths become only approximately proportional near the bottom.

Replace the stages array with your own ordered { name, value } objects — the stage-over-stage rate calculation, the dual-line labels, and the tooltip all derive from that array's order and values automatically, as long as the stages remain listed in their real sequential order (largest expected value first is not required, only real order).

Compute the withRates array from your stage data (with useMemo in React, a computed property in Vue) before passing it into the chart option, initialize the chart once against a container ref, and call setOption whenever the stage data changes. Dispose the instance on unmount and keep the ResizeObserver pattern for responsive sizing.