SBaseEditScene.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /*
  2. * *********************************************************************************************************************
  3. *
  4. * !!
  5. * .F88X
  6. * X8888Y
  7. * .}888888N;
  8. * i888888N; .:! .I$WI:
  9. * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
  10. * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
  11. * +888888N; .8888888Y "&&8Y.}8,
  12. * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
  13. * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
  14. * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
  15. * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
  16. * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
  17. * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
  18. * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
  19. * .:R888888I
  20. * .&888888I Copyright (c) 2016-2020. 博锐尚格科技股份有限公司
  21. * ~8888'
  22. * .!88~ All rights reserved.
  23. *
  24. * *********************************************************************************************************************
  25. */
  26. import {SGraphAddCommand, SGraphEditScene} from "../edit"
  27. import {SMouseEvent} from "@persagy-web/base/lib";
  28. import {SArrowStyleType, SPoint, SRect} from '@persagy-web/draw/lib';
  29. import {SItemStatus, SRectSelectItem} from '@persagy-web/big/lib';
  30. import {SGraphItem, SGraphSelectContainer} from "@persagy-web/graph/";
  31. import {uuid} from "./until";
  32. import {SBaseArrow, SBaseEquipment, SBaseExpainEdit, SBasePipeUninTool} from "./"
  33. /**
  34. * big-edit 场景
  35. *
  36. * @author 韩耀龙 <han_yao_long@163.com>
  37. */
  38. export class SBaseEditScene extends SGraphEditScene {
  39. /** 图例节点 */
  40. Nodes: any = []; // 图例节点,所有与工程信息化相关的图例(图标类型与区域)
  41. /** 图例节点 */ // 与工程信息无关的标识对象(增加文本注释,图上的图片说明)
  42. Markers: any = [];
  43. /** 管线对象 */
  44. Relations: any = [];
  45. /** 复制的对象 */
  46. copyString: any[] = [];
  47. /**
  48. * 构造函数
  49. *
  50. */
  51. constructor() {
  52. super()
  53. } // Constructor
  54. /**
  55. * 新增基础类注释
  56. *
  57. * @param event 鼠标事件参数
  58. */
  59. addExplainItem(event: SMouseEvent): void {
  60. const data = {
  61. /** 名称 */
  62. name: '基础注释文本',
  63. /** 图标 */
  64. type: "Text",
  65. /** 位置 */
  66. pos: { x: event.x, y: event.y },
  67. /** 由应用自己定义 */
  68. properties: {
  69. type: "BaseExplain",
  70. },
  71. style: {
  72. default: {
  73. text: '请在右侧属性栏输入文字!',
  74. color: "#646c73",
  75. font: 14,
  76. backgroundcolor: "#f7f9facc",
  77. }
  78. }
  79. };
  80. const item = new SBaseExpainEdit(null, data);
  81. item.moveTo(event.x, event.y);
  82. item.selectable = true;
  83. item.moveable = true;
  84. this.addItem(item);
  85. this.undoStack.push(new SGraphAddCommand(this, item));
  86. this.grabItem = null;
  87. this.finishCreated(item);
  88. } // Function addExplainItem()
  89. /**
  90. * 新增基础箭头(折线)
  91. *
  92. * @param event 鼠标事件
  93. */
  94. addPolyLineArrow(event: SMouseEvent): void {
  95. const data = {
  96. name: '基础箭头',
  97. type: "Arrow",
  98. pos: { x: 0, y: 0 },
  99. properties: {
  100. type: "BaseArrow",
  101. },
  102. style: {
  103. outLine: [{x: event.x, y: event.y}],
  104. begin: SArrowStyleType.None, //开端箭头样式
  105. end: SArrowStyleType.None, //结尾箭头样式
  106. isMove: true, //是否可以移动
  107. default: {}
  108. }
  109. };
  110. const item = new SBaseArrow(null, data);
  111. item.status = SItemStatus.Create;
  112. item.selectable = true;
  113. this.addItem(item);
  114. this.undoStack.push(new SGraphAddCommand(this, item));
  115. this.grabItem = item;
  116. item.connect("finishCreated", this, this.finishCreated);
  117. item.connect("onContextMenu", this, this.getItem);
  118. if (this.view) {
  119. this.view.update();
  120. }
  121. } // Function addPolyLineArrow()
  122. /**
  123. * 添加基本设备 item
  124. *
  125. * @param event 鼠标事件
  126. * @param legendObj 图例样式
  127. */
  128. addEuqipment(event: SMouseEvent, legendObj: any): void {
  129. const data = {
  130. /** 名称 */
  131. name: '基础设备',
  132. num: 1,
  133. size: { width: 50, height: 50 },
  134. /** 图标 (Image),线类型 (Line) */
  135. type: "Image",
  136. /** 位置 */
  137. pos: { x: event.x, y: event.y },
  138. /** 由应用自己定义 */
  139. properties: {
  140. type: "baseEquipment",
  141. },
  142. style: {
  143. default: {
  144. strokecolor: "#c0ccda",
  145. url: require('./../../../assets/images/equip/' + legendObj.url),
  146. }
  147. }
  148. }
  149. const item = new SBaseEquipment(null, data);
  150. item.status = SItemStatus.Create;
  151. this.addItem(item);
  152. this.undoStack.push(new SGraphAddCommand(this, item));
  153. item.selectable = true;
  154. item.moveable = true;
  155. this.grabItem = item;
  156. item.connect("finishCreated", this, this.finishCreated);
  157. item.connect("onContextMenu", this, this.getItem);
  158. if (this.view) {
  159. this.view.update();
  160. }
  161. } // Function addEuqipment()
  162. /**
  163. * 新增管道
  164. *
  165. * @param event 鼠标事件
  166. */
  167. addBasePipe(event: SMouseEvent) {
  168. const data = {
  169. name: '管道',
  170. type: "line",
  171. pos: { x: 0, y: 0 },
  172. properties: {
  173. type: "BasePolyline",
  174. },
  175. style: {
  176. outLine: [{ x: event.x, y: event.y }],
  177. default: {
  178. }
  179. }
  180. };
  181. const item = new SBasePipe(null, data);
  182. item.status = SItemStatus.Create;
  183. item.selectable = true;
  184. this.addItem(item);
  185. this.undoStack.push(new SGraphAddCommand(this, item));
  186. this.grabItem = item;
  187. item.connect("finishCreated", this, this.finishCreated);
  188. item.connect("onContextMenu", this, this.getItem);
  189. if (this.view) {
  190. this.view.update();
  191. }
  192. } // Function addBasePipe()
  193. /**
  194. * 添加基本管道联通器
  195. *
  196. * @param event 鼠标事件
  197. * @param cmd 命令
  198. */
  199. addPipeUninTool(event: SMouseEvent, cmd: string): void {
  200. const cmdList = {
  201. 'wantou': 2,
  202. 'santong': 3,
  203. 'sitong': 4,
  204. }
  205. const data = {
  206. /** 名称 */
  207. name: '基础管道接头',
  208. /** 图标 (Image),线类型 (Line) */
  209. type: "Image",
  210. /** 位置 */
  211. pos: { x: event.x, y: event.y },
  212. /** 由应用自己定义 */
  213. properties: {
  214. type: "BasePipeUninTool",
  215. },
  216. style: {
  217. uninToolType: cmdList[cmd] ? cmdList[cmd] : 2, //2,3,4 分别分二头连接器、三头连接器、四头连接器
  218. default: {
  219. strokecolor: "#c0ccda",
  220. }
  221. }
  222. };
  223. const item = new SBasePipeUninTool(null, data);
  224. item.status = SItemStatus.Create;
  225. item.selectable = true;
  226. item.moveable = true;
  227. this.addItem(item);
  228. this.undoStack.push(new SGraphAddCommand(this, item));
  229. this.grabItem = item;
  230. item.connect("finishCreated", this, this.finishCreated);
  231. item.connect("onContextMenu", this, this.getItem);
  232. if (this.view) {
  233. this.view.update();
  234. }
  235. } // Function addPipeUninTool()
  236. /**
  237. * 重做
  238. */
  239. redo(): void {
  240. if (this.grabItem && this.grabItem.redo) {
  241. this.grabItem.redo()
  242. } else {
  243. this.undoStack.redo();
  244. }
  245. } // Function redo()
  246. /**
  247. * 撤销
  248. */
  249. undo(): void {
  250. if (this.grabItem && this.grabItem.undo) {
  251. this.grabItem.undo()
  252. } else {
  253. this.undoStack.undo();
  254. }
  255. } // Function undo()
  256. /**
  257. * 删除
  258. *
  259. * @return 删除的图例
  260. */
  261. deleteItem(): any {
  262. if (this.selectContainer.count == 0) {
  263. return []
  264. }
  265. let itemList = this.selectContainer.itemList;
  266. itemList.forEach((element: any) => {
  267. this.removeItem(element)
  268. });
  269. if (this.view) {
  270. this.view.update()
  271. }
  272. return itemList
  273. } // Function deleteItem()
  274. /**
  275. * 框选
  276. */
  277. addRectSelect(event: SMouseEvent): void {
  278. let point = new SPoint(event.x, event.y);
  279. let rect = new SRectSelectItem(null, point);
  280. this.addItem(rect);
  281. this.grabItem = rect;
  282. } // Function addRectSelect()
  283. /**
  284. * 计算框选交集
  285. *
  286. * @param ctrl 是否点击ctrl
  287. */
  288. groupSelect(ctrl: boolean) {
  289. // if (!ctrl) {
  290. // this.selectContainer.clear()
  291. // }
  292. if (this.grabItem instanceof SRectSelectItem) {
  293. const rect = this.grabItem.boundingRect();
  294. this.arrToSelect(this.root.children, rect)
  295. }
  296. } // Function groupSelect()
  297. /**
  298. * 选中item:框选
  299. *
  300. * @param arr 实例数组
  301. * @param rect 框选矩形区域
  302. */
  303. private arrToSelect(arr: SGraphItem[], rect: SRect) {
  304. if (Array.isArray(arr) && arr.length) {
  305. arr.forEach(t => {
  306. if (!(t instanceof SGraphSelectContainer) && t.parent) {
  307. let temp = t.boundingRect();
  308. let lefttop = t.mapToScene(temp.left, temp.top)
  309. let rightbottom = t.mapToScene(temp.right, temp.bottom)
  310. let r = new SRect(lefttop, rightbottom)
  311. if (rect.isIn(r)) {
  312. this.selectContainer.toggleItem(t)
  313. }
  314. }
  315. })
  316. }
  317. } // Function arrToSelect()
  318. /////////////////////////////////////////////////////////////////////
  319. // 鼠标事件
  320. /**
  321. * 鼠标左键按下
  322. *
  323. * @param event 鼠标事件参数
  324. */
  325. onMouseDown(event: SMouseEvent): any {
  326. if (!super.onMouseDown(event) && 1 == event.buttons) {
  327. this.addRectSelect(event);
  328. }
  329. } // Function onMouseDown()
  330. /**
  331. * 鼠标抬起
  332. *
  333. * @param event 鼠标事件参数
  334. */
  335. onMouseUp(event: SMouseEvent): boolean {
  336. if (this.grabItem) {
  337. // 鼠标抬起时,如果grabItem为框选则删除框选item
  338. if (this.grabItem instanceof SRectSelectItem) {
  339. this.removeItem(this.grabItem);
  340. this.groupSelect(false);
  341. this.grabItem = null;
  342. if (this.view) {
  343. this.view.update()
  344. }
  345. return true;
  346. }
  347. return this.grabItem.onMouseUp(event);
  348. }
  349. return super.onMouseUp(event)
  350. } // Function onMouseUp()
  351. /**
  352. * 复制
  353. */
  354. copy():void {
  355. const itemList = this.selectContainer.itemList
  356. if (itemList.length) {
  357. itemList.forEach(t => {
  358. const data = JSON.parse(JSON.stringify(t.toData()))
  359. data.ID = uuid()
  360. this.copyString.push(data)
  361. })
  362. // 生成复制字符串
  363. console.log(this.copyString)
  364. // 获取input dom
  365. const input = document.createElement('input');
  366. input.setAttribute('id', 'COPYINPUT')
  367. input.value = JSON.stringify(this.copyString)
  368. sessionStorage.setItem("copyString", input.value);
  369. document.body.appendChild(input);
  370. input.select()
  371. document.execCommand('copy');
  372. input.style.display = 'none';
  373. console.log(input.value, Date.now());
  374. document.body.removeChild(input)
  375. }
  376. } // Function copy()
  377. /**
  378. * 粘贴
  379. */
  380. paste(): void {
  381. const copyList = JSON.parse(JSON.stringify(this.copyString));
  382. copyList.forEach((t: any) => {
  383. if (this.view) {
  384. t.Pos.X += 10,
  385. t.Pos.Y += 10
  386. }
  387. t.moveable = true;
  388. console.log('t', t)
  389. this.addItem(t)
  390. });
  391. this.view ? this.view.update() : ''
  392. console.log(this.view)
  393. } // Function paste()
  394. } // Class SBaseEditScene