Поле point внутри line и area

Поле point в спецификациях line и area управляет отображением отдельных точек поверх линии или области. Оно позволяет комбинировать непрерывный график с маркерами данных, делая визуализацию более читаемой и информативной.

В Vega-Lite свойство point используется внутри объекта mark.

Базовый пример:

{
  mark: {
    type: "line",
    point: true
  }
}

В результате поверх линии отображаются точки для каждого значения набора данных.


Назначение point

Линейный график хорошо показывает тренд, но не всегда позволяет определить:

  • где находятся реальные значения;
  • сколько точек участвует в построении;
  • имеются ли пропуски;
  • как распределены данные;
  • существуют ли выбросы.

Поле point решает эти задачи за счёт наложения маркеров поверх линии или области.


Простое использование

Линия с точками

const spec = {
  data: {
    values: [
      {x: 1, y: 10},
      {x: 2, y: 20},
      {x: 3, y: 15},
      {x: 4, y: 30}
    ]
  },

  mark: {
    type: "line",
    point: true
  },

  encoding: {
    x: {field: "x", type: "quantitative"},
    y: {field: "y", type: "quantitative"}
  }
};

Точки автоматически размещаются в координатах значений.


Использование внутри area

Поле point поддерживается и для графиков области.

mark: {
  type: "area",
  point: true
}

В этом случае:

  • строится залитая область;
  • поверх неё отображаются маркеры.

Пример:

const spec = {
  data: {
    values: [
      {month: "Jan", value: 30},
      {month: "Feb", value: 50},
      {month: "Mar", value: 40},
      {month: "Apr", value: 70}
    ]
  },

  mark: {
    type: "area",
    point: true
  },

  encoding: {
    x: {field: "month", type: "ordinal"},
    y: {field: "value", type: "quantitative"}
  }
};

Логическое значение true

Самый простой вариант:

point: true

Эквивалентно:

point: {}

Vega-Lite создаёт точки со стандартными параметрами:

  • форма — круг;
  • стандартный размер;
  • стандартный цвет;
  • автоматическое наследование цвета линии.

Отключение точек

point: false

или полное отсутствие свойства:

mark: "line"

Объект конфигурации point

Поле point может содержать объект с параметрами оформления.

Пример:

mark: {
  type: "line",

  point: {
    filled: true,
    size: 120,
    color: "red"
  }
}

Основные параметры point

filled

Управляет заливкой маркеров.

Без заливки

point: {
  filled: false
}

Получаются полые круги.

С заливкой

point: {
  filled: true
}

Точки становятся закрашенными.


size

Размер маркеров.

point: {
  size: 200
}

Размер задаётся в квадратных пикселях.


color

Цвет точек.

point: {
  color: "orange"
}

Если цвет не указан:

  • точки наследуют цвет линии;
  • либо используют цвет кодирования encoding.color.

shape

Форма точек.

Поддерживаются:

  • "circle"
  • "square"
  • "diamond"
  • "triangle"
  • "cross"
  • "stroke"

Пример:

point: {
  shape: "diamond"
}

stroke

Цвет обводки.

point: {
  stroke: "black"
}

strokeWidth

Толщина контура.

point: {
  strokeWidth: 2
}

opacity

Прозрачность точек.

point: {
  opacity: 0.5
}

fill

Цвет внутренней части.

point: {
  filled: true,
  fill: "yellow"
}

Полная настройка точек

const spec = {
  data: {
    values: [
      {x: 1, y: 10},
      {x: 2, y: 25},
      {x: 3, y: 18},
      {x: 4, y: 40}
    ]
  },

  mark: {
    type: "line",

    point: {
      filled: true,
      shape: "diamond",
      size: 180,
      fill: "white",
      stroke: "red",
      strokeWidth: 3,
      opacity: 0.9
    }
  },

  encoding: {
    x: {field: "x", type: "quantitative"},
    y: {field: "y", type: "quantitative"}
  }
};

