GrChartFunnel

Package: @feugene/granularity-chartscompanionGroup: misc

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

NeedTake
Show how the end of a period came out of its beginningGrChartWaterfall
Compare the quantities of categories not related by nestingGrChartBar
Show the composition of one wholeGrChartPie
Show a single conversion as a numberGrStatistic

Two shares — two denominators

From the first stage and from the previous one. Those are different numbers, and both are available at once — in the tooltip, in the hidden table and in the announcement. Mixing them in one label is not allowed: “a conversion of forty per cent” without naming the denominator means nothing, and it is exactly on that substitution that most embellished funnels are built.

The labels prop chooses what to write on the stage itself; the rest stays available beside it.

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-charts

Import

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

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

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>

Component documentationAll components