Поле numberFormat и timeFormat

В спецификации Vega-Lite форматирование числовых значений определяется через механизм, основанный на формате библиотеки D3-format. Параметр numberFormat применяется к визуальным представлениям чисел в подписях осей, легендах, метках и подсказках, позволяя контролировать отображение точности, разделителей разрядов, научной нотации и других аспектов.

Основные области применения numberFormat

Числовое форматирование в Vega-Lite может задаваться на нескольких уровнях:

  • на уровне глобальной конфигурации (config)
  • на уровне конкретной оси (axis)
  • на уровне легенды (legend)
  • на уровне меток (text, label)
  • в tooltip-значениях

Наиболее универсальный вариант — использование config.numberFormat, который задаёт формат по умолчанию для всех числовых значений в визуализации.

{
  "config": {
    "numberFormat": ".2f"
  }
}

В этом случае все числа будут отображаться с двумя знаками после запятой.

Синтаксис формата чисел (D3-format)

Форматирование чисел в Vega-Lite опирается на спецификацию:

[align][sign][symbol][0][width][,][.precision][type]

На практике чаще используются упрощённые формы:

  • .2f — фиксированная точка, 2 знака после запятой
  • .0f — целые числа без дробной части
  • ,.2f — с разделением тысяч
  • .2% — процентное представление
  • .2e — экспоненциальная запись

Примеры форматирования чисел

Округление значений

{
  "mark": "bar",
  "encoding": {
    "y": {"field": "value", "type": "quantitative"}
  },
  "config": {
    "numberFormat": ".1f"
  }
}

Значения отображаются с одной десятичной цифрой.

Разделители тысяч

{
  "config": {
    "numberFormat": ",.0f"
  }
}

Числа вида 1000000 преобразуются в 1,000,000.

Процентное отображение

{
  "config": {
    "numberFormat": ".1%"
  }
}

Значение 0.25 отображается как 25.0%.

Локальное переопределение numberFormat

Глобальная настройка может быть переопределена на уровне конкретного поля:

{
  "mark": "text",
  "encoding": {
    "text": {
      "field": "value",
      "type": "quantitative",
      "format": ".3f"
    }
  }
}

Здесь формат применяется только к текстовым меткам.

Форматирование в tooltip

Tooltip часто требует более точного контроля над отображением чисел:

{
  "mark": "point",
  "encoding": {
    "x": {"field": "x", "type": "quantitative"},
    "y": {"field": "y", "type": "quantitative"},
    "tooltip": [
      {"field": "x", "type": "quantitative", "format": ".2f"},
      {"field": "y", "type": "quantitative", "format": ".2f"}
    ]
  }
}

Каждое поле получает собственное форматирование.

Особенности поведения numberFormat

  • не изменяет исходные данные, только представление
  • применяется после вычислений агрегации
  • наследуется от конфигурации, если не переопределён
  • зависит от типа шкалы (quantitative)

Форматирование времени в Vega-Lite: timeFormat

Работа с временными данными в Vega-Lite основана на стандартах d3-time-format. Параметр timeFormat управляет тем, как временные значения отображаются в осях, легендах и текстовых элементах.

Базовая концепция временного форматирования

Временные значения в Vega-Lite имеют тип:

"type": "temporal"

И могут отображаться в различных представлениях:

  • даты
  • время
  • дата и время
  • частичные компоненты (год, месяц, день)

Форматирование управляется строками, аналогичными strftime.

Синтаксис timeFormat (d3-time-format)

Основные спецификаторы:

  • %Y — год (2026)
  • %m — месяц (01–12)
  • %d — день месяца
  • %H — часы (24-часовой формат)
  • %M — минуты
  • %S — секунды
  • %b — сокращённое название месяца
  • %B — полное название месяца
  • %a — день недели (сокращённый)
  • %A — день недели (полный)

Примеры форматирования времени

Только дата

{
  "config": {
    "timeFormat": "%Y-%m-%d"
  }
}

Результат: 2026-05-21

Только год и месяц

{
  "config": {
    "timeFormat": "%Y-%m"
  }
}

Результат: 2026-05

Полный формат даты и времени

