Цветовая доступность: контраст и дальтонизм

Цвет в графиках выполняет сразу несколько функций:

  • разделяет категории;
  • выделяет важные значения;
  • показывает динамику;
  • помогает воспринимать структуру данных;
  • управляет вниманием.

Неправильно подобранная палитра делает диаграммы трудночитаемыми, особенно для пользователей с нарушениями цветового восприятия. Визуализация может выглядеть красивой, но быть практически бесполезной для части аудитории.

В контексте веб-разработки доступность графиков особенно важна, поскольку диаграммы часто используются:

  • в аналитических панелях;
  • финансовых сервисах;
  • образовательных системах;
  • медицинских интерфейсах;
  • BI-платформах;
  • административных панелях.

Chart.js предоставляет достаточно гибкие инструменты для создания доступных цветовых схем, однако ответственность за выбор палитры полностью лежит на разработчике.


Типы нарушений цветового восприятия

Дейтеранопия

Наиболее распространённый тип дальтонизма. Пользователь плохо различает зелёные оттенки.

Проблемные комбинации:

  • зелёный и красный;
  • зелёный и коричневый;
  • зелёный и оранжевый.

Протанопия

Снижение восприятия красного цвета.

Плохо различаются:

  • красный и чёрный;
  • красный и зелёный;
  • красный и коричневый.

Тританопия

Редкая форма, связанная с восприятием синего цвета.

Проблемными становятся:

  • синий и зелёный;
  • жёлтый и розовый;
  • фиолетовый и красный.

Ахроматопсия

Практически полное отсутствие цветового восприятия.

Графики воспринимаются как градации серого.


Основные принципы доступной цветовой схемы

Не использовать цвет как единственный способ передачи информации

Плохой пример:

datasets: [{
    label: 'Прибыль',
    data: [120, 150, 170],
    backgroundColor: 'green'
}, {
    label: 'Убыток',
    data: [80, 60, 40],
    backgroundColor: 'red'
}]

Если пользователь не различает красный и зелёный, смысл теряется.

Лучше дополнять цвет:

  • подписями;
  • текстовыми значениями;
  • различными типами линий;
  • паттернами;
  • иконками;
  • маркерами.

Высокий контраст

Недостаточный контраст между элементами делает график нечитаемым.

Особенно это важно для:

  • текста;
  • осей;
  • сетки;
  • легенд;
  • подписей данных.

Ограничение количества цветов

Слишком большое число оттенков перегружает восприятие.

Рекомендуется:

  • 5–7 основных цветов;
  • дополнительные различия через форму и стиль;
  • нейтральные оттенки для второстепенных данных.

Проверка в оттенках серого

Если график остаётся понятным без цвета — это хороший признак доступности.


Контраст в Chart.js

Настройка цвета текста

options: {
    plugins: {
        legend: {
            labels: {
                color: '#111'
            }
        }
    }
}

Тёмный текст на светлом фоне обычно обеспечивает лучший контраст.


Цвет осей

options: {
    scales: {
        x: {
            ticks: {
                color: '#222'
            },
            grid: {
                color: '#d0d0d0'
            }
        },
        y: {
            ticks: {
                color: '#222'
            },
            grid: {
                color: '#d0d0d0'
            }
        }
    }
}

Слишком светлая сетка затрудняет чтение значений.


Контраст фона и данных

Плохой пример:

backgroundColor: '#ffffff',
borderColor: '#f5f5f5'

Линия почти незаметна.

Лучше:

backgroundColor: '#ffffff',
borderColor: '#1565c0'

Безопасные цветовые палитры

Палитра Color Universal Design

Одна из популярных доступных палитр:

const colors = [
    '#000000',
    '#E69F00',
    '#56B4E9',
    '#009E73',
    '#F0E442',
    '#0072B2',
    '#D55E00',
    '#CC79A7'
];

Преимущества:

  • хорошая различимость;
  • устойчивость к дальтонизму;
  • высокий контраст;
  • универсальность.

Использование палитры в Chart.js

const ctx = document.getElementById('myChart');

new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['A', 'B', 'C', 'D'],
        datasets: [{
            label: 'Продажи',
            data: [12, 19, 7, 15],
            backgroundColor: [
                '#56B4E9',
                '#E69F00',
                '#009E73',
                '#D55E00'
            ]
        }]
    }
});

Проблема красно-зелёных сочетаний

Наиболее опасная комбинация

Классический пример:

backgroundColor: [
    'red',
    'green'
]

Для многих пользователей цвета выглядят почти одинаково.


Альтернативные сочетания

Безопаснее использовать:

  • синий и оранжевый;
  • фиолетовый и жёлтый;
  • тёмно-синий и бирюзовый.

Пример:

backgroundColor: [
    '#1565C0',
    '#EF6C00'
]

Использование прозрачности

Проблемы с alpha-каналом

Полупрозрачные элементы могут ухудшать контраст.

Плохой пример:

backgroundColor: 'rgba(21, 101, 192, 0.2)'

На светлом фоне область становится почти невидимой.


Безопасная прозрачность

backgroundColor: 'rgba(21, 101, 192, 0.6)'

Либо использование плотной границы:

borderColor: '#1565C0',
borderWidth: 2

Доступность линейных графиков

Толщина линий

Тонкие линии плохо различимы.

Рекомендуется:

borderWidth: 3

Различные стили линий

Chart.js поддерживает пунктир.

