Read in:
Русский

Графики в заметках

Блок datachart в заметке превращается в интерактивный график на опубликованной странице. Никакого отдельного редактора — вы пишете график так же, как любой другой блок кода в Obsidian.

Как это работает

Добавьте в заметку огороженный блок с идентификатором языка datachart. Внутри — один JSON-объект с двумя ключами:

  • data — откуда брать данные
  • config — объект настроек Apache ECharts, который задаёт тип и внешний вид графика
{
  "data": { "source": "inline", "rows": [ ... ] },
  "config": {
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "bar", "encode": { "x": "month", "y": "sales" } }]
  }
}

trip2g читает объект data, загружает или считывает строки и автоматически подставляет их в config.dataset.source. Никакого плейсхолдера для данных писать не нужно — они просто появляются. Виджет ECharts на странице рисует график из результата.

Один блок = один график. Разместите в заметке столько блоков, сколько нужно — они отрисуются по порядку.


Живые примеры

Графики ниже отрисованы из блоков datachart прямо на этой странице — каждый это несколько строк markdown с данными внутри.

{
  "data": { "source": "inline", "rows": [
    { "month": "Янв", "sales": 120 },
    { "month": "Фев", "sales": 200 },
    { "month": "Мар", "sales": 150 },
    { "month": "Апр", "sales": 280 },
    { "month": "Май", "sales": 240 }
  ]},
  "config": {
    "title": { "text": "Продажи по месяцам (столбцы)" },
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "bar", "encode": { "x": "month", "y": "sales" } }]
  }
}
{
  "data": { "source": "inline", "rows": [
    { "day": "Пн", "visitors": 40 },
    { "day": "Вт", "visitors": 65 },
    { "day": "Ср", "visitors": 52 },
    { "day": "Чт", "visitors": 88 },
    { "day": "Пт", "visitors": 71 }
  ]},
  "config": {
    "title": { "text": "Посетители по дням (линия)" },
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "line", "encode": { "x": "day", "y": "visitors" } }]
  }
}
{
  "data": { "source": "inline", "rows": [
    { "source": "прямые", "hits": 30 },
    { "source": "поиск", "hits": 50 },
    { "source": "соцсети", "hits": 20 }
  ]},
  "config": {
    "title": { "text": "Источники трафика (круговая)" },
    "series": [{ "type": "pie", "encode": { "itemName": "source", "value": "hits" } }]
  }
}

Источники данных

Поле data.source указывает, откуда брать строки. Доступны четыре варианта.

inline — данные прямо в блоке

Самый простой случай. Все строки находятся внутри блока. Подходит для небольших статичных графиков, которые не меняются.

{
  "data": {
    "source": "inline",
    "rows": [
      { "month": "Янв", "sales": 120 },
      { "month": "Фев", "sales": 200 },
      { "month": "Мар", "sales": 150 },
      { "month": "Апр", "sales": 280 },
      { "month": "Май", "sales": 240 }
    ]
  },
  "config": {
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "bar", "encode": { "x": "month", "y": "sales" } }]
  }
}

Никаких загрузок не происходит. Строки — часть самой заметки.

frontmatter — данные из файла хранилища

Данные живут в файле .csv или .json внутри вашего хранилища Obsidian. Ссылку на файл вы указываете во frontmatter заметки, а не внутри блока кода.

Почему во frontmatter? Потому что Obsidian умеет работать с [[ссылками]] во frontmatter как с настоящими связями — автодополнение, граф, подсветка в редакторе. Ссылка внутри блока кода ничего из этого не получит.

Добавьте ссылку как свойство frontmatter, затем укажите имя этого свойства в блоке:

---
chart_sales: "[[sales.datachart.csv]]"
chart_visitors: "[[visitors.json]]"
---
{
  "data": { "source": "frontmatter", "ref": "chart_sales" },
  "config": {
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "bar", "encode": { "x": "month", "y": "sales" } }]
  }
}

Когда читатель открывает страницу, браузер загружает файл с данными напрямую — trip2g преобразует вики-ссылку в URL ресурса и вставляет его в HTML страницы. Файл раздаётся с теми же правами доступа, что и сама заметка: свободная заметка отдаёт файл публично, платная требует подписку.

