@modern-ant/model-diagram 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +396 -0
- package/THIRD_PARTY_NOTICES.md +32 -0
- package/dist/events/emitter.d.ts +8 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/events/emitter.js +30 -0
- package/dist/events/emitter.js.map +1 -0
- package/dist/events/types.d.ts +94 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +2 -0
- package/dist/events/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/jointjs/adapter.d.ts +75 -0
- package/dist/jointjs/adapter.d.ts.map +1 -0
- package/dist/jointjs/adapter.js +905 -0
- package/dist/jointjs/adapter.js.map +1 -0
- package/dist/layout/elk-layout.d.ts +15 -0
- package/dist/layout/elk-layout.d.ts.map +1 -0
- package/dist/layout/elk-layout.js +112 -0
- package/dist/layout/elk-layout.js.map +1 -0
- package/dist/model/types.d.ts +45 -0
- package/dist/model/types.d.ts.map +1 -0
- package/dist/model/types.js +2 -0
- package/dist/model/types.js.map +1 -0
- package/dist/model/validation.d.ts +8 -0
- package/dist/model/validation.d.ts.map +1 -0
- package/dist/model/validation.js +95 -0
- package/dist/model/validation.js.map +1 -0
- package/dist/rendering/diagram.d.ts +96 -0
- package/dist/rendering/diagram.d.ts.map +1 -0
- package/dist/rendering/diagram.js +733 -0
- package/dist/rendering/diagram.js.map +1 -0
- package/dist/rendering/geometry.d.ts +20 -0
- package/dist/rendering/geometry.d.ts.map +1 -0
- package/dist/rendering/geometry.js +42 -0
- package/dist/rendering/geometry.js.map +1 -0
- package/dist/rendering/store.d.ts +30 -0
- package/dist/rendering/store.d.ts.map +1 -0
- package/dist/rendering/store.js +231 -0
- package/dist/rendering/store.js.map +1 -0
- package/dist/routing/relationship-style.d.ts +15 -0
- package/dist/routing/relationship-style.d.ts.map +1 -0
- package/dist/routing/relationship-style.js +37 -0
- package/dist/routing/relationship-style.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagram.js","sourceRoot":"","sources":["../../src/rendering/diagram.ts"],"names":[],"mappings":"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","sourcesContent":["import { TypedEventEmitter } from \"../events/emitter.js\";\nimport type {\n DiagramEventListener,\n DiagramEventMap,\n DiagramEventType,\n DiagramSelection,\n Unsubscribe,\n} from \"../events/types.js\";\nimport { JointJsAdapter } from \"../jointjs/adapter.js\";\nimport {\n ElkLayoutEngine,\n type AutoLayoutOptions,\n type LayoutEngine,\n} from \"../layout/elk-layout.js\";\nimport type {\n DiagramLayout,\n DiagramModel,\n DiagramRelationshipChanges,\n Position,\n} from \"../model/types.js\";\nimport { positionsEqual } from \"./geometry.js\";\nimport { DiagramStore } from \"./store.js\";\n\nexport interface CreateDiagramOptions {\n model: DiagramModel;\n layout?: DiagramLayout;\n editable?: boolean;\n autoLayout?: boolean;\n /** Primarily useful for deterministic tests or a custom ELK worker setup. */\n layoutEngine?: LayoutEngine;\n}\n\nexport interface Diagram {\n on<K extends DiagramEventType>(\n type: K,\n listener: DiagramEventListener<K>,\n ): Unsubscribe;\n getModel(): DiagramModel;\n setModel(model: DiagramModel): void;\n setLayout(layout: DiagramLayout): void;\n setEditable(editable: boolean): void;\n getLayout(): DiagramLayout;\n canUndo(): boolean;\n canRedo(): boolean;\n undo(): void;\n redo(): void;\n clearHistory(): void;\n autoLayout(options?: AutoLayoutOptions): Promise<DiagramLayout>;\n whenReady(): Promise<void>;\n updateRelationship(\n relationshipId: string,\n changes: DiagramRelationshipChanges,\n ): void;\n addRelationshipWaypoint(\n relationshipId: string,\n position: Position,\n index?: number,\n ): void;\n moveRelationshipWaypoint(\n relationshipId: string,\n index: number,\n position: Position,\n ): void;\n removeRelationshipWaypoint(relationshipId: string, index: number): void;\n resetRelationshipRoute(relationshipId: string): void;\n fitToContent(padding?: number): void;\n setZoom(scale: number): void;\n zoomIn(): void;\n zoomOut(): void;\n panBy(dx: number, dy: number): void;\n destroy(): void;\n}\n\ninterface ClassPositionHistoryEntry {\n kind: \"class-position\";\n classId: string;\n before: Position;\n after: Position;\n}\n\ninterface NotePositionHistoryEntry {\n kind: \"note-position\";\n classId: string;\n before: Position;\n after: Position;\n beforeWasManual: boolean;\n}\n\ninterface RelationshipWaypointsHistoryEntry {\n kind: \"relationship-waypoints\";\n operation: \"add\" | \"move\" | \"remove\" | \"reset\";\n relationshipId: string;\n index?: number;\n before: Position[];\n after: Position[];\n}\n\ninterface RelationshipPropertiesHistoryEntry {\n kind: \"relationship-properties\";\n relationshipId: string;\n before: DiagramRelationshipChanges;\n after: DiagramRelationshipChanges;\n}\n\ninterface LayoutTransactionHistoryEntry {\n kind: \"layout-transaction\";\n before: Record<string, Position>;\n after: Record<string, Position>;\n}\n\ntype HistoryEntry =\n | ClassPositionHistoryEntry\n | NotePositionHistoryEntry\n | RelationshipWaypointsHistoryEntry\n | RelationshipPropertiesHistoryEntry\n | LayoutTransactionHistoryEntry;\n\ninterface ElementDragState {\n kind: \"class\" | \"note\";\n id: string;\n noteWasManual?: boolean;\n}\n\nfunction copyPosition(position: Position): Position {\n return { x: position.x, y: position.y };\n}\n\nfunction copyWaypoints(waypoints: Position[]): Position[] {\n return waypoints.map(copyPosition);\n}\n\nfunction positionsRecord(layout: DiagramLayout): Record<string, Position> {\n return Object.fromEntries(\n Object.entries(layout.classes ?? {}).map(([id, position]) => [\n id,\n copyPosition(position),\n ]),\n );\n}\n\nfunction positionRecordsEqual(\n first: Record<string, Position>,\n second: Record<string, Position>,\n): boolean {\n const firstIds = Object.keys(first);\n const secondIds = Object.keys(second);\n return (\n firstIds.length === secondIds.length &&\n firstIds.every((id) => {\n const firstPosition = first[id];\n const secondPosition = second[id];\n return Boolean(\n firstPosition &&\n secondPosition &&\n positionsEqual(firstPosition, secondPosition),\n );\n })\n );\n}\n\nfunction waypointListsEqual(first: Position[], second: Position[]): boolean {\n return (\n first.length === second.length &&\n first.every((position, index) => {\n const other = second[index];\n return Boolean(other && positionsEqual(position, other));\n })\n );\n}\n\nfunction changedWaypointIndex(before: Position[], after: Position[]): number {\n const commonLength = Math.min(before.length, after.length);\n for (let index = 0; index < commonLength; index += 1) {\n const previous = before[index];\n const next = after[index];\n if (previous && next && !positionsEqual(previous, next)) return index;\n }\n return commonLength;\n}\n\nfunction selectionsEqual(\n first: DiagramSelection | null,\n second: DiagramSelection | null,\n): boolean {\n if (first === null || second === null) return first === second;\n if (first.kind !== second.kind) return false;\n if (first.kind === \"relationship-waypoint\") {\n return (\n second.kind === \"relationship-waypoint\" &&\n first.relationshipId === second.relationshipId &&\n first.index === second.index\n );\n }\n return second.kind !== \"relationship-waypoint\" && first.id === second.id;\n}\n\nexport class ModelDiagram implements Diagram {\n private readonly events = new TypedEventEmitter();\n private readonly store: DiagramStore;\n private readonly renderer: JointJsAdapter;\n private readonly layoutEngine: LayoutEngine;\n private editable: boolean;\n private selection: DiagramSelection | null = null;\n private readyPromise: Promise<void> = Promise.resolve();\n private destroyed = false;\n private layoutGeneration = 0;\n private readonly undoStack: HistoryEntry[] = [];\n private readonly redoStack: HistoryEntry[] = [];\n private elementDragState?: ElementDragState;\n\n constructor(container: HTMLElement, options: CreateDiagramOptions) {\n if (!(container instanceof HTMLElement)) {\n throw new TypeError(\"createDiagram requires an HTMLElement container\");\n }\n this.editable = options.editable ?? false;\n this.store = new DiagramStore(options.model, options.layout);\n this.layoutEngine = options.layoutEngine ?? new ElkLayoutEngine();\n this.renderer = new JointJsAdapter(container, this.editable, {\n onSelectionChanged: (selection) => this.changeSelection(selection),\n onPositionDragStarted: (kind, id) => this.beginElementDrag(kind, id),\n onPositionPreview: (kind, id, position) =>\n this.previewElementPosition(kind, id, position),\n onPositionCommitted: (kind, id, before, after) =>\n this.commitElementPosition(kind, id, before, after),\n onWaypointsPreview: (id, waypoints) =>\n this.previewWaypoints(id, waypoints),\n onWaypointsCommitted: (id, before, after) =>\n this.commitWaypoints(id, before, after),\n onWaypointAddRequested: (id, position, index) =>\n this.addRelationshipWaypoint(id, position, index),\n onDeleteSelectedWaypoint: () => this.deleteSelectedWaypoint(),\n });\n this.renderer.render(this.store);\n\n const missingStoredPosition = options.model.classes.some(\n ({ id }) => !options.layout?.classes?.[id],\n );\n if ((options.autoLayout ?? true) && missingStoredPosition) {\n this.readyPromise = this.performAutoLayout(options.layout ?? {}, {\n preserveStoredPositions: true,\n }, false).then(() => undefined);\n }\n }\n\n on<K extends DiagramEventType>(\n type: K,\n listener: DiagramEventListener<K>,\n ): Unsubscribe {\n this.assertAlive();\n return this.events.on(type, listener);\n }\n\n getModel(): DiagramModel {\n this.assertAlive();\n return this.store.model;\n }\n\n setModel(model: DiagramModel): void {\n this.assertAlive();\n const previousLayout = this.store.getLayout();\n const previousIds = new Set(this.store.model.classes.map(({ id }) => id));\n this.store.setModel(model);\n this.layoutGeneration += 1;\n this.renderer.render(this.store);\n this.resetHistory();\n if (model.classes.some(({ id }) => !previousIds.has(id))) {\n this.readyPromise = this.performAutoLayout(previousLayout, {\n preserveStoredPositions: true,\n }, false).then(() => undefined);\n }\n }\n\n setLayout(layout: DiagramLayout): void {\n this.assertAlive();\n this.store.setLayout(layout);\n this.layoutGeneration += 1;\n this.renderer.syncAllPositions(this.store);\n this.resetHistory();\n if (this.store.model.classes.some(({ id }) => !layout.classes?.[id])) {\n this.readyPromise = this.performAutoLayout(layout, {\n preserveStoredPositions: true,\n }, false).then(() => undefined);\n }\n }\n\n setEditable(editable: boolean): void {\n this.assertAlive();\n const previous = this.historyAvailability();\n this.editable = editable;\n this.renderer.setEditable(editable);\n const next = this.historyAvailability();\n if (\n previous.canUndo !== next.canUndo ||\n previous.canRedo !== next.canRedo\n ) {\n this.emitHistoryChanged();\n }\n }\n\n getLayout(): DiagramLayout {\n this.assertAlive();\n return this.store.getLayout();\n }\n\n canUndo(): boolean {\n this.assertAlive();\n return this.historyAvailability().canUndo;\n }\n\n canRedo(): boolean {\n this.assertAlive();\n return this.historyAvailability().canRedo;\n }\n\n undo(): void {\n this.assertEditable();\n const entry = this.undoStack.pop();\n if (!entry) return;\n this.redoStack.push(entry);\n this.layoutGeneration += 1;\n this.applyHistoryEntry(entry, false);\n this.emitHistoryChanged();\n }\n\n redo(): void {\n this.assertEditable();\n const entry = this.redoStack.pop();\n if (!entry) return;\n this.undoStack.push(entry);\n this.layoutGeneration += 1;\n this.applyHistoryEntry(entry, true);\n this.emitHistoryChanged();\n }\n\n clearHistory(): void {\n this.assertAlive();\n this.resetHistory();\n }\n\n autoLayout(options: AutoLayoutOptions = {}): Promise<DiagramLayout> {\n this.assertAlive();\n const operation = this.performAutoLayout(this.store.getLayout(), {\n ...options,\n preserveStoredPositions: options.preserveStoredPositions ?? false,\n }, true);\n this.readyPromise = operation.then(() => undefined);\n return operation;\n }\n\n whenReady(): Promise<void> {\n return this.readyPromise;\n }\n\n updateRelationship(\n relationshipId: string,\n changes: DiagramRelationshipChanges,\n ): void {\n this.assertEditable();\n const previous = this.store.getRelationship(relationshipId);\n this.store.updateRelationship(relationshipId, changes);\n const next = this.store.getRelationship(relationshipId);\n const before: DiagramRelationshipChanges = {};\n const after: DiagramRelationshipChanges = {};\n\n for (const field of [\"label\"] as const) {\n if (!Object.hasOwn(changes, field) || previous[field] === next[field]) {\n continue;\n }\n before[field] = previous[field];\n after[field] = next[field];\n }\n if (Object.keys(after).length === 0) return;\n\n this.recordHistory({\n kind: \"relationship-properties\",\n relationshipId,\n before,\n after,\n });\n this.renderer.syncRelationship(relationshipId, this.store);\n this.emit(\"relationship-changed\", {\n type: \"relationship-changed\",\n relationshipId,\n changes: { ...after },\n });\n this.emitHistoryChanged();\n }\n\n addRelationshipWaypoint(\n relationshipId: string,\n position: Position,\n index?: number,\n ): void {\n this.assertEditable();\n const before = this.store.getWaypoints(relationshipId);\n const insertedIndex = this.store.addWaypoint(\n relationshipId,\n position,\n index,\n );\n const after = this.store.getWaypoints(relationshipId);\n this.recordHistory({\n kind: \"relationship-waypoints\",\n operation: \"add\",\n relationshipId,\n index: insertedIndex,\n before,\n after,\n });\n this.renderer.syncWaypoints(relationshipId, this.store);\n this.changeSelection({\n kind: \"relationship-waypoint\",\n relationshipId,\n index: insertedIndex,\n });\n this.emit(\"relationship-waypoint-added\", {\n type: \"relationship-waypoint-added\",\n relationshipId,\n index: insertedIndex,\n ...position,\n });\n this.emitHistoryChanged();\n }\n\n moveRelationshipWaypoint(\n relationshipId: string,\n index: number,\n position: Position,\n ): void {\n this.assertEditable();\n const before = this.store.getWaypoints(relationshipId);\n this.store.moveWaypoint(relationshipId, index, position);\n const after = this.store.getWaypoints(relationshipId);\n const recorded = !waypointListsEqual(before, after);\n if (recorded) {\n this.recordHistory({\n kind: \"relationship-waypoints\",\n operation: \"move\",\n relationshipId,\n index,\n before,\n after,\n });\n }\n this.renderer.syncWaypoints(relationshipId, this.store);\n this.changeSelection({\n kind: \"relationship-waypoint\",\n relationshipId,\n index,\n });\n this.emit(\"relationship-waypoint-changed\", {\n type: \"relationship-waypoint-changed\",\n relationshipId,\n index,\n ...position,\n });\n if (recorded) this.emitHistoryChanged();\n }\n\n removeRelationshipWaypoint(relationshipId: string, index: number): void {\n this.assertEditable();\n const before = this.store.getWaypoints(relationshipId);\n this.store.removeWaypoint(relationshipId, index);\n const after = this.store.getWaypoints(relationshipId);\n this.recordHistory({\n kind: \"relationship-waypoints\",\n operation: \"remove\",\n relationshipId,\n index,\n before,\n after,\n });\n this.renderer.syncWaypoints(relationshipId, this.store);\n this.changeSelection({ kind: \"relationship\", id: relationshipId });\n this.emit(\"relationship-waypoint-removed\", {\n type: \"relationship-waypoint-removed\",\n relationshipId,\n index,\n });\n this.emitHistoryChanged();\n }\n\n resetRelationshipRoute(relationshipId: string): void {\n this.assertEditable();\n const before = this.store.getWaypoints(relationshipId);\n this.store.resetRoute(relationshipId);\n const after = this.store.getWaypoints(relationshipId);\n const recorded = !waypointListsEqual(before, after);\n if (recorded) {\n this.recordHistory({\n kind: \"relationship-waypoints\",\n operation: \"reset\",\n relationshipId,\n before,\n after,\n });\n }\n this.renderer.syncWaypoints(relationshipId, this.store);\n this.changeSelection({ kind: \"relationship\", id: relationshipId });\n this.emit(\"relationship-route-reset\", {\n type: \"relationship-route-reset\",\n relationshipId,\n });\n if (recorded) this.emitHistoryChanged();\n }\n\n fitToContent(padding?: number): void {\n this.assertAlive();\n this.renderer.fitToContent(padding);\n }\n\n setZoom(scale: number): void {\n this.assertAlive();\n this.renderer.setZoom(scale);\n }\n\n zoomIn(): void {\n this.setZoom(this.renderer.getZoom() * 1.2);\n }\n\n zoomOut(): void {\n this.setZoom(this.renderer.getZoom() / 1.2);\n }\n\n panBy(dx: number, dy: number): void {\n this.assertAlive();\n this.renderer.panBy(dx, dy);\n }\n\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.renderer.destroy();\n this.undoStack.length = 0;\n this.redoStack.length = 0;\n this.elementDragState = undefined;\n this.events.clear();\n this.selection = null;\n }\n\n private async performAutoLayout(\n storedLayout: DiagramLayout,\n options: AutoLayoutOptions,\n addToHistory: boolean,\n ): Promise<DiagramLayout> {\n const generation = ++this.layoutGeneration;\n const before = positionsRecord(this.store.getLayout());\n const model = this.store.model;\n const positions = await this.layoutEngine.layout(\n model,\n storedLayout,\n options,\n );\n if (this.destroyed || generation !== this.layoutGeneration) {\n return this.store.getLayout();\n }\n this.store.applyClassPositions(positions);\n this.renderer.syncAllPositions(this.store);\n const layout = this.store.getLayout();\n const after = positionsRecord(layout);\n const recorded = addToHistory && !positionRecordsEqual(before, after);\n if (recorded) {\n this.recordHistory({\n kind: \"layout-transaction\",\n before,\n after,\n });\n }\n this.emit(\"auto-layout-completed\", {\n type: \"auto-layout-completed\",\n layout,\n });\n if (recorded) this.emitHistoryChanged();\n return layout;\n }\n\n private beginElementDrag(kind: \"class\" | \"note\", id: string): void {\n this.elementDragState = {\n kind,\n id,\n ...(kind === \"note\"\n ? { noteWasManual: this.store.hasManualNotePosition(id) }\n : {}),\n };\n }\n\n private previewElementPosition(\n kind: \"class\" | \"note\",\n id: string,\n position: Position,\n ): void {\n if (!this.editable) return;\n if (kind === \"class\") {\n this.layoutGeneration += 1;\n this.store.setClassPosition(id, position);\n if (!this.store.hasManualNotePosition(id)) {\n this.renderer.syncNotePosition(id, this.store);\n }\n this.emit(\"class-position-preview\", {\n type: \"class-position-preview\",\n classId: id,\n ...position,\n });\n } else {\n this.store.setNotePosition(id, position);\n this.emit(\"note-position-preview\", {\n type: \"note-position-preview\",\n classId: id,\n ...position,\n });\n }\n }\n\n private commitElementPosition(\n kind: \"class\" | \"note\",\n id: string,\n before: Position,\n position: Position,\n ): void {\n if (!this.editable) return;\n const dragState = this.elementDragState;\n this.elementDragState = undefined;\n if (kind === \"class\") {\n this.store.setClassPosition(id, position);\n this.recordHistory({\n kind: \"class-position\",\n classId: id,\n before: copyPosition(before),\n after: copyPosition(position),\n });\n this.emit(\"class-position-changed\", {\n type: \"class-position-changed\",\n classId: id,\n ...position,\n });\n } else {\n this.store.setNotePosition(id, position);\n this.recordHistory({\n kind: \"note-position\",\n classId: id,\n before: copyPosition(before),\n after: copyPosition(position),\n beforeWasManual:\n dragState?.kind === \"note\" && dragState.id === id\n ? Boolean(dragState.noteWasManual)\n : true,\n });\n this.emit(\"note-position-changed\", {\n type: \"note-position-changed\",\n classId: id,\n ...position,\n });\n }\n this.emitHistoryChanged();\n }\n\n private previewWaypoints(\n relationshipId: string,\n waypoints: Position[],\n ): void {\n if (!this.editable) return;\n const before = this.store.getWaypoints(relationshipId);\n const index = changedWaypointIndex(before, waypoints);\n this.store.replaceWaypoints(relationshipId, waypoints);\n\n if (waypoints.length < before.length) {\n this.changeSelection({ kind: \"relationship\", id: relationshipId });\n this.emit(\"relationship-waypoint-removed\", {\n type: \"relationship-waypoint-removed\",\n relationshipId,\n index,\n });\n return;\n }\n if (waypoints.length > before.length) {\n const added = waypoints[index];\n if (!added) return;\n this.changeSelection({\n kind: \"relationship-waypoint\",\n relationshipId,\n index,\n });\n this.emit(\"relationship-waypoint-added\", {\n type: \"relationship-waypoint-added\",\n relationshipId,\n index,\n ...added,\n });\n return;\n }\n const changed = waypoints[index];\n if (!changed) return;\n this.changeSelection({\n kind: \"relationship-waypoint\",\n relationshipId,\n index,\n });\n this.emit(\"relationship-waypoint-preview\", {\n type: \"relationship-waypoint-preview\",\n relationshipId,\n index,\n ...changed,\n });\n }\n\n private commitWaypoints(\n relationshipId: string,\n before: Position[],\n after: Position[],\n ): void {\n if (!this.editable || before.length !== after.length) return;\n this.store.replaceWaypoints(relationshipId, after);\n const recorded = !waypointListsEqual(before, after);\n if (recorded) {\n this.recordHistory({\n kind: \"relationship-waypoints\",\n operation: \"move\",\n relationshipId,\n index: changedWaypointIndex(before, after),\n before: copyWaypoints(before),\n after: copyWaypoints(after),\n });\n }\n for (let index = 0; index < after.length; index += 1) {\n const previous = before[index];\n const position = after[index];\n if (!previous || !position || positionsEqual(previous, position)) continue;\n this.changeSelection({\n kind: \"relationship-waypoint\",\n relationshipId,\n index,\n });\n this.emit(\"relationship-waypoint-changed\", {\n type: \"relationship-waypoint-changed\",\n relationshipId,\n index,\n ...position,\n });\n }\n if (recorded) this.emitHistoryChanged();\n }\n\n private recordHistory(entry: HistoryEntry): void {\n this.undoStack.push(entry);\n this.redoStack.length = 0;\n }\n\n private resetHistory(): void {\n if (this.undoStack.length === 0 && this.redoStack.length === 0) return;\n this.undoStack.length = 0;\n this.redoStack.length = 0;\n this.emitHistoryChanged();\n }\n\n private historyAvailability(): { canUndo: boolean; canRedo: boolean } {\n return {\n canUndo: this.editable && this.undoStack.length > 0,\n canRedo: this.editable && this.redoStack.length > 0,\n };\n }\n\n private emitHistoryChanged(): void {\n this.emit(\"history-changed\", {\n type: \"history-changed\",\n ...this.historyAvailability(),\n });\n }\n\n private applyHistoryEntry(entry: HistoryEntry, forward: boolean): void {\n switch (entry.kind) {\n case \"class-position\": {\n const position = forward ? entry.after : entry.before;\n this.store.setClassPosition(entry.classId, position);\n this.renderer.syncClassPosition(entry.classId, this.store);\n if (!this.store.hasManualNotePosition(entry.classId)) {\n this.renderer.syncNotePosition(entry.classId, this.store);\n }\n this.emit(\"class-position-changed\", {\n type: \"class-position-changed\",\n classId: entry.classId,\n ...position,\n });\n return;\n }\n case \"note-position\": {\n const position = forward ? entry.after : entry.before;\n if (forward || entry.beforeWasManual) {\n this.store.setNotePosition(entry.classId, position);\n } else {\n this.store.clearNotePosition(entry.classId);\n }\n this.renderer.syncNotePosition(entry.classId, this.store);\n this.emit(\"note-position-changed\", {\n type: \"note-position-changed\",\n classId: entry.classId,\n ...this.store.getNotePosition(entry.classId),\n });\n return;\n }\n case \"relationship-waypoints\": {\n const waypoints = forward ? entry.after : entry.before;\n this.store.replaceWaypoints(entry.relationshipId, waypoints);\n this.renderer.syncWaypoints(entry.relationshipId, this.store);\n this.ensureValidWaypointSelection(entry.relationshipId, waypoints.length);\n this.emitWaypointTransition(entry, forward);\n return;\n }\n case \"relationship-properties\": {\n const changes = forward ? entry.after : entry.before;\n this.store.updateRelationship(entry.relationshipId, changes);\n this.renderer.syncRelationship(entry.relationshipId, this.store);\n this.emit(\"relationship-changed\", {\n type: \"relationship-changed\",\n relationshipId: entry.relationshipId,\n changes: { ...changes },\n });\n return;\n }\n case \"layout-transaction\": {\n const positions = forward ? entry.after : entry.before;\n this.store.applyClassPositions(new Map(Object.entries(positions)));\n this.renderer.syncAllPositions(this.store);\n this.emit(\"auto-layout-completed\", {\n type: \"auto-layout-completed\",\n layout: this.store.getLayout(),\n });\n }\n }\n }\n\n private emitWaypointTransition(\n entry: RelationshipWaypointsHistoryEntry,\n forward: boolean,\n ): void {\n const before = forward ? entry.before : entry.after;\n const after = forward ? entry.after : entry.before;\n const index = entry.index ?? changedWaypointIndex(before, after);\n\n if (entry.operation === \"add\") {\n if (forward) {\n const position = after[index];\n if (position) {\n this.emit(\"relationship-waypoint-added\", {\n type: \"relationship-waypoint-added\",\n relationshipId: entry.relationshipId,\n index,\n ...position,\n });\n }\n } else {\n this.emit(\"relationship-waypoint-removed\", {\n type: \"relationship-waypoint-removed\",\n relationshipId: entry.relationshipId,\n index,\n });\n }\n return;\n }\n\n if (entry.operation === \"remove\") {\n if (forward) {\n this.emit(\"relationship-waypoint-removed\", {\n type: \"relationship-waypoint-removed\",\n relationshipId: entry.relationshipId,\n index,\n });\n } else {\n const position = after[index];\n if (position) {\n this.emit(\"relationship-waypoint-added\", {\n type: \"relationship-waypoint-added\",\n relationshipId: entry.relationshipId,\n index,\n ...position,\n });\n }\n }\n return;\n }\n\n if (entry.operation === \"reset\") {\n if (forward) {\n this.emit(\"relationship-route-reset\", {\n type: \"relationship-route-reset\",\n relationshipId: entry.relationshipId,\n });\n } else {\n for (const [restoredIndex, position] of after.entries()) {\n this.emit(\"relationship-waypoint-added\", {\n type: \"relationship-waypoint-added\",\n relationshipId: entry.relationshipId,\n index: restoredIndex,\n ...position,\n });\n }\n }\n return;\n }\n\n for (let changedIndex = 0; changedIndex < after.length; changedIndex += 1) {\n const previous = before[changedIndex];\n const position = after[changedIndex];\n if (!previous || !position || positionsEqual(previous, position)) continue;\n this.emit(\"relationship-waypoint-changed\", {\n type: \"relationship-waypoint-changed\",\n relationshipId: entry.relationshipId,\n index: changedIndex,\n ...position,\n });\n }\n }\n\n private ensureValidWaypointSelection(\n relationshipId: string,\n waypointCount: number,\n ): void {\n if (\n this.selection?.kind === \"relationship-waypoint\" &&\n this.selection.relationshipId === relationshipId &&\n this.selection.index >= waypointCount\n ) {\n this.changeSelection({ kind: \"relationship\", id: relationshipId });\n }\n }\n\n private deleteSelectedWaypoint(): void {\n if (this.selection?.kind !== \"relationship-waypoint\") return;\n this.removeRelationshipWaypoint(\n this.selection.relationshipId,\n this.selection.index,\n );\n }\n\n private changeSelection(selection: DiagramSelection | null): void {\n if (selectionsEqual(this.selection, selection)) return;\n this.selection = selection;\n this.renderer.setSelection(selection);\n this.emit(\"selection-changed\", { type: \"selection-changed\", selection });\n }\n\n private emit<K extends DiagramEventType>(\n type: K,\n event: DiagramEventMap[K],\n ): void {\n this.events.emit(type, event);\n }\n\n private assertAlive(): void {\n if (this.destroyed) throw new Error(\"Diagram has been destroyed\");\n }\n\n private assertEditable(): void {\n this.assertAlive();\n if (!this.editable) {\n throw new Error(\"Diagram is read-only\");\n }\n }\n}\n\nexport function createDiagram(\n container: HTMLElement,\n options: CreateDiagramOptions,\n): Diagram {\n return new ModelDiagram(container, options);\n}\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DiagramClass, Position } from "../model/types.js";
|
|
2
|
+
export interface Size {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
}
|
|
6
|
+
export declare const CLASS_WIDTH = 260;
|
|
7
|
+
export declare const CLASS_HEADER_HEIGHT = 58;
|
|
8
|
+
export declare const ATTRIBUTE_LINE_HEIGHT = 23;
|
|
9
|
+
export declare const CLASS_BODY_PADDING = 14;
|
|
10
|
+
export declare const NOTE_WIDTH = 220;
|
|
11
|
+
export declare const NOTE_HEIGHT = 116;
|
|
12
|
+
export declare const NOTE_GAP = 44;
|
|
13
|
+
export declare function classSize(diagramClass: DiagramClass): Size;
|
|
14
|
+
export declare function defaultNotePosition(classPosition: Position, diagramClass: DiagramClass): Position;
|
|
15
|
+
export declare function fallbackClassPosition(index: number): Position;
|
|
16
|
+
export declare function positionsEqual(a: Position, b: Position): boolean;
|
|
17
|
+
/** Convert browser client coordinates into the diagram coordinate system. */
|
|
18
|
+
export declare function clientToDiagramPosition(clientPosition: Position, viewportOrigin: Position, scale: number, translation: Position): Position;
|
|
19
|
+
export declare function copyPosition(position: Position): Position;
|
|
20
|
+
//# sourceMappingURL=geometry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../../src/rendering/geometry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,WAAW,IAAI;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,mBAAmB,KAAK,CAAC;AACtC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,UAAU,MAAM,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B,wBAAgB,SAAS,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAU1D;AAED,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,QAAQ,EACvB,YAAY,EAAE,YAAY,GACzB,QAAQ,CAMV;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAI7D;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAEhE;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,QAAQ,EACxB,cAAc,EAAE,QAAQ,EACxB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,QAAQ,GACpB,QAAQ,CAKV;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAEzD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const CLASS_WIDTH = 260;
|
|
2
|
+
export const CLASS_HEADER_HEIGHT = 58;
|
|
3
|
+
export const ATTRIBUTE_LINE_HEIGHT = 23;
|
|
4
|
+
export const CLASS_BODY_PADDING = 14;
|
|
5
|
+
export const NOTE_WIDTH = 220;
|
|
6
|
+
export const NOTE_HEIGHT = 116;
|
|
7
|
+
export const NOTE_GAP = 44;
|
|
8
|
+
export function classSize(diagramClass) {
|
|
9
|
+
const attributesHeight = (diagramClass.attributes?.length ?? 0) * ATTRIBUTE_LINE_HEIGHT;
|
|
10
|
+
return {
|
|
11
|
+
width: CLASS_WIDTH,
|
|
12
|
+
height: CLASS_HEADER_HEIGHT +
|
|
13
|
+
Math.max(ATTRIBUTE_LINE_HEIGHT, attributesHeight) +
|
|
14
|
+
CLASS_BODY_PADDING,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function defaultNotePosition(classPosition, diagramClass) {
|
|
18
|
+
const size = classSize(diagramClass);
|
|
19
|
+
return {
|
|
20
|
+
x: classPosition.x,
|
|
21
|
+
y: classPosition.y + size.height / 2 + NOTE_GAP + NOTE_HEIGHT / 2,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function fallbackClassPosition(index) {
|
|
25
|
+
const column = index % 3;
|
|
26
|
+
const row = Math.floor(index / 3);
|
|
27
|
+
return { x: 180 + column * 390, y: 140 + row * 260 };
|
|
28
|
+
}
|
|
29
|
+
export function positionsEqual(a, b) {
|
|
30
|
+
return a.x === b.x && a.y === b.y;
|
|
31
|
+
}
|
|
32
|
+
/** Convert browser client coordinates into the diagram coordinate system. */
|
|
33
|
+
export function clientToDiagramPosition(clientPosition, viewportOrigin, scale, translation) {
|
|
34
|
+
return {
|
|
35
|
+
x: (clientPosition.x - viewportOrigin.x - translation.x) / scale,
|
|
36
|
+
y: (clientPosition.y - viewportOrigin.y - translation.y) / scale,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function copyPosition(position) {
|
|
40
|
+
return { x: position.x, y: position.y };
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=geometry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"geometry.js","sourceRoot":"","sources":["../../src/rendering/geometry.ts"],"names":[],"mappings":"AAOA,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC/B,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AACtC,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAC9B,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B,MAAM,UAAU,SAAS,CAAC,YAA0B;IAClD,MAAM,gBAAgB,GACpB,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,qBAAqB,CAAC;IACjE,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,MAAM,EACJ,mBAAmB;YACnB,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,gBAAgB,CAAC;YACjD,kBAAkB;KACrB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,aAAuB,EACvB,YAA0B;IAE1B,MAAM,IAAI,GAAG,SAAS,CAAC,YAAY,CAAC,CAAC;IACrC,OAAO;QACL,CAAC,EAAE,aAAa,CAAC,CAAC;QAClB,CAAC,EAAE,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,QAAQ,GAAG,WAAW,GAAG,CAAC;KAClE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC;IACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,GAAG,GAAG,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAW,EAAE,CAAW;IACrD,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,uBAAuB,CACrC,cAAwB,EACxB,cAAwB,EACxB,KAAa,EACb,WAAqB;IAErB,OAAO;QACL,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK;QAChE,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,KAAK;KACjE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAkB;IAC7C,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;AAC1C,CAAC","sourcesContent":["import type { DiagramClass, Position } from \"../model/types.js\";\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport const CLASS_WIDTH = 260;\nexport const CLASS_HEADER_HEIGHT = 58;\nexport const ATTRIBUTE_LINE_HEIGHT = 23;\nexport const CLASS_BODY_PADDING = 14;\nexport const NOTE_WIDTH = 220;\nexport const NOTE_HEIGHT = 116;\nexport const NOTE_GAP = 44;\n\nexport function classSize(diagramClass: DiagramClass): Size {\n const attributesHeight =\n (diagramClass.attributes?.length ?? 0) * ATTRIBUTE_LINE_HEIGHT;\n return {\n width: CLASS_WIDTH,\n height:\n CLASS_HEADER_HEIGHT +\n Math.max(ATTRIBUTE_LINE_HEIGHT, attributesHeight) +\n CLASS_BODY_PADDING,\n };\n}\n\nexport function defaultNotePosition(\n classPosition: Position,\n diagramClass: DiagramClass,\n): Position {\n const size = classSize(diagramClass);\n return {\n x: classPosition.x,\n y: classPosition.y + size.height / 2 + NOTE_GAP + NOTE_HEIGHT / 2,\n };\n}\n\nexport function fallbackClassPosition(index: number): Position {\n const column = index % 3;\n const row = Math.floor(index / 3);\n return { x: 180 + column * 390, y: 140 + row * 260 };\n}\n\nexport function positionsEqual(a: Position, b: Position): boolean {\n return a.x === b.x && a.y === b.y;\n}\n\n/** Convert browser client coordinates into the diagram coordinate system. */\nexport function clientToDiagramPosition(\n clientPosition: Position,\n viewportOrigin: Position,\n scale: number,\n translation: Position,\n): Position {\n return {\n x: (clientPosition.x - viewportOrigin.x - translation.x) / scale,\n y: (clientPosition.y - viewportOrigin.y - translation.y) / scale,\n };\n}\n\nexport function copyPosition(position: Position): Position {\n return { x: position.x, y: position.y };\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DiagramClass, DiagramLayout, DiagramModel, DiagramRelationship, DiagramRelationshipChanges, Position } from "../model/types.js";
|
|
2
|
+
export declare class DiagramStore {
|
|
3
|
+
private modelValue;
|
|
4
|
+
private readonly classPositions;
|
|
5
|
+
private readonly notePositions;
|
|
6
|
+
private readonly relationshipWaypoints;
|
|
7
|
+
constructor(model: DiagramModel, layout?: DiagramLayout);
|
|
8
|
+
get model(): DiagramModel;
|
|
9
|
+
setModel(model: DiagramModel): void;
|
|
10
|
+
setLayout(layout: DiagramLayout): void;
|
|
11
|
+
getClass(id: string): DiagramClass;
|
|
12
|
+
getRelationship(id: string): DiagramRelationship;
|
|
13
|
+
updateRelationship(id: string, changes: DiagramRelationshipChanges): void;
|
|
14
|
+
getClassPosition(id: string): Position;
|
|
15
|
+
setClassPosition(id: string, position: Position): void;
|
|
16
|
+
getNotePosition(classId: string): Position;
|
|
17
|
+
hasManualNotePosition(classId: string): boolean;
|
|
18
|
+
setNotePosition(classId: string, position: Position): void;
|
|
19
|
+
clearNotePosition(classId: string): void;
|
|
20
|
+
getWaypoints(relationshipId: string): Position[];
|
|
21
|
+
replaceWaypoints(relationshipId: string, waypoints: Position[]): void;
|
|
22
|
+
addWaypoint(relationshipId: string, position: Position, index?: number): number;
|
|
23
|
+
moveWaypoint(relationshipId: string, index: number, position: Position): void;
|
|
24
|
+
removeWaypoint(relationshipId: string, index: number): void;
|
|
25
|
+
resetRoute(relationshipId: string): void;
|
|
26
|
+
applyClassPositions(positions: ReadonlyMap<string, Position>): void;
|
|
27
|
+
getLayout(): DiagramLayout;
|
|
28
|
+
private initialize;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/rendering/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,0BAA0B,EAC1B,QAAQ,EACT,MAAM,mBAAmB,CAAC;AA4C3B,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA+B;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA+B;IAC7D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAiC;gBAE3D,KAAK,EAAE,YAAY,EAAE,MAAM,GAAE,aAAkB;IAO3D,IAAI,KAAK,IAAI,YAAY,CAExB;IAED,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IA+BnC,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAsBtC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY;IAMlC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,mBAAmB;IAQhD,kBAAkB,CAChB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,0BAA0B,GAClC,IAAI;IAgBP,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAMtC,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAKtD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ;IAO1C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI/C,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI;IAQ1D,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQxC,YAAY,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,EAAE;IAMhD,gBAAgB,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI;IAKrE,WAAW,CACT,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,QAAQ,EAClB,KAAK,SAA2C,GAC/C,MAAM;IAUT,YAAY,CACV,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GACjB,IAAI;IASP,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAS3D,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI;IAKxC,mBAAmB,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI;IAQnE,SAAS,IAAI,aAAa;IA6B1B,OAAO,CAAC,UAAU;CAqBnB"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { validateDiagramLayout, validateDiagramModel, } from "../model/validation.js";
|
|
2
|
+
import { copyPosition, defaultNotePosition, fallbackClassPosition, } from "./geometry.js";
|
|
3
|
+
function normalizeOptionalText(value) {
|
|
4
|
+
return value?.trim() ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
function cloneRelationship(relationship) {
|
|
7
|
+
const cloned = { ...relationship };
|
|
8
|
+
delete cloned.description;
|
|
9
|
+
const normalizedLabel = normalizeOptionalText(cloned.label);
|
|
10
|
+
if (normalizedLabel === undefined)
|
|
11
|
+
delete cloned.label;
|
|
12
|
+
else
|
|
13
|
+
cloned.label = normalizedLabel;
|
|
14
|
+
return cloned;
|
|
15
|
+
}
|
|
16
|
+
function cloneModel(model) {
|
|
17
|
+
return {
|
|
18
|
+
classes: model.classes.map((diagramClass) => {
|
|
19
|
+
const cloned = {
|
|
20
|
+
...diagramClass,
|
|
21
|
+
attributes: diagramClass.attributes?.map((attribute) => ({
|
|
22
|
+
...attribute,
|
|
23
|
+
})),
|
|
24
|
+
};
|
|
25
|
+
delete cloned.description;
|
|
26
|
+
return cloned;
|
|
27
|
+
}),
|
|
28
|
+
relationships: model.relationships.map(cloneRelationship),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export class DiagramStore {
|
|
32
|
+
modelValue;
|
|
33
|
+
classPositions = new Map();
|
|
34
|
+
notePositions = new Map();
|
|
35
|
+
relationshipWaypoints = new Map();
|
|
36
|
+
constructor(model, layout = {}) {
|
|
37
|
+
validateDiagramModel(model);
|
|
38
|
+
validateDiagramLayout(layout, model);
|
|
39
|
+
this.modelValue = cloneModel(model);
|
|
40
|
+
this.initialize(model, layout);
|
|
41
|
+
}
|
|
42
|
+
get model() {
|
|
43
|
+
return cloneModel(this.modelValue);
|
|
44
|
+
}
|
|
45
|
+
setModel(model) {
|
|
46
|
+
validateDiagramModel(model);
|
|
47
|
+
const nextClassIds = new Set(model.classes.map(({ id }) => id));
|
|
48
|
+
const nextRelationshipIds = new Set(model.relationships.map(({ id }) => id));
|
|
49
|
+
for (const id of this.classPositions.keys()) {
|
|
50
|
+
if (!nextClassIds.has(id))
|
|
51
|
+
this.classPositions.delete(id);
|
|
52
|
+
}
|
|
53
|
+
for (const id of this.notePositions.keys()) {
|
|
54
|
+
const diagramClass = model.classes.find((item) => item.id === id);
|
|
55
|
+
if (!diagramClass?.note)
|
|
56
|
+
this.notePositions.delete(id);
|
|
57
|
+
}
|
|
58
|
+
for (const id of this.relationshipWaypoints.keys()) {
|
|
59
|
+
if (!nextRelationshipIds.has(id))
|
|
60
|
+
this.relationshipWaypoints.delete(id);
|
|
61
|
+
}
|
|
62
|
+
for (const [index, diagramClass] of model.classes.entries()) {
|
|
63
|
+
if (!this.classPositions.has(diagramClass.id)) {
|
|
64
|
+
this.classPositions.set(diagramClass.id, fallbackClassPosition(index));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
for (const relationship of model.relationships) {
|
|
68
|
+
if (!this.relationshipWaypoints.has(relationship.id)) {
|
|
69
|
+
this.relationshipWaypoints.set(relationship.id, []);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this.modelValue = cloneModel(model);
|
|
73
|
+
}
|
|
74
|
+
setLayout(layout) {
|
|
75
|
+
validateDiagramLayout(layout, this.modelValue);
|
|
76
|
+
for (const [id, position] of Object.entries(layout.classes ?? {})) {
|
|
77
|
+
this.classPositions.set(id, copyPosition(position));
|
|
78
|
+
}
|
|
79
|
+
this.notePositions.clear();
|
|
80
|
+
for (const [id, position] of Object.entries(layout.notes ?? {})) {
|
|
81
|
+
this.notePositions.set(id, copyPosition(position));
|
|
82
|
+
}
|
|
83
|
+
this.relationshipWaypoints.clear();
|
|
84
|
+
for (const relationship of this.modelValue.relationships) {
|
|
85
|
+
const waypoints = layout.relationships?.[relationship.id]?.waypoints ?? [];
|
|
86
|
+
this.relationshipWaypoints.set(relationship.id, waypoints.map(copyPosition));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
getClass(id) {
|
|
90
|
+
const diagramClass = this.modelValue.classes.find((item) => item.id === id);
|
|
91
|
+
if (!diagramClass)
|
|
92
|
+
throw new Error(`Unknown class "${id}"`);
|
|
93
|
+
return diagramClass;
|
|
94
|
+
}
|
|
95
|
+
getRelationship(id) {
|
|
96
|
+
const relationship = this.modelValue.relationships.find((item) => item.id === id);
|
|
97
|
+
if (!relationship)
|
|
98
|
+
throw new Error(`Unknown relationship "${id}"`);
|
|
99
|
+
return cloneRelationship(relationship);
|
|
100
|
+
}
|
|
101
|
+
updateRelationship(id, changes) {
|
|
102
|
+
const index = this.modelValue.relationships.findIndex((relationship) => relationship.id === id);
|
|
103
|
+
const relationship = this.modelValue.relationships[index];
|
|
104
|
+
if (!relationship)
|
|
105
|
+
throw new Error(`Unknown relationship "${id}"`);
|
|
106
|
+
const next = { ...relationship };
|
|
107
|
+
if (Object.hasOwn(changes, "label")) {
|
|
108
|
+
const label = normalizeOptionalText(changes.label);
|
|
109
|
+
if (label === undefined)
|
|
110
|
+
delete next.label;
|
|
111
|
+
else
|
|
112
|
+
next.label = label;
|
|
113
|
+
}
|
|
114
|
+
this.modelValue.relationships[index] = next;
|
|
115
|
+
}
|
|
116
|
+
getClassPosition(id) {
|
|
117
|
+
const position = this.classPositions.get(id);
|
|
118
|
+
if (!position)
|
|
119
|
+
throw new Error(`Unknown class "${id}"`);
|
|
120
|
+
return copyPosition(position);
|
|
121
|
+
}
|
|
122
|
+
setClassPosition(id, position) {
|
|
123
|
+
this.getClass(id);
|
|
124
|
+
this.classPositions.set(id, copyPosition(position));
|
|
125
|
+
}
|
|
126
|
+
getNotePosition(classId) {
|
|
127
|
+
const manualPosition = this.notePositions.get(classId);
|
|
128
|
+
if (manualPosition)
|
|
129
|
+
return copyPosition(manualPosition);
|
|
130
|
+
const diagramClass = this.getClass(classId);
|
|
131
|
+
return defaultNotePosition(this.getClassPosition(classId), diagramClass);
|
|
132
|
+
}
|
|
133
|
+
hasManualNotePosition(classId) {
|
|
134
|
+
return this.notePositions.has(classId);
|
|
135
|
+
}
|
|
136
|
+
setNotePosition(classId, position) {
|
|
137
|
+
const diagramClass = this.getClass(classId);
|
|
138
|
+
if (!diagramClass.note) {
|
|
139
|
+
throw new Error(`Class "${classId}" does not have a note`);
|
|
140
|
+
}
|
|
141
|
+
this.notePositions.set(classId, copyPosition(position));
|
|
142
|
+
}
|
|
143
|
+
clearNotePosition(classId) {
|
|
144
|
+
const diagramClass = this.getClass(classId);
|
|
145
|
+
if (!diagramClass.note) {
|
|
146
|
+
throw new Error(`Class "${classId}" does not have a note`);
|
|
147
|
+
}
|
|
148
|
+
this.notePositions.delete(classId);
|
|
149
|
+
}
|
|
150
|
+
getWaypoints(relationshipId) {
|
|
151
|
+
const waypoints = this.relationshipWaypoints.get(relationshipId);
|
|
152
|
+
if (!waypoints)
|
|
153
|
+
throw new Error(`Unknown relationship "${relationshipId}"`);
|
|
154
|
+
return waypoints.map(copyPosition);
|
|
155
|
+
}
|
|
156
|
+
replaceWaypoints(relationshipId, waypoints) {
|
|
157
|
+
this.getWaypoints(relationshipId);
|
|
158
|
+
this.relationshipWaypoints.set(relationshipId, waypoints.map(copyPosition));
|
|
159
|
+
}
|
|
160
|
+
addWaypoint(relationshipId, position, index = this.getWaypoints(relationshipId).length) {
|
|
161
|
+
const waypoints = this.getWaypoints(relationshipId);
|
|
162
|
+
if (!Number.isInteger(index) || index < 0 || index > waypoints.length) {
|
|
163
|
+
throw new RangeError(`Waypoint index ${index} is out of range`);
|
|
164
|
+
}
|
|
165
|
+
waypoints.splice(index, 0, copyPosition(position));
|
|
166
|
+
this.relationshipWaypoints.set(relationshipId, waypoints);
|
|
167
|
+
return index;
|
|
168
|
+
}
|
|
169
|
+
moveWaypoint(relationshipId, index, position) {
|
|
170
|
+
const waypoints = this.getWaypoints(relationshipId);
|
|
171
|
+
if (!waypoints[index]) {
|
|
172
|
+
throw new RangeError(`Waypoint index ${index} is out of range`);
|
|
173
|
+
}
|
|
174
|
+
waypoints[index] = copyPosition(position);
|
|
175
|
+
this.relationshipWaypoints.set(relationshipId, waypoints);
|
|
176
|
+
}
|
|
177
|
+
removeWaypoint(relationshipId, index) {
|
|
178
|
+
const waypoints = this.getWaypoints(relationshipId);
|
|
179
|
+
if (!waypoints[index]) {
|
|
180
|
+
throw new RangeError(`Waypoint index ${index} is out of range`);
|
|
181
|
+
}
|
|
182
|
+
waypoints.splice(index, 1);
|
|
183
|
+
this.relationshipWaypoints.set(relationshipId, waypoints);
|
|
184
|
+
}
|
|
185
|
+
resetRoute(relationshipId) {
|
|
186
|
+
this.getWaypoints(relationshipId);
|
|
187
|
+
this.relationshipWaypoints.set(relationshipId, []);
|
|
188
|
+
}
|
|
189
|
+
applyClassPositions(positions) {
|
|
190
|
+
for (const [id, position] of positions) {
|
|
191
|
+
if (this.classPositions.has(id)) {
|
|
192
|
+
this.classPositions.set(id, copyPosition(position));
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
getLayout() {
|
|
197
|
+
const classes = Object.fromEntries([...this.classPositions].map(([id, position]) => [
|
|
198
|
+
id,
|
|
199
|
+
copyPosition(position),
|
|
200
|
+
]));
|
|
201
|
+
const notes = Object.fromEntries([...this.notePositions].map(([id, position]) => [
|
|
202
|
+
id,
|
|
203
|
+
copyPosition(position),
|
|
204
|
+
]));
|
|
205
|
+
const relationships = Object.fromEntries([...this.relationshipWaypoints]
|
|
206
|
+
.filter(([, waypoints]) => waypoints.length > 0)
|
|
207
|
+
.map(([id, waypoints]) => [
|
|
208
|
+
id,
|
|
209
|
+
{ waypoints: waypoints.map(copyPosition) },
|
|
210
|
+
]));
|
|
211
|
+
return {
|
|
212
|
+
classes,
|
|
213
|
+
...(Object.keys(notes).length > 0 ? { notes } : {}),
|
|
214
|
+
...(Object.keys(relationships).length > 0 ? { relationships } : {}),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
initialize(model, layout) {
|
|
218
|
+
for (const [index, diagramClass] of model.classes.entries()) {
|
|
219
|
+
this.classPositions.set(diagramClass.id, copyPosition(layout.classes?.[diagramClass.id] ?? fallbackClassPosition(index)));
|
|
220
|
+
const notePosition = layout.notes?.[diagramClass.id];
|
|
221
|
+
if (notePosition) {
|
|
222
|
+
this.notePositions.set(diagramClass.id, copyPosition(notePosition));
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const relationship of model.relationships) {
|
|
226
|
+
const waypoints = layout.relationships?.[relationship.id]?.waypoints ?? [];
|
|
227
|
+
this.relationshipWaypoints.set(relationship.id, waypoints.map(copyPosition));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/rendering/store.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n DiagramClass,\n DiagramLayout,\n DiagramModel,\n DiagramRelationship,\n DiagramRelationshipChanges,\n Position,\n} from \"../model/types.js\";\nimport {\n validateDiagramLayout,\n validateDiagramModel,\n} from \"../model/validation.js\";\nimport {\n copyPosition,\n defaultNotePosition,\n fallbackClassPosition,\n} from \"./geometry.js\";\n\nfunction normalizeOptionalText(value: string | undefined): string | undefined {\n return value?.trim() ? value : undefined;\n}\n\nfunction cloneRelationship(\n relationship: DiagramRelationship,\n): DiagramRelationship {\n const cloned = { ...relationship } as DiagramRelationship & {\n description?: unknown;\n };\n delete cloned.description;\n const normalizedLabel = normalizeOptionalText(cloned.label);\n if (normalizedLabel === undefined) delete cloned.label;\n else cloned.label = normalizedLabel;\n return cloned;\n}\n\nfunction cloneModel(model: DiagramModel): DiagramModel {\n return {\n classes: model.classes.map((diagramClass) => {\n const cloned = {\n ...diagramClass,\n attributes: diagramClass.attributes?.map((attribute) => ({\n ...attribute,\n })),\n } as DiagramClass & { description?: unknown };\n delete cloned.description;\n return cloned;\n }),\n relationships: model.relationships.map(cloneRelationship),\n };\n}\n\nexport class DiagramStore {\n private modelValue: DiagramModel;\n private readonly classPositions = new Map<string, Position>();\n private readonly notePositions = new Map<string, Position>();\n private readonly relationshipWaypoints = new Map<string, Position[]>();\n\n constructor(model: DiagramModel, layout: DiagramLayout = {}) {\n validateDiagramModel(model);\n validateDiagramLayout(layout, model);\n this.modelValue = cloneModel(model);\n this.initialize(model, layout);\n }\n\n get model(): DiagramModel {\n return cloneModel(this.modelValue);\n }\n\n setModel(model: DiagramModel): void {\n validateDiagramModel(model);\n const nextClassIds = new Set(model.classes.map(({ id }) => id));\n const nextRelationshipIds = new Set(\n model.relationships.map(({ id }) => id),\n );\n\n for (const id of this.classPositions.keys()) {\n if (!nextClassIds.has(id)) this.classPositions.delete(id);\n }\n for (const id of this.notePositions.keys()) {\n const diagramClass = model.classes.find((item) => item.id === id);\n if (!diagramClass?.note) this.notePositions.delete(id);\n }\n for (const id of this.relationshipWaypoints.keys()) {\n if (!nextRelationshipIds.has(id)) this.relationshipWaypoints.delete(id);\n }\n\n for (const [index, diagramClass] of model.classes.entries()) {\n if (!this.classPositions.has(diagramClass.id)) {\n this.classPositions.set(diagramClass.id, fallbackClassPosition(index));\n }\n }\n for (const relationship of model.relationships) {\n if (!this.relationshipWaypoints.has(relationship.id)) {\n this.relationshipWaypoints.set(relationship.id, []);\n }\n }\n this.modelValue = cloneModel(model);\n }\n\n setLayout(layout: DiagramLayout): void {\n validateDiagramLayout(layout, this.modelValue);\n\n for (const [id, position] of Object.entries(layout.classes ?? {})) {\n this.classPositions.set(id, copyPosition(position));\n }\n\n this.notePositions.clear();\n for (const [id, position] of Object.entries(layout.notes ?? {})) {\n this.notePositions.set(id, copyPosition(position));\n }\n\n this.relationshipWaypoints.clear();\n for (const relationship of this.modelValue.relationships) {\n const waypoints = layout.relationships?.[relationship.id]?.waypoints ?? [];\n this.relationshipWaypoints.set(\n relationship.id,\n waypoints.map(copyPosition),\n );\n }\n }\n\n getClass(id: string): DiagramClass {\n const diagramClass = this.modelValue.classes.find((item) => item.id === id);\n if (!diagramClass) throw new Error(`Unknown class \"${id}\"`);\n return diagramClass;\n }\n\n getRelationship(id: string): DiagramRelationship {\n const relationship = this.modelValue.relationships.find(\n (item) => item.id === id,\n );\n if (!relationship) throw new Error(`Unknown relationship \"${id}\"`);\n return cloneRelationship(relationship);\n }\n\n updateRelationship(\n id: string,\n changes: DiagramRelationshipChanges,\n ): void {\n const index = this.modelValue.relationships.findIndex(\n (relationship) => relationship.id === id,\n );\n const relationship = this.modelValue.relationships[index];\n if (!relationship) throw new Error(`Unknown relationship \"${id}\"`);\n\n const next = { ...relationship };\n if (Object.hasOwn(changes, \"label\")) {\n const label = normalizeOptionalText(changes.label);\n if (label === undefined) delete next.label;\n else next.label = label;\n }\n this.modelValue.relationships[index] = next;\n }\n\n getClassPosition(id: string): Position {\n const position = this.classPositions.get(id);\n if (!position) throw new Error(`Unknown class \"${id}\"`);\n return copyPosition(position);\n }\n\n setClassPosition(id: string, position: Position): void {\n this.getClass(id);\n this.classPositions.set(id, copyPosition(position));\n }\n\n getNotePosition(classId: string): Position {\n const manualPosition = this.notePositions.get(classId);\n if (manualPosition) return copyPosition(manualPosition);\n const diagramClass = this.getClass(classId);\n return defaultNotePosition(this.getClassPosition(classId), diagramClass);\n }\n\n hasManualNotePosition(classId: string): boolean {\n return this.notePositions.has(classId);\n }\n\n setNotePosition(classId: string, position: Position): void {\n const diagramClass = this.getClass(classId);\n if (!diagramClass.note) {\n throw new Error(`Class \"${classId}\" does not have a note`);\n }\n this.notePositions.set(classId, copyPosition(position));\n }\n\n clearNotePosition(classId: string): void {\n const diagramClass = this.getClass(classId);\n if (!diagramClass.note) {\n throw new Error(`Class \"${classId}\" does not have a note`);\n }\n this.notePositions.delete(classId);\n }\n\n getWaypoints(relationshipId: string): Position[] {\n const waypoints = this.relationshipWaypoints.get(relationshipId);\n if (!waypoints) throw new Error(`Unknown relationship \"${relationshipId}\"`);\n return waypoints.map(copyPosition);\n }\n\n replaceWaypoints(relationshipId: string, waypoints: Position[]): void {\n this.getWaypoints(relationshipId);\n this.relationshipWaypoints.set(relationshipId, waypoints.map(copyPosition));\n }\n\n addWaypoint(\n relationshipId: string,\n position: Position,\n index = this.getWaypoints(relationshipId).length,\n ): number {\n const waypoints = this.getWaypoints(relationshipId);\n if (!Number.isInteger(index) || index < 0 || index > waypoints.length) {\n throw new RangeError(`Waypoint index ${index} is out of range`);\n }\n waypoints.splice(index, 0, copyPosition(position));\n this.relationshipWaypoints.set(relationshipId, waypoints);\n return index;\n }\n\n moveWaypoint(\n relationshipId: string,\n index: number,\n position: Position,\n ): void {\n const waypoints = this.getWaypoints(relationshipId);\n if (!waypoints[index]) {\n throw new RangeError(`Waypoint index ${index} is out of range`);\n }\n waypoints[index] = copyPosition(position);\n this.relationshipWaypoints.set(relationshipId, waypoints);\n }\n\n removeWaypoint(relationshipId: string, index: number): void {\n const waypoints = this.getWaypoints(relationshipId);\n if (!waypoints[index]) {\n throw new RangeError(`Waypoint index ${index} is out of range`);\n }\n waypoints.splice(index, 1);\n this.relationshipWaypoints.set(relationshipId, waypoints);\n }\n\n resetRoute(relationshipId: string): void {\n this.getWaypoints(relationshipId);\n this.relationshipWaypoints.set(relationshipId, []);\n }\n\n applyClassPositions(positions: ReadonlyMap<string, Position>): void {\n for (const [id, position] of positions) {\n if (this.classPositions.has(id)) {\n this.classPositions.set(id, copyPosition(position));\n }\n }\n }\n\n getLayout(): DiagramLayout {\n const classes = Object.fromEntries(\n [...this.classPositions].map(([id, position]) => [\n id,\n copyPosition(position),\n ]),\n );\n const notes = Object.fromEntries(\n [...this.notePositions].map(([id, position]) => [\n id,\n copyPosition(position),\n ]),\n );\n const relationships = Object.fromEntries(\n [...this.relationshipWaypoints]\n .filter(([, waypoints]) => waypoints.length > 0)\n .map(([id, waypoints]) => [\n id,\n { waypoints: waypoints.map(copyPosition) },\n ]),\n );\n\n return {\n classes,\n ...(Object.keys(notes).length > 0 ? { notes } : {}),\n ...(Object.keys(relationships).length > 0 ? { relationships } : {}),\n };\n }\n\n private initialize(model: DiagramModel, layout: DiagramLayout): void {\n for (const [index, diagramClass] of model.classes.entries()) {\n this.classPositions.set(\n diagramClass.id,\n copyPosition(\n layout.classes?.[diagramClass.id] ?? fallbackClassPosition(index),\n ),\n );\n const notePosition = layout.notes?.[diagramClass.id];\n if (notePosition) {\n this.notePositions.set(diagramClass.id, copyPosition(notePosition));\n }\n }\n for (const relationship of model.relationships) {\n const waypoints = layout.relationships?.[relationship.id]?.waypoints ?? [];\n this.relationshipWaypoints.set(\n relationship.id,\n waypoints.map(copyPosition),\n );\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { RelationshipType } from "../model/types.js";
|
|
2
|
+
export interface MarkerStyle {
|
|
3
|
+
type: "path";
|
|
4
|
+
d: string;
|
|
5
|
+
fill: string;
|
|
6
|
+
stroke: string;
|
|
7
|
+
strokeWidth: number;
|
|
8
|
+
}
|
|
9
|
+
export interface RelationshipAppearance {
|
|
10
|
+
strokeDasharray?: string;
|
|
11
|
+
sourceMarker?: MarkerStyle;
|
|
12
|
+
targetMarker?: MarkerStyle;
|
|
13
|
+
}
|
|
14
|
+
export declare function getRelationshipAppearance(type: RelationshipType): RelationshipAppearance;
|
|
15
|
+
//# sourceMappingURL=relationship-style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-style.d.ts","sourceRoot":"","sources":["../../src/routing/relationship-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,sBAAsB;IACrC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AA4BD,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,gBAAgB,GACrB,sBAAsB,CAaxB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const LINE_COLOR = "#334155";
|
|
2
|
+
const openArrow = () => ({
|
|
3
|
+
type: "path",
|
|
4
|
+
d: "M 10 -5 0 0 10 5",
|
|
5
|
+
fill: "none",
|
|
6
|
+
stroke: LINE_COLOR,
|
|
7
|
+
strokeWidth: 1.5,
|
|
8
|
+
});
|
|
9
|
+
const diamond = (fill) => ({
|
|
10
|
+
type: "path",
|
|
11
|
+
d: "M 20 0 10 -6 0 0 10 6 Z",
|
|
12
|
+
fill,
|
|
13
|
+
stroke: LINE_COLOR,
|
|
14
|
+
strokeWidth: 1.5,
|
|
15
|
+
});
|
|
16
|
+
const triangle = () => ({
|
|
17
|
+
type: "path",
|
|
18
|
+
d: "M 14 -7 0 0 14 7 Z",
|
|
19
|
+
fill: "#ffffff",
|
|
20
|
+
stroke: LINE_COLOR,
|
|
21
|
+
strokeWidth: 1.5,
|
|
22
|
+
});
|
|
23
|
+
export function getRelationshipAppearance(type) {
|
|
24
|
+
switch (type) {
|
|
25
|
+
case "association":
|
|
26
|
+
return { targetMarker: openArrow() };
|
|
27
|
+
case "aggregation":
|
|
28
|
+
return { sourceMarker: diamond("#ffffff") };
|
|
29
|
+
case "composition":
|
|
30
|
+
return { sourceMarker: diamond(LINE_COLOR) };
|
|
31
|
+
case "inheritance":
|
|
32
|
+
return { targetMarker: triangle() };
|
|
33
|
+
case "dependency":
|
|
34
|
+
return { strokeDasharray: "7 5", targetMarker: openArrow() };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=relationship-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-style.js","sourceRoot":"","sources":["../../src/routing/relationship-style.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,GAAG,SAAS,CAAC;AAE7B,MAAM,SAAS,GAAG,GAAgB,EAAE,CAAC,CAAC;IACpC,IAAI,EAAE,MAAM;IACZ,CAAC,EAAE,kBAAkB;IACrB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,GAAG;CACjB,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,IAAY,EAAe,EAAE,CAAC,CAAC;IAC9C,IAAI,EAAE,MAAM;IACZ,CAAC,EAAE,yBAAyB;IAC5B,IAAI;IACJ,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,GAAG;CACjB,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,GAAgB,EAAE,CAAC,CAAC;IACnC,IAAI,EAAE,MAAM;IACZ,CAAC,EAAE,oBAAoB;IACvB,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,GAAG;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,yBAAyB,CACvC,IAAsB;IAEtB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,aAAa;YAChB,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC;QACvC,KAAK,aAAa;YAChB,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,KAAK,aAAa;YAChB,OAAO,EAAE,YAAY,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/C,KAAK,aAAa;YAChB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,CAAC;QACtC,KAAK,YAAY;YACf,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC;IACjE,CAAC;AACH,CAAC","sourcesContent":["import type { RelationshipType } from \"../model/types.js\";\n\nexport interface MarkerStyle {\n type: \"path\";\n d: string;\n fill: string;\n stroke: string;\n strokeWidth: number;\n}\n\nexport interface RelationshipAppearance {\n strokeDasharray?: string;\n sourceMarker?: MarkerStyle;\n targetMarker?: MarkerStyle;\n}\n\nconst LINE_COLOR = \"#334155\";\n\nconst openArrow = (): MarkerStyle => ({\n type: \"path\",\n d: \"M 10 -5 0 0 10 5\",\n fill: \"none\",\n stroke: LINE_COLOR,\n strokeWidth: 1.5,\n});\n\nconst diamond = (fill: string): MarkerStyle => ({\n type: \"path\",\n d: \"M 20 0 10 -6 0 0 10 6 Z\",\n fill,\n stroke: LINE_COLOR,\n strokeWidth: 1.5,\n});\n\nconst triangle = (): MarkerStyle => ({\n type: \"path\",\n d: \"M 14 -7 0 0 14 7 Z\",\n fill: \"#ffffff\",\n stroke: LINE_COLOR,\n strokeWidth: 1.5,\n});\n\nexport function getRelationshipAppearance(\n type: RelationshipType,\n): RelationshipAppearance {\n switch (type) {\n case \"association\":\n return { targetMarker: openArrow() };\n case \"aggregation\":\n return { sourceMarker: diamond(\"#ffffff\") };\n case \"composition\":\n return { sourceMarker: diamond(LINE_COLOR) };\n case \"inheritance\":\n return { targetMarker: triangle() };\n case \"dependency\":\n return { strokeDasharray: \"7 5\", targetMarker: openArrow() };\n }\n}\n"]}
|