import { SMouseEvent, SUndoStack } from "@saga-web/base"; import { SGraphScene, SGraphLayoutType, SAnchorItem } from '@saga-web/graph/lib'; import { SFloorParser, SLineItem, SPolylineItem, SItemStatus, ItemOrder, STooltipItem, ItemColor, Transparency, SPolygonItem, SRectSelectItem } from "@saga-web/big"; import { SGraphItem, SLineStyle, SGraphPropertyCommand, SImageItem, STextItem, SGraphPointListInsert, SGraphPointListDelete, SGraphPointListUpdate, SGraphAddCommand } from "@saga-web/graph/lib"; import { SGraphAddListCommand } from "./SGraphAddListCommand" import { SGraphDeleteCommand } from "./SGraphDeleteCommand" import { SGraphDeleteListCommand } from "./SGraphDeleteListCommand" import { SZoneLegendItem } from "@/lib/items/SZoneLegendItem"; import { SSCPZZoneLegendItem } from "@/lib/items/SSCPZZoneLegendItem"; import { SFHFQZoneLegendItem } from "@/lib/items/SFHFQZoneLegendItem"; import { SImageLegendItem } from "@/lib/items/SImageLegendItem"; import { TipelineItem } from "@/lib/items/TipelineItem"; import { SImageMarkerItem } from "@/lib/items/SImageMarkerItem" import { SPoint, SFont, SColor, SRect } from '@saga-web/draw/lib'; import { Legend } from '@/lib/types/Legend'; import { Relation } from '@/lib/types/Relation'; import { uuid } from "@/components/mapClass/until"; import { STextMarkerItem } from '@/lib/items/STextMarkerItem'; import { SLineMarkerItem } from '@/lib/items/SLineMarkerItem'; import { SSpaceItem } from '@saga-web/big/lib/items/floor/SSpaceItem'; import { SMathUtil } from '@saga-web/big/lib/utils/SMathUtil'; import { MinDis } from '@saga-web/big/lib/types/MinDis'; import { HighlightItem } from '@/lib/items/HighlightItem'; import { TimeSelect } from 'element-ui'; import { STopologyParser } from '@/lib/parsers/STopologyParser'; import { SCustomLegendItem } from '@/lib/items/SCustomLegendItem'; /** * 在线绘图 * * @author 韩耀龙 */ export class EditScence extends SGraphScene { undoStack = new SUndoStack(); /** 判断是否为苹果电脑 */ public isMac = /macintosh|mac os x/i.test(navigator.userAgent); /** 命令 1 绘制直线 */ private cmd = 'choice'; /** 获取当前状态 */ get getCmd(): string { return this.cmd; } /** 编辑当前状态 */ set setCmd(cmd: string) { if (cmd == 'choice') { this.grabItem = null; } this.cmd = cmd; if (this.focusItem) { // 取消操作 this.focusItem.cancelOperate(); this.focusItem = null; // this.selectContainer.clear() } if (this.view) { this.view.update(); } }; /** 绘制区域时 是否为点选 */ isSelecting: boolean = true; /** 是否开启吸附 */ isAbsorbing: boolean = false; /** 吸附展示item */ highLight: HighlightItem | null = null; // /** 矩形选择区域 */ // rectSelectItem: SRectSelectItem | null = null; // /** 框选 */ // isRectSelection: number = 0; /** 当前选中焦点Item */ focusItem: SGraphItem | null = null; /** 当前选中焦点ItemList */ focusItemList: SGraphItem[] | null = null; /**图例节点 */ Nodes: any = []; // 图例节点,所有与工程信息化相关的图例(图标类型与区域) /**图例节点 */ // 与工程信息无关的标识对象(增加文本注释,图上的图片说明) Markers: any = []; /** 管线对象 */ Relations: any = []; _isEditStatus: Boolean = true; // 是否可编辑 set isEditStatus(bol: Boolean): void { this._isEditStatus = bol; } get isEditStatus(): Boolean { return this._isEditStatus } //复制粘贴 copyString = { Nodes: [], Markers: [], Relations: [] }; constructor() { super(); // // 选择绑定选额item事件 this.selectContainer.connect("listChange", this, this.listChange); ItemColor.spaceColor = new SColor("#f0f0f0") ItemColor.wallColor = new SColor("#d4d4d4") ItemColor.columnColor = new SColor("#d4d4d4") ItemColor.virtualWallColor = new SColor("#d4d4d4") ItemColor.selectColor = new SColor("#f0f0f0") ItemColor.spaceBorderColor = new SColor("#d4d4d4"); console.log('isMac',this.isMac) } /** 绘制图例样式 */ _legend: any | null = null; get getlegend(): any { return this._legend; }; set setlegend(obj: any) { this._legend = obj; } /** fid=>item映射,由解析器存入 */ fidToItem = {} /** * 监听变化 * @param obj 变化后的对象 */ listChange(obj: any) { let itemType: string = 'equipment'; this.focusItemList = obj.itemList; if (obj.itemList[0] instanceof STextMarkerItem) { itemType = 'baseText' } else if (obj.itemList[0] instanceof SImageMarkerItem) { itemType = 'baseImage' } else if (obj.itemList[0] instanceof SLineMarkerItem) { itemType = 'baseLine' } else if (obj.itemList[0] instanceof SZoneLegendItem) { itemType = 'Zone' } else if (obj.itemList[0] instanceof SFHFQZoneLegendItem) { itemType = 'Zone' } else if (obj.itemList[0] instanceof SSCPZZoneLegendItem) { itemType = 'Zone' } else if (obj.itemList[0] instanceof SCustomLegendItem) { itemType = 'Zone' } else if (obj.itemList[0] instanceof SImageLegendItem) { itemType = 'Image' } else if (obj.itemList[0] instanceof TipelineItem) { itemType = 'Line' } else if (obj.itemList[0] instanceof SSpaceItem) { // 点选 this.clickToAddArea(obj.itemList[0]); return } else { itemType = '' }; if (obj.itemList.length == 1) { // 获取聚焦item this.focusItem = obj.itemList[0] } else { this.focusItem = null } let msg = { itemList: obj.itemList, itemType, } this.emitChange(msg) } emitChange(msg: any) { } /** * 增加线段item */ addLine(event: SMouseEvent): boolean { const clickItem = this.clickIsItem(event); if (clickItem) { let centerPoint = clickItem.boundingRect().center(); const p = clickItem.mapToScene(centerPoint.x, centerPoint.y); event.x = p.x; event.y = p.y; } const data = { /** ID */ ID: uuid(), /** 名称 */ Name: '直线', /** 图标(Image),线类型(Line) */ Type: "Line", /** 位置 */ Pos: { X: 0, Y: 0 }, /** 由应用自己定义 */ Properties: { IconUrl: require("../../assets/images/t-line-hover.png"), Line: [{ X: event.x, Y: event.y }], LineWidth: 1, StrokeColor: "#bdc3c8" } } const item = new SLineMarkerItem(null, data); item.status = SItemStatus.Create; item.selectable = true; this.addItem(item); // this.Markers.push(item); item.connect("finishCreated", this, this.finishCreated); this.grabItem = item; this.focusItem = item; // 起始item点 item.startItem = clickItem; if (clickItem) { clickItem.connect('onMove', item, item.changePos); } return true } /** * 增加折线item */ addPolylineItem(event: SMouseEvent): boolean { const point = new SPoint(event.x, event.y) const item = new TipelineItem(null, [point]); //设置状态 item.selectable = true; item.status = SItemStatus.Create; this.addItem(item); item.connect("finishCreated", this, this.finishCreated); this.grabItem = item; this.focusItem = item; return true } /** * 增加管道 lenged */ addTipelineItem(event: SMouseEvent): boolean { const anc = this.clickIsAnchor(event); if (anc) { const p = anc.mapToScene(0, 0) anc.isConnected = true; event.x = p.x; event.y = p.y; } const LegendData: Relation = { ID: uuid(), Name: this._legend.Name, GraphElementId: this._legend.Id, PointList: [{ X: event.x, Y: event.y }], LineType: "Line", Properties: { IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url, LineDash: this._legend.LineDash, LineWidth: this._legend.LineWidth, Color: this._legend.Color, }, } const item = new TipelineItem(null, LegendData); //设置状态 item.selectable = true; item.status = SItemStatus.Create; this.addItem(item); // this.Relations.push(item); item.connect("finishCreated", this, this.finishCreated); this.grabItem = item; this.focusItem = item; // 起始锚点 item.startAnchor = anc; if (anc) { anc.parent ?.connect('changePos', item, item.changePos) item.anchor1ID = anc.id; item.node1Id = anc.parent.id; } return true } /** * 增加多边形item lenged */ addPolygonItem(event: SMouseEvent): void { const SubType = this._legend.SubType ? this._legend.SubType : ''; const LegendData: Legend = { ID: uuid(), Name: this._legend.Name, GraphElementType: this._legend.Type, Num: 1, GraphElementId: this._legend.Id, AttachObjectIds: [], Type: "Zone", Pos: { X: event.x, Y: event.y }, OutLine: [{ X: event.x, Y: event.y }], SubType: SubType, Properties: { IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url, StrokeColor: this._legend.Color, FillColor: this._legend.FillColor, LineDash: this._legend.LineDash, LineWidth: this._legend.LineWidth, font: 14, color: "#1F2429", TextPos: { X: 0, Y: 0 }, InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [], InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '', InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : [] }, } let Polylines = null; if (SubType == "SCPZ") { Polylines = new SSCPZZoneLegendItem(null, LegendData); } else if (SubType == "FHFQ") { Polylines = new SFHFQZoneLegendItem(null, LegendData); } else if (SubType == "CUSTOM") { Polylines = new SCustomLegendItem(null, LegendData); } else { Polylines = new SZoneLegendItem(null, LegendData); } Polylines.selectable = true; //设置状态 Polylines.status = SItemStatus.Create; // Polylines.moveable = true; this.addItem(Polylines); Polylines.connect("finishCreated", this, this.finishCreated); this.grabItem = Polylines; this.focusItem = Polylines; } /** * 点选创建区域 */ clickToAddArea(item: SSpaceItem): void { if (this.cmd != 'Zone') { return } if (this.isSelecting && this._legend) { //@ts-ignore item.isExtracted = true const SubType = this._legend.SubType ? this._legend.SubType : ''; const LegendData: Legend = { ID: uuid(), Name: this._legend.Name, GraphElementType: this._legend.Type, Num: 1, GraphElementId: this._legend.Id, AttachObjectIds: [], Type: "Zone", Pos: { X: item.x, Y: item.y }, OutLine: item.pointArr[0], SubType: SubType, Properties: { IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url, StrokeColor: this._legend.Color, FillColor: this._legend.FillColor, LineDash: this._legend.LineDash, LineWidth: this._legend.LineWidth, font: 14, color: "#1F2429", FID: item.data.SourceId, TextPos: { X: item.data.Location.Points[0].X, Y: -item.data.Location.Points[0].Y }, InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [], InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '', InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : [] }, } let Polylines = null; if (SubType == "SCPZ") { Polylines = new SSCPZZoneLegendItem(null, LegendData); } else if (SubType == "FHFQ") { Polylines = new SFHFQZoneLegendItem(null, LegendData); } else { Polylines = new SZoneLegendItem(null, LegendData); } Polylines.selectable = true; //设置状态 Polylines.status = SItemStatus.Normal; this.addItem(Polylines); // this.Nodes.push(Polylines); this.finishCreated(Polylines) this.focusItem = Polylines; this.scenceUpdate(this); } } /** * 增加图片Item mark */ addImgItem(event: SMouseEvent) { const data = { /** ID */ ID: uuid(), /** 名称 */ Name: '图片', Num: 1, /** 图标(Image),线类型(Line) */ Type: "Image", /** 位置 */ Pos: { X: event.x, Y: event.y }, /** 由应用自己定义 */ Properties: { IconUrl: require(`../../assets/images/t-img-hover.png`), StrokeColor: "#c0ccda", Url: '', } } const item = new SImageMarkerItem(null, data); item.selectable = true; item.moveable = true; this.addItem(item); this.Markers.push(item); this.grabItem == null; this.focusItem = item; this.finishCreated(item); this.scenceUpdate(this); } /** * 增加文字item */ addTextItem(event: SMouseEvent): void { const data = { /** ID */ ID: uuid(), /** 名称 */ Name: '文本', /** 图标 */ Type: "Text", /** 位置 */ Pos: { X: event.x, Y: event.y }, /** 由应用自己定义 */ Properties: { IconUrl: require(`../../assets/images/t-text-hover.png`), Text: '请在右侧属性栏输入文字!', Color: "#646c73", Font: 14, BackgroundColor: "#f7f9facc" } } const item = new STextMarkerItem(null, data); item.moveTo(event.x, event.y); item.selectable = true; item.moveable = true; this.addItem(item); this.Markers.push(item); this.grabItem = null; this.focusItem = item; this.cmd = 'choice'; this.finishCreated(item); this.scenceUpdate(this); } /** * 增加图标lenged图标 */ addIconItem(event: SMouseEvent): void { //获取信息工程化相关参数 const LegendData: Legend = { ID: uuid(), Name: "", GraphElementType: this._legend.Type, Num: 1, GraphElementId: this._legend.Id, AttachObjectIds: [], Pos: { X: event.x, Y: event.y }, Scale: { X: 1, Y: 1, Z: 1 }, // 缩放 Rolate: { X: 0, Y: 0, Z: 0 }, Size: { Width: 0, Height: 0 }, // 大小 Type: this._legend.Type, Properties: { IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url, Url: '/serve/topology-wanda/Picture/query/' + this._legend.Url, Num: 1, // 此num与信息工程化得num无关 Size: { Width: this._legend.Size?this._legend.Size.Width?this._legend.Size.Width:32:32, //icon 的宽 Height: this._legend.Size?this._legend.Size.Height?this._legend.Size.Height:32:32, //icon 的高 }, font: 16, //font color: "#1F2429", //字体颜色 FrameColor: this._legend.FrameColor, GraphCategoryId: this._legend.GraphCategoryId, InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '', InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [],// 铺位可视化Typeid(用于编辑工程信息化时默认问题) InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : [] }, } const cmd = this.cmd; const item = new SImageLegendItem(null, LegendData); this.cmd = 'choice'; item.selectable = true; item.moveable = true; this.addItem(item); this.Nodes.push(item); this.grabItem = null; this.focusItem = item; this.finishCreated(item); this.scenceUpdate(this); if (event.ctrlKey) { this.cmd = cmd; } } /** * 更改item对应属性 */ editItemStatus(): void { } /** * 更改文本对应属性 * @param str string 文字内容 */ updatedText(str: string): void { if (this.focusItem) { const oldMsg = this.focusItem.text; const newMsg = str; this.focusItem.text = str; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", oldMsg, newMsg)); this.scenceUpdate(this); } } /** * 更改文本fontSize属性 * @param size number 文字大小 */ updatedFontSize(size: number): void { if (this.focusItem) { let old = new SFont(this.focusItem.font); let font = new SFont(this.focusItem.font); font.size = size; this.focusItem.font = font; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font)); } } /** * 更改线宽属性 * @param lineWidth number 线宽大小 */ updatedLineWidth(lineWidth: number): void { if (this.focusItem) { const oldMsg = this.focusItem.lineWidth; const newMsg = lineWidth; this.focusItem.lineWidth = lineWidth; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "lineWidth", oldMsg, newMsg)); } } /** * 更改文本颜色属性 * @param str string 颜色 */ updatedFontColor(color: string): void { if (this.focusItem) { const oldMsg = this.focusItem.color; const newMsg = new SColor(color); this.focusItem.color = newMsg; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", oldMsg, newMsg)); } } /** * 更改border颜色 * @param color string 颜色 */ updatedBorderColor(color: string): void { if (this.focusItem) { const oldMsg = this.focusItem.strokeColor; const newMsg = new SColor(color); this.focusItem.strokeColor = newMsg; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "strokeColor", oldMsg, newMsg)); } } /** * 更改item宽 * @param width number 颜色 */ updatedWidth(width: number): void { if (this.focusItem) { let oldMsg = null; const newMsg = width; if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") { oldMsg = this.focusItem.sWidth this.focusItem.sWidth = width; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "sWidth", oldMsg, newMsg)); } else { oldMsg = this.focusItem.width this.focusItem.width = width; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "width", oldMsg, newMsg)); } } } /** * 更改item高 * @param height number 颜色 */ updatedHeight(height: number): void { if (this.focusItem) { let oldMsg = null; const newMsg = height; if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") { oldMsg = this.focusItem.sHeight; this.focusItem.sHeight = height; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "sHeight", oldMsg, newMsg)); } else { oldMsg = this.focusItem.height; this.focusItem.height = height; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "height", oldMsg, newMsg)); } } } /** * 更改item坐标 * @param x number x x坐标 * @param y number y y坐标 */ updatedPosition(x: number, y: number): void { if (this.focusItem) { let p = this.focusItem.mapFromScene(x, y) // newx - oldx = newleft - oldleft // 要求的值(新的x坐标) - 旧的x坐标 = 新的左边界(用户输入的值) - 旧的左边界 this.focusItem.x = (p.x - this.focusItem.boundingRect().left) * this.focusItem.inverseScale + this.focusItem.x; this.focusItem.y = (p.y - this.focusItem.boundingRect().top) * this.focusItem.inverseScale + this.focusItem.y; if (this.focusItem instanceof SPolylineItem || this.focusItem instanceof SPolygonItem || this.focusItem instanceof SLineItem) { this.focusItem.moveToOrigin(this.focusItem.x, this.focusItem.y) } } } /** * 更改item 背景色坐标 * @param color string 颜色color */ updatedbackColor(color: string): void { if (this.focusItem) { const newMsg = new SColor(color); const oldMsg = this.focusItem.backgroundColor; this.focusItem.backgroundColor = new SColor(color); this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "backgroundColor", oldMsg, newMsg)); } } /** * 更改item Url * @param url string 图片key */ upadataImageUrl(url: string): void { if (this.focusItem) { const newMsg = '/serve/topology-wanda/Picture/query/' + url; const oldMsg = this.focusItem.url; this.focusItem.url = newMsg; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "url", oldMsg, newMsg)); } } /** * 更改item border * @param val string border类型 */ upadataBorder(val: string): void { if (this.focusItem) { let borderStyle = null; if (val == 'dashed') { borderStyle = SLineStyle.Dashed; } else if (val == 'dotted') { borderStyle = SLineStyle.Dotted; } else if (val == 'solid') { borderStyle = SLineStyle.Solid; } const newMsg = borderStyle; const oldMsg = this.focusItem.lineStyle; this.focusItem.lineStyle = borderStyle; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "lineStyle", oldMsg, newMsg)); } } /** * 更改item 名称 * @param val string border类型 */ upadataLengedName(val: string): void { if (this.focusItem && this.focusItem.data) { const newMsg = val; const oldMsg = this.focusItem.text; this.focusItem.text = val; this.focusItem.name = val; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", oldMsg, newMsg)); this.scenceUpdate(this); } } /** * 更改item Num数量 * @param num number item数量 (只对icon设备类) */ upadatImageNum(num: number): void { if (this.focusItem && this.focusItem.num) { const newMsg = num; const oldMsg = this.focusItem.num; this.focusItem.num = num; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "num", oldMsg, newMsg)); } } /** * 更改item Num数量 * @param num number item数量 (只对icon设备类) */ upadatfillColor(fillColor: string): void { if (this.focusItem && this.focusItem.fillColor) { let fillColorT; if (fillColor.length == 7) { fillColorT = fillColor + Transparency[15]; if (this.focusItem instanceof SSCPZZoneLegendItem || this.focusItem instanceof SFHFQZoneLegendItem) { const sc = new SColor(this.focusItem.fillColor); const alp = ((sc.alpha/255)*100).toFixed() fillColorT = fillColor + Transparency[alp]; // fillColorT = fillColor + Transparency[80]; } } else { fillColorT = fillColor; } const newMsg = new SColor(fillColorT); const oldMsg = this.focusItem.fillColor; this.focusItem.fillColor = new SColor(fillColorT); this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "fillColor", oldMsg, newMsg)); } } /** * 更改图例说 * @param num number */ upadatitemExplain(ItemExplain: string): void { if (this.focusItem) { this.focusItem.data.Properties.ItemExplain = ItemExplain; } } /** * 更新工程信息化的相关数据 * @param AttachObjectIds Array */ upadatAttachObjectIds(AttachObjectIds: [], flag: boolean): void { if (this.focusItem) { this.focusItem.data.AttachObjectIds = AttachObjectIds; // 重新选中focusitem const item = this.focusItem; this.selectContainer.clear(); this.selectContainer.toggleItem(item); if ( item instanceof SImageLegendItem || item instanceof SZoneLegendItem || item instanceof SSCPZZoneLegendItem || item instanceof SFHFQZoneLegendItem ) { let arr = item.data.AttachObjectIds; if (arr && arr.length && arr[arr.length - 1].name && flag) { let name = item.name; let nameArr = name.split("\n"); if (nameArr[nameArr.length - 1] != arr[arr.length - 1].name) if (name) { item.name = name + `\n${arr[arr.length - 1].name}`; item.text = name + `\n${arr[arr.length - 1].name}`; } else { item.name = arr[arr.length - 1].name; item.text = arr[arr.length - 1].name; } } // 绑定工程信息化数据后设置状态 if (item.data.AttachObjectIds && item.data.AttachObjectIds.length) { item.isActive = true; } else { item.isActive = false; } } } } /** * 自定义多边形修改背景色 */ updateCustomBgColor(val: string):void{ if (this.focusItem) { const newMsg = new SColor(val); const oldMsg = this.focusItem.fillColor; this.focusItem.fillColor = new SColor(val) this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "fillColor", oldMsg, newMsg)); } } /** * 自定义多边形修改边框色 */ updateCustomBdColor(val: string):void{ if (this.focusItem) { const newMsg = new SColor(val); const oldMsg = this.focusItem.strokeColor; this.focusItem.strokeColor = new SColor(val) this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "strokeColor", oldMsg, newMsg)); } } /** * 删除指定item */ deleiteItem(): void { if (this.focusItem) { if ((this.focusItem instanceof SZoneLegendItem || this.focusItem instanceof SSCPZZoneLegendItem || this.focusItem instanceof SFHFQZoneLegendItem || this.focusItem instanceof TipelineItem) && this.focusItem.curIndex != -1 ) { this.focusItem.deletePoint(this.focusItem.curIndex); } else { this.undoStack.push(new SGraphDeleteCommand(this, this.focusItem)); this.removeItem(this.focusItem); let a = -1 this.Nodes.forEach((item: any, index: number) => { if (item.id == this.focusItem.id) { a = index } }); if (a > -1) { this.Nodes.splice(a, 1); } let b = -1; this.Markers.forEach((item: any, index: number) => { if (item.id == this.focusItem.id) { b = index } }); if (b > -1) { this.Markers.splice(b, 1); } let c = -1; this.Relations.forEach((item: any, index: number) => { if (item.id == this.focusItem.id) { c = index } }); if (c > -1) { this.Relations.splice(c, 1); } this.grabItem = null; this.focusItem = null; if (this.view) { this.view.update(); } this.scenceUpdate(this); } } else { //批量删除 if (!this.focusItemList) { return } this.undoStack.push(new SGraphDeleteListCommand(this, this.focusItemList)) this.focusItemList.forEach((focusItem) => { this.removeItem(focusItem); let a = -1 this.Nodes.forEach((item: any, index: number) => { if (item.id == focusItem.id) { a = index } }); if (a > -1) { this.Nodes.splice(a, 1); } let b = -1; this.Markers.forEach((item: any, index: number) => { if (item.id == focusItem.id) { b = index } }); if (b > -1) { this.Markers.splice(b, 1); } let c = -1; this.Relations.forEach((item: any, index: number) => { if (item.id == focusItem.id) { c = index } }); if (c > -1) { this.Relations.splice(c, 1); } }); this.focusItemList = []; this.grabItem = null; this.focusItem = null; if (this.view) { this.view.update(); } this.scenceUpdate(this); } } scenceUpdate(scence: any) { } /** * 对齐指定item * @param v */ changeAlignItem(v: any): void { this.selectContainer.layout(v); } /** * 图层排序 * @param v */ changeOrderItem(v: any): void { this.selectContainer.setOrder(v); } /** * 提取item */ extractItem(): void { console.log(this) } /** * 保存数据 */ saveMsgItem(): any { const Nodes: any = []; const Markers: any = []; const Relations: any = []; this.Nodes.forEach(e => { Nodes.push(e.toData()) }); this.Markers.forEach(e => { Markers.push(e.toData()) }); this.Relations.forEach(e => { Relations.push(e.toData()) }); let element = { Nodes, Markers, Relations } return element } /** * 执行取消操作 */ redo(): void { if (this.grabItem && this.grabItem.redo) { this.grabItem.redo() } else { this.undoStack.redo(); this.scenceUpdate(this); } } /** * 执行重做操作执行 */ undo(): void { if (this.grabItem && this.grabItem.undo) { this.grabItem.undo() } else { this.undoStack.undo(); this.scenceUpdate(this); } } /** * 完成事件创建的回调函数 */ finishCreated(item: any) { // let arrList = [] if (this.cmd == 'baseLine') { // arrList = this.Markers; // 对数组遍历防止相同得id注入 let canPush = true; //是否可注入 this.Markers.forEach((arrItem: any) => { if (arrItem.id == item.id) { canPush = false } }) if (canPush) { this.Markers.push(item); this.undoStack.push(new SGraphAddCommand(this, item)); } } this.cmd = 'choice'; this.selectContainer.clear() this.selectContainer.toggleItem(item) setTimeout(() => { this.focusItem = item; }); if (item instanceof SZoneLegendItem || item instanceof SFHFQZoneLegendItem || item instanceof SSCPZZoneLegendItem || item instanceof SCustomLegendItem) { let canPush = true; //是否可注入 this.Nodes.forEach((arrItem: any) => { if (arrItem.id == item.id) { canPush = false } }) if (canPush) { this.Nodes.push(item); //完成后,方可扔到Node节点 this.undoStack.push(new SGraphAddCommand(this, item)); } } // 管道完成后方可保存 if (item instanceof TipelineItem) { let canPush = true; //是否可注入 this.Relations.forEach((arrItem: any) => { if (arrItem.id == item.id) { canPush = false } }) if (canPush) { this.Relations.push(item); this.undoStack.push(new SGraphAddCommand(this, item)); } } this.scenceUpdate(this); } //////////////////////// // 以下为鼠标键盘操作事件 onMouseDown(event: SMouseEvent): any { if (!this.isEditStatus) { return true } // 判断是否开启吸附,并且有吸附的点 if ( this.isAbsorbing && this.highLight && this.highLight.visible ) { event.x = this.highLight.point.x; event.y = this.highLight.point.y; } if (this.grabItem) { if (this.grabItem instanceof TipelineItem) { this.setTipeEndanchor(event) return true; } else if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Create) { this.setLineItem(event) return true; } return this.grabItem.onMouseDown(event); } switch (this.cmd) { // case 'choice': // if (!super.onMouseDown(event)){ // this.addRectSelect(event); // } // break case 'baseLine': this.addLine(event); break; case 'baseText': this.addTextItem(event); break; case 'baseImage': this.addImgItem(event) break; case 'Zone': if (!this.isSelecting) { this.addPolygonItem(event); } else { // 点选创建区域 return super.onMouseDown(event) } break; case 'Image': this.addIconItem(event); break; case 'Line': this.addTipelineItem(event); break; default: return super.onMouseDown(event); } } onMouseMove(event: SMouseEvent): boolean { if (!this.isEditStatus) { return true } if (this.isAbsorbing) { if (!this.highLight) { this.highLight = new HighlightItem(null); this.addItem(this.highLight); } this.highLight.visible = false; this.absorbSpace(event); } if (this.grabItem){ if (this.grabItem instanceof TipelineItem) { const anc = this.clickIsAnchor(event); if (anc) { const p = anc.mapToScene(0, 0) event.x = p.x; event.y = p.y; return this.grabItem.onMouseMove(event); } } else if (this.grabItem instanceof SRectSelectItem) { return this.grabItem.onMouseMove(event); } } return super.onMouseMove(event) } onMouseUp(event: SMouseEvent): boolean { if (!this.isEditStatus) { return true } if (this.grabItem) { if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Edit) { this.setLineItem(event) return true; } else if (this.grabItem instanceof TipelineItem) { this.updateTipeAnc(event); return true; } else if (this.grabItem instanceof SRectSelectItem) { this.groupSelect(); this.removeItem(this.grabItem); this.grabItem = null; if (this.view) { this.view.update() } return true; } return this.grabItem.onMouseUp(event); } return super.onMouseUp(event) } /** * 键盘事件 * * @param event 事件参数 * @return boolean */ onKeyDown(event: KeyboardEvent): any { if (!this.isEditStatus) { return true } if (this.grabItem) { this.grabItem.onKeyDown(event); if (event.code == "Escape") { const item = this.grabItem; this.grabItem = null this.removeItem(item); if (this.view) { this.view.update() } this.setCmd = 'choice' } } // 删除键功能 if (event.code == 'Delete') { this.deleiteItem() } // 删除键功能--兼容苹果mac if (event.code == 'Backspace' && this.isMac){ this.deleiteItem() } // 复制粘贴 if (event.ctrlKey && !event.repeat) { if (event.code == 'KeyC') { console.log('ctrl c') this.copy() } else if (event.code == 'KeyV') { console.log('ctrl v') this.paste() } } return false } /** * 复制 * */ copy(){ if (this.selectContainer.itemList.length) { this.copyString = { Nodes: [], Markers: [], Relations: [] }; this.selectContainer.itemList.forEach(t => { const type = this.itemToType(t); if (type) { const data = JSON.parse(JSON.stringify(t.toData())) data.ID = '' if (data.Type == 'Image') { data.AnchorList = [] } this.copyString[type].push(data) } }) // 生成复制字符串 console.log(this.copyString) return // 获取input dom const input = document.createElement('input'); input.setAttribute('id', 'COPYINPUT') input.value = JSON.stringify(this.copyString) document.body.appendChild(input); input.select() document.execCommand('copy'); input.style.display='none'; console.log(input.value, Date.now()); document.body.removeChild(input) } } /** * 粘贴 * */ paste(){ const parserData = new STopologyParser(null); // 需要深拷贝 parserData.parseData(JSON.parse(JSON.stringify(this.copyString))) // 不需要复制区域 // parserData.zoneLegendList.forEach(t => { // if (t instanceof SCustomLegendItem) { // if (this.view) { // t.pos.x += 10 / this.view.scale // t.pos.y += 10 / this.view.scale // } // this.addItem(t) // this.Nodes.push(t); // graphItemList.push(t) // } // // 加到node // // 加命令 // }) const graphItemList = []; parserData.imageLegendList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Nodes.push(t); graphItemList.push(t) }) parserData.imageMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.lineMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.textMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.relationList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale t.moveToOrigin(t.pos.x, t.pos.y) } t.moveable = true; this.addItem(t) this.Relations.push(t); graphItemList.push(t) }) this.scenceUpdate(this); if (graphItemList.length) { this.AddListCommand(graphItemList) } } /** * 跨页面粘贴 * */ crossPagePaste(crossPageString: string){ try { console.log(crossPageString); const pageObj = JSON.parse(crossPageString) const parserData = new STopologyParser(null); // 需要深拷贝 parserData.parseData(JSON.parse(JSON.stringify(pageObj))) // 不需要复制区域 // parserData.zoneLegendList.forEach(t => { // if (t instanceof SCustomLegendItem) { // if (this.view) { // t.pos.x += 10 / this.view.scale // t.pos.y += 10 / this.view.scale // } // this.addItem(t) // this.Nodes.push(t); // graphItemList.push(t) // } // // 加到node // // 加命令 // }) const graphItemList = []; parserData.imageLegendList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Nodes.push(t); graphItemList.push(t) }) parserData.imageMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.lineMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.textMarkerList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale } t.moveable = true; this.addItem(t) this.Markers.push(t); graphItemList.push(t) }) parserData.relationList.forEach(t => { if (this.view) { t.pos.x += 10 / this.view.scale t.pos.y += 10 / this.view.scale t.moveToOrigin(t.pos.x, t.pos.y) } t.moveable = true; this.addItem(t) this.Relations.push(t); graphItemList.push(t) }) this.scenceUpdate(this); if (graphItemList.length) { this.AddListCommand(graphItemList) } } catch (e) { console.log(e); } } /** 类型转换 */ itemToType(obj:SGraphItem):String{ if (obj instanceof STextMarkerItem) { return 'Markers' } else if (obj instanceof SImageMarkerItem) { return 'Markers' } else if (obj instanceof SLineMarkerItem) { return 'Markers' } else if (obj instanceof SZoneLegendItem) { return 'Nodes' } else if (obj instanceof SFHFQZoneLegendItem) { return 'Nodes' } else if (obj instanceof SSCPZZoneLegendItem) { return 'Nodes' } else if (obj instanceof SImageLegendItem) { return 'Nodes' } else if (obj instanceof TipelineItem) { return 'Relations' } return ''; } /** * 鼠标双击事件 * * @param event 事件参数 * @return boolean */ onDoubleClick(event: SMouseEvent): boolean { if (!this.isEditStatus) { return true } else { return super.onDoubleClick(event); } } // Function onDoubleClick() /** * 设置管线结束锚点 * */ setTipeEndanchor(event: SMouseEvent): void { if (this.grabItem instanceof TipelineItem) { const anc = this.clickIsAnchor(event); if (anc) { const p = anc.mapToScene(0, 0) anc.isConnected = true; event.x = p.x; event.y = p.y; if (this.grabItem.status == SItemStatus.Create) { if (this.grabItem.pointList.length) { this.grabItem.endAnchor = anc; anc.parent ?.connect('changePos', this.grabItem, this.grabItem.changePos) } this.grabItem.anchor2ID = anc.id this.grabItem.node2Id = anc.parent.id this.grabItem.onMouseDown(event) this.grabItem.status = SItemStatus.Normal; this.finishCreated(this.grabItem) return } } this.grabItem.onMouseDown(event) } } /** * 管线item修改锚点 * */ updateTipeAnc(event: SMouseEvent): void { if (this.grabItem instanceof TipelineItem) { const anc = this.clickIsAnchor(event); if (anc) { const p = anc.mapToScene(0, 0) event.x = p.x; event.y = p.y; if (this.grabItem.status == SItemStatus.Edit) { if (this.grabItem.curIndex == 0) { if (this.grabItem.startAnchor) { this.grabItem.startAnchor.isConnected = false this.grabItem.startAnchor.parent.disconnect('changePos', this.grabItem); } anc.isConnected = true; this.grabItem.startAnchor = anc; this.grabItem.anchor1ID = anc.id this.grabItem.node1Id = anc.parent.id anc.parent.connect('changePos', this.grabItem, this.grabItem.changePos) } if (this.grabItem.curIndex == this.grabItem.pointList.length - 1) { if (this.grabItem.endAnchor) { this.grabItem.endAnchor.isConnected = false this.grabItem.endAnchor.parent.disconnect('changePos', this.grabItem); } anc.isConnected = true; this.grabItem.endAnchor = anc; this.grabItem.anchor2ID = anc.id this.grabItem.node2Id = anc.parent.id anc.parent.connect('changePos', this.grabItem, this.grabItem.changePos) } } this.grabItem.onMouseUp(event) return } else { if (this.grabItem.status == SItemStatus.Edit) { if (this.grabItem.curIndex == 0) { if (this.grabItem.startAnchor) { this.grabItem.startAnchor.isConnected = false this.grabItem.startAnchor.parent.disconnect('changePos', this.grabItem); this.grabItem.startAnchor = null; this.grabItem.anchor1ID = '' this.grabItem.node1Id = '' } } if (this.grabItem.curIndex == this.grabItem.pointList.length - 1) { if (this.grabItem.endAnchor) { this.grabItem.endAnchor.isConnected = false this.grabItem.endAnchor.parent.disconnect('changePos', this.grabItem); this.grabItem.endAnchor = null; this.grabItem.anchor2ID = '' this.grabItem.node2Id = '' } } } this.grabItem.onMouseUp(event) return } } } /** * 设置直线结束Item * */ setLineItem(event: SMouseEvent): void { if (this.grabItem instanceof SLineMarkerItem) { const item = this.clickIsItem(event); // 鼠标点是否在某个item内 if (item) { let scenePoint = item.boundingRect().center(); const p = item.mapToScene(scenePoint.x, scenePoint.y); event.x = p.x; event.y = p.y; if (this.grabItem.status == SItemStatus.Create) { // 点击在item内、创建状态且端点列表不为空时将直线结束端点和item绑定 if (this.grabItem.line.length) { if (this.grabItem.startItem ?.id == item.id) { this.grabItem.endItem = null; } else { this.grabItem.endItem = item; this.grabItem.line[1] = new SPoint(event.x, event.y); item.connect('onMove', this.grabItem, this.grabItem.changePos); } } this.grabItem.onMouseDown(event); return } else if (this.grabItem.status == SItemStatus.Edit) { // 点击在item内、编辑状态且点击的为结束端点时 if (this.grabItem.curIndex == 1) { // 直线关联的起始item是直线结束端点所在的item时,不吸附在点击item中心并将直线关联的结束item置为null if (this.grabItem.startItem ?.id == item.id) { this.grabItem.endItem = null; } else {// 反正吸附,关联 this.grabItem.endItem = item; this.grabItem.line[1] = new SPoint(event.x, event.y); item.connect('onMove', this.grabItem, this.grabItem.changePos); } } else if (this.grabItem.curIndex == 0) { if (this.grabItem.endItem ?.id == item.id) { this.grabItem.startItem = null; } else { this.grabItem.startItem = item; this.grabItem.line[0] = new SPoint(event.x, event.y); item.connect('onMove', this.grabItem, this.grabItem.changePos); } } } } else { // 如果不在item内且点击的是直线的某个端点,将端点的关联item置为null if (this.grabItem.line.length && this.grabItem.curIndex != -1) { if (this.grabItem.curIndex == 1) { this.grabItem.endItem = null; } else if (this.grabItem.curIndex == 0) { this.grabItem.startItem = null; } } else { this.grabItem.onMouseDown(event); return } } // if (this.grabItem.status == SItemStatus.Create) { // // 鼠标点是否在某个item内 // if (item) { // let scenePoint = item.boundingRect().center(); // const p = item.mapToScene(scenePoint.x, scenePoint.y); // event.x = p.x; // event.y = p.y; // if (this.grabItem.line.length && this.grabItem.curIndex == -1) { // this.grabItem.endItem = item; // this.grabItem.line[1] = new SPoint(event.x, event.y); // item.connect('onMove', this.grabItem, this.grabItem.changePos); // } // this.grabItem.onMouseDown(event); // return // } else { // if (this.grabItem.line.length && this.grabItem.curIndex != -1) { // if (this.grabItem.curIndex == 1) { // this.grabItem.endItem = null; // } else if (this.grabItem.curIndex == 0) { // this.grabItem.startItem = null; // } // } // } // } else if (this.grabItem.status == SItemStatus.Edit) { // if (this.grabItem.curIndex == 1) { // this.grabItem.endItem = item; // this.grabItem.line[1] = new SPoint(event.x, event.y); // item.connect('onMove', this.grabItem, this.grabItem.changePos); // } else if (this.grabItem.curIndex == 0) { // this.grabItem.startItem = item; // this.grabItem.line[0] = new SPoint(event.x, event.y); // item.connect('onMove', this.grabItem, this.grabItem.changePos); // } // } this.grabItem.onMouseUp(event); } } /** * 划线时点击位置是否是锚点 * * @param event 事件 * @param len 限制距离 * @return 点击的锚点 * */ clickIsAnchor(event: SMouseEvent): SAnchorItem | null { let minAnchor = null; let len: number = -1; this.Nodes.forEach(image => { // image.showAnchor = false; if (image.anchorList && image.anchorList.length) { if(image.img && image.img instanceof SImageItem) { let scenePoint = image.img.mapFromScene(event.x, event.y); if (image.img.contains(scenePoint.x, scenePoint.y)) { let anchor = image.anchorList[0] let anchorPoint = anchor.mapToScene(0, 0); let dis = SMathUtil.pointDistance( event.x, event.y, anchorPoint.x, anchorPoint.y ); console.log(dis) if (len < 0) { minAnchor = anchor; len = dis; } if (dis < len) { minAnchor = anchor; len = dis; } } // let scenePoint = image.mapFromScene(event.x, event.y); // if (image.contains(scenePoint.x, scenePoint.y)) { // image.anchorList.forEach(anchor => { // let anchorPoint = anchor.mapToScene(0, 0); // let dis = SMathUtil.pointDistance( // event.x, // event.y, // anchorPoint.x, // anchorPoint.y // ); // if (len < 0) { // len = anchor.sceneDis; // } // if (dis < len) { // minAnchor = anchor; // len = dis; // } // }) } } }) console.log('-----------------------') console.log(minAnchor) console.log('-----------------------') // if (minAnchor&&minAnchor.parent) { // minAnchor.parent.showAnchor = true // } return minAnchor; } /** * 划线时点击位置是在文本,图片,,区域内 * * @param event 事件 * @return 点击的item * */ clickIsItem(event: SMouseEvent): SGraphItem | null { let minIten = null; let len: number = -1; let itemList = this.Nodes.concat(this.Markers); itemList.forEach(item => { if ( item instanceof STextMarkerItem || item instanceof SImageMarkerItem || item instanceof SZoneLegendItem || item instanceof SFHFQZoneLegendItem || item instanceof SSCPZZoneLegendItem ) { let scenePoint = item.mapFromScene(event.x, event.y); if (item.contains(scenePoint.x, scenePoint.y)) { let dis = SMathUtil.pointDistance( scenePoint.x, scenePoint.y, item.boundingRect().center().x, item.boundingRect().center().y ); if (len < 0) { minIten = item; len = dis; } if (dis < len) { minIten = item; len = dis; } } } }) console.log('-----------------------') console.log(minIten) console.log('-----------------------') return minIten; } /** * 点是否在吸附区域内 * * @param p 要判断的点 * @param minX 空间区域 * @param minY 空间区域 * @param maxX 空间区域 * @param maxY 空间区域 */ static isPointInAbsorbArea( p: SPoint, minX: number, maxX: number, minY: number, maxY: number ): boolean { let rect = new SRect( minX - 1000, minY - 1000, maxX - minX + 2000, maxY - minY + 2000 ); return rect.contains(p.x, p.y); } // Function isPointInAbsorbArea() /** * 吸附空间 * * @param event 鼠标事件对象 * @return boolean 是否找到吸附的对象 */ absorbSpace(event: SMouseEvent): boolean { if (!this.highLight) { return false; } let absorbLen = 1000; if (this.view) { absorbLen = 10 / this.view.scale; } let P = this.absorbSpacePoint(event, absorbLen); if (P.Point) { this.highLight.distance = P.MinDis; this.highLight.point = new SPoint(P.Point.X, -P.Point.Y); this.highLight.visible = true; return true; } else { let L = this.absorbSpaceLine(event, absorbLen); if (L.Line && L.Point) { this.highLight.distance = L.MinDis; this.highLight.point = L.Point; this.highLight.line = L.Line; this.highLight.visible = true; return true; } return false; } } // Function absorbSpace() /** * 吸附空间点 * * @param event 鼠标事件对象 * @param absorbLen 吸附距离 * @return MinDis 吸附的点 */ absorbSpacePoint(event: SMouseEvent, absorbLen: number): MinDis { let minPointDis = Number.MAX_SAFE_INTEGER; let Point; this.spaceList.map((space): void => { if ( EditScence.isPointInAbsorbArea( new SPoint(event.x, event.y), space.minX, space.maxX, space.minY, space.maxY ) ) { space.data.OutLine.forEach((item): void => { let minDis = SMathUtil.getMinDisPoint( new SPoint(event.x, event.y), item ); if ( minDis && minDis.MinDis < absorbLen && minDis.MinDis < minPointDis ) { minPointDis = minDis.MinDis; Point = minDis.Point; } }); } }); return { MinDis: minPointDis, Point: Point }; } // Function absorbSpacePoint() /** * 吸附空间线 * * @param event 鼠标事件对象 * @param absorbLen 吸附距离 * @return PointToLine 吸附的线 */ absorbSpaceLine(event: SMouseEvent, absorbLen: number): PointToLine { let minPointDis = Number.MAX_SAFE_INTEGER; let Point, Line; this.spaceList.forEach((space): void => { if ( EditScence.isPointInAbsorbArea( new SPoint(event.x, event.y), space.minX, space.maxX, space.minY, space.maxY ) ) { space.data.OutLine.forEach((item): void => { let minDisLine = SMathUtil.getMinDisLine( new SPoint(event.x, event.y), item ); if ( minDisLine && minDisLine.MinDis < absorbLen && minDisLine.MinDis < minPointDis ) { minPointDis = minDisLine.MinDis; Point = minDisLine.Point; Line = minDisLine.Line; } }); } }); return { MinDis: minPointDis, Point: Point, Line: Line }; } // Function absorbSpaceLine() /** * 添加多个item命令 * @param focusItemList 鼠标事件对象 */ AddListCommand(focusItemList: any[]): void { this.undoStack.push(new SGraphAddListCommand(this, focusItemList)); } /** * 选中状态方法 * @param item 鼠标事件对象 */ toggleItem(item: SGraphItem): void { this.selectContainer.clear() this.selectContainer.toggleItem(item) } /** * 图标旋转更新角度 * * @param ang 旋转角度 */ updateItemAng(ang: number) :void{ if (this.focusItem) { if (this.focusItem instanceof SImageLegendItem) { const oldMsg = this.focusItem.img.rotate; const newMsg = ang; this.focusItem.img.rotate = ang; this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem.img, "rotate", oldMsg, newMsg)); this.scenceUpdate(this); } } } /** * 框选 */ addRectSelect(event: SMouseEvent) { let point = new SPoint(event.x, event.y); let rect = new SRectSelectItem(null, point); this.addItem(rect); this.grabItem = rect; } /** * 计算框选交集 */ groupSelect(){ this.selectContainer.clear() if (this.grabItem instanceof SRectSelectItem) { const rect = this.grabItem.boundingRect(); this.arrToSelect(this.Nodes, rect) this.arrToSelect(this.Markers, rect) this.arrToSelect(this.Relations, rect) } } /** * 选中item:框选 */ private arrToSelect(arr: SGraphItem[], rect:SRect){ if(Array.isArray(arr) && arr.length) { arr.forEach(t => { if (t.parent) { let temp = t.boundingRect(); let lefttop = t.mapToScene(temp.left, temp.top) let rightbottom = t.mapToScene(temp.right, temp.bottom) let r = new SRect(lefttop, rightbottom) if (rect.isIn(r)){ this.selectContainer.toggleItem(t) } } }) } } }