Полосовая шкала в D3.js предназначена для распределения дискретных категорий по непрерывному диапазону координат. Основная область применения — построение столбчатых диаграмм, где каждая категория получает отдельную «полосу» фиксированной ширины внутри общего диапазона.
Ключевая особенность заключается в том, что шкала работает не с числовыми интервалами, а с множеством категориальных значений, автоматически рассчитывая позиции и размеры полос.
Полосовая шкала преобразует набор категорий в равномерно распределённые интервалы на числовой оси.
Формально отображение выглядит так:
Каждой категории соответствует свой индексный слот в диапазоне.
const scale = d3.scaleBand()
После создания шкала настраивается через цепочку методов:
const scale = d3.scaleBand()
.domain(["A", "B", "C"])
.range([0, 300]);
Domain задаёт список значений, которые будут отображаться на оси.
.domain(["январь", "февраль", "март", "апрель"])
Особенности:
В отличие от линейных шкал, порядок domain критически влияет на результат отображения.
Range задаёт числовой интервал, в который будут распределены категории.
.range([0, 400])
При использовании в SVG:
Шкала автоматически вычисляет размер каждой полосы на основе количества элементов и доступного диапазона.
Метод bandwidth() возвращает вычисленную ширину одной
категории.
const width = scale.bandwidth();
Эта величина используется при построении прямоугольников:
Пример применения:
.attr("width", scale.bandwidth())
Метод step() возвращает расстояние между началом
соседних полос.
const step = scale.step();
Связь:
Полосовая шкала поддерживает два типа отступов:
Определяет расстояние между полосами внутри диапазона.
.scaleBand().paddingInner(0.1)
Определяет отступы по краям диапазона.
.scaleBand().paddingOuter(0.2)
Метод align() управляет положением полос внутри
диапазона.
.scaleBand().align(0.5)
Значения:
Метод round(true) включает округление значений до целых
чисел.
.scaleBand().round(true)
Применение:
После настройки шкала выполняет два основных преобразования:
scale("A") // → 0
scale("B") // → 80
scale("C") // → 160
Результат — позиция начала полосы.
scale.bandwidth() // → 70
const data = [
{ name: "A", value: 30 },
{ name: "B", value: 80 },
{ name: "C", value: 45 },
{ name: "D", value: 60 }
];
const x = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, 400])
.paddingInner(0.2);
const y = d3.scaleLinear()
.domain([0, 100])
.range([200, 0]);
const svg = d3.select("svg");
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("x", d => x(d.name))
.attr("y", d => y(d.value))
.attr("width", x.bandwidth())
.attr("height", d => 200 - y(d.value));
Полосовая шкала особенно эффективна при использовании с
.data() в D3:
Полосовая шкала отличается от точечной:
| Характеристика | scaleBand | scalePoint |
|---|---|---|
| Ширина области | есть | нет |
| Поддержка баров | да | нет |
| Возвращает bandwidth | да | нет |
| Использование | столбцы, бары | оси, метки |
При задании domain и range происходит расчёт:
bandwidth = (rangeEnd - rangeStart) / (N + padding adjustment)
Каждой категории назначается индекс i:
position = start + i * step
.attr("x", d => x(d.name))
.attr("width", x.bandwidth())
.attr("y", d => y(d.name))
.attr("height", y.bandwidth())
scaleBand сохраняет:
При добавлении новых категорий все позиции пересчитываются.
При обновлении данных:
x.domain(newData.map(d => d.name));
Типовые проблемы:
Шкала возвращает undefined:
d3.scaleBand().range([0, 100])("A") // undefined
Категории вне domain не отображаются корректно.
Использование фиксированной ширины приводит к перекрытиям.
При 1–2 элементах:
scaleBand является базовым инструментом построения:
Её использование обеспечивает автоматическое управление геометрией элементов без ручных вычислений координат.