EditScence.ts 61 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756
  1. import { SMouseEvent, SUndoStack } from "@saga-web/base";
  2. import { SGraphScene, SGraphLayoutType, SAnchorItem } from '@saga-web/graph/lib';
  3. import { SFloorParser, SLineItem, SPolylineItem, SItemStatus, ItemOrder, STooltipItem, ItemColor, Transparency, SPolygonItem } from "@saga-web/big";
  4. import { SGraphItem, SLineStyle, SGraphPropertyCommand, SImageItem, STextItem, SGraphPointListInsert, SGraphPointListDelete, SGraphPointListUpdate, SGraphAddCommand } from "@saga-web/graph/lib";
  5. import { SGraphAddListCommand } from "./SGraphAddListCommand"
  6. import { SGraphDeleteCommand } from "./SGraphDeleteCommand"
  7. import { SGraphDeleteListCommand } from "./SGraphDeleteListCommand"
  8. import { SZoneLegendItem } from "@/lib/items/SZoneLegendItem";
  9. import { SSCPZZoneLegendItem } from "@/lib/items/SSCPZZoneLegendItem";
  10. import { SFHFQZoneLegendItem } from "@/lib/items/SFHFQZoneLegendItem";
  11. import { SImageLegendItem } from "@/lib/items/SImageLegendItem";
  12. import { TipelineItem } from "@/lib/items/TipelineItem";
  13. import { SImageMarkerItem } from "@/lib/items/SImageMarkerItem"
  14. import { SPoint, SFont, SColor, SRect } from '@saga-web/draw/lib';
  15. import { Legend } from '@/lib/types/Legend';
  16. import { Relation } from '@/lib/types/Relation';
  17. import { uuid } from "@/components/mapClass/until";
  18. import { STextMarkerItem } from '@/lib/items/STextMarkerItem';
  19. import { SLineMarkerItem } from '@/lib/items/SLineMarkerItem';
  20. import { SSpaceItem } from '@saga-web/big/lib/items/floor/SSpaceItem';
  21. import { SMathUtil } from '@saga-web/big/lib/utils/SMathUtil';
  22. import { MinDis } from '@saga-web/big/lib/types/MinDis';
  23. import { HighlightItem } from '@/lib/items/HighlightItem';
  24. import { TimeSelect } from 'element-ui';
  25. import { STopologyParser } from '@/lib/parsers/STopologyParser';
  26. import { SCustomLegendItem } from '@/lib/items/SCustomLegendItem';
  27. /**
  28. * 在线绘图
  29. *
  30. * @author 韩耀龙
  31. */
  32. export class EditScence extends SGraphScene {
  33. undoStack = new SUndoStack();
  34. /** 命令 1 绘制直线 */
  35. private cmd = 'choice';
  36. /** 获取当前状态 */
  37. get getCmd(): string {
  38. return this.cmd;
  39. }
  40. /** 编辑当前状态 */
  41. set setCmd(cmd: string) {
  42. if (cmd == 'choice') {
  43. this.grabItem = null;
  44. }
  45. this.cmd = cmd;
  46. if (this.focusItem) {
  47. // 取消操作
  48. this.focusItem.cancelOperate();
  49. this.focusItem = null;
  50. // this.selectContainer.clear()
  51. }
  52. if (this.view) {
  53. this.view.update();
  54. }
  55. };
  56. /** 绘制区域时 是否为点选 */
  57. isSelecting: boolean = true;
  58. /** 是否开启吸附 */
  59. isAbsorbing: boolean = false;
  60. /** 吸附展示item */
  61. highLight: HighlightItem | null = null;
  62. /** 当前选中焦点Item */
  63. focusItem: SGraphItem | null = null;
  64. /** 当前选中焦点ItemList */
  65. focusItemList: SGraphItem[] | null = null;
  66. /**图例节点 */
  67. Nodes: any = []; // 图例节点,所有与工程信息化相关的图例(图标类型与区域)
  68. /**图例节点 */ // 与工程信息无关的标识对象(增加文本注释,图上的图片说明)
  69. Markers: any = [];
  70. /** 管线对象 */
  71. Relations: any = [];
  72. _isEditStatus: Boolean = true; // 是否可编辑
  73. set isEditStatus(bol: Boolean): void {
  74. this._isEditStatus = bol;
  75. }
  76. get isEditStatus(): Boolean {
  77. return this._isEditStatus
  78. }
  79. //复制粘贴
  80. copyString = {
  81. Nodes: [],
  82. Markers: [],
  83. Relations: []
  84. };
  85. constructor() {
  86. super();
  87. // // 选择绑定选额item事件
  88. this.selectContainer.connect("listChange", this, this.listChange);
  89. ItemColor.spaceColor = new SColor("#f0f0f0")
  90. ItemColor.wallColor = new SColor("#d4d4d4")
  91. ItemColor.columnColor = new SColor("#d4d4d4")
  92. ItemColor.virtualWallColor = new SColor("#d4d4d4")
  93. ItemColor.selectColor = new SColor("#f0f0f0")
  94. ItemColor.spaceBorderColor = new SColor("#d4d4d4")
  95. }
  96. /** 绘制图例样式 */
  97. _legend: any | null = null;
  98. get getlegend(): any {
  99. return this._legend;
  100. };
  101. set setlegend(obj: any) {
  102. this._legend = obj;
  103. }
  104. /** fid=>item映射,由解析器存入 */
  105. fidToItem = {}
  106. /**
  107. * 监听变化
  108. * @param obj 变化后的对象
  109. */
  110. listChange(obj: any) {
  111. let itemType: string = 'equipment';
  112. this.focusItemList = obj.itemList;
  113. if (obj.itemList[0] instanceof STextMarkerItem) {
  114. itemType = 'baseText'
  115. } else if (obj.itemList[0] instanceof SImageMarkerItem) {
  116. itemType = 'baseImage'
  117. } else if (obj.itemList[0] instanceof SLineMarkerItem) {
  118. itemType = 'baseLine'
  119. } else if (obj.itemList[0] instanceof SZoneLegendItem) {
  120. itemType = 'Zone'
  121. } else if (obj.itemList[0] instanceof SFHFQZoneLegendItem) {
  122. itemType = 'Zone'
  123. } else if (obj.itemList[0] instanceof SSCPZZoneLegendItem) {
  124. itemType = 'Zone'
  125. } else if (obj.itemList[0] instanceof SCustomLegendItem) {
  126. itemType = 'Zone'
  127. } else if (obj.itemList[0] instanceof SImageLegendItem) {
  128. itemType = 'Image'
  129. } else if (obj.itemList[0] instanceof TipelineItem) {
  130. itemType = 'Line'
  131. } else if (obj.itemList[0] instanceof SSpaceItem) { // 点选
  132. this.clickToAddArea(obj.itemList[0]);
  133. return
  134. } else {
  135. itemType = ''
  136. };
  137. if (obj.itemList.length == 1) {
  138. // 获取聚焦item
  139. this.focusItem = obj.itemList[0]
  140. } else {
  141. this.focusItem = null
  142. }
  143. let msg = {
  144. itemList: obj.itemList,
  145. itemType,
  146. }
  147. this.emitChange(msg)
  148. }
  149. emitChange(msg: any) {
  150. }
  151. /**
  152. * 增加线段item
  153. */
  154. addLine(event: SMouseEvent): boolean {
  155. const clickItem = this.clickIsItem(event);
  156. if (clickItem) {
  157. let centerPoint = clickItem.boundingRect().center();
  158. const p = clickItem.mapToScene(centerPoint.x, centerPoint.y);
  159. event.x = p.x;
  160. event.y = p.y;
  161. }
  162. const data = {
  163. /** ID */
  164. ID: uuid(),
  165. /** 名称 */
  166. Name: '直线',
  167. /** 图标(Image),线类型(Line) */
  168. Type: "Line",
  169. /** 位置 */
  170. Pos: { X: 0, Y: 0 },
  171. /** 由应用自己定义 */
  172. Properties: {
  173. IconUrl: require("../../assets/images/t-line-hover.png"),
  174. Line: [{ X: event.x, Y: event.y }],
  175. LineWidth: 1,
  176. StrokeColor: "#bdc3c8"
  177. }
  178. }
  179. const item = new SLineMarkerItem(null, data);
  180. item.status = SItemStatus.Create;
  181. item.selectable = true;
  182. this.addItem(item);
  183. // this.Markers.push(item);
  184. item.connect("finishCreated", this, this.finishCreated);
  185. this.grabItem = item;
  186. this.focusItem = item;
  187. // 起始item点
  188. item.startItem = clickItem;
  189. if (clickItem) {
  190. clickItem.connect('onMove', item, item.changePos);
  191. }
  192. return true
  193. }
  194. /**
  195. * 增加折线item
  196. */
  197. addPolylineItem(event: SMouseEvent): boolean {
  198. const point = new SPoint(event.x, event.y)
  199. const item = new TipelineItem(null, [point]);
  200. //设置状态
  201. item.selectable = true;
  202. item.status = SItemStatus.Create;
  203. this.addItem(item);
  204. item.connect("finishCreated", this, this.finishCreated);
  205. this.grabItem = item;
  206. this.focusItem = item;
  207. return true
  208. }
  209. /**
  210. * 增加管道 lenged
  211. */
  212. addTipelineItem(event: SMouseEvent): boolean {
  213. const anc = this.clickIsAnchor(event);
  214. if (anc) {
  215. const p = anc.mapToScene(0, 0)
  216. anc.isConnected = true;
  217. event.x = p.x;
  218. event.y = p.y;
  219. }
  220. const LegendData: Relation = {
  221. ID: uuid(),
  222. Name: this._legend.Name,
  223. GraphElementId: this._legend.Id,
  224. PointList: [{ X: event.x, Y: event.y }],
  225. LineType: "Line",
  226. Properties: {
  227. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  228. LineDash: this._legend.LineDash,
  229. LineWidth: this._legend.LineWidth,
  230. Color: this._legend.Color,
  231. },
  232. }
  233. const item = new TipelineItem(null, LegendData);
  234. //设置状态
  235. item.selectable = true;
  236. item.status = SItemStatus.Create;
  237. this.addItem(item);
  238. // this.Relations.push(item);
  239. item.connect("finishCreated", this, this.finishCreated);
  240. this.grabItem = item;
  241. this.focusItem = item;
  242. // 起始锚点
  243. item.startAnchor = anc;
  244. if (anc) {
  245. anc.parent ?.connect('changePos', item, item.changePos)
  246. item.anchor1ID = anc.id;
  247. item.node1Id = anc.parent.id;
  248. }
  249. return true
  250. }
  251. /**
  252. * 增加多边形item lenged
  253. */
  254. addPolygonItem(event: SMouseEvent): void {
  255. const SubType = this._legend.SubType ? this._legend.SubType : '';
  256. const LegendData: Legend = {
  257. ID: uuid(),
  258. Name: this._legend.Name,
  259. GraphElementType: this._legend.Type,
  260. Num: 1,
  261. GraphElementId: this._legend.Id,
  262. AttachObjectIds: [],
  263. Type: "Zone",
  264. Pos: { X: event.x, Y: event.y },
  265. OutLine: [{ X: event.x, Y: event.y }],
  266. SubType: SubType,
  267. Properties: {
  268. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  269. StrokeColor: this._legend.Color,
  270. FillColor: this._legend.FillColor,
  271. LineDash: this._legend.LineDash,
  272. LineWidth: this._legend.LineWidth,
  273. font: 14,
  274. color: "#1F2429",
  275. TextPos: { X: 0, Y: 0 },
  276. InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [],
  277. InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '',
  278. InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : []
  279. },
  280. }
  281. let Polylines = null;
  282. if (SubType == "SCPZ") {
  283. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  284. } else if (SubType == "FHFQ") {
  285. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  286. } else if (SubType == "CUSTOM") {
  287. Polylines = new SCustomLegendItem(null, LegendData);
  288. } else {
  289. Polylines = new SZoneLegendItem(null, LegendData);
  290. }
  291. Polylines.selectable = true;
  292. //设置状态
  293. Polylines.status = SItemStatus.Create;
  294. // Polylines.moveable = true;
  295. this.addItem(Polylines);
  296. Polylines.connect("finishCreated", this, this.finishCreated);
  297. this.grabItem = Polylines;
  298. this.focusItem = Polylines;
  299. }
  300. /**
  301. * 点选创建区域
  302. */
  303. clickToAddArea(item: SSpaceItem): void {
  304. if (this.cmd != 'Zone') {
  305. return
  306. }
  307. if (this.isSelecting && this._legend) {
  308. //@ts-ignore
  309. item.isExtracted = true
  310. const SubType = this._legend.SubType ? this._legend.SubType : '';
  311. const LegendData: Legend = {
  312. ID: uuid(),
  313. Name: this._legend.Name,
  314. GraphElementType: this._legend.Type,
  315. Num: 1,
  316. GraphElementId: this._legend.Id,
  317. AttachObjectIds: [],
  318. Type: "Zone",
  319. Pos: { X: item.x, Y: item.y },
  320. OutLine: item.pointArr[0],
  321. SubType: SubType,
  322. Properties: {
  323. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  324. StrokeColor: this._legend.Color,
  325. FillColor: this._legend.FillColor,
  326. LineDash: this._legend.LineDash,
  327. LineWidth: this._legend.LineWidth,
  328. font: 14,
  329. color: "#1F2429",
  330. FID: item.data.SourceId,
  331. TextPos: { X: item.data.Location.Points[0].X, Y: -item.data.Location.Points[0].Y },
  332. InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [],
  333. InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '',
  334. InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : []
  335. },
  336. }
  337. let Polylines = null;
  338. if (SubType == "SCPZ") {
  339. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  340. } else if (SubType == "FHFQ") {
  341. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  342. } else {
  343. Polylines = new SZoneLegendItem(null, LegendData);
  344. }
  345. Polylines.selectable = true;
  346. //设置状态
  347. Polylines.status = SItemStatus.Normal;
  348. this.addItem(Polylines);
  349. // this.Nodes.push(Polylines);
  350. this.finishCreated(Polylines)
  351. this.focusItem = Polylines;
  352. this.scenceUpdate(this);
  353. }
  354. }
  355. /**
  356. * 增加图片Item mark
  357. */
  358. addImgItem(event: SMouseEvent) {
  359. const data = {
  360. /** ID */
  361. ID: uuid(),
  362. /** 名称 */
  363. Name: '图片',
  364. Num: 1,
  365. /** 图标(Image),线类型(Line) */
  366. Type: "Image",
  367. /** 位置 */
  368. Pos: { X: event.x, Y: event.y },
  369. /** 由应用自己定义 */
  370. Properties: {
  371. IconUrl: require(`../../assets/images/t-img-hover.png`),
  372. StrokeColor: "#c0ccda",
  373. Url: '',
  374. }
  375. }
  376. const item = new SImageMarkerItem(null, data);
  377. item.selectable = true;
  378. item.moveable = true;
  379. this.addItem(item);
  380. this.Markers.push(item);
  381. this.grabItem == null;
  382. this.focusItem = item;
  383. this.finishCreated(item);
  384. this.scenceUpdate(this);
  385. }
  386. /**
  387. * 增加文字item
  388. */
  389. addTextItem(event: SMouseEvent): void {
  390. const data = {
  391. /** ID */
  392. ID: uuid(),
  393. /** 名称 */
  394. Name: '文本',
  395. /** 图标 */
  396. Type: "Text",
  397. /** 位置 */
  398. Pos: { X: event.x, Y: event.y },
  399. /** 由应用自己定义 */
  400. Properties: {
  401. IconUrl: require(`../../assets/images/t-text-hover.png`),
  402. Text: '请在右侧属性栏输入文字!',
  403. Color: "#646c73",
  404. Font: 14,
  405. BackgroundColor: "#f7f9facc"
  406. }
  407. }
  408. const item = new STextMarkerItem(null, data);
  409. item.moveTo(event.x, event.y);
  410. item.selectable = true;
  411. item.moveable = true;
  412. this.addItem(item);
  413. this.Markers.push(item);
  414. this.grabItem = null;
  415. this.focusItem = item;
  416. this.cmd = 'choice';
  417. this.finishCreated(item);
  418. this.scenceUpdate(this);
  419. }
  420. /**
  421. * 增加图标lenged图标
  422. */
  423. addIconItem(event: SMouseEvent): void {
  424. //获取信息工程化相关参数
  425. const LegendData: Legend = {
  426. ID: uuid(),
  427. Name: "",
  428. GraphElementType: this._legend.Type,
  429. Num: 1,
  430. GraphElementId: this._legend.Id,
  431. AttachObjectIds: [],
  432. Pos: { X: event.x, Y: event.y },
  433. Scale: { X: 1, Y: 1, Z: 1 }, // 缩放
  434. Rolate: { X: 0, Y: 0, Z: 0 },
  435. Size: { Width: 0, Height: 0 }, // 大小
  436. Type: this._legend.Type,
  437. Properties: {
  438. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  439. Url: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  440. Num: 1, // 此num与信息工程化得num无关
  441. Size: {
  442. Width: this._legend.Size?this._legend.Size.Width?this._legend.Size.Width:32:32, //icon 的宽
  443. Height: this._legend.Size?this._legend.Size.Height?this._legend.Size.Height:32:32, //icon 的高
  444. },
  445. font: 16, //font
  446. color: "#1F2429", //字体颜色
  447. FrameColor: this._legend.FrameColor,
  448. GraphCategoryId: this._legend.GraphCategoryId,
  449. InfoSystemId: this._legend.InfoSystemId ? this._legend.InfoSystemId : '',
  450. InfoTypeId: this._legend.InfoTypeId.length ? this._legend.InfoTypeId : [],// 铺位可视化Typeid(用于编辑工程信息化时默认问题)
  451. InfoLocal: this._legend.InfoLocal.length ? this._legend.InfoLocal : []
  452. },
  453. }
  454. const cmd = this.cmd;
  455. const item = new SImageLegendItem(null, LegendData);
  456. this.cmd = 'choice';
  457. item.selectable = true;
  458. item.moveable = true;
  459. this.addItem(item);
  460. this.Nodes.push(item);
  461. this.grabItem = null;
  462. this.focusItem = item;
  463. this.finishCreated(item);
  464. this.scenceUpdate(this);
  465. if (event.ctrlKey) {
  466. this.cmd = cmd;
  467. }
  468. }
  469. /**
  470. * 更改item对应属性
  471. */
  472. editItemStatus(): void {
  473. }
  474. /**
  475. * 更改文本对应属性
  476. * @param str string 文字内容
  477. */
  478. updatedText(str: string): void {
  479. if (this.focusItem) {
  480. const oldMsg = this.focusItem.text;
  481. const newMsg = str;
  482. this.focusItem.text = str;
  483. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", oldMsg, newMsg));
  484. this.scenceUpdate(this);
  485. }
  486. }
  487. /**
  488. * 更改文本fontSize属性
  489. * @param size number 文字大小
  490. */
  491. updatedFontSize(size: number): void {
  492. if (this.focusItem) {
  493. let old = new SFont(this.focusItem.font);
  494. let font = new SFont(this.focusItem.font);
  495. font.size = size;
  496. this.focusItem.font = font;
  497. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font));
  498. }
  499. }
  500. /**
  501. * 更改线宽属性
  502. * @param lineWidth number 线宽大小
  503. */
  504. updatedLineWidth(lineWidth: number): void {
  505. if (this.focusItem) {
  506. const oldMsg = this.focusItem.lineWidth;
  507. const newMsg = lineWidth;
  508. this.focusItem.lineWidth = lineWidth;
  509. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "lineWidth", oldMsg, newMsg));
  510. }
  511. }
  512. /**
  513. * 更改文本颜色属性
  514. * @param str string 颜色
  515. */
  516. updatedFontColor(color: string): void {
  517. if (this.focusItem) {
  518. const oldMsg = this.focusItem.color;
  519. const newMsg = new SColor(color);
  520. this.focusItem.color = newMsg;
  521. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", oldMsg, newMsg));
  522. }
  523. }
  524. /**
  525. * 更改border颜色
  526. * @param color string 颜色
  527. */
  528. updatedBorderColor(color: string): void {
  529. if (this.focusItem) {
  530. const oldMsg = this.focusItem.strokeColor;
  531. const newMsg = new SColor(color);
  532. this.focusItem.strokeColor = newMsg;
  533. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "strokeColor", oldMsg, newMsg));
  534. }
  535. }
  536. /**
  537. * 更改item宽
  538. * @param width number 颜色
  539. */
  540. updatedWidth(width: number): void {
  541. if (this.focusItem) {
  542. let oldMsg = null;
  543. const newMsg = width;
  544. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  545. oldMsg = this.focusItem.sWidth
  546. this.focusItem.sWidth = width;
  547. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "sWidth", oldMsg, newMsg));
  548. } else {
  549. oldMsg = this.focusItem.width
  550. this.focusItem.width = width;
  551. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "width", oldMsg, newMsg));
  552. }
  553. }
  554. }
  555. /**
  556. * 更改item高
  557. * @param height number 颜色
  558. */
  559. updatedHeight(height: number): void {
  560. if (this.focusItem) {
  561. let oldMsg = null;
  562. const newMsg = height;
  563. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  564. oldMsg = this.focusItem.sHeight;
  565. this.focusItem.sHeight = height;
  566. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "sHeight", oldMsg, newMsg));
  567. } else {
  568. oldMsg = this.focusItem.height;
  569. this.focusItem.height = height;
  570. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "height", oldMsg, newMsg));
  571. }
  572. }
  573. }
  574. /**
  575. * 更改item坐标
  576. * @param x number x x坐标
  577. * @param y number y y坐标
  578. */
  579. updatedPosition(x: number, y: number): void {
  580. if (this.focusItem) {
  581. let p = this.focusItem.mapFromScene(x, y)
  582. // newx - oldx = newleft - oldleft
  583. // 要求的值(新的x坐标) - 旧的x坐标 = 新的左边界(用户输入的值) - 旧的左边界
  584. this.focusItem.x = (p.x - this.focusItem.boundingRect().left) * this.focusItem.inverseScale + this.focusItem.x;
  585. this.focusItem.y = (p.y - this.focusItem.boundingRect().top) * this.focusItem.inverseScale + this.focusItem.y;
  586. if (this.focusItem instanceof SPolylineItem || this.focusItem instanceof SPolygonItem || this.focusItem instanceof SLineItem) {
  587. this.focusItem.moveToOrigin(this.focusItem.x, this.focusItem.y)
  588. }
  589. }
  590. }
  591. /**
  592. * 更改item 背景色坐标
  593. * @param color string 颜色color
  594. */
  595. updatedbackColor(color: string): void {
  596. if (this.focusItem) {
  597. const newMsg = new SColor(color);
  598. const oldMsg = this.focusItem.backgroundColor;
  599. this.focusItem.backgroundColor = new SColor(color);
  600. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "backgroundColor", oldMsg, newMsg));
  601. }
  602. }
  603. /**
  604. * 更改item Url
  605. * @param url string 图片key
  606. */
  607. upadataImageUrl(url: string): void {
  608. if (this.focusItem) {
  609. const newMsg = '/serve/topology-wanda/Picture/query/' + url;
  610. const oldMsg = this.focusItem.url;
  611. this.focusItem.url = newMsg;
  612. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "url", oldMsg, newMsg));
  613. }
  614. }
  615. /**
  616. * 更改item border
  617. * @param val string border类型
  618. */
  619. upadataBorder(val: string): void {
  620. if (this.focusItem) {
  621. let borderStyle = null;
  622. if (val == 'dashed') {
  623. borderStyle = SLineStyle.Dashed;
  624. } else if (val == 'dotted') {
  625. borderStyle = SLineStyle.Dotted;
  626. } else if (val == 'solid') {
  627. borderStyle = SLineStyle.Solid;
  628. }
  629. const newMsg = borderStyle;
  630. const oldMsg = this.focusItem.lineStyle;
  631. this.focusItem.lineStyle = borderStyle;
  632. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "lineStyle", oldMsg, newMsg));
  633. }
  634. }
  635. /**
  636. * 更改item 名称
  637. * @param val string border类型
  638. */
  639. upadataLengedName(val: string): void {
  640. if (this.focusItem && this.focusItem.data) {
  641. const newMsg = val;
  642. const oldMsg = this.focusItem.text;
  643. this.focusItem.text = val;
  644. this.focusItem.name = val;
  645. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", oldMsg, newMsg));
  646. this.scenceUpdate(this);
  647. }
  648. }
  649. /**
  650. * 更改item Num数量
  651. * @param num number item数量 (只对icon设备类)
  652. */
  653. upadatImageNum(num: number): void {
  654. if (this.focusItem && this.focusItem.num) {
  655. const newMsg = num;
  656. const oldMsg = this.focusItem.num;
  657. this.focusItem.num = num;
  658. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "num", oldMsg, newMsg));
  659. }
  660. }
  661. /**
  662. * 更改item Num数量
  663. * @param num number item数量 (只对icon设备类)
  664. */
  665. upadatfillColor(fillColor: string): void {
  666. if (this.focusItem && this.focusItem.fillColor) {
  667. let fillColorT;
  668. if (fillColor.length == 7) {
  669. fillColorT = fillColor + Transparency[15];
  670. if (this.focusItem instanceof SSCPZZoneLegendItem || this.focusItem instanceof SFHFQZoneLegendItem) {
  671. const sc = new SColor(this.focusItem.fillColor);
  672. const alp = ((sc.alpha/255)*100).toFixed()
  673. fillColorT = fillColor + Transparency[alp];
  674. // fillColorT = fillColor + Transparency[80];
  675. }
  676. } else {
  677. fillColorT = fillColor;
  678. }
  679. const newMsg = new SColor(fillColorT);
  680. const oldMsg = this.focusItem.fillColor;
  681. this.focusItem.fillColor = new SColor(fillColorT);
  682. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "fillColor", oldMsg, newMsg));
  683. }
  684. }
  685. /**
  686. * 更改图例说
  687. * @param num number
  688. */
  689. upadatitemExplain(ItemExplain: string): void {
  690. if (this.focusItem) {
  691. this.focusItem.data.Properties.ItemExplain = ItemExplain;
  692. }
  693. }
  694. /**
  695. * 更新工程信息化的相关数据
  696. * @param AttachObjectIds Array
  697. */
  698. upadatAttachObjectIds(AttachObjectIds: []): void {
  699. if (this.focusItem) {
  700. this.focusItem.data.AttachObjectIds = AttachObjectIds;
  701. // 重新选中focusitem
  702. const item = this.focusItem;
  703. this.selectContainer.clear();
  704. this.selectContainer.toggleItem(item);
  705. if (
  706. item instanceof SImageLegendItem ||
  707. item instanceof SZoneLegendItem ||
  708. item instanceof SSCPZZoneLegendItem ||
  709. item instanceof SFHFQZoneLegendItem
  710. ) {
  711. let arr = item.data.AttachObjectIds;
  712. if (arr && arr.length && arr[arr.length - 1].name) {
  713. item.text = arr[arr.length - 1].name;
  714. item.name = arr[arr.length - 1].name;
  715. }
  716. // 绑定工程信息化数据后设置状态
  717. if (item.data.AttachObjectIds && item.data.AttachObjectIds.length) {
  718. item.isActive = true;
  719. } else {
  720. item.isActive = false;
  721. }
  722. }
  723. }
  724. }
  725. /**
  726. * 自定义多边形修改背景色
  727. */
  728. updateCustomBgColor(val: string):void{
  729. if (this.focusItem) {
  730. const newMsg = new SColor(val);
  731. const oldMsg = this.focusItem.fillColor;
  732. this.focusItem.fillColor = new SColor(val)
  733. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "fillColor", oldMsg, newMsg));
  734. }
  735. }
  736. /**
  737. * 自定义多边形修改边框色
  738. */
  739. updateCustomBdColor(val: string):void{
  740. if (this.focusItem) {
  741. const newMsg = new SColor(val);
  742. const oldMsg = this.focusItem.strokeColor;
  743. this.focusItem.strokeColor = new SColor(val)
  744. this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "strokeColor", oldMsg, newMsg));
  745. }
  746. }
  747. /**
  748. * 删除指定item
  749. */
  750. deleiteItem(): void {
  751. if (this.focusItem) {
  752. if ((this.focusItem instanceof SZoneLegendItem ||
  753. this.focusItem instanceof SSCPZZoneLegendItem ||
  754. this.focusItem instanceof SFHFQZoneLegendItem ||
  755. this.focusItem instanceof TipelineItem) &&
  756. this.focusItem.curIndex != -1
  757. ) {
  758. this.focusItem.deletePoint(this.focusItem.curIndex);
  759. } else {
  760. this.undoStack.push(new SGraphDeleteCommand(this, this.focusItem));
  761. this.removeItem(this.focusItem);
  762. let a = -1
  763. this.Nodes.forEach((item: any, index: number) => {
  764. if (item.id == this.focusItem.id) {
  765. a = index
  766. }
  767. });
  768. if (a > -1) {
  769. this.Nodes.splice(a, 1);
  770. }
  771. let b = -1;
  772. this.Markers.forEach((item: any, index: number) => {
  773. if (item.id == this.focusItem.id) {
  774. b = index
  775. }
  776. });
  777. if (b > -1) {
  778. this.Markers.splice(b, 1);
  779. }
  780. let c = -1;
  781. this.Relations.forEach((item: any, index: number) => {
  782. if (item.id == this.focusItem.id) {
  783. c = index
  784. }
  785. });
  786. if (c > -1) {
  787. this.Relations.splice(c, 1);
  788. }
  789. this.grabItem = null;
  790. this.focusItem = null;
  791. if (this.view) {
  792. this.view.update();
  793. }
  794. this.scenceUpdate(this);
  795. }
  796. } else {
  797. //批量删除
  798. if (!this.focusItemList) {
  799. return
  800. }
  801. this.undoStack.push(new SGraphDeleteListCommand(this, this.focusItemList))
  802. this.focusItemList.forEach((focusItem) => {
  803. this.removeItem(focusItem);
  804. let a = -1
  805. this.Nodes.forEach((item: any, index: number) => {
  806. if (item.id == focusItem.id) {
  807. a = index
  808. }
  809. });
  810. if (a > -1) {
  811. this.Nodes.splice(a, 1);
  812. }
  813. let b = -1;
  814. this.Markers.forEach((item: any, index: number) => {
  815. if (item.id == focusItem.id) {
  816. b = index
  817. }
  818. });
  819. if (b > -1) {
  820. this.Markers.splice(b, 1);
  821. }
  822. let c = -1;
  823. this.Relations.forEach((item: any, index: number) => {
  824. if (item.id == focusItem.id) {
  825. c = index
  826. }
  827. });
  828. if (c > -1) {
  829. this.Relations.splice(c, 1);
  830. }
  831. });
  832. this.focusItemList = [];
  833. this.grabItem = null;
  834. this.focusItem = null;
  835. if (this.view) {
  836. this.view.update();
  837. }
  838. this.scenceUpdate(this);
  839. }
  840. }
  841. scenceUpdate(scence: any) {
  842. }
  843. /**
  844. * 对齐指定item
  845. * @param v
  846. */
  847. changeAlignItem(v: any): void {
  848. this.selectContainer.layout(v);
  849. }
  850. /**
  851. * 图层排序
  852. * @param v
  853. */
  854. changeOrderItem(v: any): void {
  855. this.selectContainer.setOrder(v);
  856. }
  857. /**
  858. * 提取item
  859. */
  860. extractItem(): void {
  861. console.log(this)
  862. }
  863. /**
  864. * 保存数据
  865. */
  866. saveMsgItem(): any {
  867. const Nodes: any = [];
  868. const Markers: any = [];
  869. const Relations: any = [];
  870. this.Nodes.forEach(e => {
  871. Nodes.push(e.toData())
  872. });
  873. this.Markers.forEach(e => {
  874. Markers.push(e.toData())
  875. });
  876. this.Relations.forEach(e => {
  877. Relations.push(e.toData())
  878. });
  879. let element = {
  880. Nodes, Markers, Relations
  881. }
  882. return element
  883. }
  884. /**
  885. * 执行取消操作
  886. */
  887. redo(): void {
  888. if (this.grabItem && this.grabItem.redo) {
  889. this.grabItem.redo()
  890. } else {
  891. this.undoStack.redo();
  892. this.scenceUpdate(this);
  893. }
  894. }
  895. /**
  896. * 执行重做操作执行
  897. */
  898. undo(): void {
  899. if (this.grabItem && this.grabItem.undo) {
  900. this.grabItem.undo()
  901. } else {
  902. this.undoStack.undo();
  903. this.scenceUpdate(this);
  904. }
  905. }
  906. /**
  907. * 完成事件创建的回调函数
  908. */
  909. finishCreated(item: any) {
  910. // let arrList = []
  911. if (this.cmd == 'baseLine') {
  912. // arrList = this.Markers;
  913. // 对数组遍历防止相同得id注入
  914. let canPush = true; //是否可注入
  915. this.Markers.forEach((arrItem: any) => {
  916. if (arrItem.id == item.id) {
  917. canPush = false
  918. }
  919. })
  920. if (canPush) {
  921. this.Markers.push(item);
  922. this.undoStack.push(new SGraphAddCommand(this, item));
  923. }
  924. }
  925. this.cmd = 'choice';
  926. this.selectContainer.clear()
  927. this.selectContainer.toggleItem(item)
  928. setTimeout(() => {
  929. this.focusItem = item;
  930. });
  931. if (item instanceof SZoneLegendItem || item instanceof SFHFQZoneLegendItem || item instanceof SSCPZZoneLegendItem || item instanceof SCustomLegendItem) {
  932. let canPush = true; //是否可注入
  933. this.Nodes.forEach((arrItem: any) => {
  934. if (arrItem.id == item.id) {
  935. canPush = false
  936. }
  937. })
  938. if (canPush) {
  939. this.Nodes.push(item); //完成后,方可扔到Node节点
  940. this.undoStack.push(new SGraphAddCommand(this, item));
  941. }
  942. }
  943. // 管道完成后方可保存
  944. if (item instanceof TipelineItem) {
  945. let canPush = true; //是否可注入
  946. this.Relations.forEach((arrItem: any) => {
  947. if (arrItem.id == item.id) {
  948. canPush = false
  949. }
  950. })
  951. if (canPush) {
  952. this.Relations.push(item);
  953. this.undoStack.push(new SGraphAddCommand(this, item));
  954. }
  955. }
  956. this.scenceUpdate(this);
  957. }
  958. ////////////////////////
  959. // 以下为鼠标键盘操作事件
  960. onMouseDown(event: SMouseEvent): any {
  961. if (!this.isEditStatus) {
  962. return true
  963. }
  964. // 判断是否开启吸附,并且有吸附的点
  965. if (
  966. this.isAbsorbing &&
  967. this.highLight &&
  968. this.highLight.visible
  969. ) {
  970. event.x = this.highLight.point.x;
  971. event.y = this.highLight.point.y;
  972. }
  973. if (this.grabItem) {
  974. if (this.grabItem instanceof TipelineItem) {
  975. this.setTipeEndanchor(event)
  976. return true;
  977. } else if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Create) {
  978. this.setLineItem(event)
  979. return true;
  980. }
  981. return this.grabItem.onMouseDown(event);
  982. }
  983. switch (this.cmd) {
  984. case 'baseLine':
  985. this.addLine(event);
  986. break;
  987. case 'baseText':
  988. this.addTextItem(event);
  989. break;
  990. case 'baseImage':
  991. this.addImgItem(event)
  992. break;
  993. case 'Zone':
  994. if (!this.isSelecting) {
  995. this.addPolygonItem(event);
  996. } else {
  997. // 点选创建区域
  998. return super.onMouseDown(event)
  999. }
  1000. break;
  1001. case 'Image':
  1002. this.addIconItem(event);
  1003. break;
  1004. case 'Line':
  1005. this.addTipelineItem(event);
  1006. break;
  1007. default:
  1008. return super.onMouseDown(event);
  1009. }
  1010. }
  1011. onMouseMove(event: SMouseEvent): boolean {
  1012. if (!this.isEditStatus) {
  1013. return true
  1014. }
  1015. if (this.isAbsorbing) {
  1016. if (!this.highLight) {
  1017. this.highLight = new HighlightItem(null);
  1018. this.addItem(this.highLight);
  1019. }
  1020. this.highLight.visible = false;
  1021. this.absorbSpace(event);
  1022. }
  1023. if (this.grabItem){
  1024. if (this.grabItem instanceof TipelineItem) {
  1025. const anc = this.clickIsAnchor(event);
  1026. if (anc) {
  1027. const p = anc.mapToScene(0, 0)
  1028. event.x = p.x;
  1029. event.y = p.y;
  1030. return this.grabItem.onMouseMove(event);
  1031. }
  1032. }
  1033. }
  1034. return super.onMouseMove(event)
  1035. }
  1036. onMouseUp(event: SMouseEvent): boolean {
  1037. if (!this.isEditStatus) {
  1038. return true
  1039. }
  1040. if (this.grabItem) {
  1041. if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Edit) {
  1042. this.setLineItem(event)
  1043. return true;
  1044. } else if (this.grabItem instanceof TipelineItem) {
  1045. this.updateTipeAnc(event);
  1046. return true;
  1047. }
  1048. return this.grabItem.onMouseUp(event);
  1049. }
  1050. return super.onMouseUp(event)
  1051. }
  1052. /**
  1053. * 键盘事件
  1054. *
  1055. * @param event 事件参数
  1056. * @return boolean
  1057. */
  1058. onKeyDown(event: KeyboardEvent): any {
  1059. if (!this.isEditStatus) {
  1060. return true
  1061. }
  1062. if (this.grabItem) {
  1063. this.grabItem.onKeyDown(event);
  1064. if (event.code == "Escape") {
  1065. const item = this.grabItem;
  1066. this.grabItem = null
  1067. this.removeItem(item);
  1068. if (this.view) {
  1069. this.view.update()
  1070. }
  1071. this.setCmd = 'choice'
  1072. }
  1073. }
  1074. // 删除键功能
  1075. if (event.code == 'Delete') {
  1076. this.deleiteItem()
  1077. }
  1078. // 复制粘贴
  1079. if (event.ctrlKey && !event.repeat) {
  1080. if (event.code == 'KeyC') {
  1081. console.log('ctrl c')
  1082. this.copy()
  1083. } else if (event.code == 'KeyV') {
  1084. console.log('ctrl v')
  1085. this.paste()
  1086. }
  1087. }
  1088. return false
  1089. }
  1090. /**
  1091. * 复制
  1092. *
  1093. */
  1094. copy(){
  1095. // const input = document.createElement('input');
  1096. // console.log(1111111111111111111)
  1097. // input.value = 'sfsfsfsf'
  1098. // document.body.appendChild(input);
  1099. // input.select()
  1100. // document.execCommand('copy');
  1101. // input.style.display='none';
  1102. if (this.selectContainer.itemList.length) {
  1103. this.copyString = {
  1104. Nodes: [],
  1105. Markers: [],
  1106. Relations: []
  1107. };
  1108. this.selectContainer.itemList.forEach(t => {
  1109. const type = this.itemToType(t);
  1110. if (type) {
  1111. const data = JSON.parse(JSON.stringify(t.toData()))
  1112. data.ID = ''
  1113. if (data.Type == 'Image') {
  1114. data.AnchorList = []
  1115. }
  1116. this.copyString[type].push(data)
  1117. }
  1118. })
  1119. console.log(this.copyString)
  1120. }
  1121. }
  1122. /**
  1123. * 粘贴
  1124. *
  1125. */
  1126. paste(){
  1127. const parserData = new STopologyParser(null);
  1128. // 需要深拷贝
  1129. parserData.parseData(JSON.parse(JSON.stringify(this.copyString)))
  1130. // 不需要复制区域
  1131. // parserData.zoneLegendList.forEach(t => {
  1132. // if (t instanceof SCustomLegendItem) {
  1133. // if (this.view) {
  1134. // t.pos.x += 10 / this.view.scale
  1135. // t.pos.y += 10 / this.view.scale
  1136. // }
  1137. // this.addItem(t)
  1138. // this.Nodes.push(t);
  1139. // graphItemList.push(t)
  1140. // }
  1141. // // 加到node
  1142. // // 加命令
  1143. // })
  1144. const graphItemList = [];
  1145. parserData.imageLegendList.forEach(t => {
  1146. if (this.view) {
  1147. t.pos.x += 10 / this.view.scale
  1148. t.pos.y += 10 / this.view.scale
  1149. }
  1150. t.moveable = true;
  1151. this.addItem(t)
  1152. this.Nodes.push(t);
  1153. graphItemList.push(t)
  1154. })
  1155. parserData.imageMarkerList.forEach(t => {
  1156. if (this.view) {
  1157. t.pos.x += 10 / this.view.scale
  1158. t.pos.y += 10 / this.view.scale
  1159. }
  1160. t.moveable = true;
  1161. this.addItem(t)
  1162. this.Markers.push(t);
  1163. graphItemList.push(t)
  1164. })
  1165. parserData.lineMarkerList.forEach(t => {
  1166. if (this.view) {
  1167. t.pos.x += 10 / this.view.scale
  1168. t.pos.y += 10 / this.view.scale
  1169. }
  1170. t.moveable = true;
  1171. this.addItem(t)
  1172. this.Markers.push(t);
  1173. graphItemList.push(t)
  1174. })
  1175. parserData.textMarkerList.forEach(t => {
  1176. if (this.view) {
  1177. t.pos.x += 10 / this.view.scale
  1178. t.pos.y += 10 / this.view.scale
  1179. }
  1180. t.moveable = true;
  1181. this.addItem(t)
  1182. this.Markers.push(t);
  1183. graphItemList.push(t)
  1184. })
  1185. parserData.relationList.forEach(t => {
  1186. if (this.view) {
  1187. t.pos.x += 10 / this.view.scale
  1188. t.pos.y += 10 / this.view.scale
  1189. t.moveToOrigin(t.pos.x, t.pos.y)
  1190. }
  1191. t.moveable = true;
  1192. this.addItem(t)
  1193. this.Relations.push(t);
  1194. graphItemList.push(t)
  1195. })
  1196. this.scenceUpdate(this);
  1197. if (graphItemList.length) {
  1198. this.AddListCommand(graphItemList)
  1199. }
  1200. }
  1201. /** 类型转换 */
  1202. itemToType(obj:SGraphItem):String{
  1203. if (obj instanceof STextMarkerItem) {
  1204. return 'Markers'
  1205. } else if (obj instanceof SImageMarkerItem) {
  1206. return 'Markers'
  1207. } else if (obj instanceof SLineMarkerItem) {
  1208. return 'Markers'
  1209. } else if (obj instanceof SZoneLegendItem) {
  1210. return 'Nodes'
  1211. } else if (obj instanceof SFHFQZoneLegendItem) {
  1212. return 'Nodes'
  1213. } else if (obj instanceof SSCPZZoneLegendItem) {
  1214. return 'Nodes'
  1215. } else if (obj instanceof SImageLegendItem) {
  1216. return 'Nodes'
  1217. } else if (obj instanceof TipelineItem) {
  1218. return 'Relations'
  1219. }
  1220. return '';
  1221. }
  1222. /**
  1223. * 鼠标双击事件
  1224. *
  1225. * @param event 事件参数
  1226. * @return boolean
  1227. */
  1228. onDoubleClick(event: SMouseEvent): boolean {
  1229. if (!this.isEditStatus) {
  1230. return true
  1231. } else {
  1232. return super.onDoubleClick(event);
  1233. }
  1234. } // Function onDoubleClick()
  1235. /**
  1236. * 设置管线结束锚点
  1237. *
  1238. */
  1239. setTipeEndanchor(event: SMouseEvent): void {
  1240. if (this.grabItem instanceof TipelineItem) {
  1241. const anc = this.clickIsAnchor(event);
  1242. if (anc) {
  1243. const p = anc.mapToScene(0, 0)
  1244. anc.isConnected = true;
  1245. event.x = p.x;
  1246. event.y = p.y;
  1247. if (this.grabItem.status == SItemStatus.Create) {
  1248. if (this.grabItem.pointList.length) {
  1249. this.grabItem.endAnchor = anc;
  1250. anc.parent ?.connect('changePos', this.grabItem, this.grabItem.changePos)
  1251. }
  1252. this.grabItem.anchor2ID = anc.id
  1253. this.grabItem.node2Id = anc.parent.id
  1254. this.grabItem.onMouseDown(event)
  1255. this.grabItem.status = SItemStatus.Normal;
  1256. this.finishCreated(this.grabItem)
  1257. return
  1258. }
  1259. }
  1260. this.grabItem.onMouseDown(event)
  1261. }
  1262. }
  1263. /**
  1264. * 管线item修改锚点
  1265. *
  1266. */
  1267. updateTipeAnc(event: SMouseEvent): void {
  1268. if (this.grabItem instanceof TipelineItem) {
  1269. const anc = this.clickIsAnchor(event);
  1270. if (anc) {
  1271. const p = anc.mapToScene(0, 0)
  1272. event.x = p.x;
  1273. event.y = p.y;
  1274. if (this.grabItem.status == SItemStatus.Edit) {
  1275. if (this.grabItem.curIndex == 0) {
  1276. if (this.grabItem.startAnchor) {
  1277. this.grabItem.startAnchor.isConnected = false
  1278. this.grabItem.startAnchor.parent.disconnect('changePos', this.grabItem);
  1279. }
  1280. anc.isConnected = true;
  1281. this.grabItem.startAnchor = anc;
  1282. this.grabItem.anchor1ID = anc.id
  1283. this.grabItem.node1Id = anc.parent.id
  1284. anc.parent.connect('changePos', this.grabItem, this.grabItem.changePos)
  1285. }
  1286. if (this.grabItem.curIndex == this.grabItem.pointList.length - 1) {
  1287. if (this.grabItem.endAnchor) {
  1288. this.grabItem.endAnchor.isConnected = false
  1289. this.grabItem.endAnchor.parent.disconnect('changePos', this.grabItem);
  1290. }
  1291. anc.isConnected = true;
  1292. this.grabItem.endAnchor = anc;
  1293. this.grabItem.anchor2ID = anc.id
  1294. this.grabItem.node2Id = anc.parent.id
  1295. anc.parent.connect('changePos', this.grabItem, this.grabItem.changePos)
  1296. }
  1297. }
  1298. this.grabItem.onMouseUp(event)
  1299. return
  1300. } else {
  1301. if (this.grabItem.status == SItemStatus.Edit) {
  1302. if (this.grabItem.curIndex == 0) {
  1303. if (this.grabItem.startAnchor) {
  1304. this.grabItem.startAnchor.isConnected = false
  1305. this.grabItem.startAnchor.parent.disconnect('changePos', this.grabItem);
  1306. this.grabItem.startAnchor = null;
  1307. this.grabItem.anchor1ID = ''
  1308. this.grabItem.node1Id = ''
  1309. }
  1310. }
  1311. if (this.grabItem.curIndex == this.grabItem.pointList.length - 1) {
  1312. if (this.grabItem.endAnchor) {
  1313. this.grabItem.endAnchor.isConnected = false
  1314. this.grabItem.endAnchor.parent.disconnect('changePos', this.grabItem);
  1315. this.grabItem.endAnchor = null;
  1316. this.grabItem.anchor2ID = ''
  1317. this.grabItem.node2Id = ''
  1318. }
  1319. }
  1320. }
  1321. this.grabItem.onMouseUp(event)
  1322. return
  1323. }
  1324. }
  1325. }
  1326. /**
  1327. * 设置直线结束Item
  1328. *
  1329. */
  1330. setLineItem(event: SMouseEvent): void {
  1331. if (this.grabItem instanceof SLineMarkerItem) {
  1332. const item = this.clickIsItem(event);
  1333. // 鼠标点是否在某个item内
  1334. if (item) {
  1335. let scenePoint = item.boundingRect().center();
  1336. const p = item.mapToScene(scenePoint.x, scenePoint.y);
  1337. event.x = p.x;
  1338. event.y = p.y;
  1339. if (this.grabItem.status == SItemStatus.Create) {
  1340. // 点击在item内、创建状态且端点列表不为空时将直线结束端点和item绑定
  1341. if (this.grabItem.line.length) {
  1342. if (this.grabItem.startItem ?.id == item.id) {
  1343. this.grabItem.endItem = null;
  1344. } else {
  1345. this.grabItem.endItem = item;
  1346. this.grabItem.line[1] = new SPoint(event.x, event.y);
  1347. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1348. }
  1349. }
  1350. this.grabItem.onMouseDown(event);
  1351. return
  1352. } else if (this.grabItem.status == SItemStatus.Edit) {
  1353. // 点击在item内、编辑状态且点击的为结束端点时
  1354. if (this.grabItem.curIndex == 1) {
  1355. // 直线关联的起始item是直线结束端点所在的item时,不吸附在点击item中心并将直线关联的结束item置为null
  1356. if (this.grabItem.startItem ?.id == item.id) {
  1357. this.grabItem.endItem = null;
  1358. } else {// 反正吸附,关联
  1359. this.grabItem.endItem = item;
  1360. this.grabItem.line[1] = new SPoint(event.x, event.y);
  1361. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1362. }
  1363. } else if (this.grabItem.curIndex == 0) {
  1364. if (this.grabItem.endItem ?.id == item.id) {
  1365. this.grabItem.startItem = null;
  1366. } else {
  1367. this.grabItem.startItem = item;
  1368. this.grabItem.line[0] = new SPoint(event.x, event.y);
  1369. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1370. }
  1371. }
  1372. }
  1373. } else {
  1374. // 如果不在item内且点击的是直线的某个端点,将端点的关联item置为null
  1375. if (this.grabItem.line.length && this.grabItem.curIndex != -1) {
  1376. if (this.grabItem.curIndex == 1) {
  1377. this.grabItem.endItem = null;
  1378. } else if (this.grabItem.curIndex == 0) {
  1379. this.grabItem.startItem = null;
  1380. }
  1381. } else {
  1382. this.grabItem.onMouseDown(event);
  1383. return
  1384. }
  1385. }
  1386. // if (this.grabItem.status == SItemStatus.Create) {
  1387. // // 鼠标点是否在某个item内
  1388. // if (item) {
  1389. // let scenePoint = item.boundingRect().center();
  1390. // const p = item.mapToScene(scenePoint.x, scenePoint.y);
  1391. // event.x = p.x;
  1392. // event.y = p.y;
  1393. // if (this.grabItem.line.length && this.grabItem.curIndex == -1) {
  1394. // this.grabItem.endItem = item;
  1395. // this.grabItem.line[1] = new SPoint(event.x, event.y);
  1396. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1397. // }
  1398. // this.grabItem.onMouseDown(event);
  1399. // return
  1400. // } else {
  1401. // if (this.grabItem.line.length && this.grabItem.curIndex != -1) {
  1402. // if (this.grabItem.curIndex == 1) {
  1403. // this.grabItem.endItem = null;
  1404. // } else if (this.grabItem.curIndex == 0) {
  1405. // this.grabItem.startItem = null;
  1406. // }
  1407. // }
  1408. // }
  1409. // } else if (this.grabItem.status == SItemStatus.Edit) {
  1410. // if (this.grabItem.curIndex == 1) {
  1411. // this.grabItem.endItem = item;
  1412. // this.grabItem.line[1] = new SPoint(event.x, event.y);
  1413. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1414. // } else if (this.grabItem.curIndex == 0) {
  1415. // this.grabItem.startItem = item;
  1416. // this.grabItem.line[0] = new SPoint(event.x, event.y);
  1417. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1418. // }
  1419. // }
  1420. this.grabItem.onMouseUp(event);
  1421. }
  1422. }
  1423. /**
  1424. * 划线时点击位置是否是锚点
  1425. *
  1426. * @param event 事件
  1427. * @param len 限制距离
  1428. * @return 点击的锚点
  1429. * */
  1430. clickIsAnchor(event: SMouseEvent): SAnchorItem | null {
  1431. let minAnchor = null;
  1432. let len: number = -1;
  1433. this.Nodes.forEach(image => {
  1434. // image.showAnchor = false;
  1435. if (image.anchorList && image.anchorList.length) {
  1436. if(image.img && image.img instanceof SImageItem) {
  1437. let scenePoint = image.img.mapFromScene(event.x, event.y);
  1438. if (image.img.contains(scenePoint.x, scenePoint.y)) {
  1439. let anchor = image.anchorList[0]
  1440. let anchorPoint = anchor.mapToScene(0, 0);
  1441. let dis = SMathUtil.pointDistance(
  1442. event.x,
  1443. event.y,
  1444. anchorPoint.x,
  1445. anchorPoint.y
  1446. );
  1447. console.log(dis)
  1448. if (len < 0) {
  1449. minAnchor = anchor;
  1450. len = dis;
  1451. }
  1452. if (dis < len) {
  1453. minAnchor = anchor;
  1454. len = dis;
  1455. }
  1456. }
  1457. // let scenePoint = image.mapFromScene(event.x, event.y);
  1458. // if (image.contains(scenePoint.x, scenePoint.y)) {
  1459. // image.anchorList.forEach(anchor => {
  1460. // let anchorPoint = anchor.mapToScene(0, 0);
  1461. // let dis = SMathUtil.pointDistance(
  1462. // event.x,
  1463. // event.y,
  1464. // anchorPoint.x,
  1465. // anchorPoint.y
  1466. // );
  1467. // if (len < 0) {
  1468. // len = anchor.sceneDis;
  1469. // }
  1470. // if (dis < len) {
  1471. // minAnchor = anchor;
  1472. // len = dis;
  1473. // }
  1474. // })
  1475. }
  1476. }
  1477. })
  1478. console.log('-----------------------')
  1479. console.log(minAnchor)
  1480. console.log('-----------------------')
  1481. // if (minAnchor&&minAnchor.parent) {
  1482. // minAnchor.parent.showAnchor = true
  1483. // }
  1484. return minAnchor;
  1485. }
  1486. /**
  1487. * 划线时点击位置是在文本,图片,,区域内
  1488. *
  1489. * @param event 事件
  1490. * @return 点击的item
  1491. * */
  1492. clickIsItem(event: SMouseEvent): SGraphItem | null {
  1493. let minIten = null;
  1494. let len: number = -1;
  1495. let itemList = this.Nodes.concat(this.Markers);
  1496. itemList.forEach(item => {
  1497. if (
  1498. item instanceof STextMarkerItem ||
  1499. item instanceof SImageMarkerItem ||
  1500. item instanceof SZoneLegendItem ||
  1501. item instanceof SFHFQZoneLegendItem ||
  1502. item instanceof SSCPZZoneLegendItem
  1503. ) {
  1504. let scenePoint = item.mapFromScene(event.x, event.y);
  1505. if (item.contains(scenePoint.x, scenePoint.y)) {
  1506. let dis = SMathUtil.pointDistance(
  1507. scenePoint.x,
  1508. scenePoint.y,
  1509. item.boundingRect().center().x,
  1510. item.boundingRect().center().y
  1511. );
  1512. if (len < 0) {
  1513. minIten = item;
  1514. len = dis;
  1515. }
  1516. if (dis < len) {
  1517. minIten = item;
  1518. len = dis;
  1519. }
  1520. }
  1521. }
  1522. })
  1523. console.log('-----------------------')
  1524. console.log(minIten)
  1525. console.log('-----------------------')
  1526. return minIten;
  1527. }
  1528. /**
  1529. * 点是否在吸附区域内
  1530. *
  1531. * @param p 要判断的点
  1532. * @param minX 空间区域
  1533. * @param minY 空间区域
  1534. * @param maxX 空间区域
  1535. * @param maxY 空间区域
  1536. */
  1537. static isPointInAbsorbArea(
  1538. p: SPoint,
  1539. minX: number,
  1540. maxX: number,
  1541. minY: number,
  1542. maxY: number
  1543. ): boolean {
  1544. let rect = new SRect(
  1545. minX - 1000,
  1546. minY - 1000,
  1547. maxX - minX + 2000,
  1548. maxY - minY + 2000
  1549. );
  1550. return rect.contains(p.x, p.y);
  1551. } // Function isPointInAbsorbArea()
  1552. /**
  1553. * 吸附空间
  1554. *
  1555. * @param event 鼠标事件对象
  1556. * @return boolean 是否找到吸附的对象
  1557. */
  1558. absorbSpace(event: SMouseEvent): boolean {
  1559. if (!this.highLight) {
  1560. return false;
  1561. }
  1562. let absorbLen = 1000;
  1563. if (this.view) {
  1564. absorbLen = 10 / this.view.scale;
  1565. }
  1566. let P = this.absorbSpacePoint(event, absorbLen);
  1567. if (P.Point) {
  1568. this.highLight.distance = P.MinDis;
  1569. this.highLight.point = new SPoint(P.Point.X, -P.Point.Y);
  1570. this.highLight.visible = true;
  1571. return true;
  1572. } else {
  1573. let L = this.absorbSpaceLine(event, absorbLen);
  1574. if (L.Line && L.Point) {
  1575. this.highLight.distance = L.MinDis;
  1576. this.highLight.point = L.Point;
  1577. this.highLight.line = L.Line;
  1578. this.highLight.visible = true;
  1579. return true;
  1580. }
  1581. return false;
  1582. }
  1583. } // Function absorbSpace()
  1584. /**
  1585. * 吸附空间点
  1586. *
  1587. * @param event 鼠标事件对象
  1588. * @param absorbLen 吸附距离
  1589. * @return MinDis 吸附的点
  1590. */
  1591. absorbSpacePoint(event: SMouseEvent, absorbLen: number): MinDis {
  1592. let minPointDis = Number.MAX_SAFE_INTEGER;
  1593. let Point;
  1594. this.spaceList.map((space): void => {
  1595. if (
  1596. EditScence.isPointInAbsorbArea(
  1597. new SPoint(event.x, event.y),
  1598. space.minX,
  1599. space.maxX,
  1600. space.minY,
  1601. space.maxY
  1602. )
  1603. ) {
  1604. space.data.OutLine.forEach((item): void => {
  1605. let minDis = SMathUtil.getMinDisPoint(
  1606. new SPoint(event.x, event.y),
  1607. item
  1608. );
  1609. if (
  1610. minDis &&
  1611. minDis.MinDis < absorbLen &&
  1612. minDis.MinDis < minPointDis
  1613. ) {
  1614. minPointDis = minDis.MinDis;
  1615. Point = minDis.Point;
  1616. }
  1617. });
  1618. }
  1619. });
  1620. return {
  1621. MinDis: minPointDis,
  1622. Point: Point
  1623. };
  1624. } // Function absorbSpacePoint()
  1625. /**
  1626. * 吸附空间线
  1627. *
  1628. * @param event 鼠标事件对象
  1629. * @param absorbLen 吸附距离
  1630. * @return PointToLine 吸附的线
  1631. */
  1632. absorbSpaceLine(event: SMouseEvent, absorbLen: number): PointToLine {
  1633. let minPointDis = Number.MAX_SAFE_INTEGER;
  1634. let Point, Line;
  1635. this.spaceList.forEach((space): void => {
  1636. if (
  1637. EditScence.isPointInAbsorbArea(
  1638. new SPoint(event.x, event.y),
  1639. space.minX,
  1640. space.maxX,
  1641. space.minY,
  1642. space.maxY
  1643. )
  1644. ) {
  1645. space.data.OutLine.forEach((item): void => {
  1646. let minDisLine = SMathUtil.getMinDisLine(
  1647. new SPoint(event.x, event.y),
  1648. item
  1649. );
  1650. if (
  1651. minDisLine &&
  1652. minDisLine.MinDis < absorbLen &&
  1653. minDisLine.MinDis < minPointDis
  1654. ) {
  1655. minPointDis = minDisLine.MinDis;
  1656. Point = minDisLine.Point;
  1657. Line = minDisLine.Line;
  1658. }
  1659. });
  1660. }
  1661. });
  1662. return {
  1663. MinDis: minPointDis,
  1664. Point: Point,
  1665. Line: Line
  1666. };
  1667. } // Function absorbSpaceLine()
  1668. /**
  1669. * 添加多个item命令
  1670. * @param focusItemList 鼠标事件对象
  1671. */
  1672. AddListCommand(focusItemList: any[]): void {
  1673. this.undoStack.push(new SGraphAddListCommand(this, focusItemList));
  1674. }
  1675. /**
  1676. * 选中状态方法
  1677. * @param item 鼠标事件对象
  1678. */
  1679. toggleItem(item: SGraphItem): void {
  1680. this.selectContainer.clear()
  1681. this.selectContainer.toggleItem(item)
  1682. }
  1683. }