Skip to content

Визуальные состояния ​

Соединение выглядит по-разному, пока над ним курсор, пока оно выделено и пока у него клавиатурный фокус. Все визуальные сущности — линии, маркеры, порты и подписи — описывают эти виды одинаково: собственные поля плюс по одной корзине на состояние с теми полями, которые меняются.

ts
lines: {
  color: '#2e8b57',
  width: 2,
  hover: { width: 4, dashed: true },
  selected: { color: '#1f6feb' },
}

Четыре состояния ​

  • hover — курсор над самой линией соединения. Нужен interaction.hover.
  • highlight — курсор над одним из блоков соединения, из-за чего подсвечиваются все соединения, которые в нём заканчиваются. Нужен interaction.highlight. Пока корзина highlight не задана, выглядит так же, как hover; задайте её, чтобы линии наведённого блока реагировали тише, чем линия под курсором.
  • selected — соединение выделено (см. Выделение и доступность).
  • focus — у линии соединения клавиатурный фокус.

Состояния складываются. У соединения, которое выделено и под курсором, действуют поля selected, а поверх них поля hover. Порядок от слабого к сильному:

  1. собственные поля сущности,
  2. selected,
  3. highlight,
  4. hover,
  5. focus.

Поле, которое не задало ни одно активное состояние, сохраняет значение нижнего слоя.

Включение hover и highlight ​

hover и highlight по умолчанию выключены: диаграмма, на которую просто смотрят, не реагирует на курсор, а у её линий нет курсора-указателя. Включаются они в группе interaction конфигурации:

ts
interaction: { hover: true, highlight: true }
  • interaction.hover — boolean · по умолчанию: false. Курсор над линией переводит её в состояние hover и показывает над ней курсор-указатель.
  • interaction.highlight — boolean · по умолчанию: false. Курсор над блоком переводит соединения, которые в нём заканчиваются, в состояние highlight.

Каждый из них можно задать для одной сущности, и локальное значение сильнее глобального: hoverable у соединения и highlightable у блока. hoverable: false оставляет одну линию неподвижной, пока всё остальное реагирует; highlightable: true позволяет одному блоку подсвечивать свои линии на диаграмме, которая в остальном статична.

Корзина hover или highlight ничего не делает, пока её режим выключен. Состояния selected и focus, выделение и управление с клавиатуры от этих флагов не зависят, а выделяемая линия всё равно показывает курсор-указатель. События connection:mouseenter, connection:mouseleave, block:mouseenter и block:mouseleave приходят в любом случае. Оба флага можно менять во время работы через setConfig.

Что может менять состояние ​

Корзина состояния принимает те же поля, что и сама сущность:

  • Линии — color, width, dashed, opacity. Если толщина состояния не задана, выделенная или подсвеченная линия всё равно получает небольшую прибавку к явной толщине, чтобы выделяться.
  • Маркеры — shape, size, color, strokeColor, strokeWidth, opacity, svg, arrow. Маркер может превратиться из точки в ромб при наведении или подменить целый собственный svg.
  • Порты — radius, fill, stroke, strokeWidth, opacity.
  • Подписи — background, border, color, fontSize, paddingX, paddingY, opacity.

Маркеры, порты и подписи следуют состоянию своего соединения. Точка порта, общая для нескольких соединений, берёт самое сильное состояние среди них. У блоков состояний нет: это ваша собственная разметка, а движок добавляет к ней только классы vl-draggable и vl-dragging, поэтому оформляйте блоки через CSS.

Маркер следует за линией ​

Маркер без собственного color красится в цвет, который линия имеет в текущем состоянии. Когда линия краснеет при наведении, её стрелка краснеет вместе с ней, и никаких настроек маркера для этого не нужно. Цвет, заданный на самом маркере, сохраняется во всех состояниях, если корзина состояния не задаёт другой.

ts
markers: {
  end: {
    shape: 'circle',
    size: 6,
    hover: { shape: 'diamond', size: 10, strokeColor: '#ffffff', strokeWidth: 1 },
    selected: { shape: 'arrow', size: 8 },
  },
}

size маркера — это кратность толщины линии, поэтому он растёт сам, когда линия становится толще; size в корзине состояния это переопределяет.

Состояния в нескольких местах ​

Группа конфигурации и собственный style соединения оба содержат корзины. Они сливаются по состояниям и по полям: hover.width соединения заменяет hover.width группы, а hover.color группы продолжает действовать.

ts
createVisualLinker(el, { lines: { hover: { color: '#6366f1', width: 4 } } })

linker.setConnections([
  { id: 'a-b', from, to, style: { hover: { width: 6 } } }, // hover: толщина 6, цвет '#6366f1'
])

Корзина состояния сильнее базовых полей на любом уровне. Если группа задаёт hover.color, а соединение задаёт только собственный базовый color, при наведении это соединение покажет цвет наведения из группы. Чтобы сохранить свой цвет, соединение задаёт ещё и hover.color.

Клавиатурный фокус ​

Состояние focus применяется к соединениям, которые могут получать фокус, а для этого нужен interaction.selectable. Сфокусированная линия получает ореол цвета focusRing из темы поверх того, что задаёт focus.

Прозрачность ​

opacity — отдельное поле, поэтому оно может меняться в состоянии: приглушите соединения в покое и верните одному полную силу при наведении.

ts
lines: { opacity: 0.55, hover: { opacity: 1 } }

Маркер без собственной opacity блёкнет вместе со своей линией. Анимированная линия дополнительно притемняется, чтобы бегущий узор был виден, поэтому её итоговая прозрачность — произведение двух значений.