domain и range являются фундаментальными свойствами системы масштабирования в Vega и Vega-Lite, определяющими, как исходные данные преобразуются в визуальные координаты, цвета, размеры и другие эстетические параметры визуализации. Эти поля описывают пространство входных значений и пространство выходных отображаемых значений, формируя математическое соответствие между данными и графическим представлением.
domain задаёт набор значений, которые считаются «входом» для шкалы (scale). Это исходная область данных, которая подлежит преобразованию.
В Vega-Lite domain может задаваться несколькими способами:
В большинстве случаев Vega-Lite выводит domain автоматически из данных, привязанных к шкале. Например, при построении линейного графика по числовому полю:
"scale": {
"domain": "data"
}
При таком подходе система анализирует выбранное поле и определяет минимальное и максимальное значения (для количественных данных) или полный набор уникальных категорий (для номинальных данных).
Для количественных шкал применяется:
Для категориальных:
domain может задаваться вручную, если требуется контроль над отображаемым диапазоном:
"scale": {
"domain": [0, 100]
}
Такой подход фиксирует границы шкалы независимо от данных. Это критически важно при:
В случае дискретных данных domain задаёт порядок категорий:
"scale": {
"domain": ["A", "B", "C", "D"]
}
Порядок в массиве напрямую определяет визуальный порядок на оси или в цветовой шкале. Это позволяет:
Vega-Lite поддерживает привязку domain к конкретному полю:
"scale": {
"domain": {
"field": "category"
}
}
В этом случае система извлекает все значения указанного поля и формирует domain динамически.
Расширенная форма:
"domain": {
"data": "table",
"field": "value"
}
Здесь domain строится из конкретного набора данных, что особенно важно при использовании нескольких источников данных в одной визуализации.
range определяет, в какие визуальные значения преобразуются данные из domain. Это «выходное пространство», в котором работают пиксели, цвета, размеры, углы и другие графические параметры.
range зависит от типа шкалы:
Для осевых шкал range обычно задаёт диапазон пикселей:
"scale": {
"range": [0, 400]
}
Это означает, что минимальное значение domain будет отображено в 0 пикселей, максимальное — в 400.
Важно учитывать инверсию:
Для категориальных данных range задаёт список дискретных визуальных значений:
"scale": {
"range": ["red", "blue", "green"]
}
Каждой категории из domain сопоставляется соответствующий элемент range. Если категорий больше, чем значений в range, применяется циклическое повторение.
В Vega и Vega-Lite цветовые шкалы используют range для определения палитры:
"scale": {
"type": "ordinal",
"range": "category"
}
Здесь range может ссылаться на предопределённые палитры:
Также допускается пользовательский список цветов:
"range": ["#1f77b4", "#ff7f0e", "#2ca02c"]
Для количественных данных используется интерполяция:
"scale": {
"type": "linear",
"range": ["#ffffff", "#000000"]
}
Значения между крайними точками domain интерполируются по цветовой шкале.
Связь между domain и range задаётся функцией масштабирования:
f(x): domain → range
Для линейных шкал используется формула:
(x - d_min) / (d_max - d_min) → нормализованное значение
Далее нормализованное значение проецируется на range.
Для категориальных шкал используется дискретное соответствие:
index(domain_value) → range[index]
domain должен содержать положительные значения:
"scale": {
"type": "log",
"domain": [1, 1000]
}
range остаётся линейным, но преобразование нелинейное.
Используется для категорий:
domain задаёт категории, range распределяет точки равномерно:
При наличии нескольких слоёв данных Vega-Lite может автоматически расширять domain для объединения значений. Однако явное задание domain отключает авторасширение.
Пример конфликтного поведения:
Авто domain: [0, 20]
Явный domain: [0, 10] или [5, 20] (в зависимости от задания)
domain участвует в нормализации:
Это позволяет единообразно обрабатывать:
Для временных данных domain принимает даты:
"scale": {
"type": "time",
"domain": ["2020-01-01", "2025-01-01"]
}
Значения интерпретируются как timestamps, а range преобразуется в пиксели по временной оси.
Связка domain/range напрямую влияет на:
Слишком широкий domain при фиксированном range приводит к сжатию данных, слишком узкий — к потере контекста.
При построении сложных визуализаций каждая шкала имеет собственные domain и range:
Разделение domain и range по шкалам обеспечивает независимость измерений и предсказуемость визуального результата