D3.js предоставляет мощный набор инструментов для преобразования
данных в визуальные представления, и одной из базовых концепций в этой
библиотеке являются шкалы (scales). Шкала — это функция преобразования
входных данных (domain) в визуальные значения (range). Линейная шкала,
реализуемая через d3.scaleLinear(), является
фундаментальным инструментом для работы с числовыми данными, где
требуется пропорциональное отображение значений.
Линейная шкала устанавливает прямое соответствие между двумя числовыми диапазонами:
Формально преобразование можно представить как линейную функцию:
genui{“math_block_widget_always_prefetch_v2”:{“content”:“y = ax + b”}}
где:
x — входное значение из domainy — преобразованное значение в rangea и b вычисляются автоматически на основе
заданных диапазоновБазовый синтаксис:
const scale = d3.scaleLinear();
После создания шкалу необходимо настроить:
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
В этом примере:
0 соответствует 0100 соответствует 500const scale = d3.scaleLinear()
.domain([0, 10])
.range([0, 100]);
console.log(scale(0)); // 0
console.log(scale(5)); // 50
console.log(scale(10)); // 100
Линейность означает сохранение пропорций между значениями.
Линейная шкала поддерживает обратное преобразование:
const scale = d3.scaleLinear()
.domain([0, 10])
.range([0, 100]);
console.log(scale.invert(50)); // 5
Это особенно важно при:
По умолчанию шкала допускает выход за пределы domain:
const scale = d3.scaleLinear()
.domain([0, 10])
.range([0, 100]);
console.log(scale(-5)); // -50
console.log(scale(15)); // 150
Чтобы ограничить значения, используется clamp:
const scale = d3.scaleLinear()
.domain([0, 10])
.range([0, 100])
.clamp(true);
console.log(scale(-5)); // 0
console.log(scale(15)); // 100
Линейная шкала фактически выполняет нормализацию:
t =
и затем масштабирование:
y = r_{min} + t (r_{max} - r_{min})
где:
d_min, d_max — границы domainr_min, r_max — границы rangeЛинейные шкалы тесно связаны с осями:
const xScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 600]);
const xAxis = d3.axisBottom(xScale);
Шкала определяет:
Позволяет получить “красивые” значения для оси:
const scale = d3.scaleLinear()
.domain([0, 97])
.range([0, 500]);
console.log(scale.ticks(5));
Результат будет приближен к удобным числам, например:
[0, 20, 40, 60, 80, 100]
Автоматически расширяет domain до округлых значений:
scale.nice();
Если было:
[3, 97]
может стать:
[0, 100]
Линейная шкала не ограничена числами в range. Она может интерполировать любые типы:
const colorScale = d3.scaleLinear()
.domain([0, 100])
.range(["blue", "red"]);
Здесь происходит интерполяция цвета:
Если входное значение невозможно преобразовать в число, результат
будет NaN:
const scale = d3.scaleLinear()
.domain([0, 10])
.range([0, 100]);
console.log(scale("abc")); // NaN
Поэтому данные часто предварительно очищаются или приводятся к числовому виду.
Линейная шкала применяется при построении координатных систем:
const x = d3.scaleLinear()
.domain([0, 100])
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, 50])
.range([height, 0]);
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", d => x(d.x))
.attr("cy", d => y(d.y))
.attr("r", 4);
Особенность:
Линейные шкалы часто комбинируются:
const opacityScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 1]);
const sizeScale = d3.scaleLinear()
.domain([0, 100])
.range([2, 20]);
Это позволяет управлять несколькими визуальными параметрами одновременно.
Линейная шкала:
При изменении domain или range коэффициенты пересчитываются автоматически.
Перепутанный domain и range
.domain([0, 500]).range([0, 100])
приводит к неожиданному масштабу
Инверсия оси без учета range
Отсутствие обработки NaN
Использование строк вместо чисел
Линейная шкала является базовым строительным блоком:
Она обеспечивает строгую математическую связь между данными и визуальной формой, сохраняя пропорции и делая визуализацию интерпретируемой без дополнительных преобразований.