Автоматическое наследование свойств

Точки наследуют некоторые параметры линии.

Например:

mark: {
  type: "line",
  color: "green",
  point: true
}

Точки также станут зелёными.


Переопределение цвета

mark: {
  type: "line",
  color: "blue",

  point: {
    color: "red"
  }
}

Линия остаётся синей, точки становятся красными.


Использование с encoding.color

Группировка линий

encoding: {
  color: {
    field: "category",
    type: "nominal"
  }
}

Каждая серия:

  • получает собственный цвет;
  • отображает точки того же цвета.

Пример многосерийного графика

const spec = {
  data: {
    values: [
      {year: 2020, value: 10, type: "A"},
      {year: 2021, value: 20, type: "A"},
      {year: 2022, value: 30, type: "A"},

      {year: 2020, value: 15, type: "B"},
      {year: 2021, value: 18, type: "B"},
      {year: 2022, value: 25, type: "B"}
    ]
  },

  mark: {
    type: "line",
    point: true
  },

  encoding: {
    x: {field: "year", type: "ordinal"},

    y: {
      field: "value",
      type: "quantitative"
    },

    color: {
      field: "type",
      type: "nominal"
    }
  }
};

Поле point и интерактивность

Точки особенно полезны при использовании:

  • tooltip;
  • hover-эффектов;
  • выделения;
  • выбора (selection);
  • событий мыши.

Tooltip на точках

const spec = {
  data: {
    values: [
      {x: 1, y: 5},
      {x: 2, y: 15},
      {x: 3, y: 10}
    ]
  },

  mark: {
    type: "line",
    point: true
  },

  encoding: {
    x: {field: "x", type: "quantitative"},
    y: {field: "y", type: "quantitative"},

    tooltip: [
      {field: "x"},
      {field: "y"}
    ]
  }
};

Точки упрощают наведение мыши, особенно на плотных графиках.


Условное отображение точек

В Vega-Lite можно отображать точки только при наведении.


Hover-point

const spec = {
  data: {
    values: [
      {x: 1, y: 8},
      {x: 2, y: 12},
      {x: 3, y: 18},
      {x: 4, y: 10}
    ]
  },

  params: [
    {
      name: "hover",
      select: {
        type: "point",
        nearest: true,
        on: "mouseover",
        clear: "mouseout"
      }
    }
  ],

  mark: {
    type: "line",

    point: {
      filled: true
    }
  },

  encoding: {
    x: {field: "x", type: "quantitative"},
    y: {field: "y", type: "quantitative"},

    size: {
      condition: {
        param: "hover",
        value: 200
      },
      value: 50
    }
  }
};

При наведении точка увеличивается.


Скрытие точек на больших данных

При большом количестве значений точки могут:

  • перегружать график;
  • ухудшать читаемость;
  • замедлять рендеринг.

Пример проблемы:

point: true

при тысячах значений.


Частичное решение через прозрачность

point: {
  opacity: 0.3
}

Использование маленького размера

point: {
  size: 20
}

Поле point и производительность

Каждая точка — отдельный графический объект.

При больших объёмах данных:

  • возрастает число DOM/SVG элементов;
  • усложняется hit-testing;
  • ухудшается производительность Canvas/SVG.

Особенно заметно:

  • в браузерах;
  • на мобильных устройствах;
  • при анимации;
  • при интерактивных фильтрах.

Разница между point и отдельным слоем point

Существует два подхода:

1. Встроенное поле point

mark: {
  type: "line",
  point: true
}

Плюсы

  • компактность;
  • простота;
  • меньше кода.

Минусы

  • ограниченная гибкость;
  • сложнее управлять отдельно.

2. Отдельный слой

layer: [
  {
    mark: "line"
  },

  {
    mark: "point"
  }
]

Пример layered-подхода

