Инверсия масштаба в D3.js реализуется методом .invert(),
который выполняет обратное преобразование по отношению к прямому
отображению значений через масштаб. Если обычная функция масштаба
переводит значения из области определения (domain) в
диапазон отображения (range), то инверсия возвращает
исходное значение домена по заданному значению диапазона.
Масштабы в D3 строятся вокруг двух ключевых понятий:
Прямое преобразование:
scale(x) → y
Инверсия:
scale.invert(y) → x
Это свойство делает возможным двустороннюю связь между данными и визуальным представлением.
Метод .invert() доступен не во всех масштабах D3.
Поддерживаемые непрерывные шкалы:
d3.scaleLineard3.scaleTimed3.scaleLogd3.scalePowd3.scaleSqrtd3.scaleIdentityНеподдерживаемые:
d3.scaleOrdinald3.scaleBandd3.scalePointПричина заключается в природе отображения: дискретные шкалы не имеют однозначного обратного соответствия.
Для линейного масштаба преобразование задаётся формулой:
genui{“math_block_widget_always_prefetch_v2”:{“content”:“y = a x + b”}}
Инверсия вычисляется как:
x =
Где коэффициенты a и b определяются на
основе domain и range.
Если задано:
domain = [d0, d1]range = [r0, r1]то:
a =
и:
b = r0 - a d0
Метод .invert() использует эти зависимости в обратном
направлении для вычисления исходного значения.
Типичный пример линейного масштаба:
const scale = d3.scaleLinear()
.domain([0, 100])
.range([0, 500]);
scale(50);
// 250
scale.invert(250);
// 50
Инверсия позволяет переходить от координат визуализации к данным, что критично для интерактивных интерфейсов.
Одно из ключевых применений — работа с мышью.
Координаты события находятся в пикселях, а данные — в domain масштаба:
const xScale = d3.scaleLinear()
.domain([0, 100])
.range([0, 600]);
svg.on("click", function(event) {
const [x] = d3.pointer(event);
const value = xScale.invert(x);
console.log(value);
});
Здесь происходит преобразование:
Для временных данных используется scaleTime, где domain
состоит из объектов Date.
const timeScale = d3.scaleTime()
.domain([new Date(2020, 0, 1), new Date(2020, 11, 31)])
.range([0, 1000]);
const date = timeScale.invert(500);
Результат — конкретная дата, соответствующая середине диапазона визуализации.
Инверсия не всегда даёт идеально точные значения из-за особенностей чисел с плавающей точкой и округления пикселей.
Типичные источники погрешности:
Пример:
const scale = d3.scaleLinear()
.domain([0, 3])
.range([0, 10]);
scale.invert(3.3333333);
Результат может слегка отличаться от ожидаемого математического значения.
В логарифмических шкалах используется обратная экспоненциальная функция.
Прямое отображение:
genui{“math_block_widget_always_prefetch_v2”:{“content”:“y = _a(x)“}}
Инверсия:
x = a^y
Пример D3:
const logScale = d3.scaleLog()
.domain([1, 1000])
.range([0, 300]);
logScale.invert(150);
Значение возвращается в исходную экспоненциальную область.
Если у шкалы включено ограничение значений:
scale.clamp(true)
инверсия всё равно выполняется по математической модели, но поведение прямого преобразования ограничивается диапазоном.
Это означает:
scale.invert() не учитывает clamp напрямуюПри построении графиков инверсия используется для синхронизации визуальных элементов и данных:
const x = d3.scaleLinear()
.domain([0, 100])
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
svg.on("mousemove", (event) => {
const [px, py] = d3.pointer(event);
const dataX = x.invert(px);
const dataY = y.invert(py);
});
Инверсия позволяет получать координаты в системе данных, а не в системе пикселей.
Работа .invert() основана на предположении
непрерывности:
Если это условие нарушается, например в пользовательских трансформациях или составных шкалах, инверсия становится некорректной или недоступной.
Инверсия масштаба активно используется в задачах:
Пример brush:
brush.on("brush", (event) => {
const selection = event.selection;
const start = xScale.invert(selection[0]);
const end = xScale.invert(selection[1]);
});
Здесь инверсия превращает пиксельный диапазон обратно в диапазон данных.
Изменение параметров масштаба автоматически изменяет результат
.invert().
xScale.domain([0, 200]);
xScale.invert(250); // изменится логика отображения
Инверсия всегда строго зависит от текущего состояния масштаба, а не от исходной конфигурации.
Внутри D3 шкалы представляют собой функции с дополнительными методами:
scale(value) — прямое отображениеscale.invert(value) — обратное отображениеscale.domain() / scale.range() —
конфигурацияИнверсия реализуется как математически обратное преобразование интерполятора, используемого для range.
Метод .invert() является ключевым механизмом
двунаправленного взаимодействия между данными и визуализацией,
обеспечивая возможность восстановления исходных значений из экранных
координат без дополнительного хранения состояния преобразования.