Поддерживаются оба формата. JSON-файл должен содержать массив объектов-строк. CSV-файл должен иметь строку заголовков; виджет разбирает её автоматически и приводит числовые колонки к числовому типу.

url — данные из внешнего HTTP-эндпойнта

Живые данные с любого HTTP-JSON эндпойнта, которым вы управляете. trip2g обращается к URL на стороне сервера, кеширует результат и встраивает его в отрисованный HTML. URL эндпойнта и тело запроса никогда не попадают в исходный код страницы.

{
  "data": {
    "source": "url",
    "url": "http://localhost:8090/v1/query",
    "body": "{\"sql\":\"SELECT day, revenue FROM stats ORDER BY day\"}"
  },
  "config": {
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "line", "encode": { "x": "day", "y": "revenue" } }]
  }
}

Эндпойнт должен возвращать плоский JSON-массив объектов-строк:

[
  { "day": "2026-06-01", "revenue": 1234 },
  { "day": "2026-06-02", "revenue": 1891 }
]

Когда грузятся данные. trip2g запрашивает URL на сервере, когда заметку публикуют или пересобирают (во время загрузки заметки) — не когда читатель открывает страницу. Читатель всегда получает готовый HTML. Пока идёт первая загрузка, график показывает индикатор; как только данные приходят, страница перерисовывается с ними. Дальше кешированный результат переиспользуется до следующей публикации заметки.

Заголовки авторизации (скоро). Эндпойнты с заголовком авторизации — ключ или токен — будут работать через зашифрованные серверные секреты, так что данные доступа не попадут в браузер.

internal — запрос к данным вашего сайта (скоро)

data.source = "internal" с полем sql позволит строить графики по собственному опубликованному контенту — заметки по статусу, публикации за период и подобное. Этот источник данных пока недоступен; на живом сайте график показывает индикатор загрузки.


Свойства frontmatter

Два необязательных свойства управляют поведением графиков на уровне заметки.

chart_ttl (частота обновления — скоро)

Желаемый интервал обновления данных url/internal в формате длительности Go: 30m, 1h, 24h. Обновление по расписанию пока не работает — сейчас данные грузятся один раз при публикации и обновляются только при повторной публикации заметки.

chart_ttl: 1h

charts: custom

Отключает встроенную отрисовку графиков. Блоки всё равно разбираются и доступны кастомному шаблону через ctx.Charts(), чтобы вы могли расположить их в нужных местах макета.

charts: custom

Это продвинутая настройка для кастомных шаблонов. Большинству авторов она не нужна.


Типы графиков

Тип графика задаётся в config.series[].type. Три самых распространённых:

Тип series[].type Примечание
Столбчатый "bar" encode: { x: "колонка", y: "колонка" } для привязки данных
Линейный "line" Та же схема encode, что и у bar
Круговой "pie" encode: { itemName: "колонка", value: "колонка" }

Доступны все типы графиков ECharts — полный список в справочнике ECharts. Объект config передаётся в ECharts напрямую, поэтому всё, что работает в ECharts, работает и здесь.


Пример: столбчатый, линейный и круговой в одной заметке

Заметка ниже использует три типа из разных источников данных:

---
free: true
title: Обзор трафика
chart_ttl: 1h
---
{
  "data": {
    "source": "url",
    "url": "http://localhost:8090/v1/query",
    "body": "{\"sql\":\"SELECT product, revenue FROM sales ORDER BY revenue DESC LIMIT 5\"}"
  },
  "config": {
    "xAxis": { "type": "category" },
    "yAxis": { "type": "value" },
    "series": [{ "type": "bar", "encode": { "x": "product", "y": "revenue" } }]
  }
}
{
  "data": {
    "source": "inline",
    "rows": [
      { "source": "direct", "hits": 30 },
      { "source": "search", "hits": 50 },
      { "source": "social", "hits": 20 }
    ]
  },
  "config": {
    "series": [{ "type": "pie", "encode": { "itemName": "source", "value": "hits" } }]
  }
}