const spec = {
  data: {
    values: [
      {x: 1, y: 10},
      {x: 2, y: 30},
      {x: 3, y: 20}
    ]
  },

  layer: [
    {
      mark: {
        type: "line",
        color: "steelblue"
      }
    },

    {
      mark: {
        type: "point",
        color: "red",
        size: 150
      }
    }
  ],

  encoding: {
    x: {field: "x", type: "quantitative"},
    y: {field: "y", type: "quantitative"}
  }
};

Когда использовать встроенный point

Подходит для:

  • стандартных линейных графиков;
  • простых dashboard;
  • отображения наблюдений;
  • временных рядов;
  • быстрых прототипов.

Когда лучше использовать отдельный слой

Layered-подход предпочтителен, если требуется:

  • отдельная анимация точек;
  • независимая интерактивность;
  • разные tooltip;
  • выборочное отображение;
  • фильтрация только точек;
  • отдельные условия отображения.

Особенности работы с area

В area точки строятся по верхней линии области.

Пример:

mark: {
  type: "area",
  point: true
}

Точки располагаются:

  • не внутри области;
  • не по центру;
  • а по линии значений.

Комбинация line, area и point

Часто используется многослойный вариант:

layer: [
  {
    mark: "area"
  },

  {
    mark: "line"
  },

  {
    mark: "point"
  }
]

Такой подход обеспечивает:

  • красивую заливку;
  • чёткую линию;
  • хорошо заметные точки.

Полный пример комбинированного графика

const spec = {
  data: {
    values: [
      {day: 1, temp: 20},
      {day: 2, temp: 24},
      {day: 3, temp: 22},
      {day: 4, temp: 28},
      {day: 5, temp: 26}
    ]
  },

  layer: [
    {
      mark: {
        type: "area",
        opacity: 0.3
      }
    },

    {
      mark: {
        type: "line",
        strokeWidth: 3
      }
    },

    {
      mark: {
        type: "point",
        filled: true,
        size: 120
      }
    }
  ],

  encoding: {
    x: {
      field: "day",
      type: "quantitative"
    },

    y: {
      field: "temp",
      type: "quantitative"
    }
  }
};

Поле point и тема оформления

Точки автоматически адаптируются под:

  • theme Vega-Lite;
  • конфигурацию config;
  • глобальные параметры mark.

Глобальная настройка точек

config: {
  point: {
    filled: true,
    size: 80
  }
}

Теперь все point по умолчанию используют эти параметры.


Особенности SVG и Canvas

В Vega-Lite рендеринг возможен через:

  • SVG;
  • Canvas.

SVG

Преимущества:

  • качественная интерактивность;
  • отдельные DOM-элементы;
  • удобная стилизация.

Недостатки:

  • большое количество точек ухудшает производительность.

Canvas

Преимущества:

  • быстрее на больших данных;
  • меньше нагрузка на DOM.

Недостатки:

  • сложнее дебажить;
  • меньше возможностей прямой стилизации.

Типичные ошибки

Слишком крупные точки

point: {
  size: 1000
}

График становится перегруженным.


Использование точек на плотных временных рядах

При тысячах значений точки превращаются в шум.


Конфликт цветов

mark: {
  color: "blue",

  point: {
    fill: "white",
    stroke: "white"
  }
}

Точки могут стать невидимыми.


Избыточная прозрачность

point: {
  opacity: 0.05
}

Точки практически исчезают.


Практические рекомендации

Для временных рядов

Оптимально:

point: {
  size: 40
}

Для аналитических dashboard

Часто используют:

point: {
  filled: true
}

Для hover-интерактивности

Лучше:

  • маленькие базовые точки;
  • увеличение при наведении.

Для презентационной графики

Эффективны:

  • контрастная обводка;
  • белая заливка;
  • умеренный размер.

Пример:

point: {
  filled: true,
  fill: "white",
  stroke: "#1f77b4",
  strokeWidth: 2,
  size: 120
}