cnhis-design-vue 2.1.78 → 2.1.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (598) hide show
  1. package/.prettierrc.js +27 -27
  2. package/CHANGELOG.md +2953 -2911
  3. package/README.md +90 -90
  4. package/commitlint.config.js +1 -1
  5. package/es/affix/index.js +8 -8
  6. package/es/age/index.js +18 -18
  7. package/es/alert/index.js +8 -8
  8. package/es/anchor/index.js +8 -8
  9. package/es/auto-complete/index.js +8 -8
  10. package/es/avatar/index.js +8 -8
  11. package/es/back-top/index.js +8 -8
  12. package/es/badge/index.js +8 -8
  13. package/es/base/index.js +8 -8
  14. package/es/big-table/index.js +358 -338
  15. package/es/big-table/style.css +1 -1
  16. package/es/breadcrumb/index.js +8 -8
  17. package/es/button/index.js +31 -31
  18. package/es/calendar/index.js +8 -8
  19. package/es/captcha/index.js +7 -7
  20. package/es/card/index.js +8 -8
  21. package/es/carousel/index.js +8 -8
  22. package/es/cascader/index.js +8 -8
  23. package/es/checkbox/index.js +17 -17
  24. package/es/col/index.js +8 -8
  25. package/es/collapse/index.js +8 -8
  26. package/es/color-picker/index.js +5 -5
  27. package/es/comment/index.js +8 -8
  28. package/es/config-provider/index.js +8 -8
  29. package/es/date-picker/index.js +30 -30
  30. package/es/descriptions/index.js +8 -8
  31. package/es/divider/index.js +8 -8
  32. package/es/drag-layout/index.js +5 -5
  33. package/es/drawer/index.js +8 -8
  34. package/es/dropdown/index.js +8 -8
  35. package/es/editor/index.js +1 -1
  36. package/es/ellipsis/index.js +1 -1
  37. package/es/empty/index.js +8 -8
  38. package/es/fabric-chart/index.js +45 -45
  39. package/es/form/index.js +8 -8
  40. package/es/form-model/index.js +8 -8
  41. package/es/form-table/index.js +144 -144
  42. package/es/grid/index.js +4 -4
  43. package/es/index/index.js +3657 -2281
  44. package/es/index/style.css +1 -1
  45. package/es/input/index.js +11 -11
  46. package/es/input-number/index.js +8 -8
  47. package/es/keep-cache/index.js +9 -9
  48. package/es/layout/index.js +8 -8
  49. package/es/list/index.js +8 -8
  50. package/es/locale-provider/index.js +8 -8
  51. package/es/map/index.js +13 -13
  52. package/es/mentions/index.js +8 -8
  53. package/es/menu/index.js +8 -8
  54. package/es/message/index.js +8 -8
  55. package/es/multi-chat/index.js +117 -117
  56. package/es/multi-chat-client/index.js +111 -111
  57. package/es/multi-chat-history/index.js +6 -6
  58. package/es/multi-chat-record/index.js +27 -27
  59. package/es/multi-chat-setting/index.js +43 -43
  60. package/es/multi-chat-sip/index.js +1 -1
  61. package/es/notification/index.js +8 -8
  62. package/es/page-header/index.js +8 -8
  63. package/es/pagination/index.js +8 -8
  64. package/es/popconfirm/index.js +8 -8
  65. package/es/popover/index.js +8 -8
  66. package/es/progress/index.js +8 -8
  67. package/es/radio/index.js +17 -17
  68. package/es/rate/index.js +8 -8
  69. package/es/result/index.js +8 -8
  70. package/es/row/index.js +8 -8
  71. package/es/scale-container/index.js +1 -1
  72. package/es/scale-view/index.js +200 -198
  73. package/es/scale-view/style.css +1 -1
  74. package/es/select/index.js +44 -44
  75. package/es/select-label/index.js +75 -73
  76. package/es/select-label/style.css +1 -1
  77. package/es/select-person/index.js +45 -41
  78. package/es/select-person/style.css +1 -1
  79. package/es/shortcut-setter/index.js +10 -10
  80. package/es/skeleton/index.js +8 -8
  81. package/es/slider/index.js +8 -8
  82. package/es/space/index.js +8 -8
  83. package/es/spin/index.js +8 -8
  84. package/es/statistic/index.js +8 -8
  85. package/es/steps/index.js +8 -8
  86. package/es/switch/index.js +8 -8
  87. package/es/table-filter/index.js +2697 -1347
  88. package/es/table-filter/style.css +1 -1
  89. package/es/tabs/index.js +8 -8
  90. package/es/tag/index.js +9 -9
  91. package/es/time-picker/index.js +8 -8
  92. package/es/timeline/index.js +8 -8
  93. package/es/tooltip/index.js +8 -8
  94. package/es/transfer/index.js +8 -8
  95. package/es/tree/index.js +8 -8
  96. package/es/tree-select/index.js +8 -8
  97. package/es/upload/index.js +8 -8
  98. package/es/utils/clickoutside.js +7 -7
  99. package/es/utils/kty.min-1.0.0.js +5 -5
  100. package/es/utils/time-domain.js +16 -16
  101. package/es/utils/utils-map.js +32 -32
  102. package/es/utils/vexutils.js +27 -27
  103. package/es/verification-code/index.js +2 -2
  104. package/lib/cui.common.js +11438 -9918
  105. package/lib/cui.umd.js +11438 -9918
  106. package/lib/cui.umd.min.js +69 -69
  107. package/package.json +110 -110
  108. package/packages/affix/index.js +12 -12
  109. package/packages/affix/src/Affix.jsx +12 -12
  110. package/packages/age/index.js +27 -27
  111. package/packages/age/src/age/index.vue +139 -139
  112. package/packages/age/src/age-com/index.vue +209 -209
  113. package/packages/alert/index.js +12 -12
  114. package/packages/alert/src/Alert.jsx +11 -11
  115. package/packages/anchor/index.js +18 -18
  116. package/packages/anchor/src/Anchor.jsx +11 -11
  117. package/packages/anchor/src/Link.jsx +11 -11
  118. package/packages/auto-complete/index.js +12 -12
  119. package/packages/auto-complete/src/AutoComplete.jsx +12 -12
  120. package/packages/avatar/index.js +12 -12
  121. package/packages/avatar/src/Avatar.jsx +11 -11
  122. package/packages/back-top/index.js +12 -12
  123. package/packages/back-top/src/BackTop.jsx +11 -11
  124. package/packages/badge/index.js +12 -12
  125. package/packages/badge/src/Badge.jsx +11 -11
  126. package/packages/base/index.js +3 -3
  127. package/packages/big-table/index.js +16 -16
  128. package/packages/big-table/src/BigTable.vue +3205 -3193
  129. package/packages/big-table/src/Fieldset.vue +2067 -2067
  130. package/packages/big-table/src/assets/iconfont/iconfont.css +21 -21
  131. package/packages/big-table/src/assets/style/table-base.less +390 -387
  132. package/packages/big-table/src/assets/style/table-global.less +175 -175
  133. package/packages/big-table/src/components/AutoLayoutButton.vue +307 -307
  134. package/packages/big-table/src/components/NoData.vue +81 -81
  135. package/packages/big-table/src/components/TextOverTooltip.vue +120 -120
  136. package/packages/big-table/src/components/edit-form/EditForm.vue +509 -509
  137. package/packages/big-table/src/components/edit-form/edit-component/config-data/index.js +68 -68
  138. package/packages/big-table/src/components/edit-form/edit-component/edit-date-picker/edit-date-picker.vue +60 -60
  139. package/packages/big-table/src/components/edit-form/edit-component/edit-digital/edit-digital.vue +54 -54
  140. package/packages/big-table/src/components/edit-form/edit-component/edit-input/edit-input.vue +39 -39
  141. package/packages/big-table/src/components/edit-form/edit-component/edit-input-password/edit-input-password.vue +79 -79
  142. package/packages/big-table/src/components/edit-form/edit-component/edit-month-picker/edit-month-picker.vue +37 -37
  143. package/packages/big-table/src/components/edit-form/edit-component/edit-search/edit-search.vue +82 -82
  144. package/packages/big-table/src/components/edit-form/edit-component/edit-search-more/edit-search-more.vue +95 -95
  145. package/packages/big-table/src/components/edit-form/edit-component/edit-select/edit-select.vue +40 -40
  146. package/packages/big-table/src/components/edit-form/edit-component/edit-select-multiple/edit-select-multiple.vue +55 -55
  147. package/packages/big-table/src/components/edit-form/edit-component/edit-switch/edit-switch.vue +43 -43
  148. package/packages/big-table/src/components/edit-form/edit-component/edit-textarea/edit-textarea.vue +41 -41
  149. package/packages/big-table/src/components/edit-form/edit-component/edit-time-picker/edit-time-picker.vue +40 -40
  150. package/packages/big-table/src/components/edit-form/edit-component/mixins/bound-date.js +3 -3
  151. package/packages/big-table/src/components/edit-form/edit-component/mixins/dateType.js +217 -217
  152. package/packages/big-table/src/components/edit-form/edit-component/mixins/item-default.js +639 -639
  153. package/packages/big-table/src/components/edit-form/edit-component/mixins/search.js +1247 -1247
  154. package/packages/big-table/src/components/edit-form/edit-component/register-com.js +26 -26
  155. package/packages/big-table/src/components/edit-form/edit-item/form-event.js +80 -80
  156. package/packages/big-table/src/components/edit-form/edit-item/global-props.js +33 -33
  157. package/packages/big-table/src/components/edit-form/edit-item/index.js +4 -4
  158. package/packages/big-table/src/components/edit-form/edit-item/render-methods.js +28 -28
  159. package/packages/big-table/src/components/edit-form/edit-item/validate-rules.js +463 -463
  160. package/packages/big-table/src/components/edit-form/edit-mixins/form-commom.js +673 -673
  161. package/packages/big-table/src/components/edit-form/edit-mixins/index.js +3 -3
  162. package/packages/big-table/src/components/edit-form/edit-utils/index.js +112 -112
  163. package/packages/big-table/src/components/password-com.vue +58 -58
  164. package/packages/big-table/src/components/player-vod/index.vue +57 -57
  165. package/packages/big-table/src/components/player-vod/player.vue +193 -193
  166. package/packages/big-table/src/components/player-vod/video-list.vue +265 -265
  167. package/packages/big-table/src/components/player-vod/video-modal.vue +126 -126
  168. package/packages/big-table/src/utils/CustomPagination.vue +86 -86
  169. package/packages/big-table/src/utils/batchEditing.js +610 -610
  170. package/packages/big-table/src/utils/bigTableProps.js +108 -108
  171. package/packages/big-table/src/utils/eventBroadcast.js +24 -24
  172. package/packages/big-table/src/utils/format.js +557 -557
  173. package/packages/big-table/src/utils/nestTable.js +109 -109
  174. package/packages/big-table/src/utils/tableParse.js +234 -234
  175. package/packages/breadcrumb/index.js +21 -21
  176. package/packages/breadcrumb/src/Breadcrumb.jsx +11 -11
  177. package/packages/breadcrumb/src/BreadcrumbItem.jsx +11 -11
  178. package/packages/breadcrumb/src/BreadcrumbSeparator.jsx +11 -11
  179. package/packages/button/index.js +21 -21
  180. package/packages/button/src/Button.jsx +11 -11
  181. package/packages/button/src/ButtonGroup.jsx +11 -11
  182. package/packages/button/src/ButtonPrint/components/IdentityVerification.vue +181 -181
  183. package/packages/button/src/ButtonPrint/index.vue +766 -766
  184. package/packages/button/src/ButtonPrint/mixin/his-print.js +95 -95
  185. package/packages/calendar/index.js +12 -12
  186. package/packages/calendar/src/Calendar.jsx +11 -11
  187. package/packages/captcha/index.js +9 -9
  188. package/packages/captcha/src/Captcha.vue +164 -164
  189. package/packages/captcha/src/Index.vue +47 -47
  190. package/packages/captcha/src/SlideVerify.vue +285 -285
  191. package/packages/card/index.js +21 -21
  192. package/packages/card/src/Card.jsx +12 -12
  193. package/packages/card/src/CardGrid.js +7 -7
  194. package/packages/card/src/CardMeta.js +7 -7
  195. package/packages/carousel/index.js +12 -12
  196. package/packages/carousel/src/Carousel.jsx +12 -12
  197. package/packages/cascader/index.js +12 -12
  198. package/packages/cascader/src/Cascader.jsx +11 -11
  199. package/packages/checkbox/index.js +30 -30
  200. package/packages/checkbox/src/Checkbox.jsx +11 -11
  201. package/packages/checkbox/src/CheckboxImg/index.vue +141 -141
  202. package/packages/checkbox/src/Group.jsx +11 -11
  203. package/packages/col/index.js +13 -13
  204. package/packages/col/src/Col.jsx +11 -11
  205. package/packages/collapse/index.js +18 -18
  206. package/packages/collapse/src/Collapse.jsx +11 -11
  207. package/packages/collapse/src/Panel.jsx +11 -11
  208. package/packages/color-picker/index.js +10 -10
  209. package/packages/color-picker/src/color-picker.vue +191 -191
  210. package/packages/color-picker/src/style.less +109 -109
  211. package/packages/comment/index.js +12 -12
  212. package/packages/comment/src/Comment.jsx +11 -11
  213. package/packages/config-provider/index.js +12 -12
  214. package/packages/config-provider/src/ConfigProvider.jsx +11 -11
  215. package/packages/date-picker/index.js +26 -26
  216. package/packages/date-picker/src/DatePicker.jsx +12 -12
  217. package/packages/date-picker/src/MonthPicker.jsx +11 -11
  218. package/packages/date-picker/src/RangePicker.jsx +11 -11
  219. package/packages/date-picker/src/WeekPicker.jsx +11 -11
  220. package/packages/date-picker/src/utils/index.js +374 -374
  221. package/packages/descriptions/index.js +18 -18
  222. package/packages/descriptions/src/Descriptions.jsx +11 -11
  223. package/packages/descriptions/src/Item.jsx +11 -11
  224. package/packages/divider/index.js +12 -12
  225. package/packages/divider/src/Divider.jsx +11 -11
  226. package/packages/drag-layout/DragFormLeftItem.vue +173 -173
  227. package/packages/drag-layout/DragFormRightItem.vue +284 -284
  228. package/packages/drag-layout/I18n-mixins.js +10 -10
  229. package/packages/drag-layout/drag-layout.vue +778 -778
  230. package/packages/drag-layout/index.js +12 -12
  231. package/packages/drawer/index.js +12 -12
  232. package/packages/drawer/src/Drawer.jsx +11 -11
  233. package/packages/dropdown/index.js +12 -12
  234. package/packages/dropdown/src/Dropdown.jsx +11 -11
  235. package/packages/editor/index.js +9 -9
  236. package/packages/ellipsis/index.js +8 -8
  237. package/packages/ellipsis/src/Ellipsis.vue +65 -65
  238. package/packages/empty/index.js +12 -12
  239. package/packages/empty/src/Empty.jsx +11 -11
  240. package/packages/fabric-chart/index.js +9 -9
  241. package/packages/fabric-chart/src/FabricGrid.vue +67 -67
  242. package/packages/fabric-chart/src/components/DropPopup.vue +90 -90
  243. package/packages/fabric-chart/src/components/MouseRightClick.vue +168 -168
  244. package/packages/fabric-chart/src/components/TimeScaleValue.vue +125 -125
  245. package/packages/fabric-chart/src/const/defaultVaule.js +60 -60
  246. package/packages/fabric-chart/src/fabric-chart/FabricLines.vue +617 -617
  247. package/packages/fabric-chart/src/fabric-chart/FabricPolylines.vue +1191 -1191
  248. package/packages/fabric-chart/src/fabric-chart/FabricScaleValue.vue +139 -139
  249. package/packages/fabric-chart/src/fabric-chart/FabricTextGroup.vue +651 -651
  250. package/packages/fabric-chart/src/mixins/fabricCommon.js +81 -81
  251. package/packages/fabric-chart/src/mixins/fabricObject.js +193 -193
  252. package/packages/fabric-chart/src/mixins/type.js +5 -5
  253. package/packages/fabric-chart/src/utils/bus.js +2 -2
  254. package/packages/form/index.js +16 -16
  255. package/packages/form/src/Form.jsx +11 -11
  256. package/packages/form/src/Item.jsx +11 -11
  257. package/packages/form-model/index.js +14 -14
  258. package/packages/form-model/src/FormModel.jsx +11 -11
  259. package/packages/form-model/src/Item.jsx +11 -11
  260. package/packages/form-table/index.js +16 -16
  261. package/packages/form-table/src/FormTable.vue +1110 -1110
  262. package/packages/form-table/src/components/table-component/config-data/index.js +80 -80
  263. package/packages/form-table/src/components/table-component/global-props.js +22 -22
  264. package/packages/form-table/src/components/table-component/index.js +8 -8
  265. package/packages/form-table/src/components/table-component/mixins/bound-date.js +455 -455
  266. package/packages/form-table/src/components/table-component/mixins/dateType.js +217 -217
  267. package/packages/form-table/src/components/table-component/mixins/item-default.js +257 -257
  268. package/packages/form-table/src/components/table-component/mixins/search.js +1242 -1242
  269. package/packages/form-table/src/components/table-component/register-com.js +30 -30
  270. package/packages/form-table/src/components/table-component/table-age/table-age.vue +175 -175
  271. package/packages/form-table/src/components/table-component/table-date-picker/table-date-picker.vue +87 -87
  272. package/packages/form-table/src/components/table-component/table-digital/table-digital.vue +93 -93
  273. package/packages/form-table/src/components/table-component/table-input/table-input.vue +81 -81
  274. package/packages/form-table/src/components/table-component/table-input-password/table-input-password.vue +126 -126
  275. package/packages/form-table/src/components/table-component/table-month-picker/table-month-picker.vue +55 -55
  276. package/packages/form-table/src/components/table-component/table-search/table-search.vue +174 -174
  277. package/packages/form-table/src/components/table-component/table-search-more/table-search-more.vue +191 -191
  278. package/packages/form-table/src/components/table-component/table-select/table-select.vue +64 -64
  279. package/packages/form-table/src/components/table-component/table-select-multiple/table-select-multiple.vue +81 -81
  280. package/packages/form-table/src/components/table-component/table-textarea/table-textarea.vue +76 -76
  281. package/packages/form-table/src/components/table-component/table-time-picker/table-time-picker.vue +55 -55
  282. package/packages/form-table/src/components/table-component/table-tree-select/table-tree-select.vue +135 -135
  283. package/packages/form-table/src/components/table-component/text-over-tooltip/TextOverTooltip.vue +97 -97
  284. package/packages/form-table/src/components/table-item/form-event.js +81 -81
  285. package/packages/form-table/src/components/table-item/global-props.js +27 -27
  286. package/packages/form-table/src/components/table-item/index.js +4 -4
  287. package/packages/form-table/src/components/table-item/render-methods.js +28 -28
  288. package/packages/form-table/src/components/table-item/validate-rules.js +520 -520
  289. package/packages/form-table/src/components/table-mixins/form-commom.js +98 -98
  290. package/packages/form-table/src/components/table-mixins/index.js +3 -3
  291. package/packages/form-table/src/components/table-utils/index.js +112 -112
  292. package/packages/form-table/src/disabledDetail.less +46 -46
  293. package/packages/grid/index.js +10 -10
  294. package/packages/grid/src/grid.js +28 -28
  295. package/packages/icon/index.js +10 -10
  296. package/packages/icon/src/icon.js +13 -13
  297. package/packages/index.js +313 -313
  298. package/packages/input/index.js +30 -30
  299. package/packages/input/src/Group.jsx +11 -11
  300. package/packages/input/src/Input.jsx +11 -11
  301. package/packages/input/src/Password.jsx +11 -11
  302. package/packages/input/src/Search.jsx +11 -11
  303. package/packages/input/src/TextArea.jsx +11 -11
  304. package/packages/input/src/input-quick/components/quick-item.vue +284 -284
  305. package/packages/input/src/input-quick/components/quick-popover.vue +596 -596
  306. package/packages/input/src/input-quick/index.vue +137 -137
  307. package/packages/input-number/index.js +12 -12
  308. package/packages/input-number/src/InputNumber.jsx +11 -11
  309. package/packages/keep-cache/KeepCache.js +236 -236
  310. package/packages/keep-cache/index.css +2 -2
  311. package/packages/keep-cache/index.js +8 -8
  312. package/packages/layout/index.js +27 -27
  313. package/packages/layout/src/Content.jsx +11 -11
  314. package/packages/layout/src/Footer.jsx +11 -11
  315. package/packages/layout/src/Header.jsx +11 -11
  316. package/packages/layout/src/Layout.jsx +11 -11
  317. package/packages/layout/src/Sider.jsx +11 -11
  318. package/packages/list/index.js +21 -21
  319. package/packages/list/src/Item.jsx +11 -11
  320. package/packages/list/src/ItemMeta.jsx +11 -11
  321. package/packages/list/src/List.jsx +11 -11
  322. package/packages/locale-provider/index.js +12 -12
  323. package/packages/locale-provider/src/LocaleProvider.jsx +11 -11
  324. package/packages/map/index.js +9 -9
  325. package/packages/map/src/Map.vue +484 -484
  326. package/packages/map/src/popup-map.vue +53 -53
  327. package/packages/mentions/index.js +18 -18
  328. package/packages/mentions/src/Mentions.jsx +11 -11
  329. package/packages/mentions/src/Option.jsx +11 -11
  330. package/packages/menu/index.js +27 -27
  331. package/packages/menu/src/Divider.jsx +11 -11
  332. package/packages/menu/src/Item.jsx +11 -11
  333. package/packages/menu/src/ItemGroup.jsx +11 -11
  334. package/packages/menu/src/Menu.jsx +11 -11
  335. package/packages/menu/src/SubMenu.jsx +11 -11
  336. package/packages/message/index.js +8 -8
  337. package/packages/modal/index.js +10 -10
  338. package/packages/modal/src/Modal.js +7 -7
  339. package/packages/multi-chat/chat/addConference.vue +200 -200
  340. package/packages/multi-chat/chat/addMembers.vue +411 -411
  341. package/packages/multi-chat/chat/advancedFilter.vue +372 -372
  342. package/packages/multi-chat/chat/calling.vue +246 -246
  343. package/packages/multi-chat/chat/chatFooter.vue +1647 -1647
  344. package/packages/multi-chat/chat/chatHistory.vue +605 -605
  345. package/packages/multi-chat/chat/chatMain.vue +1490 -1490
  346. package/packages/multi-chat/chat/client/index.vue +149 -149
  347. package/packages/multi-chat/chat/delay.vue +177 -177
  348. package/packages/multi-chat/chat/evaluate.vue +343 -343
  349. package/packages/multi-chat/chat/messageRecord.vue +324 -324
  350. package/packages/multi-chat/chat/mixins/NoData.js +20 -20
  351. package/packages/multi-chat/chat/mixins/base.js +97 -97
  352. package/packages/multi-chat/chat/mixins/uniRTCAPI.js +80 -80
  353. package/packages/multi-chat/chat/mixins/viewerOptions.js +67 -67
  354. package/packages/multi-chat/chat/quickReply.vue +439 -439
  355. package/packages/multi-chat/chat/robot/index.vue +312 -312
  356. package/packages/multi-chat/chat/scrollList.vue +1259 -1259
  357. package/packages/multi-chat/chat/videoVoiceList.vue +348 -348
  358. package/packages/multi-chat/chat/voice.vue +431 -431
  359. package/packages/multi-chat/components/avatar.vue +113 -113
  360. package/packages/multi-chat/components/chat-tabs-header.vue +251 -251
  361. package/packages/multi-chat/components/classify-tabs.vue +185 -185
  362. package/packages/multi-chat/components/empty.vue +24 -24
  363. package/packages/multi-chat/components/modal-refuse-reason.vue +112 -112
  364. package/packages/multi-chat/components/modal-sip.vue +160 -160
  365. package/packages/multi-chat/components/modal-user-transfer.vue +98 -98
  366. package/packages/multi-chat/components/msg-describe.vue +138 -138
  367. package/packages/multi-chat/components/msg-picture.vue +68 -68
  368. package/packages/multi-chat/components/msg-prescription.vue +205 -205
  369. package/packages/multi-chat/components/read-record.vue +133 -133
  370. package/packages/multi-chat/components/read-status.vue +34 -34
  371. package/packages/multi-chat/components/user-status.vue +198 -198
  372. package/packages/multi-chat/components/vuecmf-dialog.vue +322 -322
  373. package/packages/multi-chat/index.js +7 -7
  374. package/packages/multi-chat/setting/authority/index.vue +156 -156
  375. package/packages/multi-chat/setting/authority/roleSetting.vue +204 -204
  376. package/packages/multi-chat/setting/baseInfo/index.vue +1343 -1343
  377. package/packages/multi-chat/setting/customerService/batchSelect.vue +403 -403
  378. package/packages/multi-chat/setting/customerService/index.vue +273 -273
  379. package/packages/multi-chat/setting/event/edit/condition.vue +128 -128
  380. package/packages/multi-chat/setting/event/edit/index.vue +437 -437
  381. package/packages/multi-chat/setting/event/edit/notice.vue +129 -129
  382. package/packages/multi-chat/setting/event/edit/strategy.vue +98 -98
  383. package/packages/multi-chat/setting/event/index.vue +249 -249
  384. package/packages/multi-chat/setting/index.vue +269 -269
  385. package/packages/multi-chat/setting/page.vue +14 -14
  386. package/packages/multi-chat/setting/sessionList/index.vue +412 -412
  387. package/packages/multi-chat/setting/sessionList/messageRecord.vue +372 -372
  388. package/packages/multi-chat/setting/userConfig/index.vue +124 -124
  389. package/packages/multi-chat/setting/worktime/index.vue +274 -274
  390. package/packages/multi-chat/store/actions.js +452 -452
  391. package/packages/multi-chat/store/getters.js +380 -380
  392. package/packages/multi-chat/store/helper.js +66 -66
  393. package/packages/multi-chat/store/index.js +50 -50
  394. package/packages/multi-chat/store/mutation.js +305 -305
  395. package/packages/multi-chat/store/state.js +120 -120
  396. package/packages/multi-chat/style/emoji.css +315 -315
  397. package/packages/multi-chat/style/message.mixin.less +38 -38
  398. package/packages/multi-chat/utils/chatSock.js +93 -93
  399. package/packages/multi-chat/utils/compressImage.js +115 -115
  400. package/packages/multi-chat/utils/emoji.json +68 -68
  401. package/packages/multi-chat/utils/index.js +259 -259
  402. package/packages/multi-chat/utils/observer-scroll.js +49 -49
  403. package/packages/multi-chat/utils/panelsetting.js +48 -48
  404. package/packages/multi-chat-client/index.js +7 -7
  405. package/packages/multi-chat-history/index.js +7 -7
  406. package/packages/multi-chat-record/index.js +7 -7
  407. package/packages/multi-chat-setting/index.js +7 -7
  408. package/packages/multi-chat-sip/index.js +6 -6
  409. package/packages/notification/index.js +8 -8
  410. package/packages/page-header/index.js +12 -12
  411. package/packages/page-header/src/PageHeader.jsx +11 -11
  412. package/packages/pagination/index.js +12 -12
  413. package/packages/pagination/src/Pagination.jsx +11 -11
  414. package/packages/popconfirm/index.js +12 -12
  415. package/packages/popconfirm/src/Popconfirm.jsx +11 -11
  416. package/packages/popover/index.js +12 -12
  417. package/packages/popover/src/Popover.jsx +11 -11
  418. package/packages/progress/index.js +12 -12
  419. package/packages/progress/src/Progress.jsx +11 -11
  420. package/packages/radio/index.js +33 -33
  421. package/packages/radio/src/Group.jsx +11 -11
  422. package/packages/radio/src/Radio.jsx +11 -11
  423. package/packages/radio/src/RadioButton.jsx +11 -11
  424. package/packages/radio/src/RadioImg/index.vue +124 -124
  425. package/packages/rate/index.js +12 -12
  426. package/packages/rate/src/Rate.jsx +11 -11
  427. package/packages/result/index.js +12 -12
  428. package/packages/result/src/Result.jsx +11 -11
  429. package/packages/row/index.js +12 -12
  430. package/packages/row/src/Row.jsx +11 -11
  431. package/packages/scale-container/index.js +8 -8
  432. package/packages/scale-container/src/ScaleContainer.vue +197 -197
  433. package/packages/scale-view/NoData.vue +81 -81
  434. package/packages/scale-view/answerParse.vue +133 -133
  435. package/packages/scale-view/customList.vue +801 -801
  436. package/packages/scale-view/data.js +80 -80
  437. package/packages/scale-view/evaluateCountdown.vue +155 -155
  438. package/packages/scale-view/evaluatePage.vue +202 -202
  439. package/packages/scale-view/formitem/data.js +3991 -3991
  440. package/packages/scale-view/formitem/index.js +7 -7
  441. package/packages/scale-view/formitem/r-address.vue +245 -245
  442. package/packages/scale-view/formitem/r-choice.vue +746 -746
  443. package/packages/scale-view/formitem/r-input.vue +93 -93
  444. package/packages/scale-view/formitem/r-prompt.vue +52 -52
  445. package/packages/scale-view/formitem/r-sign.vue +218 -218
  446. package/packages/scale-view/formitem/r-time.vue +285 -285
  447. package/packages/scale-view/formitem/r-upload-custom-list.vue +242 -242
  448. package/packages/scale-view/formitem/r-upload.vue +287 -287
  449. package/packages/scale-view/formitem/sign-com.vue +316 -316
  450. package/packages/scale-view/formitem/text-over-tooltip/TextOverTooltip.vue +98 -98
  451. package/packages/scale-view/index.js +17 -17
  452. package/packages/scale-view/mixin/NoData.js +38 -38
  453. package/packages/scale-view/mixin/addressVal.js +156 -156
  454. package/packages/scale-view/mixin/evaluate.js +146 -146
  455. package/packages/scale-view/mixin/index.js +337 -337
  456. package/packages/scale-view/mixin/judgeTypes.js +267 -267
  457. package/packages/scale-view/scaleView.vue +2017 -2017
  458. package/packages/select/index.js +27 -27
  459. package/packages/select/src/CustomSelect/index.vue +130 -130
  460. package/packages/select/src/OptGroup.jsx +11 -11
  461. package/packages/select/src/Option.jsx +11 -11
  462. package/packages/select/src/Select/Select.vue +231 -231
  463. package/packages/select/src/Select/index.js +12 -12
  464. package/packages/select/src/TableSelect/index.vue +514 -514
  465. package/packages/select-label/index.js +14 -14
  466. package/packages/select-label/label-classify.vue +129 -129
  467. package/packages/select-label/labelFormContent.vue +787 -787
  468. package/packages/select-label/select-label.vue +597 -581
  469. package/packages/select-person/index.js +10 -10
  470. package/packages/select-person/search-tree.vue +373 -373
  471. package/packages/select-person/select-person.vue +1703 -1696
  472. package/packages/shortcut-setter/index.js +12 -12
  473. package/packages/shortcut-setter/src/ShortcutSetter.vue +55 -55
  474. package/packages/shortcut-setter/src/ShortcutSetterItem.vue +85 -85
  475. package/packages/shortcut-setter/src/utils/index.js +63 -63
  476. package/packages/skeleton/index.js +12 -12
  477. package/packages/skeleton/src/Skeleton.jsx +11 -11
  478. package/packages/slider/index.js +12 -12
  479. package/packages/slider/src/Slider.jsx +11 -11
  480. package/packages/space/index.js +12 -12
  481. package/packages/space/src/Space.jsx +11 -11
  482. package/packages/spin/index.js +12 -12
  483. package/packages/spin/src/Spin.jsx +11 -11
  484. package/packages/statistic/index.js +18 -18
  485. package/packages/statistic/src/Countdown.jsx +11 -11
  486. package/packages/statistic/src/Statistic.jsx +11 -11
  487. package/packages/steps/index.js +18 -18
  488. package/packages/steps/src/Step.jsx +11 -11
  489. package/packages/steps/src/Steps.jsx +11 -11
  490. package/packages/switch/index.js +12 -12
  491. package/packages/switch/src/Switch.jsx +11 -11
  492. package/packages/table-filter/index.js +27 -27
  493. package/packages/table-filter/src/base-search-com/BaseSearch.vue +2622 -2630
  494. package/packages/table-filter/src/classification/Classification-com.vue +1760 -1760
  495. package/packages/table-filter/src/classification/search-class-name.vue +266 -266
  496. package/packages/table-filter/src/classification/search-professional-model.vue +680 -680
  497. package/packages/table-filter/src/components/TextOverTooltip.vue +120 -107
  498. package/packages/table-filter/src/components/age-com/index.vue +205 -205
  499. package/packages/table-filter/src/components/button-group/ButtonGroup.vue +162 -162
  500. package/packages/table-filter/src/components/button-icon/button-icon.js +33 -33
  501. package/packages/table-filter/src/components/button-icon/getBtnIcon.js +34 -34
  502. package/packages/table-filter/src/components/c-tree-select/tree-select.vue +336 -336
  503. package/packages/table-filter/src/components/checkbox-group/CheckboxGroup.vue +53 -0
  504. package/packages/table-filter/src/components/drop-button/drop-button.vue +224 -224
  505. package/packages/table-filter/src/components/drop-button/head-btn-icon.js +33 -33
  506. package/packages/table-filter/src/components/drop-view/drop-view.vue +89 -89
  507. package/packages/table-filter/src/components/multi-select/multi-select.vue +242 -236
  508. package/packages/table-filter/src/components/out-quick-search/out-quick-search.vue +232 -346
  509. package/packages/table-filter/src/components/range-age/index.vue +171 -172
  510. package/packages/table-filter/src/components/render-widget/components/CheckboxGroup.vue +51 -51
  511. package/packages/table-filter/src/components/render-widget/components/DateRangeQuick.vue +212 -0
  512. package/packages/table-filter/src/components/render-widget/components/NumberRange.vue +145 -0
  513. package/packages/table-filter/src/components/render-widget/components/Select.vue +50 -50
  514. package/packages/table-filter/src/components/render-widget/components/SelectDynamic.vue +304 -0
  515. package/packages/table-filter/src/components/render-widget/components/index.js +7 -7
  516. package/packages/table-filter/src/components/render-widget/enums.js +34 -29
  517. package/packages/table-filter/src/components/render-widget/index.vue +124 -91
  518. package/packages/table-filter/src/components/render-widget/mixins/dynamic-method.js +158 -0
  519. package/packages/table-filter/src/components/render-widget/widgetCfgMaps.js +245 -140
  520. package/packages/table-filter/src/components/search-condition/SearchCondition.vue +1907 -1907
  521. package/packages/table-filter/src/components/search-condition/fieldTypeList.js +169 -169
  522. package/packages/table-filter/src/components/search-filter/SearchFilter.vue +280 -278
  523. package/packages/table-filter/src/components/search-modal/set-classification.vue +336 -336
  524. package/packages/table-filter/src/components/table-modal/TableModal.vue +477 -477
  525. package/packages/table-filter/src/const/dataOptions.js +43 -43
  526. package/packages/table-filter/src/const/index.js +1 -1
  527. package/packages/table-filter/src/index.vue +584 -584
  528. package/packages/table-filter/src/mixins/mixins.js +773 -714
  529. package/packages/table-filter/src/mixins/out-quick-method.js +123 -0
  530. package/packages/table-filter/src/mixins/renderWidget.js +97 -89
  531. package/packages/table-filter/src/mixins/tableSearchCon.js +128 -128
  532. package/packages/table-filter/src/mixins/wordBookutils.js +113 -113
  533. package/packages/table-filter/src/quick-search/QuickSearch.vue +2190 -2167
  534. package/packages/tabs/index.js +18 -18
  535. package/packages/tabs/src/TabPane.jsx +11 -11
  536. package/packages/tabs/src/Tabs.jsx +11 -11
  537. package/packages/tag/index.js +21 -21
  538. package/packages/tag/src/CheckableTag.jsx +11 -11
  539. package/packages/tag/src/Tag.jsx +11 -11
  540. package/packages/tag/src/TagGroup.vue +621 -621
  541. package/packages/time-picker/index.js +12 -12
  542. package/packages/time-picker/src/TimePicker.jsx +11 -11
  543. package/packages/timeline/index.js +14 -14
  544. package/packages/timeline/src/Item.jsx +11 -11
  545. package/packages/timeline/src/Timeline.jsx +11 -11
  546. package/packages/tooltip/index.js +12 -12
  547. package/packages/tooltip/src/Tooltip.jsx +11 -11
  548. package/packages/transfer/index.js +12 -12
  549. package/packages/transfer/src/Transfer.jsx +11 -11
  550. package/packages/tree/index.js +18 -18
  551. package/packages/tree/src/Tree.jsx +11 -11
  552. package/packages/tree/src/TreeNode.jsx +11 -11
  553. package/packages/tree-select/index.js +18 -18
  554. package/packages/tree-select/src/TreeNode.jsx +11 -11
  555. package/packages/tree-select/src/TreeSelect.jsx +11 -11
  556. package/packages/upload/chunk-upload/chunk-upload-new.vue +1001 -1001
  557. package/packages/upload/chunk-upload/vod-chunk-upload.vue +749 -749
  558. package/packages/upload/chunk-upload/vod-upload-modal.vue +100 -100
  559. package/packages/upload/index.js +12 -12
  560. package/packages/upload/src/Upload.jsx +11 -11
  561. package/packages/verification-code/SlideVerify.vue +306 -306
  562. package/packages/verification-code/index.js +17 -17
  563. package/packages/verification-code/verification-code.vue +147 -147
  564. package/src/component/player-vod/index.vue +57 -57
  565. package/src/component/player-vod/player.vue +192 -192
  566. package/src/component/player-vod/video-list.vue +262 -262
  567. package/src/component/player-vod/video-modal.vue +128 -128
  568. package/src/component/select-options/index.vue +430 -430
  569. package/src/component/select-pages/index.vue +95 -95
  570. package/src/component/svg/index.vue +59 -59
  571. package/src/core/create.js +6 -6
  572. package/src/core/event.js +23 -23
  573. package/src/core/table-methods.js +444 -444
  574. package/src/directive/flexibleResize.js +151 -151
  575. package/src/directive/preventReClick.js +12 -12
  576. package/src/directive/scroll.js +230 -230
  577. package/src/global/variable.js +2 -2
  578. package/src/style/normalize.css +424 -424
  579. package/src/style/style.less +49 -49
  580. package/src/utils/UniRTCv2.js +626 -626
  581. package/src/utils/chatFetch.js +61 -61
  582. package/src/utils/clickoutside.js +75 -75
  583. package/src/utils/crypto.js +25 -25
  584. package/src/utils/index.js +81 -81
  585. package/src/utils/kty-sdk.js +582 -582
  586. package/src/utils/kty.min-1.0.0.js +14378 -14378
  587. package/src/utils/sip-device.js +79 -79
  588. package/src/utils/time-domain.js +249 -249
  589. package/src/utils/trtc.js +1 -1
  590. package/src/utils/utils-map.js +485 -485
  591. package/src/utils/vexutils.js +836 -836
  592. package/.idea/cnhis-design-vue.iml +0 -12
  593. package/.idea/codeStyles/Project.xml +0 -57
  594. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  595. package/.idea/git_toolbox_prj.xml +0 -15
  596. package/.idea/inspectionProfiles/Project_Default.xml +0 -6
  597. package/.idea/modules.xml +0 -8
  598. package/.idea/vcs.xml +0 -6
