Типы переменных: linear, point, log

В библиотеке Nivo тип переменной определяет способ интерпретации данных на оси графика. От выбранной шкалы зависит:

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

В Nivo наиболее распространены три типа шкал:

  • linear
  • point
  • log

Каждый тип решает отдельный класс задач и применяется в разных сценариях визуализации.


Linear

Назначение linear

Тип linear используется для непрерывных числовых значений. Это базовая шкала для:

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

Шкала интерпретирует данные как непрерывный диапазон чисел.

Пример:

[
  { x: 0, y: 10 },
  { x: 1, y: 20 },
  { x: 2, y: 40 }
]

Каждое значение располагается пропорционально своему числовому положению.


Принцип работы linear

Шкала вычисляет отношение между:

  • минимальным значением;
  • максимальным значением;
  • размером области графика.

Если диапазон значений:

0 → 100

и ширина графика:

500px

то значение 50 окажется ровно посередине.


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

Наиболее часто шкала задаётся в свойствах:

xScale={{
    type: 'linear'
}}

yScale={{
    type: 'linear'
}}

Полный пример:

<ResponsiveLine
    data={data}
    xScale={{
        type: 'linear',
        min: 0,
        max: 100
    }}
    yScale={{
        type: 'linear',
        min: 0,
        max: 1000
    }}
/>

Свойства linear

min

Минимальное значение шкалы.

min: 0

Также допускаются:

min: 'auto'

При auto Nivo самостоятельно вычисляет минимум.


max

Максимальное значение.

max: 100

или:

max: 'auto'

stacked

Используется для накопительных графиков.

stacked: true

Применяется в:

  • stacked bar charts;
  • area charts;
  • stream charts.

reverse

Инвертирует направление шкалы.

reverse: true

Ось начинает отображаться в обратном порядке.

Пример:

100 → 0

clamp

Ограничивает значения границами шкалы.

clamp: true

Если значение выходит за диапазон, оно фиксируется на границе.


Пример linear для Line Chart

const data = [
    {
        id: 'CPU',
        data: [
            { x: 0, y: 15 },
            { x: 1, y: 30 },
            { x: 2, y: 55 },
            { x: 3, y: 80 }
        ]
    }
]

<ResponsiveLine
    data={data}
    xScale={{
        type: 'linear'
    }}
    yScale={{
        type: 'linear',
        min: 0,
        max: 100
    }}
/>

Когда использовать linear

Шкала подходит для:

Тип данных Подходит
Температура Да
Доход Да
Скорость Да
Проценты Да
Координаты Да

Проблемы linear

Большой разброс значений

Если данные:

1
5
20
1000000

малые значения визуально “схлопываются”.

Это делает график нечитаемым.

В таких случаях используется log.


Неправильное использование категорий

Ошибка:

xScale={{
    type: 'linear'
}}

для данных:

x: 'January'

linear не работает со строковыми категориями.

Для этого нужен point.


Point

Назначение point

Тип point применяется для дискретных категорий.

Примеры:

  • месяцы;
  • названия продуктов;
  • имена пользователей;
  • категории товаров;
  • статусы;
  • этапы процесса.

Шкала не вычисляет числовые интервалы.

Она размещает точки равномерно.


Принцип работы point

Если значения:

January
February
March
April

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


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

xScale={{
    type: 'point'
}}

Пример:

const data = [
    {
        id: 'Sales',
        data: [
            { x: 'Jan', y: 120 },
            { x: 'Feb', y: 210 },
            { x: 'Mar', y: 180 }
        ]
    }
]

<ResponsiveLine
    data={data}
    xScale={{
        type: 'point'
    }}
    yScale={{
        type: 'linear'
    }}
/>

Особенности point

Нет промежуточных значений

Для шкалы:

A
B
C

между A и B нет значения 0.5.

Шкала работает исключительно с категориями.


Равномерное распределение

Даже если данные логически отличаются:

2010
2020
2025

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


Строковые значения

point идеально подходит для строк.

x: 'Frontend'

Пример point в Bar Chart

<ResponsiveBar
    data={[
        {
            country: 'USA',
            users: 500
        },
        {
            country: 'Germany',
            users: 300
        }
    ]}
    keys={['users']}
    indexBy="country"
/>

Внутри Nivo здесь используется категориальная шкала.


Когда использовать point

Тип данных Подходит
Месяцы Да
Имена Да
Категории Да
Статусы Да
Теги Да

Ограничения point

Отсутствие числовой интерполяции

Нельзя:

  • вычислять пропорции;
  • строить математические интервалы;
  • корректно масштабировать расстояния.

Не подходит для непрерывных данных

Ошибка:

x: 1
x: 2
x: 100

с point приводит к одинаковому расстоянию между точками.

Хотя реальная разница отличается.


Log

Назначение log

Шкала log используется для данных с огромным диапазоном значений.

Примеры:

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

Проблема, которую решает log

