UNPKG

devexpress-diagram

Version:

DevExpress Diagram Control

117 lines (98 loc) 4.68 kB
import { Rectangle } from "@devexpress/utils/lib/geometry/rectangle"; import { Point } from "@devexpress/utils/lib/geometry/point"; import { Metrics } from "@devexpress/utils/lib/geometry/metrics"; import { Connector } from "./Connectors/Connector"; import { SvgPrimitive } from "../Render/Primitives/Primitive"; import { ObjectUtils } from "../Utils"; import { IKeyOwner } from "../Interfaces"; import { Style, TextStyle } from "./Style"; import { ConnectionPoint } from "./ConnectionPoint"; import { Shape } from "./Shapes/Shape"; import { INativeItem } from "../Api/INativeItem"; import { DiagramUnit } from "../Enums"; export enum ConnectionPointSide { Undefined = -1, North = 0, East = 1, South = 2, West = 3 } export type ItemKey = string; export type ItemDataKey = string | number; export type ItemsMap = {[key: string]: boolean}; export const DEFAULT_ZINDEX = 0; export abstract class DiagramItem implements IKeyOwner { key: ItemKey = undefined; dataKey: ItemDataKey = undefined; customData: any = undefined; attachedConnectors: Connector[] = []; zIndex: number = DEFAULT_ZINDEX; locked: boolean = false; container: Shape = undefined; style: Style = new Style(); styleText: TextStyle = new TextStyle(); abstract createPrimitives(): SvgPrimitive<SVGGraphicsElement>[]; abstract createSelectorPrimitives(): SvgPrimitive<SVGGraphicsElement>[]; assign(item: DiagramItem) { item.key = this.key; item.dataKey = this.dataKey; item.customData = ObjectUtils.cloneObject(this.customData); item.locked = this.locked; item.attachedConnectors = this.attachedConnectors.slice(); item.style = <Style> this.style.clone(); item.styleText = <TextStyle> this.styleText.clone(); item.zIndex = this.zIndex; item.container = this.container; } getConnectionPointPosition(index: number, targetPoint?: Point): Point { return this.getConnectionPoint(index, targetPoint).toPoint(); } protected getConnectionPoint(index: number, targetPoint?: Point): ConnectionPoint { if(index < 0 && targetPoint) index = this.getNearestConnectionPoint(targetPoint); const connectionPoints = this.getConnectionPoints(); return connectionPoints[index] || connectionPoints[0]; } protected getNearestConnectionPoint(targetPoint: Point): number { let distance = Number.MAX_VALUE; let result: number; this.getConnectionPoints().forEach((pt, index) => { const ptDistance = Metrics.euclideanDistance(pt, targetPoint); if(ptDistance < distance) { distance = ptDistance; result = index; } }); return result; } getConnectionPointIndex(side: ConnectionPointSide): number { const points = this.getConnectionPoints(); return points.reduce((prevIndex, pt, index) => { if(side === ConnectionPointSide.North && pt.y < points[prevIndex].y) return index; if(side === ConnectionPointSide.South && pt.y > points[prevIndex].y) return index; if(side === ConnectionPointSide.West && pt.x < points[prevIndex].x) return index; if(side === ConnectionPointSide.East && pt.x > points[prevIndex].x) return index; return prevIndex; }, 0); } getConnectionPointSideByIndex(index: number, targetPoint?: Point): ConnectionPointSide { const point = this.getConnectionPoint(index, targetPoint); return this.getConnectionPointSide(point, targetPoint); } getConnectionPointIndexForSide(side: ConnectionPointSide): number { return side; } abstract get rectangle(): Rectangle; get enableText() { return true; } get allowEditText() { return true; } get hasTemplate() { return false; } get enableChildren() { return false; } get isLocked() { return this.locked || (this.container && this.container.isLocked); } get allowResizeHorizontally() { return false; } get allowResizeVertically() { return false; } get strokeWidth() { return this.style.strokeWidth; } abstract getConnectionPoints(): ConnectionPoint[]; abstract getConnectionPointSide(point: ConnectionPoint, targetPoint?: Point): ConnectionPointSide; abstract toNative(units?: DiagramUnit): INativeItem; intersectedByRect(rect: Rectangle): boolean { return Rectangle.areIntersected(this.rectangle, rect); } }