import { SMouseEvent, SUndoStack } from "@saga-web/base"; import { SGraphScene, SGraphLayoutType, SAnchorItem } from '@saga-web/graph/lib'; import { SFloorParser, SLineItem, SPolylineItem, SItemStatus, ItemOrder, STooltipItem, ItemColor } 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'; /** * 在线绘图 * * @author 韩耀龙 */ export class EditScence extends SGraphScene { undoStack = new SUndoStack(); /** 命令 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 = false; /** 是否开启吸附 */ isAbsorbing: boolean = false; /** 吸附展示item */ highLight: HighlightItem | null = null; /** 当前选中焦点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 } constructor() { super(); // // 选择绑定选额item事件 this.selectContainer.connect("listChange", this, this.listChange); ItemColor.spaceColor = new SColor("#A4ABB22B") ItemColor.wallColor = new SColor("#A7AEB3FF") ItemColor.columnColor = new SColor("#A7AEB3FF") ItemColor.virtualWallColor = new SColor("#A7AEB3FF") ItemColor.selectColor = new SColor("#84A0BB2B") ItemColor.spaceBorderColor = new SColor("#A7AEB3FF") } /** 绘制图例样式 */ _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 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: 2 } } const item = new SLineMarkerItem(null, data); item.status = SItemStatus.Create; item.zOrder = ItemOrder.lineOrder; 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); } this.scenceUpdate(this); 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; item.zOrder = ItemOrder.polylineOrder 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; item.zOrder = ItemOrder.polylineOrder 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; } this.scenceUpdate(this); 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: 0, color: '', TextPos: { X: 0, Y: 0 } }, } 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.Create; Polylines.zOrder = ItemOrder.polygonOrder; // Polylines.moveable = true; this.addItem(Polylines); this.Nodes.push(Polylines); Polylines.connect("finishCreated", this, this.finishCreated); this.grabItem = Polylines; this.focusItem = Polylines; this.scenceUpdate(this); } /** * 点选创建区域 */ 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: 12, color: '', FID: item.data.SourceId, TextPos: { X: item.data.Location.Points[0].X, Y: -item.data.Location.Points[0].Y } }, } 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`), Url: '', } } const item = new SImageMarkerItem(null, data); item.zOrder = ItemOrder.imageOrder; 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: '', Font: 12, BackgroundColor: '#f7f9fa' } } const item = new STextMarkerItem(null, data); item.moveTo(event.x, event.y); item.selectable = true; item.moveable = true; item.zOrder = ItemOrder.textOrder; this.addItem(item); this.Markers.push(item); this.grabItem = item; this.focusItem = item; this.cmd = 'choice'; this.finishCreated(item); this.scenceUpdate(this); } /** * 增加图标lenged图标 */ addIconItem(event: SMouseEvent): void { //获取信息工程化相关参数 const InfoSystemId = this._legend.InfoSystemId ? this._legend.InfoSystemId : ''; const LegendData: Legend = { ID: uuid(), Name: this._legend.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无关 sWidth: 24, //icon 的宽 sHeight: 24, //icon 的高 font: 12, //font color: '', //字体颜色 GraphCategoryId: this._legend.GraphCategoryId, InfoSystemId: InfoSystemId //信息工程话分类ID分类 }, } const item = new SImageLegendItem(null, LegendData); this.cmd = 'choice'; item.selectable = true; item.moveable = true; item.zOrder = ItemOrder.markOrder; this.addItem(item); this.Nodes.push(item); this.grabItem = item; this.focusItem = item; this.finishCreated(item); this.scenceUpdate(this); } /** * 更改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.x; this.focusItem.y = p.y - this.focusItem.boundingRect().top + 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.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) { const newMsg = new SColor(fillColor); const oldMsg = this.focusItem.fillColor; this.focusItem.fillColor = new SColor(fillColor); this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "num", oldMsg, newMsg)); } } /** * 更改图例说 * @param num number */ upadatitemExplain(ItemExplain: string): void { if (this.focusItem) { this.focusItem.data.Properties.ItemExplain = ItemExplain; } } /** * 更新工程信息化的相关数据 * @param AttachObjectIds Array */ upadatAttachObjectIds(AttachObjectIds: []): void { if (this.focusItem) { this.focusItem.data.AttachObjectIds = AttachObjectIds; // 重新选中focusitem const item = this.focusItem; this.selectContainer.clear(); this.selectContainer.toggleItem(item) } } /** * 删除指定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.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 = []; if (this.view) { this.view.update(); } this.scenceUpdate(this); } } scenceUpdate(scence: any) { } /** * 对齐指定item * @param v */ changeAlignItem(v: any): void { this.selectContainer.layout(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(); } } /** * 执行重做操作执行 */ undo(): void { if (this.grabItem && this.grabItem.undo) { this.grabItem.undo() } else { this.undoStack.undo(); } } /** * 完成事件创建的回调函数 */ finishCreated(item: any) { let arrList = [] if(this.cmd == 'baseLine'){ arrList = this.Markers } this.cmd = 'choice'; this.selectContainer.clear() this.selectContainer.toggleItem(item) setTimeout(() => { this.focusItem = item; }) this.undoStack.push(new SGraphAddCommand(this, item,arrList)); } //////////////////////// // 以下为鼠标键盘操作事件 onMouseDown(event: SMouseEvent): any { if (!this.isEditStatus) { return super.onMouseDown(event); } // 判断是否开启吸附,并且有吸附的点 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 '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 super.onMouseMove(event); } if (this.isAbsorbing) { if (!this.highLight) { this.highLight = new HighlightItem(null); this.addItem(this.highLight); } this.highLight.visible = false; this.absorbSpace(event); } return super.onMouseMove(event) } onMouseUp(event: SMouseEvent): boolean { 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; } return this.grabItem.onMouseUp(event); } return super.onMouseUp(event) } /** * 键盘事件 * * @param event 事件参数 * @return boolean */ onKeyDown(event: KeyboardEvent): any { if (!this.isEditStatus) { return super.onKeyDown(event); } 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.key == "Enter") { // this.cmd = 0 // } return false } /** * 鼠标双击事件 * * @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 => { if (image.anchorList && image.anchorList.length) { 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('-----------------------') 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)); } }