Графики
Категориальная палитра
Шесть тонов, различающих ряды графика. Единственное место в ките, где цвет не кодирует состояние, — и потому единственное, у которого свои правила.
- Ряд 1
- Ряд 2
- Ряд 3
- Ряд 4
- Ряд 5
- Ряд 6
Разметка
<ul class="inst-legend">
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-1)"></span>Ряд 1</li>
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-2)"></span>Ряд 2</li>
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-3)"></span>Ряд 3</li>
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-4)"></span>Ряд 4</li>
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-5)"></span>Ряд 5</li>
<li class="inst-legend-item"><span class="inst-legend-swatch" style="--series:var(--chart-6)"></span>Ряд 6</li>
</ul>
Первый закон кита требует, чтобы цвет кодировал состояние, категорию или полярность. Ряд графика — это категория, поэтому палитра закон не нарушает, а уточняет его. Исключение оговорено в конституции поимённо, и вместе с ним оговорены пять правил, которых нет больше нигде в ките.
Использование
Ряд назначается через --series, инлайном, как канал данных: номер ряда
приходит вместе с данными и не может быть известен статическому CSS.
Разметка
<svg class="inst-sparkline" viewBox="0 0 120 32" preserveAspectRatio="none" aria-hidden="true" style="--series:var(--chart-3)">
<path class="inst-sparkline-area" d="M0,20 24,14 48,18 72,9 96,12 120,5 120,32 0,32Z"/>
<path class="inst-sparkline-line" d="M0,20 24,14 48,18 72,9 96,12 120,5"/>
</svg>
| Что | Обязательно | Почему |
|---|---|---|
--series на корне ряда |
да | Один раз на <svg> или на метку легенды — все узлы ряда наследуют её |
Тон через --series, а не напрямую |
да | Компонент читает приёмник, а не тон ряда: иначе переназначить ряд можно только правкой разметки каждого узла |
| Легенда при двух рядах и больше | да | Без расшифровки цвет ничего не сообщает |
--series при одном ряде |
нет | Умолчание --chart-1 достаточно |
Компоненты, читающие --series:
| Компонент | Узлы |
|---|---|
| Легенда | inst-legend-swatch |
| Спарклайн | inst-sparkline-line · inst-sparkline-area · inst-sparkline-last |
| Аватар | Тон группы: аватар различает сущности, а не сообщает состояние — та же работа, что у ряда |
Кольцо и мера --series не читают: они
показывают одну величину и берут --tone-mark.
/* Именованный ряд приложения — привязка номера к показателю в одном месте */
.chart-render { --series: var(--chart-1); }
.chart-physics { --series: var(--chart-2); }
Такая привязка — самый дешёвый способ выполнить первое правило: показатель получает номер один раз, а не в каждом шаблоне.
Когда использовать
| Используйте | Возьмите другое |
|---|---|
| Различить ряды на одном графике — вместе с легендой | Состояние объекта — data-tone и бейдж: статусные тона закреплены и в палитре не участвуют |
| Метку ряда в легенде того же графика | Заливку кнопки или подсветку строки — кнопка и акцент: категориальный цвет вне графика запрещён |
| Пять-шесть рядов максимум | Седьмой ряд — это не график, а таблица |
| Ряд, чей номер известен из данных | Величину одного показателя — мера или кольцо: у них один тон, потому что сравнивается одна величина |
Варианты
| Токен | Тон | Светлота (светлая тема) | Светлота (тёмная) |
|---|---|---|---|
--chart-1 |
280 | 0.520 | 0.700 |
--chart-2 |
320 | 0.600 | 0.760 |
--chart-3 |
355 | 0.550 | 0.720 |
--chart-4 |
55 | 0.650 | 0.800 |
--chart-5 |
115 | 0.580 | 0.740 |
--chart-6 |
190 | 0.620 | 0.780 |
Значения записаны в OKLCH через light-dark(): тон и насыщенность держатся, а
светлота переворачивается по теме. Ни один тон не попадает в зарезервированные
коридоры — 25 (ошибка), 85 (предупреждение), 150 (успех), 250 (акцент
и «идёт»).
Ряд №3 стоит на 355, то есть в 30° от ошибочного 25: это ближайшее
сближение во всей палитре, и дальше её расширять нельзя не только из-за
различимости, но и потому, что свободных коридоров не осталось.
Правила
Пять, и каждое ловит ошибку, которую иначе никто не заметит.
Так Порядок — часть контракта
Ряд №1 всегда --chart-1, на любом экране. Показатель, меняющий цвет от
страницы к странице, обесценивает цвет вообще.
Не так Цвет по порядку сортировки
Легенда по величине при графике по времени даёт две нумерации одного и того же, и легенду приходится перечитывать заново.
Так Тона в 25° от статусных и акцента
Коридоры 25, 85, 150, 250 заняты. Ряд, попавший в них, читается как
«упало» или как «нажми сюда».
Не так Категориальный цвет вне графика
В роли статуса, заливки кнопки или подсветки строки он запрещён: это второй акцент, заведённый чёрным ходом.
Так Разная светлота внутри палитры
Выбрана намеренно: при дальтонизме и на чёрно-белой печати тон исчезает, а яркость остаётся.
Не так Седьмой ряд
Шесть — потолок. Седьмой означает, что показывать надо таблицей: различить семь тонов человек уже не может.
Легенда обязательна при двух и более рядах. Правило принадлежит палитре, а не легенде: без расшифровки цвет ничего не сообщает, и тогда его незачем было назначать. Подробности — на странице легенды.
Чего палитра не делает:
| Не делает | Почему |
|---|---|
| Не кодирует полярность | Рост и падение — это метрика и её дельта, где цвет означает «лучше» и «хуже» |
| Не кодирует состояние | Статусные тона закреплены за data-tone, и коридоры разведены нарочно |
| Не даёт последовательной шкалы | Шесть различимых тонов — это категории. Шкала «мало → много» одним тоном разной светлоты в ките не заведена |
| Не растягивается | Седьмого токена нет, и добавить его локально — значит нарушить потолок, а не расширить палитру |
Доступность
| Цвет не единственный носитель | Ряд всегда назван словом в легенде. Палитра различает ряды, но не сообщает о них ничего — сообщает подпись |
| Дальтонизм | Разная светлота внутри палитры выбрана для этого: при потере тона ряды остаются различимы по яркости |
| Чёрно-белая печать | Тот же механизм. Шесть тонов одной светлоты слились бы в один серый |
| Контраст | Каждый тон держит 3:1 против поверхности в шести темах: линия и метка ряда — несущие знаки |
| Подписи | Категориальный тон не используется для текста: 3:1 хватает знаку, но не подписи. Текст берёт --text-primary или --tone-ink |
| Режим принудительных цветов | Категориальные тона сбрасываются системой, и это правильно: различать ряды в таком режиме обязана легенда со словами |
API
| Имя | Значение | Что делает |
|---|---|---|
| переменная | ||
--series | --chart-1 | Приёмник тона. Компонент ряда читает её, а не тон напрямую |
| токен | ||
--chart-1 | light-dark(oklch(0.520 0.150 280), oklch(0.700 0.130 280)) | Тон ряда №1. Порядок — часть контракта: ряд №1 всегда этот тон |
--chart-2 | light-dark(oklch(0.600 0.150 320), oklch(0.760 0.120 320)) | Тон ряда №2. Порядок — часть контракта: ряд №2 всегда этот тон |
--chart-3 | light-dark(oklch(0.550 0.140 355), oklch(0.720 0.120 355)) | Тон ряда №3. Порядок — часть контракта: ряд №3 всегда этот тон |
--chart-4 | light-dark(oklch(0.650 0.120 55), oklch(0.800 0.110 55)) | Тон ряда №4. Порядок — часть контракта: ряд №4 всегда этот тон |
--chart-5 | light-dark(oklch(0.580 0.130 115), oklch(0.740 0.120 115)) | Тон ряда №5. Порядок — часть контракта: ряд №5 всегда этот тон |
--chart-6 | light-dark(oklch(0.620 0.110 190), oklch(0.780 0.100 190)) | Тон ряда №6. Порядок — часть контракта: ряд №6 всегда этот тон |
Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument