Для кого: авторы custom shapes, расширяющие cell-иерархию.
Что получите: выбор базового класса, минимальная реализация, parametric/links, сериализация.
Предварительные знания: Архитектура движка, typeName и сериализация cell-классов.
flowchart TD
start[Нужен новый элемент?]
start -->|Прямоугольник / hatch / param| CP[CellParametric]
start -->|Линия / polyline| LP[LineParametric или Segment]
start -->|Коннектор со стрелками| LK[Link]
start -->|Из JSON StencilLibItem| CC[CustomCell]
start -->|Простая cell без param| C[Cell]
CP --> TN[typeName + registerElement]
LP --> TN
LK --> TN
CC --> TN
C --> TN
import { CellParametric } from "@engine/entities/cell/CellParametric"
import { CellOptions } from "@etypes/Cell"
import { DrawCommand } from "@etypes/PathAttrs"
export class MyRect extends CellParametric {
static readonly typeName: string = "MyRect"
_drawRules: Record<string, () => DrawCommand> = {
body: () => ({
name: "rect",
args: [0, 0, this.width, this.height],
}),
}
constructor(options: CellOptions = {}) {
super({ name: "My Rect", width: 80, height: 40, ...options })
this.recalcDrawPaths()
}
}
Ключевые методы:
recalcDrawPaths() — пересчёт drawPaths из _drawRulesupdate() — обновление bbox и связанных link после измененийSegment / Spline — наследники LineParametric. Точки в this.points, bbox через getLinearBBox.
Link / Connector — routing, arrowSource / arrowTarget, LinkType.ORTHO и др.
Эталоны: src/engine/entities/cell/primitives/Segment.ts, libs/diagram/Connector.ts.
CustomCell + fromLibItemJSON для элементов из StencilLibItem. Используется в JSON-библиотеках и diagram figures.
Эталон: CustomCell.ts, libs/diagram/DiagramElement.ts.
getControls() — resize/rotate handles (CellControls)isPointInDrawing(point, ctx, scale) — точное попаданиеСм. entities/cell/BaseCell.ts, entities/Controls/.
По умолчанию className берётся из typeName автоматически. Переопределяйте только при нестандартных полях:
// Пример: ChartShape — foreign chart data
toJSON(): CellJSON {
const res = super.toJSON()
if (this.foreign) {
res.foreign = { /* chart config */ }
}
return res
}
const shape = new MyRect({ width: 100, height: 50 })
const json = shape.toJSON()
const restored = new MyRect({}).fromJSON(json)
console.assert(restored.width === 100)
console.assert(json.className === "MyRect")
Для регистрации в движке:
engine.registerElement(MyRect)
const fromLib = new (engine.elementsLib["MyRect"] as typeof MyRect)({})
fromLib.fromJSON(json)
typeName на наследнике — унаследован от родителя, ошибка assertCellTypeNamerecalcDrawPaths после смены размеров — пустая отрисовка| Задача | Файл |
|---|---|
| Parametric | libs/electric/shapes/Battery.ts |
| Line | primitives/Segment.ts, primitives/Spline.ts |
| Connector | libs/diagram/Connector.ts |
| Chart / foreign | shapes/extShapes/ChartShape.ts |
| Table | primitives/TableEditable/TableEditable.ts |