GrChartFunnel
Machine-translated from the Russian original, not yet reviewed. Read the original
When to take it
- a sequence of stages where each is a subset of the previous one — registration, activation, payment: the funnel shows on which transition the most is lost;
- there are three stages or more — for two a pair of numbers is enough, and at three the numbers already stop answering;
- both the absolute quantity and the share matter — the width carries the value, and the label switches between the value and either of the two shares;
- the funnel may “widen” — growth between stages is sometimes legitimate (different cohorts) and sometimes an error in the data: the component draws it honestly and says so in the description.
When to take something else
| Need | Take |
|---|---|
| Show how the end of a period came out of its beginning | GrChartWaterfall |
| Compare the quantities of categories not related by nesting | GrChartBar |
| Show the composition of one whole | GrChartPie |
| Show a single conversion as a number | GrStatistic |
The width is proportional to the value rather than to the order
The decrease is drawn because it is in the data. A stage that is larger than the previous one is not
straightened out: it is drawn wider and enters ariaDescription as a separate phrase. Quietly
“fixing” such a chart would mean hiding either an error in the data or the fact that the stages were
counted over different cohorts.
A zero stage is visible
“Nobody got here” is a result rather than the absence of a stage. The stage keeps a minimum width and a label with the value, otherwise the funnel would look shorter than it is.
The ribbon and the bars give the same numbers
shape: 'trapezoid' narrows towards the next stage, and shape: 'bar' draws rectangles — the
values, the shares and the content of the table match to the digit in the process. The shape here is
a matter of taste rather than of meaning.
The keyboard walks the stages with both pairs of arrows
The funnel stands as a single column, so ↑↓ mean exactly the same as ←→. A stage is announced as
a whole: the value and both shares.
Limits
The component does not compute the funnel from events — the values are given by the consumer. There is no branching (several paths out of one stage), and no comparison of two funnels side by side either.
Install
npm i @feugene/granularity-chartsImport
import { GrChartFunnel } from '@feugene/granularity-charts/components/GrChartFunnel'API
The API for this component has not been generated yet: the showcase generator only covers the core so far. Until it does, the reference lives in the package documentation.
Examples 2
Basic
<script setup lang="ts">
import { ref } from 'vue'
/**
* Воронка отвечает на вопрос «где теряем», которого нет у трёх чисел рядом.
*
* Подпись переключается между значением и двумя долями — от первой ступени и от
* предыдущей. Это разные знаменатели, и смешивать их в одной подписи нельзя.
*/
const stages = [
{ label: 'Зарегистрировались', value: 4820 },
{ label: 'Подтвердили почту', value: 3910 },
{ label: 'Создали проект', value: 1640 },
{ label: 'Пригласили команду', value: 720 },
{ label: 'Оплатили', value: 214 },
]
const labels = ref<'value' | 'share-first' | 'share-prev'>('share-prev')
const hint = {
'value': 'Абсолютные величины: сколько человек дошло до каждой ступени.',
'share-first': 'Доля от первой ступени: какая часть всех пришедших добралась досюда.',
'share-prev': 'Доля от предыдущей: конверсия каждого перехода по отдельности. Именно здесь видно, что самый дорогой шаг — создание проекта.',
}
</script>
<template>
<div class="grid gap-3">
<div class="flex flex-wrap items-baseline justify-between gap-4">
<span class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
Онбординг за месяц
</span>
<GrSegmented
v-model="labels"
size="sm"
:options="[
{ value: 'value', label: 'Значение' },
{ value: 'share-first', label: 'От первой' },
{ value: 'share-prev', label: 'От предыдущей' },
]"
aria-label="Что писать у ступени"
/>
</div>
<GrChartFunnel :stages="stages" :labels="labels" :height="300" aria-label="Воронка онбординга" />
<p class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
{{ hint[labels] }} Обе доли доступны одновременно — в тултипе, в скрытой таблице и в
объявлении: «конверсия сорок процентов» без указания знаменателя не значит ничего.
</p>
</div>
</template>Shape
<script setup lang="ts">
import { ref } from 'vue'
/**
* Ступень, которая больше предыдущей, воронка не выпрямляет: это либо ошибка
* данных, либо разные когорты, и решать должен читатель, а не компонент.
*
* Факт роста попадает в описание графика — иначе он существовал бы только для
* зрячих.
*/
const stages = [
{ label: 'Открыли форму', value: 1200 },
{ label: 'Начали заполнять', value: 860 },
{ label: 'Отправили', value: 940 },
{ label: 'Прошли модерацию', value: 610 },
]
const shape = ref<'trapezoid' | 'bar'>('trapezoid')
</script>
<template>
<div class="grid gap-3">
<div class="flex flex-wrap items-baseline justify-between gap-4">
<span class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
Заявки: форма и модерация
</span>
<GrSegmented
v-model="shape"
size="sm"
:options="[
{ value: 'trapezoid', label: 'Лента' },
{ value: 'bar', label: 'Полосы' },
]"
aria-label="Форма ступеней"
/>
</div>
<GrChartFunnel
:stages="stages"
:shape="shape"
labels="value"
:height="280"
data-table="visible"
aria-label="Воронка заявок"
/>
<p class="text-[length:var(--gr-control-text-sm)] text-[var(--gr-muted-fg)]">
«Отправили» шире, чем «начали заполнять»: часть заявок пришла из сохранённых черновиков.
Ширина ступени пропорциональна <strong>значению</strong>, а не порядку, поэтому рост виден —
и назван в описании графика словами. Лента и полосы дают одни и те же числа в таблице.
</p>
</div>
</template>