Vega-Lite в Markdown: статистические графики текстом

blogtest · 21.08.2026 21:06 #markdown #справка
Vega-Lite в Markdown: статистические графики текстом
Содержание

Диаграммы Mermaid у нас давно, но у них слабо со статистикой: гистограммы, регрессии, боксы, хитмапы — не их жанр. Для этого появился новый fence — vega: описываем график декларативным JSON (спека Vega-Lite), а рендерит его браузер. Никаких картинок — только текст, как мы любим.

Как это устроено

```vega
{
  "width": "container",
  "data": {"values": [{"x": 1, "y": 5}]},
  "mark": "bar"
}
```

Что происходит под капотом:

  • фенс кладёт спеку в <script type="application/json"> внутри контейнера;
  • клиентский скрипт лениво грузит vega + vega-lite + vega-embed с CDN — только если на странице есть хоть один график;
  • при переключении светлой/тёмной темы блога график перерисовывается сам;
  • при наведении на график появляется кнопка «Развернуть» — фуллскрин, где интерактивность полностью сохраняется;
  • невалидный JSON не роняет страницу, а показывается красным блоком с исходником.

Столбчатая диаграмма

Цены за 1000 токенов из обзора моделей Yandex Cloud:

Наведите курсор на столбцы — тултипы работают без единой строчки нашего JS.

Гистограмма без кнопки зума

Распределение времён ответа (мс). На этом графике висит класс .zoom-0 — кнопки «Развернуть» у него нет:

.zoom-0 — общий класс отказа от нашего зума: он действует и на картинки, и на mermaid-схемы (можно вешать на обёртку — например, на весь box).

Точечный график с регрессией

Вот это уже чистый seaborn-жанр: облако точек плюс линия регрессии одним трансформом regression:

Свечной график с объёмом

Классика биржевых терминалов: тело свечи — от открытия к закрытию, тень — от минимума до максимума, под ними объёмы тех же дней. Две диаграммы в vconcat, направление дня считает один трансформ calculate; данные синтетические, 48 торговых дней:

Зелёные свечи — день закрылся выше открытия, красные — ниже. Наведите на свечу: тултип покажет все четыре цены и объём. В развёрнутом виде видно, как всплески объёма совпадают с сильными движениями цены.

Цена, SMA и полосы Боллинджера

Оконные трансформы window считают индикаторы прямо в спеке: короткая SMA(20) и длинная SMA(50) — скользящие средние двух горизонтов, а лента Боллинджера — среднее плюс-минус два stdev за 20 дней. Синяя линия — цена, оранжевый пунктир — SMA(20), зелёная — SMA(50), сиреневая зона — канал Боллинджера:

К концу периода волатильность растёт — лента расходится ровно затем, чтобы это показывать. Обратите внимание: линии начинаются не с первого дня, пока окно не наберет min_periods точек, значения пустые.

Зум осей из коробки

Параметр bind: "scales" даёт нативный pan/zoom прямо в статье: тащите мышью — двигается график, крутите колесо — зум, двойной клик — сброс:

В развёрнутом виде (кнопка справа вверху) с ним особенно удобно.

Классы работают как у всех фенсов

attr_list на открывающей строке попадает на контейнер:

```vega {: .h-scroll-narrow}
{"...": "..."}
```

— широкий график получит горизонтальный скролл на телефоне, а на десктопе будет вести себя как обычный блок.

А пропорции теперь удобно задавать не числом, а классом .ar-W-H: высота считается от реальной ширины контейнера (без жёсткого height из спеки, который на широком экране превращает график в «колбасу»):

```vega {: .ar-16-9}
{"...": "..."}
```

Класс вешаем на открывающую строку фенса — как и у всех фенсов. Если в спеке заданы width/height числами, скрипт пересчитывает высоту от реальной ширины, сохраняя пропорцию автора; узкий числовой график при этом центрируется по контейнеру, а не липнет к левому краю.

Где брать спеки

  • Галерея примеров: vega.github.io/vega-lite/examples — сотни готовых спек от баров до карт и кроссфильтров;
  • Онлайн-редактор: vega.github.io/editor — покрутили, получили JSON, вставили в статью.

Совет

Ставьте "width": "container" — график впишется в колонку статьи, а не уедет за край. Данные можно держать прямо в спеке (values), генерировать (sequence) или подтягивать файлом (data.url — помните про CORS). В составных диаграммах (vconcat, hconcat, facet) скрипт подставляет ширину и в дочерние панели сам — в ряду hconcat она делится поровну; нужен точный контроль — задайте число. Высоту можно выставить классом .ar-W-H на фенсе — она перекрывает фикс-height и считается от реальной ширины.

Комментарии

Пока нет комментариев.

Войдите, чтобы комментировать.