{
  "config": {
    "timeFormat": "%Y-%m-%d %H:%M:%S"
  }
}

Результат: 2026-05-21 14:30:00

Локальное переопределение timeFormat

Формат времени может быть задан на уровне конкретного канала:

{
  "mark": "line",
  "encoding": {
    "x": {
      "field": "date",
      "type": "temporal",
      "axis": {
        "format": "%d.%m.%Y"
      }
    }
  }
}

Здесь формат применяется только к оси X.

timeFormat в оси и легенде

Ось времени

{
  "encoding": {
    "x": {
      "field": "date",
      "type": "temporal",
      "axis": {
        "format": "%b %Y"
      }
    }
  }
}

Отображение: Jan 2026, Feb 2026 и т.д.

Легенда с временными метками

{
  "encoding": {
    "color": {
      "field": "date",
      "type": "temporal",
      "legend": {
        "format": "%Y"
      }
    }
  }
}

timeUnit vs timeFormat

В Vega-Lite существует принципиальное различие между timeUnit и timeFormat.

timeUnit

timeUnit преобразует данные до визуализации:

{
  "timeUnit": "yearmonth",
  "field": "date"
}

Результат — агрегация по месяцам.

timeFormat

timeFormat не изменяет данные, а только их отображение.

Разделение функций:

  • timeUnit — трансформация данных
  • timeFormat — визуальное представление

Глобальная конфигурация времени

{
  "config": {
    "timeFormat": "%Y-%m-%d",
    "axis": {
      "labelAngle": 0
    }
  }
}

Все временные значения получают единый формат, если не переопределены локально.

Особенности временного форматирования

  • зависит от локали браузера при отсутствии явного формата
  • работает поверх JavaScript Date объектов
  • не изменяет исходный timestamp
  • поддерживает только спецификации d3-time-format
  • применяется после преобразования данных и агрегации

Комбинированное использование numberFormat и timeFormat

В реальных визуализациях оба механизма часто используются одновременно:

{
  "config": {
    "numberFormat": ",.1f",
    "timeFormat": "%Y-%m-%d"
  },
  "mark": "line",
  "encoding": {
    "x": {"field": "date", "type": "temporal"},
    "y": {"field": "value", "type": "quantitative"}
  }
}

Числовые значения получают разделители тысяч и округление, временные значения — человекочитаемый формат даты.


Поведение при отсутствии формата

Если numberFormat или timeFormat не указаны:

  • Vega-Lite использует стандартные настройки Vega
  • применяется локаль браузера
  • формат выбирается автоматически в зависимости от масштаба данных

Автоматическое форматирование может меняться при изменении диапазона значений, что особенно заметно на динамических графиках и при масштабировании осей.


Форматирование в сложных структурах

Facet-графики

{
  "facet": {
    "field": "category",
    "type": "nominal"
  },
  "spec": {
    "mark": "bar",
    "encoding": {
      "x": {"field": "date", "type": "temporal"},
      "y": {
        "field": "value",
        "type": "quantitative",
        "format": ".0f"
      }
    }
  }
}

Каждая ячейка может наследовать или переопределять форматирование независимо.

Сложные tooltip с форматированием

{
  "encoding": {
    "tooltip": [
      {
        "field": "date",
        "type": "temporal",
        "format": "%A, %d %B %Y"
      },
      {
        "field": "value",
        "type": "quantitative",
        "format": ",.2f"
      }
    ]
  }
}

В одном tooltip одновременно применяются оба типа форматирования.


Практические ограничения и нюансы

  • форматирование не поддерживает условные выражения напрямую
  • не может изменять тип данных (string ↔︎ number/date)
  • зависит от корректности входных типов данных
  • экспоненциальные и процентные форматы могут конфликтовать с кастомными шкалами
  • временные зоны не учитываются без явной настройки данных

Взаимодействие с локализацией

Vega-Lite может использовать локализацию для чисел и дат, если не заданы явные форматы:

  • разделитель тысяч зависит от locale
  • формат дат может варьироваться (US/EU)
  • поведение отличается в разных браузерах

При явном указании numberFormat и timeFormat локализация частично подавляется в пользу заданного шаблона.