datasets: [{
    label: '2024',
    data: [12, 15, 18],
    borderColor: '#1565C0',
    borderDash: []
}, {
    label: '2025',
    data: [10, 13, 16],
    borderColor: '#EF6C00',
    borderDash: [8, 4]
}]

Даже без различения цветов линии остаются отличимыми.


Использование точек

pointRadius: 5,
pointHoverRadius: 7

Крупные точки улучшают восприятие.


Доступность столбчатых диаграмм

Контур столбцов

borderColor: '#000',
borderWidth: 1

Контуры помогают различать соседние элементы.


Разделение оттенков по яркости

Плохой пример:

[
    '#1976D2',
    '#1E88E5',
    '#2196F3'
]

Цвета слишком похожи.

Лучше:

[
    '#003f5c',
    '#7a5195',
    '#ef5675'
]

Доступность круговых диаграмм

Главная проблема pie chart

Сегменты часто различаются только цветом.

Это делает круговые диаграммы одной из самых проблемных визуализаций с точки зрения доступности.


Добавление границ

borderColor: '#fff',
borderWidth: 3

Сегменты становятся визуально отделёнными.


Ограничение количества сегментов

Лучше избегать:

  • 10–15 категорий;
  • близких оттенков;
  • мелких частей.

Оптимально:

  • 4–6 сегментов.

Использование паттернов

Зачем нужны паттерны

Текстуры помогают различать элементы без цвета.

Например:

  • полосы;
  • точки;
  • диагонали;
  • сетка.

Подключение Patternomaly

Популярная библиотека:

<script src="https://cdn.jsdelivr.net/npm/patternomaly"></script>

Пример использования

const patterns = [
    pattern.draw('dot', '#1565C0'),
    pattern.draw('dash', '#EF6C00')
];

new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['A', 'B'],
        datasets: [{
            data: [10, 20],
            backgroundColor: patterns
        }]
    }
});

Паттерны значительно повышают доступность.


Проверка WCAG-контраста

Коэффициент контрастности

WCAG рекомендует:

  • минимум 4.5:1 для обычного текста;
  • минимум 3:1 для крупного текста;
  • высокий контраст для интерактивных элементов.

Онлайн-инструменты проверки

Полезные сервисы:

  • WebAIM Contrast Checker;
  • Accessible Colors;
  • Contrast Ratio.

Адаптация под тёмную тему

Ошибки тёмных интерфейсов

Частая проблема:

color: '#666'

На тёмном фоне текст становится плохо читаемым.


Настройка тёмой темы

options: {
    plugins: {
        legend: {
            labels: {
                color: '#eee'
            }
        }
    },
    scales: {
        x: {
            ticks: {
                color: '#ddd'
            },
            grid: {
                color: '#444'
            }
        },
        y: {
            ticks: {
                color: '#ddd'
            },
            grid: {
                color: '#444'
            }
        }
    }
}

Генерация доступных палитр

Использование HSL

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

Пример:

function generateColors(count) {
    const colors = [];

    for (let i = 0; i < count; i++) {
        const hue = (360 / count) * i;

        colors.push(`hsl(${hue}, 70%, 45%)`);
    }

    return colors;
}

Контроль яркости

Слишком светлые цвета плохо видны.

Рекомендуемые значения:

  • saturation: 60–80%;
  • lightness: 35–55%.

Плагины для повышения доступности

chartjs-plugin-datalabels

Позволяет отображать значения прямо на графике.

plugins: {
    datalabels: {
        color: '#111',
        font: {
            weight: 'bold'
        }
    }
}

Текстовые подписи уменьшают зависимость от цвета.


Доступность легенды

Размер текста

Мелкая легенда ухудшает читаемость.

legend: {
    labels: {
        font: {
            size: 14
        }
    }
}

Увеличение маркеров

labels: {
    boxWidth: 20,
    boxHeight: 20
}

Проверка графиков на доступность

Симуляция дальтонизма

Инструменты:

  • Color Oracle;
  • браузерные DevTools;
  • Stark;
  • расширения Chrome.

Проверка в grayscale

Полезный метод:

  1. сделать скриншот графика;
  2. перевести изображение в grayscale;
  3. проверить различимость элементов.

Практический пример доступного графика

const ctx = document.getElementById('salesChart');

new Chart(ctx, {
    type: 'line',

    data: {
        labels: ['Янв', 'Фев', 'Мар', 'Апр'],

        datasets: [
            {
                label: '2024',
                data: [10, 20, 15, 30],

                borderColor: '#1565C0',
                backgroundColor: 'rgba(21, 101, 192, 0.3)',

                borderWidth: 3,

                pointRadius: 5
            },

            {
                label: '2025',
                data: [15, 18, 22, 28],

                borderColor: '#EF6C00',

                borderDash: [8, 4],

                borderWidth: 3,

                pointRadius: 5
            }
        ]
    },

    options: {
        responsive: true,

        plugins: {
            legend: {
                labels: {
                    color: '#111',

                    font: {
                        size: 14
                    }
                }
            }
        },

        scales: {
            x: {
                ticks: {
                    color: '#222'
                },

                grid: {
                    color: '#d0d0d0'
                }
            },

            y: {
                ticks: {
                    color: '#222'
                },

                grid: {
                    color: '#d0d0d0'
                }
            }
        }
    }
});

В этом примере используются:

  • контрастные цвета;
  • разные стили линий;
  • крупные точки;
  • читаемые подписи;
  • нейтральная сетка;
  • отказ от красно-зелёной схемы;
  • достаточная толщина линий.