GrChartFunnel

Пакет: @feugene/granularity-chartsспутникГруппа: Прочее

Берут, когда последовательность ступеней, где каждая — подмножество предыдущей.

Когда брать

  • последовательность ступеней, где каждая — подмножество предыдущей — регистрация, активация, оплата: воронка показывает, на каком переходе теряется больше всего;
  • ступеней три и больше — на двух хватает пары чисел, на трёх числа уже перестают отвечать;
  • важна и абсолютная величина, и доля — ширина несёт значение, подпись переключается между значением и любой из двух долей;
  • воронка может «расширяться» — рост между ступенями бывает законным (разные когорты) и бывает ошибкой данных: компонент рисует его честно и говорит об этом в описании.

Когда взять другое

НужноБерите
Показать, как из начала периода получился конецGrChartWaterfall
Сравнить величины категорий, не связанных вложенностьюGrChartBar
Показать состав одного целогоGrChartPie
Показать одну конверсию числомGrStatistic

Две доли — два знаменателя

От первой ступени и от предыдущей. Это разные числа, и обе доступны сразу — в тултипе, в скрытой таблице и в объявлении. Смешивать их в одной подписи нельзя: «конверсия сорок процентов» без указания знаменателя не значит ничего, и именно на этой подмене строится большинство приукрашенных воронок.

Проп labels выбирает, что писать на самой ступени; остальное остаётся доступным рядом.

Ширина пропорциональна значению, а не порядку

Убывание рисуется потому, что оно есть в данных. Ступень, которая больше предыдущей, не выпрямляется: она рисуется шире и попадает в ariaDescription отдельной фразой. Молча «починить» такой график значило бы скрыть либо ошибку данных, либо факт того, что ступени считаны по разным когортам.

Нулевая ступень видима

«Сюда не дошёл никто» — это результат, а не отсутствие ступени. У ступени остаётся минимальная ширина и подпись со значением, иначе воронка выглядела бы короче, чем есть.

Лента и полосы дают одни и те же числа

shape: 'trapezoid' сужается к следующей ступени, shape: 'bar' рисует прямоугольники — значения, доли и содержимое таблицы при этом совпадают до знака. Форма здесь вопрос вкуса, а не смысла.

Клавиатура идёт по ступеням обеими парами стрелок

Воронка стоит одной колонкой, поэтому ↑↓ значат ровно то же, что ←→. Объявляется ступень целиком: значение и обе доли.

Границы

Компонент не считает воронку из событий — значения даёт потребитель. Ветвления (нескольких путей из одной ступени) нет, сравнения двух воронок рядом — тоже.

Установка

npm i @feugene/granularity-charts

Импорт

import { GrChartFunnel } from '@feugene/granularity-charts/components/GrChartFunnel'

API

API этого компонента ещё не посчитан: генератор витрины пока обходит только ядро. Пока его нет, справочник — в документации пакета.

Примеры 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>

Документация компонентаВсе компоненты