Тема
Plugin API
Plugins подключаются через prop plugins и расширяют timeline overlays, markers или runtime lifecycle.
Исполняемый примерTimeline: markersМаркеры и overlay-слои.
import { Nova, NovaNode, type NovaSchema } from '@endge/nova'
// Документационный сценарий: timeline-chart-markers
class ExampleNode extends NovaNode<Record<string, Event>> {
render(): void {
const schema: NovaSchema = [
{
type: 'rect',
x: 24,
y: 24,
width: this.width - 48,
height: this.height - 48,
styles: { background: '#0d2745' },
},
{
type: 'text',
x: 44,
y: 44,
width: this.width - 88,
height: 32,
text: 'Timeline: markers',
styles: { color: '#e8f5ff' },
},
]
this.renderer.schema(schema)
this.setRenderBoundsFromSchema(schema)
}
}
export function mountExample(canvas: HTMLCanvasElement) {
const app = Nova.createApp({
target: canvas,
size: { width: canvas.clientWidth, height: canvas.clientHeight, maxDpr: 2 },
scheduler: { loop: false },
})
const surface = app.surface({ id: 'airport-layers' })
surface.createNode(ExampleNode)
return () => app.destroy()
}Граница ответственности
Plugin должен быть изолированным: не хранить бизнес-cache приложения и корректно очищать listeners/resources при destroy.
Marquee selection
TimelineChart.plugins.marqueeSelection() включает выделение задач прямоугольником. Для кнопочного режима используйте controller:
ts
const controller = TimelineChart.plugins.createMarqueeSelectionController({
enabled: false,
once: true,
})
const plugins = [
TimelineChart.plugins.marqueeSelection({ controller }),
]В NovaCSS можно настроить стандартный прямоугольник:
css
@theme light {
--nova-timeline-marquee-fill: rgba(29, 115, 255, 0.10);
--nova-timeline-marquee-border: #1d73ff;
--nova-timeline-marquee-border-width: 1;
--nova-timeline-marquee-dash: 5,4;
}DSL-вариант поддерживает кастомный #box:
vue
<TimelineChart.MarqueeSelection :controller="controller" once>
<template #box="{ rect, style, api }">
<Rect
:x="rect.x"
:y="rect.y"
:width="rect.width"
:height="rect.height"
:background="api.resolveThemeToken('--nova-timeline-marquee-fill', style.fill)"
:border="{ color: style.border, width: style.borderWidth, dashPattern: style.dash }"
/>
</template>
</TimelineChart.MarqueeSelection>Link create
TimelineChart.plugins.linkCreate() включает кнопочный режим создания links через annotation ports. Пока controller активен, plugin показывает доступные порты; drag от source-port к target-port создает link. Escape или повторное выключение controller сбрасывает draft.
ts
const controller = TimelineChart.plugins.createLinkCreateController({
enabled: false,
once: true,
})
const plugins = [
TimelineChart.plugins.linkCreate({
controller,
createLink: ({ from, to }) => ({
id: crypto.randomUUID(),
from,
to,
route: { mode: 'auto', type: 'orthogonal' },
selectable: true,
editable: true,
}),
}),
]По умолчанию используется direction: 'from-to': старт только из outgoing|both, drop только в incoming|both. Self-link на одну entity запрещен за счет списка target-портов. Готовые links добавляются через root.add({ links }); для ручного сохранения используйте commit: 'event' и onCreate.