@@ -1,1191 +1,1191 @@
1
- <template>
2
- <div class="poly-line">
3
- <MouseRightClick v-show="isRightVisible" :getContainer="getContainer" :nodeList="rightClickNode" :rightPos="rightPos" @nodeClick="handleRightClick" @closeRight="isRightVisible = false" />
4
-
5
- <DropPopup v-show="isDropVisible" :val="dropVal" :dropPos="dropPos" />
6
- </div>
7
- </template>
8
-
9
- <script>
10
- import FabricCommon from '../mixins/fabricCommon';
11
- import draw from '../mixins/draw';
12
- import eventCommon from '../mixins/eventCommon';
13
- import MouseRightClick from '../components/MouseRightClick';
14
- import DropPopup from '../components/DropPopup';
15
- import defaultVaule from '../const/defaultVaule';
16
- import Bus from '../utils/bus';
17
-
18
- /**
19
- * @description: 递归遍历节点,设置颜色属性
20
- * @param {fabric.Object[]} pointArr
21
- * @param {string}} color
22
- * @return {*}
23
- */
24
-
25
- function resetPointColor(pointArr, color) {
26
- pointArr.forEach(point => {
27
- const { fill, stroke } = point;
28
- if (fill && !fill.includes('#fff') && fill !== 'transparent') {
29
- point.set({ fill: color });
30
- }
31
- if (stroke && !stroke.includes('#fff') && stroke !== 'transparent') {
32
- point.set({ stroke: color });
33
- }
34
- if (point._objects?.length) {
35
- resetPointColor(point._objects, color);
36
- }
37
- });
38
- }
39
- const setPointLineColor = (point, color, conditionHasLine2) => {
40
- point.line1?.set({ stroke: color });
41
- conditionHasLine2 && point.line2?.set({ stroke: color });
42
- };
43
-
44
- const isEffectiveNode = node => {
45
- return node?.time && (node?.value || node?.value === 0);
46
- };
47
- const rightClickNode = [
48
- { name: '新增节点', type: 'add' },
49
- { name: '检测项设置', type: 'set' },
50
- { name: '删除节点', type: 'delete' }
51
- ];
52
- const rightClickNodeConnect = [
53
- { name: '新增节点连接右侧节点', type: 'add' },
54
- { name: '新增节点连接左侧节点', type: 'add' }
55
- ];
56
- export default {
57
- name: 'fabric-polylines',
58
- mixins: [FabricCommon, draw, eventCommon],
59
- inject: ['$propItems'],
60
- props: {
61
- polyline: {
62
- type: Array,
63
- required: true
64
- },
65
- other: {
66
- type: Object,
67
- default: () => {}
68
- }
69
- },
70
- components: {
71
- MouseRightClick,
72
- DropPopup
73
- },
74
- data() {
75
- return {
76
- isDropVisible: false,
77
- dropVal: {},
78
- dropPos: { clientX: 0, clientY: 0 },
79
- rightPos: { clientX: 0, clientY: 0 },
80
- rightClickNode: [],
81
- activeEvent: null, // 当前可右键活动的对象
82
- addPointList: [], // 快速新增的节点list
83
- addPointObjList: [], // 批量新增节点对象的缓存
84
- isSelectArea: false, // 是否正在选区
85
- selectArea: null, // 选区矩形对象
86
- currentDelPoint: null, // 缓存当前可批量删除的项目线段上的点
87
- polylinePointList: [], // 缓存折线项目节点
88
- isMovingToOtherTarget: false,
89
- interval: null,
90
- flickerablePoints: [] // 记录需要闪烁的节点
91
- };
92
- },
93
- computed: {
94
- eventStyle() {
95
- return this.propItems.eventStyle;
96
- },
97
- spaceWidth() {
98
- const { xCellWidth, table } = this.propItems;
99
- // const addPointSpaceGridNumbers = table.addPointSpaceGridNumbers || [];
100
- let addPointSpaceGridNumber = table.addPointSpaceGridNumber || 1;
101
- const spaceWidth = xCellWidth * addPointSpaceGridNumber;
102
- return spaceWidth;
103
- }
104
- },
105
-
106
- watch: {},
107
-
108
- mounted() {
109
- Bus.$on('mouseoverTarget', isMovingToOtherTarget => {
110
- this.isMovingToOtherTarget = isMovingToOtherTarget;
111
- if (isMovingToOtherTarget) this.isDropVisible = false;
112
- });
113
- },
114
-
115
- methods: {
116
- init() {
117
- this.drawPolylineTitle();
118
- this.polylinePointList = [];
119
- this.flickerablePoints = [];
120
- this.polyline.forEach((polylineType, polylineTypeId) => {
121
- this.createPolyline(polylineType, polylineTypeId);
122
- });
123
- this.eventStyle.evented && this.createEvent();
124
- this.setFlicker();
125
- },
126
- createEvent() {
127
- this.canvas.on('mouse:up', event => {
128
- if (event.button === 3) {
129
- const { x, y } = event.pointer;
130
- if (this.isGridLimit(x, y)) {
131
- this.activeEvent = event;
132
- !this.isAddEventListenerContextmenu && this.canvas.wrapperEl.addEventListener('contextmenu', this.addEventListenerContextmenu, true);
133
- this.isAddEventListenerContextmenu = true;
134
- }
135
- }
136
- // 左键松开鼠标-批量删除
137
- this.isSelectArea = false;
138
- if (event.button === 1 && !event.target && this.selectArea) {
139
- const points = this.selectArea.ponits;
140
- const delList = this.getAreaPonits(points);
141
- delList.length === 0 && this.removeSelectArea();
142
- if (delList.length > 0 && this.selectArea) {
143
- this.$emit('pointOperation', 'delete', delList);
144
- this.currentDelPoint = null;
145
- }
146
- }
147
- });
148
- let selectAreaOrigin = { left: 0, top: 0 };
149
- this.canvas.on('mouse:down', event => {
150
- if (event.button === 1 && !event.target) {
151
- this.isSelectArea = true;
152
- selectAreaOrigin.left = event.pointer.x;
153
- selectAreaOrigin.top = event.pointer.y;
154
- }
155
- });
156
- this.canvas.on('mouse:move', event => {
157
- this.isSelectArea && this.createSelectArea(event, selectAreaOrigin);
158
- });
159
- },
160
- handleMoving(event) {
161
- // 如果移动到其他节点如气血分析、标记位节点上时需要隐藏折线组件中的提示弹框
162
- if (this.isMovingToOtherTarget) return;
163
- const { pointer } = event;
164
- const { x, y } = pointer;
165
- this.dropPointer = { ...pointer };
166
- const left = this.getYValue('left', y);
167
- const right = this.getYValue('right', y);
168
- const movingPopupContentList = [
169
- { id: '1', name: '时间', value: this.getXValue(x) },
170
- {
171
- id: '2',
172
- name: '值',
173
- value: `${this.formatValue('left', left)} / ${this.formatValue('right', right)}℃`
174
- }
175
- ];
176
- this.movingShowPopup(movingPopupContentList);
177
- },
178
- // 获取选区内包含的节点
179
- getAreaPonits(points) {
180
- const delList = [];
181
- const [x1, y1, x2, y2] = points;
182
- this.canvas.forEachObject(obj => {
183
- const { id, left, top } = obj;
184
- const isArea = left >= x1 && left <= x2 && top >= y1 && top <= y2;
185
- if (id && /_polyline(Point)_/.test(id) && !id.includes('isTitle') && isArea) {
186
- if (this.currentDelPoint) {
187
- const { polylineIndex } = this.currentDelPoint;
188
- if (polylineIndex == obj.polylineIndex) {
189
- delList.push(this.getDataById(id));
190
- }
191
- } else {
192
- delList.push(this.getDataById(id));
193
- }
194
- }
195
- });
196
- return delList;
197
- },
198
- // 创建选区
199
- createSelectArea(event, selectAreaOrigin) {
200
- this.selectArea && this.canvas.remove(this.selectArea);
201
- this.selectArea = new this.fabric.Rect({
202
- ...defaultVaule.style,
203
- fill: '#CAF982',
204
- opacity: 0.4,
205
- left: selectAreaOrigin.left,
206
- top: selectAreaOrigin.top,
207
- width: event.pointer.x - selectAreaOrigin.left,
208
- height: event.pointer.y - selectAreaOrigin.top,
209
- ponits: [selectAreaOrigin.left, selectAreaOrigin.top, event.pointer.x, event.pointer.y]
210
- });
211
- this.canvas.add(this.selectArea);
212
- // this.canvas.renderAll();
213
- },
214
- // 每一个折线类别
215
- createPolyline(polylineType, polylineTypeId) {
216
- polylineType.dataList.forEach((polylineItem, polylineIndex) => {
217
- this.drawPolyline(polylineItem, polylineIndex, polylineType, polylineTypeId);
218
- });
219
- },
220
- // 绘制左侧折线标题
221
- drawPolylineTitle() {
222
- const { canvasHeight, treeTableminCellWidth, originX, xScaleList, xScaleCellList, endX } = this.propItems;
223
- const leftYScalevalue = this.polyline.find(v => v.position === 'left');
224
- const lableMargin = leftYScalevalue.lableMargin || [5, 30];
225
- const lableLineHeight = leftYScalevalue.lableLineHeight || 20;
226
- const style = leftYScalevalue.style || { fontSize: 12, fill: '#000' };
227
-
228
- const leftTitleList = [];
229
-
230
- const minTime = Math.min(...xScaleList);
231
- const maxTime = Math.max(...xScaleList);
232
-
233
- this.polyline.forEach((item, index) => {
234
- item.dataList.forEach((v, i) => {
235
- const point = v.list.find(k => isEffectiveNode(k) && new Date(k.time).getTime() >= minTime && new Date(k.time).getTime() <= maxTime);
236
- const firstPointLeft = point ? this.cumputedX(point.time) : 0;
237
- const rightLimit = point ? firstPointLeft - this.spaceWidth : '';
238
- // 配置是否可拖动标题图标批量增加-
239
- const isAdd = (firstPointLeft || endX) - this.spaceWidth >= originX;
240
- leftTitleList.push({
241
- title: v.title,
242
- type: v.type,
243
- pointAttr: v.pointAttr,
244
- lineAttr: v.lineAttr,
245
- polylineTypeId: index,
246
- polylineIndex: i,
247
- isAdd,
248
- rightLimit
249
- });
250
- });
251
- });
252
-
253
- // 配置左侧title图标(但不是折线项目)
254
- if (this.other?.list && Array.isArray(this.other.list)) {
255
- const otherList = this.other.list.map(v => {
256
- return {
257
- title: v.name,
258
- type: v.type,
259
- pointAttr: v,
260
- isAdd: false,
261
- polylineTypeId: -1,
262
- polylineIndex: -1
263
- };
264
- });
265
- if (this.other.position && this.other.position === 'top') {
266
- leftTitleList.push(...otherList);
267
- } else {
268
- leftTitleList.unshift(...otherList);
269
- }
270
- }
271
-
272
- const eventStyle = { selectable: false, evented: false };
273
- leftTitleList.forEach(async (v, i) => {
274
- const baseTop = canvasHeight - lableMargin[1];
275
- const top = baseTop - i * lableLineHeight;
276
- const left = lableMargin[0] + treeTableminCellWidth;
277
- const pointId = `${v.polylineTypeId}_${v.polylineIndex}_-1_polylinePoint_'${new Date().getTime()}_isTitle`;
278
- const { fill: fillColor = '#000', stroke } = v.pointAttr;
279
- let text = new this.fabric.Text(String(v.title), {
280
- fontSize: style.fontSize,
281
- fill: fillColor && stroke ? stroke : fillColor,
282
- left,
283
- top,
284
- originY: 'center',
285
- ...defaultVaule.style,
286
- id: pointId
287
- });
288
- const iconLeft = text.width + text.left + 10;
289
- const option = {
290
- left: iconLeft,
291
- top,
292
- ...v.pointAttr,
293
- originY: 'center',
294
- originX: 'center',
295
- lineAttr: v.lineAttr || '',
296
- pointAttr: v.pointAttr,
297
- id: pointId,
298
- polylineTypeId: v.polylineTypeId,
299
- polylineIndex: v.polylineIndex,
300
- ...(v.isAdd && this.eventStyle.evented ? {} : eventStyle),
301
- rightLimit: v.rightLimit || ''
302
- };
303
- let ele;
304
- if (v.type === 'img' && v.pointAttr?.iconClassName) {
305
- ele = await this.createImage(v.pointAttr.iconClassName, v.pointAttr);
306
- }
307
- const icon = await this.createPoint(v.type, {
308
- ele: ele || '',
309
- ...option
310
- });
311
- icon.hasControls = icon.hasBorders = false;
312
- let originTop = top;
313
- let cloneIconId;
314
- icon.on('moving', () => {
315
- // 优化左侧图标太小不容易选中的问题
316
- if (!icon.url && icon.scaleX == 1.8 && icon.scaleY == 1.8) {
317
- icon.set({
318
- scaleX: 1,
319
- scaleY: 1
320
- });
321
- }
322
-
323
- if (!cloneIconId) {
324
- cloneIconId = '_polylinePoint_temp_' + new Date().getTime();
325
- icon.clone(clonedObj => {
326
- clonedObj.set({
327
- id: cloneIconId // 此id必须,用于remove节点的时候
328
- });
329
- clonedObj.bringForward();
330
- this.canvas.add(clonedObj);
331
- });
332
- }
333
-
334
- icon.set({ originX: 'center' });
335
- this.moveLimit(icon);
336
- icon.left >= originX && icon.left < originX + 5 && (originTop = icon.top);
337
- if (icon.left >= originX) {
338
- this.showDrapPopup(icon);
339
- } else {
340
- this.isDropVisible = false;
341
- }
342
- // this.canvas.renderAll();
343
- });
344
- // 标题折线点停止拖拽后 更新
345
- icon.on('moved', () => {
346
- this.setLeft(icon);
347
- icon.set({
348
- id: icon.id.replace('_isTitle', '')
349
- });
350
- // this.canvas.renderAll();
351
- this.removeTitle();
352
- this.removePolyline(cloneIconId);
353
-
354
- if (icon.id.includes('_polylinePoint_') && this.isDropVisible) {
355
- this.isDropVisible = false;
356
- if (icon.left >= originX) {
357
- // this.setEmitFunction(icon);
358
- this.setAddPointList(icon);
359
- this.$emit('pointOperation', 'increasePointBatch', this.addPointList);
360
- this.addPointList = [];
361
- }
362
- }
363
- this.removePolyline(icon.id);
364
- // 重绘折线标题
365
- this.drawPolylineTitle();
366
- });
367
-
368
- // 优化左侧图标太小不容易选中的问题
369
- if (icon.evented && !icon.url) {
370
- const maxVal = Math.max(icon.width * icon.scale, icon.height * icon.scale);
371
- if (maxVal < 7) {
372
- icon.set({
373
- scaleX: 1.8,
374
- scaleY: 1.8
375
- });
376
- }
377
- }
378
-
379
- this.canvas.add(text, icon);
380
- // this.canvas.requestRenderAll();
381
- });
382
- },
383
- // 限制节点新增位置与右侧节点间隔的spaceWidth格子树必须为整数
384
- setLeft(icon) {
385
- const { originX } = this.propItems;
386
- let tempLeft = icon.rightLimit;
387
-
388
- if (!tempLeft) return;
389
- const leftLimit = icon.left + this.spaceWidth;
390
- let i = 0;
391
- while (tempLeft >= leftLimit) {
392
- tempLeft = icon.rightLimit - i * this.spaceWidth;
393
- i++;
394
- }
395
- icon.left = tempLeft < originX ? originX : tempLeft;
396
- },
397
- // 点移动限制
398
- moveLimit(point) {
399
- point.setCoords();
400
- const { treeTableminCellWidth, endX } = this.propItems;
401
- const leftLimit = treeTableminCellWidth;
402
- const rightLimit = point.rightLimit || endX;
403
- if (point.top < this.propItems.originY) {
404
- point.set('top', this.propItems.originY);
405
- }
406
- if (point.top > this.propItems.endY) {
407
- point.set('top', this.propItems.endY);
408
- }
409
- if (point.left < leftLimit) {
410
- point.set('left', leftLimit);
411
- }
412
- if (point.left > rightLimit) {
413
- point.set('left', rightLimit);
414
- }
415
- },
416
- removeTitle() {
417
- this.canvas.forEachObject(obj => {
418
- if (obj.id && obj.id.includes('isTitle')) {
419
- this.canvas.remove(obj);
420
- }
421
- });
422
- },
423
- isLimit(time) {
424
- const minMinute = Math.min(...this.propItems.xScaleList);
425
- const maxMinute = Math.max(...this.propItems.xScaleList);
426
- const getTime = new Date(time).getTime();
427
- return getTime >= minMinute && getTime <= maxMinute;
428
- },
429
- // 设置节点闪烁
430
- setFlicker() {
431
- setTimeout(() => {
432
- if (this.interval) clearInterval(this.interval);
433
- if (this.flickerablePoints?.length) {
434
- this.interval = setInterval(() => {
435
- this.flickerablePoints.forEach(o => o?.set('opacity', o.opacity === 1 ? 0.5 : 1));
436
- this.canvas.renderAll();
437
- }, 800);
438
- }
439
- });
440
- },
441
- // 创建危急值和差异值
442
- createAttrVaule({ attr, polyline, polylineIndex, polylineType, polylineTypeId }) {
443
- const { list } = polyline;
444
- const { max, min } = polyline[attr] || {};
445
- if (!max && !min) return;
446
-
447
- const { originX, endX } = this.propItems;
448
- const isMax = max?.show && max?.value && list.some(v => +v.value >= +max.value && this.isLimit(v.time));
449
- const isMin = min?.show && min?.value && list.some(v => +v.value <= +min.value && this.isLimit(v.time));
450
- const lines = [];
451
-
452
- const drawLine = ({ value, lineStyle }) => {
453
- const top = this.cumputedY(polylineType, +value);
454
- return this.drawLine([originX, top, endX, top], { polylineIndex, lineIndex: 0, polylineTypeId, ...(lineStyle || defaultVaule.criticalStyle) });
455
- };
456
- const drawText = ({ name, nameStyle }, top) => {
457
- return new this.fabric.Text(String(name || ''), {
458
- ...defaultVaule.style,
459
- ...defaultVaule.textStyle,
460
- ...nameStyle,
461
- originY: 'bottom',
462
- left: originX + 5,
463
- top: top - 5
464
- });
465
- };
466
- const isDraw = (isMaxOrMin, maxOrMin) => isMaxOrMin && !maxOrMin?.flickerable;
467
-
468
- if (isDraw(isMax, max)) {
469
- const line = drawLine(max);
470
- const text = drawText(max, line.top);
471
- line.text = text;
472
- lines.push(line, text);
473
- }
474
- if (isDraw(isMin, min)) {
475
- const line = drawLine(min);
476
- const text = drawText(min, line.top);
477
- line.text = text;
478
- lines.push(line, text);
479
- }
480
- this.canvas.add(...lines);
481
- },
482
- /**
483
- * 绘制一条折线
484
- * @param {polyline} 折线属性
485
- * @param {polyline.type} 折线点形状 circle: 圆 | triangle: 三角
486
- * @param {polyline.pointAttr} 参数 fill: 填充色 | stroke: 描边色 | strokeWidth: 宽度 | radius: 半径 | width: 宽度 | height: 高度
487
- * @param {polyline.list} 折线点坐标数组
488
- * @param {polylineIndex} 当前折线 index
489
- */
490
- drawPolyline(polyline, polylineIndex, polylineType, polylineTypeId) {
491
- const { originY, endY } = this.propItems;
492
- const { pointAttr, lineAttr, list = [], critical = {}, diffValue = {} } = polyline;
493
- this._iconClassName = polyline.type === 'img' && pointAttr.iconClassName ? pointAttr.iconClassName : '';
494
-
495
- const pointList = [];
496
- let lineList = [];
497
- const _this = this;
498
- function getPointer(point) {
499
- let isInit = false;
500
- let points = null;
501
- if (isEffectiveNode(point) && _this.isLimit(point.time)) {
502
- const x = _this.cumputedX(point.time);
503
- const y = _this.cumputedY(polylineType, point.value);
504
- isInit = y < originY || y > endY;
505
- points = [x, y < originY ? originY : y > endY ? endY : y];
506
- }
507
- return { isInit, points };
508
- }
509
- this.flickerablePoints = this.flickerablePoints.filter(point => point.polylineTypeId !== polylineTypeId && point.polylineIndex !== polylineIndex);
510
- list.forEach((linePoints, index) => {
511
- // 当前点
512
- let { points, isInit } = getPointer(linePoints);
513
-
514
- // 下一个点
515
- const nextPoints = list[index + 1];
516
- let { points: nextPoint } = getPointer(nextPoints);
517
-
518
- let line;
519
- let point;
520
- let previousLine;
521
- line = points && nextPoint ? this.drawLine([...points, ...nextPoint], { polylineIndex, polylineTypeId, lineIndex: index, ...lineAttr }) : null;
522
- previousLine = lineList[index - 1];
523
- const pointOthers = { polylineTypeId, polylineIndex, pointIndex: index, ...pointAttr, lineAttr };
524
- if (points) {
525
- Object.assign(pointOthers, {
526
- originLeft: points[0],
527
- originTop: points[1],
528
- time: linePoints.time,
529
- __value: linePoints.value
530
- });
531
- point = previousLine ? this.drawPoint(...points, previousLine, line, polyline.type, pointOthers, isInit) : this.drawPoint(...points, null, line, polyline.type, pointOthers, isInit);
532
- }
533
- lineList.push(line);
534
- point && pointList.push(point);
535
- });
536
-
537
- Promise.all(pointList).then(res => {
538
- const polylineObj = this.polylinePointList.find(v => v.polylineTypeId == polylineTypeId && v.polylineIndex == polylineIndex);
539
- const pointerList = res.map(v => v.left);
540
- if (polylineObj) {
541
- Object.assign(polylineObj, {
542
- pointerList,
543
- pointList: res
544
- });
545
- polylineObj.pointerList = pointerList;
546
- } else {
547
- this.polylinePointList.push({
548
- polylineTypeId,
549
- polylineIndex,
550
- pointerList,
551
- color: lineAttr.stroke,
552
- pointList: res
553
- });
554
- }
555
- lineList = lineList.filter(v => v);
556
- let prevPoint = null;
557
- res = res.filter(v => {
558
- if (v && prevPoint) {
559
- prevPoint.nextPoint = v; // 记录下一个点 id
560
- v.prevPoint = prevPoint;
561
- }
562
- prevPoint = v || prevPoint;
563
- return v;
564
- });
565
- this.canvas.add(...lineList, ...res);
566
-
567
- // 缓存需要闪烁的节点
568
- setFlickerablePoints.call(this, critical);
569
- setFlickerablePoints.call(this, diffValue);
570
- function setFlickerablePoints(diffObj) {
571
- const { max, min } = diffObj;
572
- if (max?.flickerable || min?.flickerable) {
573
- const maxVal = max?.value;
574
- const minVal = min?.value;
575
- if (maxVal && max?.flickerable) {
576
- this.flickerablePoints.push(...res.filter(point => +point.__value >= +maxVal).filter(point => !this.flickerablePoints.some(_point => isSamePoint(point, _point))));
577
- }
578
- if (minVal && min?.flickerable) {
579
- this.flickerablePoints.push(...res.filter(point => +point.__value <= +minVal).filter(point => !this.flickerablePoints.some(_point => isSamePoint(point, _point))));
580
- }
581
- }
582
- }
583
- function isSamePoint(point, _point) {
584
- return point.polylineTypeId == _point.polylineTypeId && point.polylineIndex === _point.polylineIndex && point.pointIndex === _point.pointIndex;
585
- }
586
- });
587
-
588
- const params = { polyline, polylineIndex, polylineType, polylineTypeId };
589
- this.createAttrVaule({ ...params, attr: 'critical' });
590
- this.createAttrVaule({ ...params, attr: 'diffValue' });
591
- },
592
- // 计算y轴坐标
593
- cumputedY(polylineType, linePointY) {
594
- const { position = 'left', list = [] } = polylineType;
595
- const key = position === 'left' ? 'Left' : 'Right';
596
- const yScaleCell = this.propItems[`yScaleCell${key}`];
597
- const yCellUnit = linePointY - Math.min(...list);
598
- return this.propItems.endY - yScaleCell * yCellUnit;
599
- },
600
- /**
601
- * 绘制折线点
602
- * @param {left, top} 折线点坐标
603
- * @param {line1, line2} 与折线点关联的线
604
- * @param {type} 折线点类型
605
- * @param {others} 参数 polylineIndex | pointIndex | ...polyline.pointAttr
606
- */
607
- async drawPoint(left, top, line1, line2, type, others, isInit) {
608
- const pointId = `${others.polylineTypeId}_${others.polylineIndex}_${others.pointIndex}_polylinePoint_${new Date().getTime()}`;
609
- const ele = this._iconClassName && (await this.createImage(this._iconClassName, others));
610
- let point = await this.createPoint(type, {
611
- id: pointId,
612
- left: left,
613
- top: top,
614
- ele: ele || '',
615
- ...defaultVaule.pointStyle,
616
- ...others,
617
- ...(!this.eventStyle.evented
618
- ? {
619
- lockMovementX: true,
620
- lockMovementY: true
621
- }
622
- : {})
623
- });
624
- point.hasControls = point.hasBorders = false;
625
- line1 && (point.line1 = line1);
626
- line2 && (point.line2 = line2);
627
- point.on('mouseover', () => {
628
- this.showDrapPopup(point);
629
- this.pointToFront(point);
630
- });
631
- point.on('mouseout', () => {
632
- this.isDropVisible = false;
633
- });
634
- // 折线点移动中 实时更新相关联的线的坐标
635
- if (this.eventStyle.evented) {
636
- point.on('moving', () => {
637
- this.pointMoveLimit(point, false);
638
- this.pointMoveUpdateLine(point);
639
- this.addPoint(point);
640
- // this.canvas.renderAll();
641
- this.showDrapPopup(point);
642
- });
643
- // 折线点停止拖拽后 更新polyline中对应的坐标
644
- point.on('moved', () => {
645
- if (point && point.id.includes('_polylinePoint_')) {
646
- this.isDropVisible = false;
647
- this.setEmitFunction(point);
648
- this.addPointObjList = [];
649
- }
650
- });
651
- point.on('mouseup', event => {
652
- const { button, isClick } = event;
653
- if (button == 1 && isClick) {
654
- // 可配置批量删除当前项目上的点了
655
- this.currentDelPoint = point;
656
- }
657
- });
658
- }
659
-
660
- // 超出表格最高或最低值则需要触发pointChange事件并且不能更新视图,否则连接节点判断不会成功
661
- isInit && this.setEmitFunction(point, isInit);
662
-
663
- return point;
664
- },
665
- // 拖动停止后 设置回调触发方法
666
- setEmitFunction(point, isInit = false) {
667
- const { operable } = this.propItems;
668
- const { data, x, y } = this.getValue(point);
669
- Object.assign(data, {
670
- value: { time: operable.lockMovementX ? point.time : x, value: y },
671
- isInit
672
- });
673
- if (this.addPointList.length === 0) {
674
- if (point.prevPoint?.time.includes(x) || point.nextPoint?.time.includes(x)) {
675
- // 此方法更新节点后其事件都失效了,暂时采用下方repaintPolyline方法更新整条节点
676
- // point.setCoords();
677
- // point.set('left', point.originLeft);
678
- // point.set({
679
- // left: point.originLeft,
680
- // top: point.originTop
681
- // });
682
- // this.pointMoveUpdateLine(point);
683
- this.repaintPolyline(data.position, data.dataIndex);
684
- return;
685
- }
686
- this.$emit('pointChange', data);
687
- } else {
688
- this.$nextTick(() => {
689
- // 拖动新增节点时默认所有节点可删除
690
- this.currentDelPoint = null;
691
- });
692
- const lastPoint = this.addPointList[this.addPointList.length - 1];
693
- const position = this.polyline[point.polylineTypeId].position;
694
- const [firstPoint] = this.addPointList;
695
- // 如果是重合/连线节点
696
- if (point.get('scaleX') !== point.scale) {
697
- const addOjb = {
698
- ...lastPoint,
699
- value: {
700
- time: this.getXValue(this._concatPoint?.left),
701
- value: this.getYValue(position, this._concatPoint?.top)
702
- }
703
- };
704
- if (lastPoint.value.time == addOjb.value.time) {
705
- this.addPointList.splice(-1, 1, addOjb);
706
- } else {
707
- this.addPointList.push(addOjb);
708
- }
709
- this.addPointList.forEach(v => Object.assign(v, { isConcat: true, concatIndex: this._concatIndex }));
710
- } else if (point.line2 || (point.nextPoint && lastPoint.left >= point.nextPoint.left)) {
711
- // 1、存在右连线 2、无右侧连线,并且存在下一个节点的情况
712
- this.addPointList = [];
713
- this.repaintPolyline(position, point.polylineIndex);
714
- return;
715
- }
716
- !point.line2 && firstPoint.left <= point.originLeft && this.addPointList.splice(0, 1);
717
- !point.id.includes('isTitle') && this.removePolyline(point.id);
718
- if (this.addPointList.length > 0) {
719
- this.$emit('pointOperation', 'increasePointBatch', this.addPointList);
720
- this.addPointList = [];
721
- } else {
722
- this.repaintPolyline(position, point.polylineIndex);
723
- }
724
- }
725
- },
726
- // 设置批量新增数据
727
- setAddPointList(point) {
728
- const { data, x, y } = this.getValue(point);
729
- data.value = { time: x, value: y };
730
- data.left = point.left;
731
- data.top = top;
732
- this.addPointList.push(data);
733
- },
734
- // 纠正线段坐标
735
- setLinePatch(point) {
736
- const { originLeft, originTop } = point;
737
- for (let i = 0, len = this.addPointList.length; i < len; i++) {
738
- const currentPoint = this.addPointList[i];
739
- const prevPoint = this.addPointList[i - 1] || { left: point.prePoint?.left ?? originLeft, top: point.prePoint?.top ?? originTop };
740
- const currentPointObj = this.addPointObjList.find(obj => obj.left === currentPoint.left);
741
- if (currentPointObj?.line1?.x1 !== prevPoint.left) {
742
- currentPointObj.line1.set({
743
- x1: prevPoint.left,
744
- y1: prevPoint.top,
745
- x2: currentPoint.left,
746
- y2: currentPoint.top
747
- });
748
- }
749
- }
750
- },
751
- // 检查批量新增拖动过程中是否存在漏点的情况
752
- checkPoints(point) {
753
- const { originLeft, originTop, left, polylineTypeId } = point;
754
- const PointLens = Math.floor((left - originLeft) / this.spaceWidth);
755
- if (PointLens > 1 && this.addPointList?.length <= PointLens) {
756
- const position = this.polyline[polylineTypeId].position;
757
- for (let k = 0; k <= PointLens; k++) {
758
- if (k > 0) {
759
- const curLeft = originLeft + this.spaceWidth * k;
760
- // 判断this.addPointList中的left是否包含curLeft,不包含就说明是漏了
761
- const hasPoint = this.addPointList.some(p => Math.abs(p.left - curLeft) <= 0.001);
762
- // const hasPoint = this.addPointList.some(v => v.left == curLeft);
763
- if (!hasPoint) {
764
- let index;
765
- const pointObj = this.addPointList.find((v, i) => {
766
- if (v.left > curLeft) {
767
- index = i;
768
- }
769
- return v.left > curLeft;
770
- });
771
- if (pointObj) {
772
- let cloneObj = JSON.parse(JSON.stringify(pointObj));
773
- const prePoint = this.addPointList[index - 1] || {
774
- left: originLeft,
775
- top: originTop
776
- };
777
- const len = ~~((pointObj.left - (curLeft - this.spaceWidth)) / this.spaceWidth);
778
- const spaceHeight = (pointObj.top - prePoint.top) / len;
779
- cloneObj.top = prePoint.top + spaceHeight;
780
- cloneObj.value.time = this.getXValue(curLeft);
781
- cloneObj.value.value = this.getYValue(position, cloneObj.top);
782
- cloneObj.left = curLeft;
783
- this.addPointList.splice(index, 0, cloneObj);
784
- this.clonePoint(point, [prePoint.left, prePoint.top, cloneObj.left, cloneObj.top]);
785
- }
786
- }
787
- }
788
- }
789
- }
790
- // 纠正节点上的line1的坐标
791
- this.setLinePatch(point);
792
- },
793
- /**
794
- * @description: 拖动批量新增节点
795
- * @param {*} point 拖动的最后一个节点
796
- * @return {*}
797
- */
798
- addPoint(point) {
799
- let { left, top, originLeft, originTop } = point;
800
- const currentLeft = left;
801
-
802
- const startLength = this.addPointList.length;
803
- const n = 6; // 拖动范围,在需要增加节点的刻度左右吸入的范围值
804
- const residue = (left - originLeft) % this.spaceWidth;
805
-
806
- const condition = residue > 0 && (residue > this.spaceWidth - n || residue < n);
807
- const conditionNoLine2 = !point.line2 && left > originLeft;
808
- const conditionHasLine2 = point.line2 && left > originLeft + this.spaceWidth;
809
-
810
- // if (!point.line2 && left > originLeft && condition) {
811
- if (condition && (conditionNoLine2 || conditionHasLine2)) {
812
- if (residue > this.spaceWidth - n) left = left - residue + this.spaceWidth;
813
- if (residue < n) left = left - residue;
814
- point.set({
815
- left
816
- });
817
-
818
- // const i = Math.floor((left - originLeft) / this.spaceWidth);
819
- // 复制点和线
820
- if (conditionNoLine2 || conditionHasLine2) {
821
- // point.line1 && this.removePolyline(point.line1.id);
822
- setPointLineColor(point, 'transparent', conditionHasLine2);
823
- this.addPointList.length == 0 && this.clonePoint(point, [point.line1 ? point.line1.x1 : originLeft, point.line1 ? point.line1.y1 : originTop, originLeft, originTop]);
824
- if (this.addPointList.every(v => v.left !== left)) {
825
- // const points1 = i === 1 ? [originLeft, originTop] : point.prePoints;
826
- const points1 = this.addPointList.length == 0 ? [originLeft, originTop] : point.prePoints;
827
- if (points1) {
828
- // this.setAddPointList(point);
829
- // 调用上面方法就会导致线段绘制失败,目前还不知道为啥子
830
- const { data, x, y } = this.getValue(point);
831
- data.value = { time: x, value: y };
832
- data.left = left;
833
- data.top = top;
834
- // 避免重复添加
835
- if (this.addPointObjList.every(o => o.left !== left)) {
836
- this.addPointList.push(data);
837
- this.clonePoint(point, [...points1, left, top]);
838
- }
839
- }
840
- }
841
- this.checkPoints(point);
842
- }
843
- }
844
-
845
- // 断点相连
846
- function concatPoint(target) {
847
- const { left: targetLeft, top: targetTop } = target;
848
- point.setCoords();
849
- if (left >= targetLeft - n && left <= targetLeft + n && top <= targetTop + n && top >= targetTop - n) {
850
- point.set({
851
- left: targetLeft,
852
- top: targetTop,
853
- scaleX: point.scale === 1 ? 2.5 : 0.1,
854
- scaleY: point.scale === 1 ? 2.5 : 0.1
855
- });
856
- } else {
857
- point.set({
858
- scaleX: point.scale,
859
- scaleY: point.scale
860
- });
861
- }
862
- }
863
-
864
- // 检查是否显示重合连线放大节点的标识
865
- const { polylineTypeId, polylineIndex } = point;
866
- const polylineObj = this.polylinePointList.find(v => v.polylineTypeId == polylineTypeId && v.polylineIndex == polylineIndex);
867
- polylineObj?.pointList.forEach(v => v.bringToFront());
868
- if (point.nextPoint) {
869
- this._concatIndex = polylineObj?.pointerList.findIndex(v => v + n > left && v > originLeft);
870
- if (!~this._concatIndex) {
871
- point.set({
872
- scaleX: point.scale,
873
- scaleY: point.scale
874
- });
875
- } else {
876
- concatPoint(polylineObj?.pointList[this._concatIndex]);
877
- }
878
- this._concatPoint = polylineObj?.pointList?.[this._concatIndex] || null;
879
-
880
- // 被覆盖节点置灰配置
881
- polylineObj?.pointerList.forEach((v, i) => {
882
- const obj = polylineObj?.pointList[i];
883
- if (v > originLeft && v < left) {
884
- // 此处需要递归遍历group节点的所有子节点,然后更改其颜色
885
- resetPointColor([obj], '#999');
886
- obj.line2?.set({ stroke: '#999' });
887
- } else {
888
- resetPointColor([obj], polylineObj.color);
889
- obj.line2?.set({ stroke: polylineObj.color });
890
- }
891
- });
892
- if ((point.line1 || point.line2) && left < originLeft + this.spaceWidth) {
893
- setPointLineColor(point, polylineObj.color, true);
894
- } else {
895
- setPointLineColor(point, 'transparent', true);
896
- }
897
- }
898
-
899
- // 如果往回拖动则删除经过的已存在的节点
900
- if (startLength > 0 && currentLeft <= this.addPointList[startLength - 1].left) {
901
- this.removePolyline('increasePointBatch', left);
902
- this.addPointList = this.addPointList.filter(v => v.left < left);
903
- const endLength = this.addPointList.length;
904
- if (endLength === 0) {
905
- setPointLineColor(point, polylineObj?.color, conditionHasLine2);
906
- this.removePolyline('increasePointBatch', originLeft);
907
- }
908
- if (endLength > 0) {
909
- point.set({
910
- prePoints: [this.addPointList[endLength - 1].left, this.addPointList[endLength - 1].top]
911
- });
912
- }
913
- }
914
- },
915
- clonePoint(point, points) {
916
- let evented, selectable, lineIndex, polylineIndex, lineAttr, polylineTypeId;
917
- evented = selectable = false;
918
- lineAttr = { ...point.lineAttr };
919
- lineIndex = point.pointIndex;
920
- polylineIndex = point.polylineIndex;
921
- polylineTypeId = point.polylineTypeId;
922
-
923
- // return new Promise((resolve, reject) => {
924
- point.clone(clonedObj => {
925
- clonedObj.set({
926
- left: points[2],
927
- top: points[3],
928
- idClone: 'increasePointBatch',
929
- id: '_polylinePoint_' + new Date().getTime(), // 此id必须,用于remove节点的时候
930
- polylineTypeId,
931
- polylineIndex: point.polylineIndex,
932
- scaleX: point.scale,
933
- scaleY: point.scale
934
- });
935
- clonedObj.hasControls = clonedObj.hasBorders = false;
936
- point.prePoints = [point.left, point.top];
937
- const line = this.drawLine([...points], { evented, selectable, ...lineAttr, polylineIndex, polylineTypeId, lineIndex });
938
- clonedObj.line1 = line;
939
- this.canvas.sendBackwards(line);
940
- clonedObj.bringForward();
941
- this.canvas.add(clonedObj);
942
- this.addPointObjList.push(clonedObj);
943
- // resolve(clonedObj);
944
- });
945
- // });
946
- },
947
- getValue(point) {
948
- const x = this.getXValue(point.left);
949
- if (point.id) {
950
- const data = this.getDataById(point.id);
951
- const position = data.position;
952
- const y = this.getYValue(position, point.top);
953
- return { data, x, y };
954
- } else {
955
- const left = this.getYValue('left', point.top);
956
- const right = this.getYValue('right', point.top);
957
- return { x, left, right };
958
- }
959
- },
960
- getYValue(position, top) {
961
- const key = position == 'left' ? 'Left' : 'Right';
962
- const list = this.polyline.find(item => item.position == position)?.list || [];
963
- const v = list.length ? Math.min(...list) : 0;
964
- const y = (this.propItems.endY - top) / this.propItems[`yScaleCell${key}`] + v;
965
- return y;
966
- },
967
- /**
968
- * 绘制折线点
969
- * @param {lines} 线坐标 [x1, y1, x2, y2]
970
- * @param {others} 参数 polylineIndex | pointIndex | ...polyline.lineAttr
971
- */
972
- drawLine(lines, others) {
973
- const lineId = `${others.lineIndex}_${others.polylineIndex}_polylineLine_${new Date().getTime()}`;
974
- const line = new this.fabric.Line(lines, {
975
- id: lineId,
976
- hoverCursor: 'default',
977
- // objectCaching: false,
978
- selectable: false,
979
- evented: false,
980
- ...others
981
- });
982
-
983
- return line;
984
- },
985
- formatValue(position, y) {
986
- if (position == 'right') {
987
- if (y.toString().includes('.')) {
988
- const [m, n] = y.toString().split('.');
989
- return (parseFloat(`${m}.${n.slice(0, 1)}`) * 10) / 10;
990
- }
991
- return y;
992
- } else {
993
- return Math.round(y);
994
- }
995
- },
996
- showDrapPopup(point) {
997
- this.isDropVisible = true;
998
- this.dropPos = {
999
- left: point.left,
1000
- top: point.top,
1001
- margin: { top: this.propItems.yCellHeight }
1002
- };
1003
- let { x, y, data } = this.getValue(point);
1004
- this.dropVal = {
1005
- title: data.title,
1006
- list: [
1007
- { id: '11', name: '时间', value: x },
1008
- { id: '22', name: '值', value: this.formatValue(data.position, y) }
1009
- ]
1010
- };
1011
- },
1012
- // 折线点移动时 setCoords()方法手动更新相关联的线坐标
1013
- pointMoveUpdateLine(point) {
1014
- if (point.line1) {
1015
- point.line1.setCoords();
1016
- point.line1.set({ x2: point.left, y2: point.top });
1017
- }
1018
- if (point.line2) {
1019
- point.line2.setCoords();
1020
- point.line2.set({ x1: point.left, y1: point.top });
1021
- }
1022
- },
1023
- // 打开右键菜单
1024
- openRightModal() {
1025
- const { clientX, pageX, clientY, pageY } = this.activeEvent.e;
1026
- this.rightPos = {
1027
- clientX: clientX ?? pageX,
1028
- clientY: clientY ?? pageY
1029
- };
1030
- this.isRightVisible = false;
1031
- const target = this.activeEvent.target;
1032
- const id = target?.id || '';
1033
- this.$nextTick(() => {
1034
- if (id && id.includes('_polylinePoint_')) {
1035
- this._currentPoint = target;
1036
- let nodeConnect = [];
1037
- if (this.propItems.operable.connect) {
1038
- if (!target.line2 && target.nextPoint) {
1039
- nodeConnect = rightClickNodeConnect.slice(0, 1);
1040
- }
1041
- if (!target.line1 && target.prevPoint) {
1042
- nodeConnect = rightClickNodeConnect.slice(1);
1043
- }
1044
- if (!target.line1 && !target.line2 && target.prevPoint && target.nextPoint) {
1045
- nodeConnect = rightClickNodeConnect.slice();
1046
- }
1047
- }
1048
- this.rightClickNode = Object.freeze(
1049
- rightClickNode
1050
- .slice(0, 1)
1051
- .concat(nodeConnect)
1052
- .concat(rightClickNode.slice(-1))
1053
- );
1054
- this.isRightVisible = true;
1055
- } else if (!id) {
1056
- const { operable } = this.propItems;
1057
- this._currentPoint = null;
1058
- this.rightClickNode = Object.freeze(operable.set ? rightClickNode.slice(0, 2) : rightClickNode.slice(0, 1));
1059
- this.isRightVisible = true;
1060
- }
1061
- });
1062
- },
1063
- // 关闭右键菜单,打开添加节点弹窗表单
1064
- handleRightClick({ type, name }) {
1065
- this.isRightVisible = false;
1066
- const id = this._currentPoint?.id;
1067
- const { left, top } = this._active;
1068
- let data = id ? this.getDataById(id) : this.getValue({ left, top });
1069
- if (type == 'add') {
1070
- if (name.includes('左')) {
1071
- data.range = {
1072
- time: [this._currentPoint.prevPoint.time, this._currentPoint.time],
1073
- direction: 'left'
1074
- };
1075
- }
1076
- if (name.includes('右')) {
1077
- data.range = {
1078
- time: [this._currentPoint.time, this._currentPoint.nextPoint.time],
1079
- direction: 'right'
1080
- };
1081
- }
1082
- }
1083
- this.$emit('pointOperation', type, data);
1084
- this._currentPoint = null;
1085
- },
1086
- getDataById(id) {
1087
- const arr = id.replace(/_?[a-zA-Z]+.+$/, '').split('_');
1088
- const [typeIndex, lineIndex, pointIndex] = arr;
1089
- const data = this.polyline[typeIndex];
1090
- const value = data?.dataList?.[lineIndex]?.list?.[pointIndex]?.data || '';
1091
- return {
1092
- title: data?.dataList?.[lineIndex].title || '',
1093
- position: data.position,
1094
- dataIndex: lineIndex,
1095
- pointIndex: pointIndex,
1096
- data: value
1097
- };
1098
- },
1099
- isOnePolyLine(obj, polylineTypeId, polylineIndex) {
1100
- // 排除左侧标题
1101
- const isPolyLine = obj.polylineTypeId === polylineTypeId && obj.polylineIndex === polylineIndex;
1102
- if (obj.id && /_polyline(Point|Line)_/.test(obj.id) && !obj.id.includes('isTitle') && isPolyLine) return true;
1103
- return;
1104
- },
1105
- // 将当条线段以及点层级置顶
1106
- // 线段不能先置顶,会挡住其他线段上的点
1107
- pointToFront(point) {
1108
- this.canvas.forEachObject(obj => {
1109
- if (this.isOnePolyLine(obj, point.polylineTypeId, point.polylineIndex)) {
1110
- this.canvas.bringToFront(obj);
1111
- }
1112
- });
1113
- },
1114
- removePolyline(id, left, position, polylineIndex) {
1115
- // 根据id或者idClone删除
1116
- if (id) {
1117
- const pointId = left ? 'idClone' : 'id';
1118
- if (pointId === 'idClone') {
1119
- this.addPointObjList.forEach(obj => {
1120
- if (obj.left >= left) {
1121
- this.canvas.remove(obj);
1122
- obj.line1 && this.canvas.remove(obj.line1);
1123
- }
1124
- });
1125
- this.addPointObjList = this.addPointObjList.filter(obj => obj.left < left);
1126
- } else {
1127
- const point = this.canvas.getObjects().filter(item => item[pointId] === id);
1128
- if (point && point.length > 0) {
1129
- point.forEach(v => {
1130
- if (!left) {
1131
- this.canvas.remove(v);
1132
- v.line1 && this.canvas.remove(v.line1);
1133
- }
1134
- });
1135
- }
1136
- }
1137
-
1138
- return;
1139
- }
1140
- // 删除一条线
1141
- if (position && (polylineIndex === 0 || polylineIndex)) {
1142
- const polylineTypeId = this.polyline.findIndex(v => v.position === position);
1143
- this.canvas.forEachObject(obj => {
1144
- if (this.isOnePolyLine(obj, polylineTypeId, polylineIndex)) {
1145
- obj.text && this.canvas.remove(obj.text);
1146
- obj.line1 && this.canvas.remove(obj.line1);
1147
- obj.line2 && this.canvas.remove(obj.line2);
1148
- this.canvas.remove(obj);
1149
- }
1150
- });
1151
- return;
1152
- }
1153
- // 删除折线图上的所有点和线
1154
- this.canvas.forEachObject(obj => {
1155
- if (obj.id && /_polyline(Point|Line)_/.test(obj.id) && !obj.id.includes('isTitle')) {
1156
- obj.text && this.canvas.remove(obj.text);
1157
- this.canvas.remove(obj);
1158
- }
1159
- });
1160
- },
1161
- removeSelectArea() {
1162
- if (this.selectArea) {
1163
- this.canvas.remove(this.selectArea);
1164
- this.selectArea = null;
1165
- }
1166
- },
1167
- repaintPolyline(position, dadaIndex) {
1168
- if (arguments.length < 2) {
1169
- if (this.polyline.length) {
1170
- this.removePolyline();
1171
- }
1172
- this.polylinePointList = [];
1173
- this.flickerablePoints = [];
1174
- this.polyline.forEach((polylineType, polylineTypeId) => {
1175
- this.createPolyline(polylineType, polylineTypeId);
1176
- });
1177
- this.removeTitle();
1178
- this.drawPolylineTitle();
1179
- } else {
1180
- const polylineTypeId = this.polyline.findIndex(v => v.position === position);
1181
- this.removePolyline(null, null, position, parseInt(dadaIndex));
1182
- this.drawPolyline(this.polyline[polylineTypeId].dataList[parseInt(dadaIndex)], parseInt(dadaIndex), this.polyline[polylineTypeId], polylineTypeId);
1183
- }
1184
- }
1185
- },
1186
- beforeDestroy() {
1187
- clearInterval(this.interval);
1188
- this.interval = null;
1189
- }
1190
- };
1191
- </script>
1
+ <template>
2
+ <div class="poly-line">
3
+ <MouseRightClick v-show="isRightVisible" :getContainer="getContainer" :nodeList="rightClickNode" :rightPos="rightPos" @nodeClick="handleRightClick" @closeRight="isRightVisible = false" />
4
+
5
+ <DropPopup v-show="isDropVisible" :val="dropVal" :dropPos="dropPos" />
6
+ </div>
7
+ </template>
8
+
9
+ <script>
10
+ import FabricCommon from '../mixins/fabricCommon';
11
+ import draw from '../mixins/draw';
12
+ import eventCommon from '../mixins/eventCommon';
13
+ import MouseRightClick from '../components/MouseRightClick';
14
+ import DropPopup from '../components/DropPopup';
15
+ import defaultVaule from '../const/defaultVaule';
16
+ import Bus from '../utils/bus';
17
+
18
+ /**
19
+ * @description: 递归遍历节点,设置颜色属性
20
+ * @param {fabric.Object[]} pointArr
21
+ * @param {string}} color
22
+ * @return {*}
23
+ */
24
+
25
+ function resetPointColor(pointArr, color) {
26
+ pointArr.forEach(point => {
27
+ const { fill, stroke } = point;
28
+ if (fill && !fill.includes('#fff') && fill !== 'transparent') {
29
+ point.set({ fill: color });
30
+ }
31
+ if (stroke && !stroke.includes('#fff') && stroke !== 'transparent') {
32
+ point.set({ stroke: color });
33
+ }
34
+ if (point._objects?.length) {
35
+ resetPointColor(point._objects, color);
36
+ }
37
+ });
38
+ }
39
+ const setPointLineColor = (point, color, conditionHasLine2) => {
40
+ point.line1?.set({ stroke: color });
41
+ conditionHasLine2 && point.line2?.set({ stroke: color });
42
+ };
43
+
44
+ const isEffectiveNode = node => {
45
+ return node?.time && (node?.value || node?.value === 0);
46
+ };
47
+ const rightClickNode = [
48
+ { name: '新增节点', type: 'add' },
49
+ { name: '检测项设置', type: 'set' },
50
+ { name: '删除节点', type: 'delete' }
51
+ ];
52
+ const rightClickNodeConnect = [
53
+ { name: '新增节点连接右侧节点', type: 'add' },
54
+ { name: '新增节点连接左侧节点', type: 'add' }
55
+ ];
56
+ export default {
57
+ name: 'fabric-polylines',
58
+ mixins: [FabricCommon, draw, eventCommon],
59
+ inject: ['$propItems'],
60
+ props: {
61
+ polyline: {
62
+ type: Array,
63
+ required: true
64
+ },
65
+ other: {
66
+ type: Object,
67
+ default: () => {}
68
+ }
69
+ },
70
+ components: {
71
+ MouseRightClick,
72
+ DropPopup
73
+ },
74
+ data() {
75
+ return {
76
+ isDropVisible: false,
77
+ dropVal: {},
78
+ dropPos: { clientX: 0, clientY: 0 },
79
+ rightPos: { clientX: 0, clientY: 0 },
80
+ rightClickNode: [],
81
+ activeEvent: null, // 当前可右键活动的对象
82
+ addPointList: [], // 快速新增的节点list
83
+ addPointObjList: [], // 批量新增节点对象的缓存
84
+ isSelectArea: false, // 是否正在选区
85
+ selectArea: null, // 选区矩形对象
86
+ currentDelPoint: null, // 缓存当前可批量删除的项目线段上的点
87
+ polylinePointList: [], // 缓存折线项目节点
88
+ isMovingToOtherTarget: false,
89
+ interval: null,
90
+ flickerablePoints: [] // 记录需要闪烁的节点
91
+ };
92
+ },
93
+ computed: {
94
+ eventStyle() {
95
+ return this.propItems.eventStyle;
96
+ },
97
+ spaceWidth() {
98
+ const { xCellWidth, table } = this.propItems;
99
+ // const addPointSpaceGridNumbers = table.addPointSpaceGridNumbers || [];
100
+ let addPointSpaceGridNumber = table.addPointSpaceGridNumber || 1;
101
+ const spaceWidth = xCellWidth * addPointSpaceGridNumber;
102
+ return spaceWidth;
103
+ }
104
+ },
105
+
106
+ watch: {},
107
+
108
+ mounted() {
109
+ Bus.$on('mouseoverTarget', isMovingToOtherTarget => {
110
+ this.isMovingToOtherTarget = isMovingToOtherTarget;
111
+ if (isMovingToOtherTarget) this.isDropVisible = false;
112
+ });
113
+ },
114
+
115
+ methods: {
116
+ init() {
117
+ this.drawPolylineTitle();
118
+ this.polylinePointList = [];
119
+ this.flickerablePoints = [];
120
+ this.polyline.forEach((polylineType, polylineTypeId) => {
121
+ this.createPolyline(polylineType, polylineTypeId);
122
+ });
123
+ this.eventStyle.evented && this.createEvent();
124
+ this.setFlicker();
125
+ },
126
+ createEvent() {
127
+ this.canvas.on('mouse:up', event => {
128
+ if (event.button === 3) {
129
+ const { x, y } = event.pointer;
130
+ if (this.isGridLimit(x, y)) {
131
+ this.activeEvent = event;
132
+ !this.isAddEventListenerContextmenu && this.canvas.wrapperEl.addEventListener('contextmenu', this.addEventListenerContextmenu, true);
133
+ this.isAddEventListenerContextmenu = true;
134
+ }
135
+ }
136
+ // 左键松开鼠标-批量删除
137
+ this.isSelectArea = false;
138
+ if (event.button === 1 && !event.target && this.selectArea) {
139
+ const points = this.selectArea.ponits;
140
+ const delList = this.getAreaPonits(points);
141
+ delList.length === 0 && this.removeSelectArea();
142
+ if (delList.length > 0 && this.selectArea) {
143
+ this.$emit('pointOperation', 'delete', delList);
144
+ this.currentDelPoint = null;
145
+ }
146
+ }
147
+ });
148
+ let selectAreaOrigin = { left: 0, top: 0 };
149
+ this.canvas.on('mouse:down', event => {
150
+ if (event.button === 1 && !event.target) {
151
+ this.isSelectArea = true;
152
+ selectAreaOrigin.left = event.pointer.x;
153
+ selectAreaOrigin.top = event.pointer.y;
154
+ }
155
+ });
156
+ this.canvas.on('mouse:move', event => {
157
+ this.isSelectArea && this.createSelectArea(event, selectAreaOrigin);
158
+ });
159
+ },
160
+ handleMoving(event) {
161
+ // 如果移动到其他节点如气血分析、标记位节点上时需要隐藏折线组件中的提示弹框
162
+ if (this.isMovingToOtherTarget) return;
163
+ const { pointer } = event;
164
+ const { x, y } = pointer;
165
+ this.dropPointer = { ...pointer };
166
+ const left = this.getYValue('left', y);
167
+ const right = this.getYValue('right', y);
168
+ const movingPopupContentList = [
169
+ { id: '1', name: '时间', value: this.getXValue(x) },
170
+ {
171
+ id: '2',
172
+ name: '值',
173
+ value: `${this.formatValue('left', left)} / ${this.formatValue('right', right)}℃`
174
+ }
175
+ ];
176
+ this.movingShowPopup(movingPopupContentList);
177
+ },
178
+ // 获取选区内包含的节点
179
+ getAreaPonits(points) {
180
+ const delList = [];
181
+ const [x1, y1, x2, y2] = points;
182
+ this.canvas.forEachObject(obj => {
183
+ const { id, left, top } = obj;
184
+ const isArea = left >= x1 && left <= x2 && top >= y1 && top <= y2;
185
+ if (id && /_polyline(Point)_/.test(id) && !id.includes('isTitle') && isArea) {
186
+ if (this.currentDelPoint) {
187
+ const { polylineIndex } = this.currentDelPoint;
188
+ if (polylineIndex == obj.polylineIndex) {
189
+ delList.push(this.getDataById(id));
190
+ }
191
+ } else {
192
+ delList.push(this.getDataById(id));
193
+ }
194
+ }
195
+ });
196
+ return delList;
197
+ },
198
+ // 创建选区
199
+ createSelectArea(event, selectAreaOrigin) {
200
+ this.selectArea && this.canvas.remove(this.selectArea);
201
+ this.selectArea = new this.fabric.Rect({
202
+ ...defaultVaule.style,
203
+ fill: '#CAF982',
204
+ opacity: 0.4,
205
+ left: selectAreaOrigin.left,
206
+ top: selectAreaOrigin.top,
207
+ width: event.pointer.x - selectAreaOrigin.left,
208
+ height: event.pointer.y - selectAreaOrigin.top,
209
+ ponits: [selectAreaOrigin.left, selectAreaOrigin.top, event.pointer.x, event.pointer.y]
210
+ });
211
+ this.canvas.add(this.selectArea);
212
+ // this.canvas.renderAll();
213
+ },
214
+ // 每一个折线类别
215
+ createPolyline(polylineType, polylineTypeId) {
216
+ polylineType.dataList.forEach((polylineItem, polylineIndex) => {
217
+ this.drawPolyline(polylineItem, polylineIndex, polylineType, polylineTypeId);
218
+ });
219
+ },
220
+ // 绘制左侧折线标题
221
+ drawPolylineTitle() {
222
+ const { canvasHeight, treeTableminCellWidth, originX, xScaleList, xScaleCellList, endX } = this.propItems;
223
+ const leftYScalevalue = this.polyline.find(v => v.position === 'left');
224
+ const lableMargin = leftYScalevalue.lableMargin || [5, 30];
225
+ const lableLineHeight = leftYScalevalue.lableLineHeight || 20;
226
+ const style = leftYScalevalue.style || { fontSize: 12, fill: '#000' };
227
+
228
+ const leftTitleList = [];
229
+
230
+ const minTime = Math.min(...xScaleList);
231
+ const maxTime = Math.max(...xScaleList);
232
+
233
+ this.polyline.forEach((item, index) => {
234
+ item.dataList.forEach((v, i) => {
235
+ const point = v.list.find(k => isEffectiveNode(k) && new Date(k.time).getTime() >= minTime && new Date(k.time).getTime() <= maxTime);
236
+ const firstPointLeft = point ? this.cumputedX(point.time) : 0;
237
+ const rightLimit = point ? firstPointLeft - this.spaceWidth : '';
238
+ // 配置是否可拖动标题图标批量增加-
239
+ const isAdd = (firstPointLeft || endX) - this.spaceWidth >= originX;
240
+ leftTitleList.push({
241
+ title: v.title,
242
+ type: v.type,
243
+ pointAttr: v.pointAttr,
244
+ lineAttr: v.lineAttr,
245
+ polylineTypeId: index,
246
+ polylineIndex: i,
247
+ isAdd,
248
+ rightLimit
249
+ });
250
+ });
251
+ });
252
+
253
+ // 配置左侧title图标(但不是折线项目)
254
+ if (this.other?.list && Array.isArray(this.other.list)) {
255
+ const otherList = this.other.list.map(v => {
256
+ return {
257
+ title: v.name,
258
+ type: v.type,
259
+ pointAttr: v,
260
+ isAdd: false,
261
+ polylineTypeId: -1,
262
+ polylineIndex: -1
263
+ };
264
+ });
265
+ if (this.other.position && this.other.position === 'top') {
266
+ leftTitleList.push(...otherList);
267
+ } else {
268
+ leftTitleList.unshift(...otherList);
269
+ }
270
+ }
271
+
272
+ const eventStyle = { selectable: false, evented: false };
273
+ leftTitleList.forEach(async (v, i) => {
274
+ const baseTop = canvasHeight - lableMargin[1];
275
+ const top = baseTop - i * lableLineHeight;
276
+ const left = lableMargin[0] + treeTableminCellWidth;
277
+ const pointId = `${v.polylineTypeId}_${v.polylineIndex}_-1_polylinePoint_'${new Date().getTime()}_isTitle`;
278
+ const { fill: fillColor = '#000', stroke } = v.pointAttr;
279
+ let text = new this.fabric.Text(String(v.title), {
280
+ fontSize: style.fontSize,
281
+ fill: fillColor && stroke ? stroke : fillColor,
282
+ left,
283
+ top,
284
+ originY: 'center',
285
+ ...defaultVaule.style,
286
+ id: pointId
287
+ });
288
+ const iconLeft = text.width + text.left + 10;
289
+ const option = {
290
+ left: iconLeft,
291
+ top,
292
+ ...v.pointAttr,
293
+ originY: 'center',
294
+ originX: 'center',
295
+ lineAttr: v.lineAttr || '',
296
+ pointAttr: v.pointAttr,
297
+ id: pointId,
298
+ polylineTypeId: v.polylineTypeId,
299
+ polylineIndex: v.polylineIndex,
300
+ ...(v.isAdd && this.eventStyle.evented ? {} : eventStyle),
301
+ rightLimit: v.rightLimit || ''
302
+ };
303
+ let ele;
304
+ if (v.type === 'img' && v.pointAttr?.iconClassName) {
305
+ ele = await this.createImage(v.pointAttr.iconClassName, v.pointAttr);
306
+ }
307
+ const icon = await this.createPoint(v.type, {
308
+ ele: ele || '',
309
+ ...option
310
+ });
311
+ icon.hasControls = icon.hasBorders = false;
312
+ let originTop = top;
313
+ let cloneIconId;
314
+ icon.on('moving', () => {
315
+ // 优化左侧图标太小不容易选中的问题
316
+ if (!icon.url && icon.scaleX == 1.8 && icon.scaleY == 1.8) {
317
+ icon.set({
318
+ scaleX: 1,
319
+ scaleY: 1
320
+ });
321
+ }
322
+
323
+ if (!cloneIconId) {
324
+ cloneIconId = '_polylinePoint_temp_' + new Date().getTime();
325
+ icon.clone(clonedObj => {
326
+ clonedObj.set({
327
+ id: cloneIconId // 此id必须,用于remove节点的时候
328
+ });
329
+ clonedObj.bringForward();
330
+ this.canvas.add(clonedObj);
331
+ });
332
+ }
333
+
334
+ icon.set({ originX: 'center' });
335
+ this.moveLimit(icon);
336
+ icon.left >= originX && icon.left < originX + 5 && (originTop = icon.top);
337
+ if (icon.left >= originX) {
338
+ this.showDrapPopup(icon);
339
+ } else {
340
+ this.isDropVisible = false;
341
+ }
342
+ // this.canvas.renderAll();
343
+ });
344
+ // 标题折线点停止拖拽后 更新
345
+ icon.on('moved', () => {
346
+ this.setLeft(icon);
347
+ icon.set({
348
+ id: icon.id.replace('_isTitle', '')
349
+ });
350
+ // this.canvas.renderAll();
351
+ this.removeTitle();
352
+ this.removePolyline(cloneIconId);
353
+
354
+ if (icon.id.includes('_polylinePoint_') && this.isDropVisible) {
355
+ this.isDropVisible = false;
356
+ if (icon.left >= originX) {
357
+ // this.setEmitFunction(icon);
358
+ this.setAddPointList(icon);
359
+ this.$emit('pointOperation', 'increasePointBatch', this.addPointList);
360
+ this.addPointList = [];
361
+ }
362
+ }
363
+ this.removePolyline(icon.id);
364
+ // 重绘折线标题
365
+ this.drawPolylineTitle();
366
+ });
367
+
368
+ // 优化左侧图标太小不容易选中的问题
369
+ if (icon.evented && !icon.url) {
370
+ const maxVal = Math.max(icon.width * icon.scale, icon.height * icon.scale);
371
+ if (maxVal < 7) {
372
+ icon.set({
373
+ scaleX: 1.8,
374
+ scaleY: 1.8
375
+ });
376
+ }
377
+ }
378
+
379
+ this.canvas.add(text, icon);
380
+ // this.canvas.requestRenderAll();
381
+ });
382
+ },
383
+ // 限制节点新增位置与右侧节点间隔的spaceWidth格子树必须为整数
384
+ setLeft(icon) {
385
+ const { originX } = this.propItems;
386
+ let tempLeft = icon.rightLimit;
387
+
388
+ if (!tempLeft) return;
389
+ const leftLimit = icon.left + this.spaceWidth;
390
+ let i = 0;
391
+ while (tempLeft >= leftLimit) {
392
+ tempLeft = icon.rightLimit - i * this.spaceWidth;
393
+ i++;
394
+ }
395
+ icon.left = tempLeft < originX ? originX : tempLeft;
396
+ },
397
+ // 点移动限制
398
+ moveLimit(point) {
399
+ point.setCoords();
400
+ const { treeTableminCellWidth, endX } = this.propItems;
401
+ const leftLimit = treeTableminCellWidth;
402
+ const rightLimit = point.rightLimit || endX;
403
+ if (point.top < this.propItems.originY) {
404
+ point.set('top', this.propItems.originY);
405
+ }
406
+ if (point.top > this.propItems.endY) {
407
+ point.set('top', this.propItems.endY);
408
+ }
409
+ if (point.left < leftLimit) {
410
+ point.set('left', leftLimit);
411
+ }
412
+ if (point.left > rightLimit) {
413
+ point.set('left', rightLimit);
414
+ }
415
+ },
416
+ removeTitle() {
417
+ this.canvas.forEachObject(obj => {
418
+ if (obj.id && obj.id.includes('isTitle')) {
419
+ this.canvas.remove(obj);
420
+ }
421
+ });
422
+ },
423
+ isLimit(time) {
424
+ const minMinute = Math.min(...this.propItems.xScaleList);
425
+ const maxMinute = Math.max(...this.propItems.xScaleList);
426
+ const getTime = new Date(time).getTime();
427
+ return getTime >= minMinute && getTime <= maxMinute;
428
+ },
429
+ // 设置节点闪烁
430
+ setFlicker() {
431
+ setTimeout(() => {
432
+ if (this.interval) clearInterval(this.interval);
433
+ if (this.flickerablePoints?.length) {
434
+ this.interval = setInterval(() => {
435
+ this.flickerablePoints.forEach(o => o?.set('opacity', o.opacity === 1 ? 0.5 : 1));
436
+ this.canvas.renderAll();
437
+ }, 800);
438
+ }
439
+ });
440
+ },
441
+ // 创建危急值和差异值
442
+ createAttrVaule({ attr, polyline, polylineIndex, polylineType, polylineTypeId }) {
443
+ const { list } = polyline;
444
+ const { max, min } = polyline[attr] || {};
445
+ if (!max && !min) return;
446
+
447
+ const { originX, endX } = this.propItems;
448
+ const isMax = max?.show && max?.value && list.some(v => +v.value >= +max.value && this.isLimit(v.time));
449
+ const isMin = min?.show && min?.value && list.some(v => +v.value <= +min.value && this.isLimit(v.time));
450
+ const lines = [];
451
+
452
+ const drawLine = ({ value, lineStyle }) => {
453
+ const top = this.cumputedY(polylineType, +value);
454
+ return this.drawLine([originX, top, endX, top], { polylineIndex, lineIndex: 0, polylineTypeId, ...(lineStyle || defaultVaule.criticalStyle) });
455
+ };
456
+ const drawText = ({ name, nameStyle }, top) => {
457
+ return new this.fabric.Text(String(name || ''), {
458
+ ...defaultVaule.style,
459
+ ...defaultVaule.textStyle,
460
+ ...nameStyle,
461
+ originY: 'bottom',
462
+ left: originX + 5,
463
+ top: top - 5
464
+ });
465
+ };
466
+ const isDraw = (isMaxOrMin, maxOrMin) => isMaxOrMin && !maxOrMin?.flickerable;
467
+
468
+ if (isDraw(isMax, max)) {
469
+ const line = drawLine(max);
470
+ const text = drawText(max, line.top);
471
+ line.text = text;
472
+ lines.push(line, text);
473
+ }
474
+ if (isDraw(isMin, min)) {
475
+ const line = drawLine(min);
476
+ const text = drawText(min, line.top);
477
+ line.text = text;
478
+ lines.push(line, text);
479
+ }
480
+ this.canvas.add(...lines);
481
+ },
482
+ /**
483
+ * 绘制一条折线
484
+ * @param {polyline} 折线属性
485
+ * @param {polyline.type} 折线点形状 circle: 圆 | triangle: 三角
486
+ * @param {polyline.pointAttr} 参数 fill: 填充色 | stroke: 描边色 | strokeWidth: 宽度 | radius: 半径 | width: 宽度 | height: 高度
487
+ * @param {polyline.list} 折线点坐标数组
488
+ * @param {polylineIndex} 当前折线 index
489
+ */
490
+ drawPolyline(polyline, polylineIndex, polylineType, polylineTypeId) {
491
+ const { originY, endY } = this.propItems;
492
+ const { pointAttr, lineAttr, list = [], critical = {}, diffValue = {} } = polyline;
493
+ this._iconClassName = polyline.type === 'img' && pointAttr.iconClassName ? pointAttr.iconClassName : '';
494
+
495
+ const pointList = [];
496
+ let lineList = [];
497
+ const _this = this;
498
+ function getPointer(point) {
499
+ let isInit = false;
500
+ let points = null;
501
+ if (isEffectiveNode(point) && _this.isLimit(point.time)) {
502
+ const x = _this.cumputedX(point.time);
503
+ const y = _this.cumputedY(polylineType, point.value);
504
+ isInit = y < originY || y > endY;
505
+ points = [x, y < originY ? originY : y > endY ? endY : y];
506
+ }
507
+ return { isInit, points };
508
+ }
509
+ this.flickerablePoints = this.flickerablePoints.filter(point => point.polylineTypeId !== polylineTypeId && point.polylineIndex !== polylineIndex);
510
+ list.forEach((linePoints, index) => {
511
+ // 当前点
512
+ let { points, isInit } = getPointer(linePoints);
513
+
514
+ // 下一个点
515
+ const nextPoints = list[index + 1];
516
+ let { points: nextPoint } = getPointer(nextPoints);
517
+
518
+ let line;
519
+ let point;
520
+ let previousLine;
521
+ line = points && nextPoint ? this.drawLine([...points, ...nextPoint], { polylineIndex, polylineTypeId, lineIndex: index, ...lineAttr }) : null;
522
+ previousLine = lineList[index - 1];
523
+ const pointOthers = { polylineTypeId, polylineIndex, pointIndex: index, ...pointAttr, lineAttr };
524
+ if (points) {
525
+ Object.assign(pointOthers, {
526
+ originLeft: points[0],
527
+ originTop: points[1],
528
+ time: linePoints.time,
529
+ __value: linePoints.value
530
+ });
531
+ point = previousLine ? this.drawPoint(...points, previousLine, line, polyline.type, pointOthers, isInit) : this.drawPoint(...points, null, line, polyline.type, pointOthers, isInit);
532
+ }
533
+ lineList.push(line);
534
+ point && pointList.push(point);
535
+ });
536
+
537
+ Promise.all(pointList).then(res => {
538
+ const polylineObj = this.polylinePointList.find(v => v.polylineTypeId == polylineTypeId && v.polylineIndex == polylineIndex);
539
+ const pointerList = res.map(v => v.left);
540
+ if (polylineObj) {
541
+ Object.assign(polylineObj, {
542
+ pointerList,
543
+ pointList: res
544
+ });
545
+ polylineObj.pointerList = pointerList;
546
+ } else {
547
+ this.polylinePointList.push({
548
+ polylineTypeId,
549
+ polylineIndex,
550
+ pointerList,
551
+ color: lineAttr.stroke,
552
+ pointList: res
553
+ });
554
+ }
555
+ lineList = lineList.filter(v => v);
556
+ let prevPoint = null;
557
+ res = res.filter(v => {
558
+ if (v && prevPoint) {
559
+ prevPoint.nextPoint = v; // 记录下一个点 id
560
+ v.prevPoint = prevPoint;
561
+ }
562
+ prevPoint = v || prevPoint;
563
+ return v;
564
+ });
565
+ this.canvas.add(...lineList, ...res);
566
+
567
+ // 缓存需要闪烁的节点
568
+ setFlickerablePoints.call(this, critical);
569
+ setFlickerablePoints.call(this, diffValue);
570
+ function setFlickerablePoints(diffObj) {
571
+ const { max, min } = diffObj;
572
+ if (max?.flickerable || min?.flickerable) {
573
+ const maxVal = max?.value;
574
+ const minVal = min?.value;
575
+ if (maxVal && max?.flickerable) {
576
+ this.flickerablePoints.push(...res.filter(point => +point.__value >= +maxVal).filter(point => !this.flickerablePoints.some(_point => isSamePoint(point, _point))));
577
+ }
578
+ if (minVal && min?.flickerable) {
579
+ this.flickerablePoints.push(...res.filter(point => +point.__value <= +minVal).filter(point => !this.flickerablePoints.some(_point => isSamePoint(point, _point))));
580
+ }
581
+ }
582
+ }
583
+ function isSamePoint(point, _point) {
584
+ return point.polylineTypeId == _point.polylineTypeId && point.polylineIndex === _point.polylineIndex && point.pointIndex === _point.pointIndex;
585
+ }
586
+ });
587
+
588
+ const params = { polyline, polylineIndex, polylineType, polylineTypeId };
589
+ this.createAttrVaule({ ...params, attr: 'critical' });
590
+ this.createAttrVaule({ ...params, attr: 'diffValue' });
591
+ },
592
+ // 计算y轴坐标
593
+ cumputedY(polylineType, linePointY) {
594
+ const { position = 'left', list = [] } = polylineType;
595
+ const key = position === 'left' ? 'Left' : 'Right';
596
+ const yScaleCell = this.propItems[`yScaleCell${key}`];
597
+ const yCellUnit = linePointY - Math.min(...list);
598
+ return this.propItems.endY - yScaleCell * yCellUnit;
599
+ },
600
+ /**
601
+ * 绘制折线点
602
+ * @param {left, top} 折线点坐标
603
+ * @param {line1, line2} 与折线点关联的线
604
+ * @param {type} 折线点类型
605
+ * @param {others} 参数 polylineIndex | pointIndex | ...polyline.pointAttr
606
+ */
607
+ async drawPoint(left, top, line1, line2, type, others, isInit) {
608
+ const pointId = `${others.polylineTypeId}_${others.polylineIndex}_${others.pointIndex}_polylinePoint_${new Date().getTime()}`;
609
+ const ele = this._iconClassName && (await this.createImage(this._iconClassName, others));
610
+ let point = await this.createPoint(type, {
611
+ id: pointId,
612
+ left: left,
613
+ top: top,
614
+ ele: ele || '',
615
+ ...defaultVaule.pointStyle,
616
+ ...others,
617
+ ...(!this.eventStyle.evented
618
+ ? {
619
+ lockMovementX: true,
620
+ lockMovementY: true
621
+ }
622
+ : {})
623
+ });
624
+ point.hasControls = point.hasBorders = false;
625
+ line1 && (point.line1 = line1);
626
+ line2 && (point.line2 = line2);
627
+ point.on('mouseover', () => {
628
+ this.showDrapPopup(point);
629
+ this.pointToFront(point);
630
+ });
631
+ point.on('mouseout', () => {
632
+ this.isDropVisible = false;
633
+ });
634
+ // 折线点移动中 实时更新相关联的线的坐标
635
+ if (this.eventStyle.evented) {
636
+ point.on('moving', () => {
637
+ this.pointMoveLimit(point, false);
638
+ this.pointMoveUpdateLine(point);
639
+ this.addPoint(point);
640
+ // this.canvas.renderAll();
641
+ this.showDrapPopup(point);
642
+ });
643
+ // 折线点停止拖拽后 更新polyline中对应的坐标
644
+ point.on('moved', () => {
645
+ if (point && point.id.includes('_polylinePoint_')) {
646
+ this.isDropVisible = false;
647
+ this.setEmitFunction(point);
648
+ this.addPointObjList = [];
649
+ }
650
+ });
651
+ point.on('mouseup', event => {
652
+ const { button, isClick } = event;
653
+ if (button == 1 && isClick) {
654
+ // 可配置批量删除当前项目上的点了
655
+ this.currentDelPoint = point;
656
+ }
657
+ });
658
+ }
659
+
660
+ // 超出表格最高或最低值则需要触发pointChange事件并且不能更新视图,否则连接节点判断不会成功
661
+ isInit && this.setEmitFunction(point, isInit);
662
+
663
+ return point;
664
+ },
665
+ // 拖动停止后 设置回调触发方法
666
+ setEmitFunction(point, isInit = false) {
667
+ const { operable } = this.propItems;
668
+ const { data, x, y } = this.getValue(point);
669
+ Object.assign(data, {
670
+ value: { time: operable.lockMovementX ? point.time : x, value: y },
671
+ isInit
672
+ });
673
+ if (this.addPointList.length === 0) {
674
+ if (point.prevPoint?.time.includes(x) || point.nextPoint?.time.includes(x)) {
675
+ // 此方法更新节点后其事件都失效了,暂时采用下方repaintPolyline方法更新整条节点
676
+ // point.setCoords();
677
+ // point.set('left', point.originLeft);
678
+ // point.set({
679
+ // left: point.originLeft,
680
+ // top: point.originTop
681
+ // });
682
+ // this.pointMoveUpdateLine(point);
683
+ this.repaintPolyline(data.position, data.dataIndex);
684
+ return;
685
+ }
686
+ this.$emit('pointChange', data);
687
+ } else {
688
+ this.$nextTick(() => {
689
+ // 拖动新增节点时默认所有节点可删除
690
+ this.currentDelPoint = null;
691
+ });
692
+ const lastPoint = this.addPointList[this.addPointList.length - 1];
693
+ const position = this.polyline[point.polylineTypeId].position;
694
+ const [firstPoint] = this.addPointList;
695
+ // 如果是重合/连线节点
696
+ if (point.get('scaleX') !== point.scale) {
697
+ const addOjb = {
698
+ ...lastPoint,
699
+ value: {
700
+ time: this.getXValue(this._concatPoint?.left),
701
+ value: this.getYValue(position, this._concatPoint?.top)
702
+ }
703
+ };
704
+ if (lastPoint.value.time == addOjb.value.time) {
705
+ this.addPointList.splice(-1, 1, addOjb);
706
+ } else {
707
+ this.addPointList.push(addOjb);
708
+ }
709
+ this.addPointList.forEach(v => Object.assign(v, { isConcat: true, concatIndex: this._concatIndex }));
710
+ } else if (point.line2 || (point.nextPoint && lastPoint.left >= point.nextPoint.left)) {
711
+ // 1、存在右连线 2、无右侧连线,并且存在下一个节点的情况
712
+ this.addPointList = [];
713
+ this.repaintPolyline(position, point.polylineIndex);
714
+ return;
715
+ }
716
+ !point.line2 && firstPoint.left <= point.originLeft && this.addPointList.splice(0, 1);
717
+ !point.id.includes('isTitle') && this.removePolyline(point.id);
718
+ if (this.addPointList.length > 0) {
719
+ this.$emit('pointOperation', 'increasePointBatch', this.addPointList);
720
+ this.addPointList = [];
721
+ } else {
722
+ this.repaintPolyline(position, point.polylineIndex);
723
+ }
724
+ }
725
+ },
726
+ // 设置批量新增数据
727
+ setAddPointList(point) {
728
+ const { data, x, y } = this.getValue(point);
729
+ data.value = { time: x, value: y };
730
+ data.left = point.left;
731
+ data.top = top;
732
+ this.addPointList.push(data);
733
+ },
734
+ // 纠正线段坐标
735
+ setLinePatch(point) {
736
+ const { originLeft, originTop } = point;
737
+ for (let i = 0, len = this.addPointList.length; i < len; i++) {
738
+ const currentPoint = this.addPointList[i];
739
+ const prevPoint = this.addPointList[i - 1] || { left: point.prePoint?.left ?? originLeft, top: point.prePoint?.top ?? originTop };
740
+ const currentPointObj = this.addPointObjList.find(obj => obj.left === currentPoint.left);
741
+ if (currentPointObj?.line1?.x1 !== prevPoint.left) {
742
+ currentPointObj.line1.set({
743
+ x1: prevPoint.left,
744
+ y1: prevPoint.top,
745
+ x2: currentPoint.left,
746
+ y2: currentPoint.top
747
+ });
748
+ }
749
+ }
750
+ },
751
+ // 检查批量新增拖动过程中是否存在漏点的情况
752
+ checkPoints(point) {
753
+ const { originLeft, originTop, left, polylineTypeId } = point;
754
+ const PointLens = Math.floor((left - originLeft) / this.spaceWidth);
755
+ if (PointLens > 1 && this.addPointList?.length <= PointLens) {
756
+ const position = this.polyline[polylineTypeId].position;
757
+ for (let k = 0; k <= PointLens; k++) {
758
+ if (k > 0) {
759
+ const curLeft = originLeft + this.spaceWidth * k;
760
+ // 判断this.addPointList中的left是否包含curLeft,不包含就说明是漏了
761
+ const hasPoint = this.addPointList.some(p => Math.abs(p.left - curLeft) <= 0.001);
762
+ // const hasPoint = this.addPointList.some(v => v.left == curLeft);
763
+ if (!hasPoint) {
764
+ let index;
765
+ const pointObj = this.addPointList.find((v, i) => {
766
+ if (v.left > curLeft) {
767
+ index = i;
768
+ }
769
+ return v.left > curLeft;
770
+ });
771
+ if (pointObj) {
772
+ let cloneObj = JSON.parse(JSON.stringify(pointObj));
773
+ const prePoint = this.addPointList[index - 1] || {
774
+ left: originLeft,
775
+ top: originTop
776
+ };
777
+ const len = ~~((pointObj.left - (curLeft - this.spaceWidth)) / this.spaceWidth);
778
+ const spaceHeight = (pointObj.top - prePoint.top) / len;
779
+ cloneObj.top = prePoint.top + spaceHeight;
780
+ cloneObj.value.time = this.getXValue(curLeft);
781
+ cloneObj.value.value = this.getYValue(position, cloneObj.top);
782
+ cloneObj.left = curLeft;
783
+ this.addPointList.splice(index, 0, cloneObj);
784
+ this.clonePoint(point, [prePoint.left, prePoint.top, cloneObj.left, cloneObj.top]);
785
+ }
786
+ }
787
+ }
788
+ }
789
+ }
790
+ // 纠正节点上的line1的坐标
791
+ this.setLinePatch(point);
792
+ },
793
+ /**
794
+ * @description: 拖动批量新增节点
795
+ * @param {*} point 拖动的最后一个节点
796
+ * @return {*}
797
+ */
798
+ addPoint(point) {
799
+ let { left, top, originLeft, originTop } = point;
800
+ const currentLeft = left;
801
+
802
+ const startLength = this.addPointList.length;
803
+ const n = 6; // 拖动范围,在需要增加节点的刻度左右吸入的范围值
804
+ const residue = (left - originLeft) % this.spaceWidth;
805
+
806
+ const condition = residue > 0 && (residue > this.spaceWidth - n || residue < n);
807
+ const conditionNoLine2 = !point.line2 && left > originLeft;
808
+ const conditionHasLine2 = point.line2 && left > originLeft + this.spaceWidth;
809
+
810
+ // if (!point.line2 && left > originLeft && condition) {
811
+ if (condition && (conditionNoLine2 || conditionHasLine2)) {
812
+ if (residue > this.spaceWidth - n) left = left - residue + this.spaceWidth;
813
+ if (residue < n) left = left - residue;
814
+ point.set({
815
+ left
816
+ });
817
+
818
+ // const i = Math.floor((left - originLeft) / this.spaceWidth);
819
+ // 复制点和线
820
+ if (conditionNoLine2 || conditionHasLine2) {
821
+ // point.line1 && this.removePolyline(point.line1.id);
822
+ setPointLineColor(point, 'transparent', conditionHasLine2);
823
+ this.addPointList.length == 0 && this.clonePoint(point, [point.line1 ? point.line1.x1 : originLeft, point.line1 ? point.line1.y1 : originTop, originLeft, originTop]);
824
+ if (this.addPointList.every(v => v.left !== left)) {
825
+ // const points1 = i === 1 ? [originLeft, originTop] : point.prePoints;
826
+ const points1 = this.addPointList.length == 0 ? [originLeft, originTop] : point.prePoints;
827
+ if (points1) {
828
+ // this.setAddPointList(point);
829
+ // 调用上面方法就会导致线段绘制失败,目前还不知道为啥子
830
+ const { data, x, y } = this.getValue(point);
831
+ data.value = { time: x, value: y };
832
+ data.left = left;
833
+ data.top = top;
834
+ // 避免重复添加
835
+ if (this.addPointObjList.every(o => o.left !== left)) {
836
+ this.addPointList.push(data);
837
+ this.clonePoint(point, [...points1, left, top]);
838
+ }
839
+ }
840
+ }
841
+ this.checkPoints(point);
842
+ }
843
+ }
844
+
845
+ // 断点相连
846
+ function concatPoint(target) {
847
+ const { left: targetLeft, top: targetTop } = target;
848
+ point.setCoords();
849
+ if (left >= targetLeft - n && left <= targetLeft + n && top <= targetTop + n && top >= targetTop - n) {
850
+ point.set({
851
+ left: targetLeft,
852
+ top: targetTop,
853
+ scaleX: point.scale === 1 ? 2.5 : 0.1,
854
+ scaleY: point.scale === 1 ? 2.5 : 0.1
855
+ });
856
+ } else {
857
+ point.set({
858
+ scaleX: point.scale,
859
+ scaleY: point.scale
860
+ });
861
+ }
862
+ }
863
+
864
+ // 检查是否显示重合连线放大节点的标识
865
+ const { polylineTypeId, polylineIndex } = point;
866
+ const polylineObj = this.polylinePointList.find(v => v.polylineTypeId == polylineTypeId && v.polylineIndex == polylineIndex);
867
+ polylineObj?.pointList.forEach(v => v.bringToFront());
868
+ if (point.nextPoint) {
869
+ this._concatIndex = polylineObj?.pointerList.findIndex(v => v + n > left && v > originLeft);
870
+ if (!~this._concatIndex) {
871
+ point.set({
872
+ scaleX: point.scale,
873
+ scaleY: point.scale
874
+ });
875
+ } else {
876
+ concatPoint(polylineObj?.pointList[this._concatIndex]);
877
+ }
878
+ this._concatPoint = polylineObj?.pointList?.[this._concatIndex] || null;
879
+
880
+ // 被覆盖节点置灰配置
881
+ polylineObj?.pointerList.forEach((v, i) => {
882
+ const obj = polylineObj?.pointList[i];
883
+ if (v > originLeft && v < left) {
884
+ // 此处需要递归遍历group节点的所有子节点,然后更改其颜色
885
+ resetPointColor([obj], '#999');
886
+ obj.line2?.set({ stroke: '#999' });
887
+ } else {
888
+ resetPointColor([obj], polylineObj.color);
889
+ obj.line2?.set({ stroke: polylineObj.color });
890
+ }
891
+ });
892
+ if ((point.line1 || point.line2) && left < originLeft + this.spaceWidth) {
893
+ setPointLineColor(point, polylineObj.color, true);
894
+ } else {
895
+ setPointLineColor(point, 'transparent', true);
896
+ }
897
+ }
898
+
899
+ // 如果往回拖动则删除经过的已存在的节点
900
+ if (startLength > 0 && currentLeft <= this.addPointList[startLength - 1].left) {
901
+ this.removePolyline('increasePointBatch', left);
902
+ this.addPointList = this.addPointList.filter(v => v.left < left);
903
+ const endLength = this.addPointList.length;
904
+ if (endLength === 0) {
905
+ setPointLineColor(point, polylineObj?.color, conditionHasLine2);
906
+ this.removePolyline('increasePointBatch', originLeft);
907
+ }
908
+ if (endLength > 0) {
909
+ point.set({
910
+ prePoints: [this.addPointList[endLength - 1].left, this.addPointList[endLength - 1].top]
911
+ });
912
+ }
913
+ }
914
+ },
915
+ clonePoint(point, points) {
916
+ let evented, selectable, lineIndex, polylineIndex, lineAttr, polylineTypeId;
917
+ evented = selectable = false;
918
+ lineAttr = { ...point.lineAttr };
919
+ lineIndex = point.pointIndex;
920
+ polylineIndex = point.polylineIndex;
921
+ polylineTypeId = point.polylineTypeId;
922
+
923
+ // return new Promise((resolve, reject) => {
924
+ point.clone(clonedObj => {
925
+ clonedObj.set({
926
+ left: points[2],
927
+ top: points[3],
928
+ idClone: 'increasePointBatch',
929
+ id: '_polylinePoint_' + new Date().getTime(), // 此id必须,用于remove节点的时候
930
+ polylineTypeId,
931
+ polylineIndex: point.polylineIndex,
932
+ scaleX: point.scale,
933
+ scaleY: point.scale
934
+ });
935
+ clonedObj.hasControls = clonedObj.hasBorders = false;
936
+ point.prePoints = [point.left, point.top];
937
+ const line = this.drawLine([...points], { evented, selectable, ...lineAttr, polylineIndex, polylineTypeId, lineIndex });
938
+ clonedObj.line1 = line;
939
+ this.canvas.sendBackwards(line);
940
+ clonedObj.bringForward();
941
+ this.canvas.add(clonedObj);
942
+ this.addPointObjList.push(clonedObj);
943
+ // resolve(clonedObj);
944
+ });
945
+ // });
946
+ },
947
+ getValue(point) {
948
+ const x = this.getXValue(point.left);
949
+ if (point.id) {
950
+ const data = this.getDataById(point.id);
951
+ const position = data.position;
952
+ const y = this.getYValue(position, point.top);
953
+ return { data, x, y };
954
+ } else {
955
+ const left = this.getYValue('left', point.top);
956
+ const right = this.getYValue('right', point.top);
957
+ return { x, left, right };
958
+ }
959
+ },
960
+ getYValue(position, top) {
961
+ const key = position == 'left' ? 'Left' : 'Right';
962
+ const list = this.polyline.find(item => item.position == position)?.list || [];
963
+ const v = list.length ? Math.min(...list) : 0;
964
+ const y = (this.propItems.endY - top) / this.propItems[`yScaleCell${key}`] + v;
965
+ return y;
966
+ },
967
+ /**
968
+ * 绘制折线点
969
+ * @param {lines} 线坐标 [x1, y1, x2, y2]
970
+ * @param {others} 参数 polylineIndex | pointIndex | ...polyline.lineAttr
971
+ */
972
+ drawLine(lines, others) {
973
+ const lineId = `${others.lineIndex}_${others.polylineIndex}_polylineLine_${new Date().getTime()}`;
974
+ const line = new this.fabric.Line(lines, {
975
+ id: lineId,
976
+ hoverCursor: 'default',
977
+ // objectCaching: false,
978
+ selectable: false,
979
+ evented: false,
980
+ ...others
981
+ });
982
+
983
+ return line;
984
+ },
985
+ formatValue(position, y) {
986
+ if (position == 'right') {
987
+ if (y.toString().includes('.')) {
988
+ const [m, n] = y.toString().split('.');
989
+ return (parseFloat(`${m}.${n.slice(0, 1)}`) * 10) / 10;
990
+ }
991
+ return y;
992
+ } else {
993
+ return Math.round(y);
994
+ }
995
+ },
996
+ showDrapPopup(point) {
997
+ this.isDropVisible = true;
998
+ this.dropPos = {
999
+ left: point.left,
1000
+ top: point.top,
1001
+ margin: { top: this.propItems.yCellHeight }
1002
+ };
1003
+ let { x, y, data } = this.getValue(point);
1004
+ this.dropVal = {
1005
+ title: data.title,
1006
+ list: [
1007
+ { id: '11', name: '时间', value: x },
1008
+ { id: '22', name: '值', value: this.formatValue(data.position, y) }
1009
+ ]
1010
+ };
1011
+ },
1012
+ // 折线点移动时 setCoords()方法手动更新相关联的线坐标
1013
+ pointMoveUpdateLine(point) {
1014
+ if (point.line1) {
1015
+ point.line1.setCoords();
1016
+ point.line1.set({ x2: point.left, y2: point.top });
1017
+ }
1018
+ if (point.line2) {
1019
+ point.line2.setCoords();
1020
+ point.line2.set({ x1: point.left, y1: point.top });
1021
+ }
1022
+ },
1023
+ // 打开右键菜单
1024
+ openRightModal() {
1025
+ const { clientX, pageX, clientY, pageY } = this.activeEvent.e;
1026
+ this.rightPos = {
1027
+ clientX: clientX ?? pageX,
1028
+ clientY: clientY ?? pageY
1029
+ };
1030
+ this.isRightVisible = false;
1031
+ const target = this.activeEvent.target;
1032
+ const id = target?.id || '';
1033
+ this.$nextTick(() => {
1034
+ if (id && id.includes('_polylinePoint_')) {
1035
+ this._currentPoint = target;
1036
+ let nodeConnect = [];
1037
+ if (this.propItems.operable.connect) {
1038
+ if (!target.line2 && target.nextPoint) {
1039
+ nodeConnect = rightClickNodeConnect.slice(0, 1);
1040
+ }
1041
+ if (!target.line1 && target.prevPoint) {
1042
+ nodeConnect = rightClickNodeConnect.slice(1);
1043
+ }
1044
+ if (!target.line1 && !target.line2 && target.prevPoint && target.nextPoint) {
1045
+ nodeConnect = rightClickNodeConnect.slice();
1046
+ }
1047
+ }
1048
+ this.rightClickNode = Object.freeze(
1049
+ rightClickNode
1050
+ .slice(0, 1)
1051
+ .concat(nodeConnect)
1052
+ .concat(rightClickNode.slice(-1))
1053
+ );
1054
+ this.isRightVisible = true;
1055
+ } else if (!id) {
1056
+ const { operable } = this.propItems;
1057
+ this._currentPoint = null;
1058
+ this.rightClickNode = Object.freeze(operable.set ? rightClickNode.slice(0, 2) : rightClickNode.slice(0, 1));
1059
+ this.isRightVisible = true;
1060
+ }
1061
+ });
1062
+ },
1063
+ // 关闭右键菜单,打开添加节点弹窗表单
1064
+ handleRightClick({ type, name }) {
1065
+ this.isRightVisible = false;
1066
+ const id = this._currentPoint?.id;
1067
+ const { left, top } = this._active;
1068
+ let data = id ? this.getDataById(id) : this.getValue({ left, top });
1069
+ if (type == 'add') {
1070
+ if (name.includes('左')) {
1071
+ data.range = {
1072
+ time: [this._currentPoint.prevPoint.time, this._currentPoint.time],
1073
+ direction: 'left'
1074
+ };
1075
+ }
1076
+ if (name.includes('右')) {
1077
+ data.range = {
1078
+ time: [this._currentPoint.time, this._currentPoint.nextPoint.time],
1079
+ direction: 'right'
1080
+ };
1081
+ }
1082
+ }
1083
+ this.$emit('pointOperation', type, data);
1084
+ this._currentPoint = null;
1085
+ },
1086
+ getDataById(id) {
1087
+ const arr = id.replace(/_?[a-zA-Z]+.+$/, '').split('_');
1088
+ const [typeIndex, lineIndex, pointIndex] = arr;
1089
+ const data = this.polyline[typeIndex];
1090
+ const value = data?.dataList?.[lineIndex]?.list?.[pointIndex]?.data || '';
1091
+ return {
1092
+ title: data?.dataList?.[lineIndex].title || '',
1093
+ position: data.position,
1094
+ dataIndex: lineIndex,
1095
+ pointIndex: pointIndex,
1096
+ data: value
1097
+ };
1098
+ },
1099
+ isOnePolyLine(obj, polylineTypeId, polylineIndex) {
1100
+ // 排除左侧标题
1101
+ const isPolyLine = obj.polylineTypeId === polylineTypeId && obj.polylineIndex === polylineIndex;
1102
+ if (obj.id && /_polyline(Point|Line)_/.test(obj.id) && !obj.id.includes('isTitle') && isPolyLine) return true;
1103
+ return;
1104
+ },
1105
+ // 将当条线段以及点层级置顶
1106
+ // 线段不能先置顶,会挡住其他线段上的点
1107
+ pointToFront(point) {
1108
+ this.canvas.forEachObject(obj => {
1109
+ if (this.isOnePolyLine(obj, point.polylineTypeId, point.polylineIndex)) {
1110
+ this.canvas.bringToFront(obj);
1111
+ }
1112
+ });
1113
+ },
1114
+ removePolyline(id, left, position, polylineIndex) {
1115
+ // 根据id或者idClone删除
1116
+ if (id) {
1117
+ const pointId = left ? 'idClone' : 'id';
1118
+ if (pointId === 'idClone') {
1119
+ this.addPointObjList.forEach(obj => {
1120
+ if (obj.left >= left) {
1121
+ this.canvas.remove(obj);
1122
+ obj.line1 && this.canvas.remove(obj.line1);
1123
+ }
1124
+ });
1125
+ this.addPointObjList = this.addPointObjList.filter(obj => obj.left < left);
1126
+ } else {
1127
+ const point = this.canvas.getObjects().filter(item => item[pointId] === id);
1128
+ if (point && point.length > 0) {
1129
+ point.forEach(v => {
1130
+ if (!left) {
1131
+ this.canvas.remove(v);
1132
+ v.line1 && this.canvas.remove(v.line1);
1133
+ }
1134
+ });
1135
+ }
1136
+ }
1137
+
1138
+ return;
1139
+ }
1140
+ // 删除一条线
1141
+ if (position && (polylineIndex === 0 || polylineIndex)) {
1142
+ const polylineTypeId = this.polyline.findIndex(v => v.position === position);
1143
+ this.canvas.forEachObject(obj => {
1144
+ if (this.isOnePolyLine(obj, polylineTypeId, polylineIndex)) {
1145
+ obj.text && this.canvas.remove(obj.text);
1146
+ obj.line1 && this.canvas.remove(obj.line1);
1147
+ obj.line2 && this.canvas.remove(obj.line2);
1148
+ this.canvas.remove(obj);
1149
+ }
1150
+ });
1151
+ return;
1152
+ }
1153
+ // 删除折线图上的所有点和线
1154
+ this.canvas.forEachObject(obj => {
1155
+ if (obj.id && /_polyline(Point|Line)_/.test(obj.id) && !obj.id.includes('isTitle')) {
1156
+ obj.text && this.canvas.remove(obj.text);
1157
+ this.canvas.remove(obj);
1158
+ }
1159
+ });
1160
+ },
1161
+ removeSelectArea() {
1162
+ if (this.selectArea) {
1163
+ this.canvas.remove(this.selectArea);
1164
+ this.selectArea = null;
1165
+ }
1166
+ },
1167
+ repaintPolyline(position, dadaIndex) {
1168
+ if (arguments.length < 2) {
1169
+ if (this.polyline.length) {
1170
+ this.removePolyline();
1171
+ }
1172
+ this.polylinePointList = [];
1173
+ this.flickerablePoints = [];
1174
+ this.polyline.forEach((polylineType, polylineTypeId) => {
1175
+ this.createPolyline(polylineType, polylineTypeId);
1176
+ });
1177
+ this.removeTitle();
1178
+ this.drawPolylineTitle();
1179
+ } else {
1180
+ const polylineTypeId = this.polyline.findIndex(v => v.position === position);
1181
+ this.removePolyline(null, null, position, parseInt(dadaIndex));
1182
+ this.drawPolyline(this.polyline[polylineTypeId].dataList[parseInt(dadaIndex)], parseInt(dadaIndex), this.polyline[polylineTypeId], polylineTypeId);
1183
+ }
1184
+ }
1185
+ },
1186
+ beforeDestroy() {
1187
+ clearInterval(this.interval);
1188
+ this.interval = null;
1189
+ }
1190
+ };
1191
+ </script>