Данные:

1
10
100
1000
10000

На linear-графике первые значения почти не видны.

Логарифмическая шкала сжимает большие значения.


Принцип работы log

Вместо линейного расстояния используется логарифм.

Пример:

log10(1) = 0
log10(10) = 1
log10(100) = 2

Поэтому расстояния между:

1 → 10
10 → 100
100 → 1000

становятся одинаковыми.


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

yScale={{
    type: 'log',
    base: 10
}}

Полный пример:

<ResponsiveLine
    data={data}
    xScale={{
        type: 'point'
    }}
    yScale={{
        type: 'log',
        base: 10,
        min: 1,
        max: 100000
    }}
/>

Свойства log

base

Основание логарифма.

base: 10

Возможные варианты:

base: 2
base: Math.E

min

Минимум обязательно должен быть больше нуля.

Нельзя:

min: 0

Поскольку:

log(0)

не существует.


max

Максимальная граница шкалы.

max: 1000000

Важнейшее ограничение log

Логарифмическая шкала не поддерживает:

  • 0
  • отрицательные значения

Ошибка:

log(-5)

невозможна математически.


Корректная подготовка данных

Неправильно:

[
  { x: 1, y: 0 },
  { x: 2, y: 100 }
]

Правильно:

[
  { x: 1, y: 1 },
  { x: 2, y: 100 }
]

Пример log для аналитики

const data = [
    {
        id: 'Requests',
        data: [
            { x: '00:00', y: 1 },
            { x: '01:00', y: 10 },
            { x: '02:00', y: 100 },
            { x: '03:00', y: 1000 }
        ]
    }
]

<ResponsiveLine
    data={data}
    xScale={{
        type: 'point'
    }}
    yScale={{
        type: 'log',
        base: 10,
        min: 1,
        max: 1000
    }}
/>

Сравнение linear, point и log

Характеристика linear point log
Тип данных Числовой Категориальный Числовой
Интерполяция Да Нет Да
Поддержка строк Нет Да Нет
Большие диапазоны Плохо Не применимо Отлично
Работа с 0 Да Да Нет
Работа с отрицательными Да Да Нет
Пропорциональность Линейная Равномерная Логарифмическая

Выбор правильной шкалы

Когда нужен linear

Используется при:

  • обычных числовых данных;
  • аналитике;
  • временных рядах;
  • статистике;
  • метриках.

Пример:

Температура
Продажи
CPU usage

Когда нужен point

Используется для:

  • категорий;
  • названий;
  • дискретных значений.

Пример:

Monday
Tuesday
Wednesday

Когда нужен log

Используется при огромном диапазоне данных.

Пример:

1 → 1000000

Типичные сценарии:

  • latency;
  • scientific datasets;
  • big data metrics;
  • network traffic.

Комбинирование шкал

На практике часто комбинируются разные типы.

Пример:

xScale={{
    type: 'point'
}}

yScale={{
    type: 'linear'
}}

или:

xScale={{
    type: 'linear'
}}

yScale={{
    type: 'log'
}}

Ошибки при выборе шкалы

Использование point для чисел

Ошибка:

1
2
100

будут отображаться с одинаковыми интервалами.


Использование linear для строк

Ошибка:

x: 'A'

linear ожидает числа.


Использование log с нулём

Ошибка:

y: 0

вызывает некорректное построение графика.


Влияние шкалы на визуализацию

Тип шкалы влияет на:

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

Неверно выбранная шкала способна полностью исказить смысл графика.


Внутреннее устройство шкал в Nivo

Nivo строится поверх библиотеки D3.

Шкалы основаны на:

  • d3.scaleLinear
  • d3.scalePoint
  • d3.scaleLog

Поэтому поведение полностью соответствует экосистеме D3.


Практический пример сравнения

Linear

1
10
100
1000

На графике:

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

Log

Те же данные:

1
10
100
1000

На графике:

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

Point

Данные:

Low
Medium
High

Каждая категория занимает одинаковое пространство независимо от значения.


Производительность и шкалы

linear и point работают быстрее всего.

log требует дополнительных вычислений:

  • преобразование логарифмов;
  • обработка границ;
  • проверка допустимости значений.

При больших объёмах данных это может влиять на производительность рендера.


Типичные конфигурации

Категории + числа

xScale={{ type: 'point' }}
yScale={{ type: 'linear' }}

Самый распространённый вариант.


Научные данные

xScale={{ type: 'linear' }}
yScale={{ type: 'log', base: 10 }}

Финансовые метрики

xScale={{ type: 'linear' }}
yScale={{
    type: 'linear',
    min: 'auto',
    max: 'auto'
}}

Рекомендации по использованию

linear

Подходит по умолчанию для большинства задач.


point

Используется только для категориальных данных.


log

Применяется исключительно при действительно больших диапазонах значений.

Для обычной аналитики логарифмическая шкала ухудшает читаемость.