Eulergraph
    Preparing search index...

    Разработка cell-классов

    Для кого: авторы 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 из _drawRules
    • update() — обновление 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) — точное попадание
    • Magnet points — для привязки link

    См. 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 на наследнике — унаследован от родителя, ошибка assertCellTypeName
    • Не вызван recalcDrawPaths после смены размеров — пустая отрисовка
    • Прямое изменение param без Editor — нет undo в истории

    Задача Файл
    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