@flexem/fc-gui 3.0.0-alpha.16 → 3.0.0-alpha.160

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 (567) hide show
  1. package/CHANGELOG.md +492 -69
  2. package/README.md +4 -4
  3. package/assets/img/alert.svg +18 -18
  4. package/assets/img/black_first_page.png +0 -0
  5. package/assets/img/black_last_page.png +0 -0
  6. package/assets/img/black_next_page.png +0 -0
  7. package/assets/img/black_previous_page.png +0 -0
  8. package/assets/img/first_page.svg +19 -19
  9. package/assets/img/last_page.svg +19 -19
  10. package/assets/img/next_page.svg +14 -14
  11. package/assets/img/previous_page.svg +14 -14
  12. package/bundles/@flexem/fc-gui.umd.js +25472 -20764
  13. package/bundles/@flexem/fc-gui.umd.js.map +1 -1
  14. package/bundles/@flexem/fc-gui.umd.min.js +5 -5
  15. package/bundles/@flexem/fc-gui.umd.min.js.map +1 -1
  16. package/communication/index.d.ts +1 -1
  17. package/communication/index.js +1 -1
  18. package/communication/variable/index.d.ts +5 -5
  19. package/communication/variable/index.js +4 -4
  20. package/communication/variable/variable-communicator.d.ts +16 -12
  21. package/communication/variable/variable-definition.d.ts +10 -10
  22. package/communication/variable/variable-definition.js +14 -14
  23. package/communication/variable/variable-state-enum.d.ts +8 -7
  24. package/communication/variable/variable-state-enum.js +9 -8
  25. package/communication/variable/variable-state-enum.metadata.json +1 -1
  26. package/communication/variable/variable-state.d.ts +6 -6
  27. package/communication/variable/variable-state.js +6 -6
  28. package/communication/variable/variable-value.d.ts +11 -8
  29. package/communication/variable/variable-value.js +11 -8
  30. package/communication/variable/variable-value.metadata.json +1 -1
  31. package/config/alarm/alarm.store.d.ts +6 -0
  32. package/config/alarm/alarm.store.js +0 -0
  33. package/config/alarm/alarm.store.metadata.json +1 -0
  34. package/config/alarm/get-alarms-args.d.ts +12 -0
  35. package/config/alarm/get-alarms-args.js +13 -0
  36. package/config/alarm/get-alarms-args.metadata.json +1 -0
  37. package/config/alarm/index.d.ts +2 -0
  38. package/config/alarm/index.js +1 -0
  39. package/config/alarm/index.metadata.json +1 -0
  40. package/config/config-store.d.ts +17 -15
  41. package/config/graph/graph-result.d.ts +9 -9
  42. package/config/graph/graph-result.js +13 -13
  43. package/config/graph/graph-store.d.ts +9 -9
  44. package/config/graph/graph-type.d.ts +4 -4
  45. package/config/graph/graph-type.js +5 -5
  46. package/config/graph/graph.d.ts +6 -6
  47. package/config/graph/graph.js +6 -6
  48. package/config/gui-feature-config.d.ts +3 -0
  49. package/config/gui-feature-config.js +3 -0
  50. package/config/gui-feature-config.metadata.json +1 -0
  51. package/config/history-data/get-history-data-args.d.ts +22 -22
  52. package/config/history-data/get-history-data-args.js +21 -21
  53. package/config/history-data/historical-curve.time-range.d.ts +18 -18
  54. package/config/history-data/historical-curve.time-range.js +19 -19
  55. package/config/history-data/history-data-value.d.ts +6 -6
  56. package/config/history-data/history-data-value.js +6 -6
  57. package/config/history-data/history-data.model.d.ts +7 -7
  58. package/config/history-data/history-data.model.js +7 -7
  59. package/config/history-data/history-data.store.d.ts +10 -10
  60. package/config/history-data/index.d.ts +4 -4
  61. package/config/history-data/index.js +3 -3
  62. package/config/image/image-store.d.ts +6 -6
  63. package/config/index.d.ts +12 -10
  64. package/config/index.js +8 -6
  65. package/config/index.metadata.json +1 -1
  66. package/config/variable/get-variable-name-args.d.ts +6 -6
  67. package/config/variable/get-variable-name-args.js +7 -7
  68. package/config/variable/index.d.ts +2 -2
  69. package/config/variable/index.js +1 -1
  70. package/config/variable/variable-store.d.ts +8 -7
  71. package/config/view/view-store.d.ts +20 -20
  72. package/config/view/view.model.d.ts +4 -4
  73. package/config/view/view.model.js +5 -5
  74. package/core/index.d.ts +1 -1
  75. package/core/index.js +1 -1
  76. package/core/stringifying-map.d.ts +11 -11
  77. package/core/stringifying-map.js +24 -24
  78. package/core/stringifying-set.d.ts +10 -10
  79. package/core/stringifying-set.js +21 -21
  80. package/elements/air-quality/air-quality-element.d.ts +31 -0
  81. package/elements/air-quality/air-quality-element.js +194 -0
  82. package/elements/air-quality/air-quality-element.metadata.json +1 -0
  83. package/elements/alarm/alarm-element.d.ts +69 -0
  84. package/elements/alarm/alarm-element.js +497 -0
  85. package/elements/alarm/alarm-element.metadata.json +1 -0
  86. package/elements/bar-graph-element.d.ts +29 -21
  87. package/elements/bar-graph-element.js +244 -114
  88. package/elements/bar-graph-element.metadata.json +1 -1
  89. package/elements/base/base-element.d.ts +11 -11
  90. package/elements/base/base-element.js +9 -9
  91. package/elements/base/conditional-control-element.d.ts +16 -16
  92. package/elements/base/conditional-control-element.js +87 -87
  93. package/elements/base/conditional-display-element.d.ts +24 -24
  94. package/elements/base/conditional-display-element.js +86 -86
  95. package/elements/base/conditional-dynamic-display-element.d.ts +26 -26
  96. package/elements/base/conditional-dynamic-display-element.js +142 -142
  97. package/elements/base/conditional-enable-element.d.ts +21 -21
  98. package/elements/base/conditional-enable-element.js +100 -100
  99. package/elements/base/index.d.ts +3 -3
  100. package/elements/base/index.js +3 -3
  101. package/elements/base/readable-element.d.ts +20 -15
  102. package/elements/base/readable-element.js +122 -58
  103. package/elements/base/readable-element.metadata.json +1 -1
  104. package/elements/base/state-control-element.d.ts +26 -24
  105. package/elements/base/state-control-element.js +196 -180
  106. package/elements/character-display/character-display-element.d.ts +35 -35
  107. package/elements/character-display/character-display-element.js +312 -311
  108. package/elements/character-display/character-display-element.metadata.json +1 -1
  109. package/elements/datetime-display/datetime-display-element.d.ts +22 -21
  110. package/elements/datetime-display/datetime-display-element.js +140 -132
  111. package/elements/datetime-display/datetime-display-element.metadata.json +1 -1
  112. package/elements/datetime-display/time-zone-select-json.d.ts +8 -0
  113. package/elements/datetime-display/time-zone-select-json.js +558 -0
  114. package/elements/historical-curve/historical-curve-element-status.d.ts +6 -6
  115. package/elements/historical-curve/historical-curve-element-status.js +7 -7
  116. package/elements/historical-curve/historical-curve.element.d.ts +96 -59
  117. package/elements/historical-curve/historical-curve.element.js +990 -364
  118. package/elements/historical-curve/historical-curve.element.metadata.json +1 -1
  119. package/elements/historical-curve/historical-curve.element.option.d.ts +13 -13
  120. package/elements/historical-curve/historical-curve.time-period.d.ts +4 -4
  121. package/elements/main-element.d.ts +46 -45
  122. package/elements/main-element.js +373 -307
  123. package/elements/main-element.metadata.json +1 -1
  124. package/elements/meter-element.d.ts +26 -20
  125. package/elements/meter-element.js +139 -70
  126. package/elements/meter-element.metadata.json +1 -1
  127. package/elements/numerical-display/numerical-display-element.d.ts +60 -41
  128. package/elements/numerical-display/numerical-display-element.js +476 -361
  129. package/elements/numerical-display/numerical-display-element.metadata.json +1 -1
  130. package/elements/per-view-variable-communicator.d.ts +20 -17
  131. package/elements/per-view-variable-communicator.js +59 -45
  132. package/elements/per-view-variable-communicator.metadata.json +1 -1
  133. package/elements/pipe/pipe-element.d.ts +19 -19
  134. package/elements/pipe/pipe-element.js +141 -141
  135. package/elements/ring-graph/ring-graph-element.d.ts +31 -19
  136. package/elements/ring-graph/ring-graph-element.js +250 -89
  137. package/elements/ring-graph/ring-graph-element.metadata.json +1 -1
  138. package/elements/scroll-alarm/scroll-alarm-element.d.ts +74 -0
  139. package/elements/scroll-alarm/scroll-alarm-element.js +761 -0
  140. package/elements/scroll-alarm/scroll-alarm-element.metadata.json +1 -0
  141. package/elements/shared/graph/graph-state-element.d.ts +28 -27
  142. package/elements/shared/graph/graph-state-element.js +139 -110
  143. package/elements/shared/graph/graph-state-element.metadata.json +1 -1
  144. package/elements/shared/math-utils.d.ts +2 -2
  145. package/elements/shared/math-utils.js +14 -14
  146. package/elements/shared/text/text-element.d.ts +22 -8
  147. package/elements/shared/text/text-element.js +106 -68
  148. package/elements/shared/text/text-element.metadata.json +1 -1
  149. package/elements/shared/text/text-state-element.d.ts +58 -23
  150. package/elements/shared/text/text-state-element.js +286 -136
  151. package/elements/shared/text/text-state-element.metadata.json +1 -1
  152. package/elements/shared/text/text-state.model.d.ts +5 -5
  153. package/elements/shared/text/text-utils.d.ts +5 -5
  154. package/elements/shared/text/text-utils.js +45 -45
  155. package/elements/static-elements/hyperlink-element.d.ts +40 -14
  156. package/elements/static-elements/hyperlink-element.js +197 -48
  157. package/elements/static-elements/hyperlink-element.metadata.json +1 -1
  158. package/elements/static-elements/image-element.d.ts +14 -14
  159. package/elements/static-elements/image-element.js +41 -41
  160. package/elements/static-elements/text-element.d.ts +42 -16
  161. package/elements/static-elements/text-element.js +205 -55
  162. package/elements/static-elements/text-element.metadata.json +1 -1
  163. package/elements/switch-indicator-light/bit-indicator-light-operator.d.ts +21 -20
  164. package/elements/switch-indicator-light/bit-indicator-light-operator.js +85 -78
  165. package/elements/switch-indicator-light/bit-indicator-light-operator.metadata.json +1 -1
  166. package/elements/switch-indicator-light/bit-switch-operator.d.ts +19 -19
  167. package/elements/switch-indicator-light/bit-switch-operator.js +107 -107
  168. package/elements/switch-indicator-light/current-stateId-value.d.ts +6 -6
  169. package/elements/switch-indicator-light/current-stateId-value.js +8 -8
  170. package/elements/switch-indicator-light/indicator-light-operator.d.ts +8 -8
  171. package/elements/switch-indicator-light/switch-indicator-light-element.d.ts +48 -39
  172. package/elements/switch-indicator-light/switch-indicator-light-element.js +302 -251
  173. package/elements/switch-indicator-light/switch-indicator-light-element.metadata.json +1 -1
  174. package/elements/switch-indicator-light/switch-operator.d.ts +6 -6
  175. package/elements/switch-indicator-light/word-indicator-light-operator.d.ts +19 -18
  176. package/elements/switch-indicator-light/word-indicator-light-operator.js +72 -65
  177. package/elements/switch-indicator-light/word-indicator-light-operator.metadata.json +1 -1
  178. package/elements/switch-indicator-light/word-switch-operator.d.ts +18 -18
  179. package/elements/switch-indicator-light/word-switch-operator.js +75 -75
  180. package/elements/table/table-element.d.ts +9 -9
  181. package/elements/table/table-element.js +6 -6
  182. package/elements/vector-graphics/ellipse-element.d.ts +9 -9
  183. package/elements/vector-graphics/ellipse-element.js +6 -6
  184. package/elements/vector-graphics/poly-line-element.d.ts +12 -12
  185. package/elements/vector-graphics/poly-line-element.js +19 -19
  186. package/elements/vector-graphics/polygon-element.d.ts +12 -12
  187. package/elements/vector-graphics/polygon-element.js +19 -19
  188. package/elements/vector-graphics/rectangle-element.d.ts +9 -9
  189. package/elements/vector-graphics/rectangle-element.js +6 -6
  190. package/elements/vector-graphics/sector-element.d.ts +9 -9
  191. package/elements/vector-graphics/sector-element.js +6 -6
  192. package/elements/vector-graphics/straight-line-element.d.ts +12 -12
  193. package/elements/vector-graphics/straight-line-element.js +19 -19
  194. package/elements/video/video-element.d.ts +37 -27
  195. package/elements/video/video-element.js +258 -160
  196. package/elements/video/video-element.metadata.json +1 -1
  197. package/elements/view-operation/view-operation.element.d.ts +62 -36
  198. package/elements/view-operation/view-operation.element.js +348 -194
  199. package/elements/view-operation/view-operation.element.metadata.json +1 -1
  200. package/elements/weather/weater-element.d.ts +38 -38
  201. package/elements/weather/weater-element.js +237 -238
  202. package/gui/gui-context.d.ts +33 -16
  203. package/gui/gui-host.d.ts +50 -50
  204. package/gui/gui-host.js +173 -173
  205. package/gui/gui-view.d.ts +45 -42
  206. package/gui/gui-view.js +265 -204
  207. package/gui/gui-view.metadata.json +1 -1
  208. package/gui/gui.component.d.ts +45 -42
  209. package/gui/gui.component.html +3 -3
  210. package/gui/gui.component.js +240 -227
  211. package/gui/gui.component.metadata.json +1 -1
  212. package/gui/interfaces/gui-options.d.ts +6 -6
  213. package/gui.module.d.ts +2 -2
  214. package/gui.module.js +78 -78
  215. package/localization/index.d.ts +2 -2
  216. package/localization/index.js +2 -2
  217. package/localization/localization.service.d.ts +62 -51
  218. package/localization/localization.service.js +61 -50
  219. package/localization/localization.service.metadata.json +1 -1
  220. package/localization/localization.service.zh_CN.d.ts +2 -2
  221. package/localization/localization.service.zh_CN.js +59 -48
  222. package/localization/localization.service.zh_CN.metadata.json +1 -1
  223. package/logger/console-logger.service.d.ts +13 -13
  224. package/logger/console-logger.service.js +38 -38
  225. package/logger/index.d.ts +2 -2
  226. package/logger/index.js +2 -2
  227. package/logger/logger.service.d.ts +14 -14
  228. package/logger/logger.service.js +2 -2
  229. package/modal/alert/alert-modal.component.d.ts +10 -10
  230. package/modal/alert/alert-modal.component.html +11 -11
  231. package/modal/alert/alert-modal.component.js +38 -38
  232. package/modal/alert/alert-modal.component.less +59 -59
  233. package/modal/confirm-operation/confirm-operation-modal.component.d.ts +10 -10
  234. package/modal/confirm-operation/confirm-operation-modal.component.html +16 -16
  235. package/modal/confirm-operation/confirm-operation-modal.component.js +41 -41
  236. package/modal/confirm-operation/confirm-operation-modal.component.less +58 -58
  237. package/modal/verify-password/verify-password-modal.component.d.ts +18 -18
  238. package/modal/verify-password/verify-password-modal.component.html +22 -22
  239. package/modal/verify-password/verify-password-modal.component.js +66 -66
  240. package/modal/verify-password/verify-password-modal.component.less +65 -65
  241. package/modal/write-character/write-character-modal-args.d.ts +7 -7
  242. package/modal/write-character/write-character-modal-args.js +8 -8
  243. package/modal/write-character/write-character-modal.component.d.ts +25 -25
  244. package/modal/write-character/write-character-modal.component.html +21 -21
  245. package/modal/write-character/write-character-modal.component.js +74 -74
  246. package/modal/write-character/write-character-modal.component.less +49 -49
  247. package/modal/write-value/write-value-modal-args.d.ts +16 -12
  248. package/modal/write-value/write-value-modal-args.js +14 -12
  249. package/modal/write-value/write-value-modal-args.metadata.json +1 -1
  250. package/modal/write-value/write-value-modal.component.d.ts +60 -54
  251. package/modal/write-value/write-value-modal.component.html +26 -21
  252. package/modal/write-value/write-value-modal.component.js +279 -204
  253. package/modal/write-value/write-value-modal.component.less +56 -56
  254. package/modal/write-value/write-value-modal.component.metadata.json +1 -1
  255. package/modal/write-value/write-value-model-result.d.ts +3 -3
  256. package/model/air-quality/air-quality-info.d.ts +23 -0
  257. package/model/air-quality/air-quality-info.js +4 -0
  258. package/model/air-quality/air-quality-info.metadata.json +1 -0
  259. package/model/air-quality/air-quality.model.d.ts +7 -0
  260. package/model/air-quality/air-quality.model.js +0 -0
  261. package/model/air-quality/air-quality.model.metadata.json +1 -0
  262. package/model/alarm/alarm.model.d.ts +13 -0
  263. package/model/alarm/alarm.model.js +0 -0
  264. package/model/alarm/alarm.model.metadata.json +1 -0
  265. package/model/bar-graph/FontStyleData.d.ts +7 -7
  266. package/model/bar-graph/bar-graph-direction.d.ts +6 -6
  267. package/model/bar-graph/bar-graph-direction.js +7 -7
  268. package/model/bar-graph/bar-graph.d.ts +26 -22
  269. package/model/base/base-element-model.d.ts +5 -5
  270. package/model/base/base-element-model.js +2 -2
  271. package/model/base/conditional-control-model.d.ts +6 -6
  272. package/model/base/conditional-display-model.d.ts +9 -9
  273. package/model/base/conditional-dynamic-display-model.d.ts +13 -13
  274. package/model/base/conditional-enable-model.d.ts +9 -9
  275. package/model/base/font-setting-model.d.ts +29 -8
  276. package/model/base/font-setting-model.metadata.json +1 -1
  277. package/model/base/index.d.ts +7 -7
  278. package/model/base/index.js +1 -1
  279. package/model/base/readable-model.d.ts +14 -10
  280. package/model/base/security-model.d.ts +6 -6
  281. package/model/character-display/character-display.d.ts +19 -19
  282. package/model/datetime-display/date-format-type.d.ts +5 -5
  283. package/model/datetime-display/date-format-type.js +6 -6
  284. package/model/datetime-display/datetime-display-settings.d.ts +17 -17
  285. package/model/datetime-display/datetime-display.d.ts +21 -20
  286. package/model/datetime-display/datetime-separator-type.d.ts +6 -6
  287. package/model/datetime-display/datetime-separator-type.js +7 -7
  288. package/model/datetime-display/time-format-type.d.ts +4 -4
  289. package/model/datetime-display/time-format-type.js +5 -5
  290. package/model/historical-curve/curve-type.d.ts +5 -5
  291. package/model/historical-curve/curve-type.js +6 -6
  292. package/model/historical-curve/historical-curve-axis-settings.d.ts +17 -6
  293. package/model/historical-curve/historical-curve-axis-settings.js +5 -0
  294. package/model/historical-curve/historical-curve-axis-settings.metadata.json +1 -1
  295. package/model/historical-curve/historical-curve-chanel.model.d.ts +22 -14
  296. package/model/historical-curve/historical-curve.data-settings.d.ts +9 -9
  297. package/model/historical-curve/historical-curve.display-settings.d.ts +19 -19
  298. package/model/historical-curve/historical-curve.model.d.ts +8 -8
  299. package/model/historical-curve/index.d.ts +4 -4
  300. package/model/hyperlink/hyperlink.model.d.ts +8 -8
  301. package/model/image/image-fill-type.d.ts +4 -4
  302. package/model/image/image-fill-type.js +5 -5
  303. package/model/image/image.d.ts +9 -9
  304. package/model/index.d.ts +15 -15
  305. package/model/index.js +8 -8
  306. package/model/meter/meter.d.ts +17 -13
  307. package/model/numerical-display/index.d.ts +8 -8
  308. package/model/numerical-display/index.js +2 -2
  309. package/model/numerical-display/numerical-display.d.ts +29 -29
  310. package/model/numerical-display/numerical-operation-settings.d.ts +6 -6
  311. package/model/numerical-display/numerical-operation-type.d.ts +4 -4
  312. package/model/numerical-display/numerical-operation-type.js +5 -5
  313. package/model/numerical-display/numerical-operation.d.ts +19 -11
  314. package/model/numerical-display/proportional-conversion.d.ts +4 -4
  315. package/model/numerical-display/type-settings.d.ts +6 -6
  316. package/model/numerical-display/zoom.d.ts +4 -4
  317. package/model/pipe/flow-direction-type.d.ts +4 -4
  318. package/model/pipe/flow-direction-type.js +5 -5
  319. package/model/pipe/index.d.ts +2 -2
  320. package/model/pipe/index.js +1 -1
  321. package/model/pipe/pipe.d.ts +17 -17
  322. package/model/poly-line/poly-line-model.d.ts +4 -4
  323. package/model/polygon/polygon-model.d.ts +4 -4
  324. package/model/ring-graph/ring-graph.model.d.ts +33 -25
  325. package/model/scroll-alarm/scroll-alarm.model.d.ts +21 -0
  326. package/model/scroll-alarm/scroll-alarm.model.js +0 -0
  327. package/model/scroll-alarm/scroll-alarm.model.metadata.json +1 -0
  328. package/model/settings/background/view-background-fill-type.d.ts +5 -5
  329. package/model/settings/background/view-background-fill-type.js +6 -6
  330. package/model/settings/background/view-background.model.d.ts +8 -8
  331. package/model/settings/index.d.ts +3 -3
  332. package/model/settings/index.js +2 -2
  333. package/model/settings/popup/view-popup-backdrop-type.d.ts +4 -4
  334. package/model/settings/popup/view-popup-backdrop-type.js +5 -5
  335. package/model/settings/popup/view-popup-location-type.d.ts +4 -4
  336. package/model/settings/popup/view-popup-location-type.js +5 -5
  337. package/model/settings/popup/view-popup-setting.model.d.ts +17 -17
  338. package/model/settings/popup/view-popup-setting.model.js +2 -2
  339. package/model/settings/view-settings.model.d.ts +6 -6
  340. package/model/shared/alarm/alarm-range.model.d.ts +6 -6
  341. package/model/shared/arc.model.d.ts +4 -4
  342. package/model/shared/binary.d.ts +7 -7
  343. package/model/shared/binary.js +37 -37
  344. package/model/shared/condition/bit-condition-item-observer.d.ts +14 -14
  345. package/model/shared/condition/bit-condition-item-observer.js +53 -53
  346. package/model/shared/condition/bit-condition-logic.d.ts +4 -4
  347. package/model/shared/condition/bit-condition-logic.js +5 -5
  348. package/model/shared/condition/bit-condition-model.d.ts +8 -8
  349. package/model/shared/condition/bit-condition.d.ts +4 -4
  350. package/model/shared/condition/condition-control-result-value.d.ts +5 -5
  351. package/model/shared/condition/condition-helper.d.ts +4 -4
  352. package/model/shared/condition/condition-helper.js +22 -22
  353. package/model/shared/condition/condition-item-model.d.ts +10 -10
  354. package/model/shared/condition/condition-item-observer.d.ts +12 -12
  355. package/model/shared/condition/condition-item-observer.js +14 -14
  356. package/model/shared/condition/condition-items-observer.d.ts +5 -5
  357. package/model/shared/condition/condition-items-result-observer.d.ts +16 -16
  358. package/model/shared/condition/condition-items-result-observer.js +87 -87
  359. package/model/shared/condition/condition-model.d.ts +6 -6
  360. package/model/shared/condition/condition-type.d.ts +4 -4
  361. package/model/shared/condition/condition-type.js +5 -5
  362. package/model/shared/condition/convert-condition-model.d.ts +5 -5
  363. package/model/shared/condition/index.d.ts +11 -11
  364. package/model/shared/condition/index.js +4 -4
  365. package/model/shared/condition/relation-condition-result-state.d.ts +6 -6
  366. package/model/shared/condition/relation-condition-result-state.js +8 -8
  367. package/model/shared/condition/relation-condition-result.d.ts +8 -8
  368. package/model/shared/condition/relation-condition-result.js +7 -7
  369. package/model/shared/condition/relation-type.d.ts +5 -5
  370. package/model/shared/condition/relation-type.js +6 -6
  371. package/model/shared/condition/relational-operator.d.ts +8 -8
  372. package/model/shared/condition/relational-operator.js +9 -9
  373. package/model/shared/condition/variable-value-logic-model.d.ts +11 -11
  374. package/model/shared/condition/variable-value-type.d.ts +4 -4
  375. package/model/shared/condition/variable-value-type.js +5 -5
  376. package/model/shared/condition/word-condition-item-observer.d.ts +21 -21
  377. package/model/shared/condition/word-condition-item-observer.js +165 -165
  378. package/model/shared/condition/word-condition-model.d.ts +8 -8
  379. package/model/shared/condition/word-condition.d.ts +5 -5
  380. package/model/shared/data-type/display-data-type.d.ts +5 -5
  381. package/model/shared/data-type/display-data-type.js +6 -6
  382. package/model/shared/data-type/fbox-data-type.d.ts +15 -15
  383. package/model/shared/data-type/fbox-data-type.js +16 -16
  384. package/model/shared/data-type/fcloud-data-Type.d.ts +8 -8
  385. package/model/shared/data-type/fcloud-data-Type.js +9 -9
  386. package/model/shared/dynamic-display/dynamic-behavior-type.d.ts +5 -5
  387. package/model/shared/dynamic-display/dynamic-behavior-type.js +6 -6
  388. package/model/shared/dynamic-display/dynamic-display-behavior-model.d.ts +5 -5
  389. package/model/shared/dynamic-display/dynamic-display-model.d.ts +10 -10
  390. package/model/shared/dynamic-display/dynamic-display-result-model.d.ts +7 -7
  391. package/model/shared/dynamic-display/dynamic-display-result-model.js +7 -7
  392. package/model/shared/dynamic-display/dynamic-display.d.ts +11 -11
  393. package/model/shared/dynamic-display/dynamic-display.js +35 -35
  394. package/model/shared/graph/custom-style.d.ts +14 -14
  395. package/model/shared/graph/graph-setting.d.ts +10 -10
  396. package/model/shared/index.d.ts +8 -8
  397. package/model/shared/index.js +3 -3
  398. package/model/shared/point.model.d.ts +4 -4
  399. package/model/shared/rotation/rotation-behavior-model.d.ts +4 -4
  400. package/model/shared/rotation/rotation-behavior.d.ts +9 -9
  401. package/model/shared/rotation/rotation-behavior.js +101 -101
  402. package/model/shared/rotation/rotation-direction-type.d.ts +4 -4
  403. package/model/shared/rotation/rotation-direction-type.js +5 -5
  404. package/model/shared/rotation/rotation-model.d.ts +14 -14
  405. package/model/shared/rotation/rotation-observer-model.d.ts +4 -4
  406. package/model/shared/rotation/rotation-observer.d.ts +11 -11
  407. package/model/shared/rotation/rotation-observer.js +28 -28
  408. package/model/shared/scale/scale-mark.model.d.ts +6 -6
  409. package/model/shared/scale/scale-model.d.ts +20 -20
  410. package/model/shared/size.model.d.ts +7 -7
  411. package/model/shared/size.model.js +12 -12
  412. package/model/shared/state/index.d.ts +1 -1
  413. package/model/shared/state/index.js +1 -1
  414. package/model/shared/state/state.d.ts +9 -8
  415. package/model/shared/state/state.js +10 -9
  416. package/model/shared/state/state.metadata.json +1 -1
  417. package/model/shared/text/font.d.ts +10 -10
  418. package/model/shared/text/index.d.ts +2 -2
  419. package/model/shared/text/text.d.ts +8 -5
  420. package/model/shared/translation/translation-behavior-model.d.ts +4 -4
  421. package/model/shared/translation/translation-behavior.d.ts +12 -12
  422. package/model/shared/translation/translation-behavior.js +63 -63
  423. package/model/shared/translation/translation-direction-type.d.ts +4 -4
  424. package/model/shared/translation/translation-direction-type.js +5 -5
  425. package/model/shared/translation/translation-model.d.ts +12 -12
  426. package/model/shared/translation/translation-observer-model.d.ts +4 -4
  427. package/model/shared/translation/translation-observer.d.ts +10 -10
  428. package/model/shared/translation/translation-observer.js +27 -27
  429. package/model/shared/variable/variable-identifier.model.d.ts +5 -5
  430. package/model/shared/variable/variable-name.model.d.ts +5 -5
  431. package/model/straight-line/straight-line-model.d.ts +4 -4
  432. package/model/switch-indicator-light/bit-indicator-light-settings.d.ts +8 -8
  433. package/model/switch-indicator-light/bit-switch-operation.d.ts +6 -6
  434. package/model/switch-indicator-light/bit-switch-operation.js +7 -7
  435. package/model/switch-indicator-light/bit-switch-settings.d.ts +11 -11
  436. package/model/switch-indicator-light/fault-flicker.d.ts +5 -5
  437. package/model/switch-indicator-light/flicker.d.ts +5 -5
  438. package/model/switch-indicator-light/flicker.js +6 -6
  439. package/model/switch-indicator-light/index.d.ts +14 -14
  440. package/model/switch-indicator-light/index.js +5 -5
  441. package/model/switch-indicator-light/indicator-light-fault-flicker.d.ts +5 -5
  442. package/model/switch-indicator-light/indicator-light-settings.d.ts +7 -7
  443. package/model/switch-indicator-light/indicator-light-type.d.ts +4 -4
  444. package/model/switch-indicator-light/indicator-light-type.js +5 -5
  445. package/model/switch-indicator-light/switch-indicator-light.d.ts +35 -33
  446. package/model/switch-indicator-light/switch-indicator-state.d.ts +8 -8
  447. package/model/switch-indicator-light/switch-settings.d.ts +7 -7
  448. package/model/switch-indicator-light/switch-type.d.ts +4 -4
  449. package/model/switch-indicator-light/switch-type.js +5 -5
  450. package/model/switch-indicator-light/word-indicator-light-settings.d.ts +6 -6
  451. package/model/switch-indicator-light/word-switch-operation.d.ts +5 -5
  452. package/model/switch-indicator-light/word-switch-operation.js +6 -6
  453. package/model/switch-indicator-light/word-switch-settings.d.ts +13 -13
  454. package/model/table/table-model.d.ts +9 -9
  455. package/model/text/text.model.d.ts +7 -7
  456. package/model/video/video.model.d.ts +8 -8
  457. package/model/view-operation/index.d.ts +2 -2
  458. package/model/view-operation/index.js +1 -1
  459. package/model/view-operation/view-operation-element.model.d.ts +25 -19
  460. package/model/view-operation/view-operation-type.d.ts +18 -18
  461. package/model/view-operation/view-operation-type.js +19 -19
  462. package/model/weather/weather-info.d.ts +11 -11
  463. package/model/weather/weather-info.js +2 -2
  464. package/model/weather/weather.model.d.ts +7 -7
  465. package/package.json +1 -1
  466. package/public_api.d.ts +14 -14
  467. package/public_api.js +12 -11
  468. package/remote/communication/variable/remote-variable-communicator.d.ts +59 -30
  469. package/remote/communication/variable/remote-variable-communicator.js +395 -215
  470. package/remote/communication/variable/remote-variable-communicator.metadata.json +1 -1
  471. package/remote/communication/variable/remote-variable-protocol.d.ts +18 -13
  472. package/remote/config/graph/get-released-graph-state-result.d.ts +6 -6
  473. package/remote/config/graph/get-released-graph-states.d.ts +4 -4
  474. package/remote/config/graph/graph-state-key.d.ts +6 -6
  475. package/remote/config/graph/graph-state-result.d.ts +5 -5
  476. package/remote/config/graph/graph-state.d.ts +4 -4
  477. package/remote/config/graph/remote-graph-protocol.d.ts +11 -11
  478. package/remote/config/graph/remote-graph-store.d.ts +16 -16
  479. package/remote/config/graph/remote-graph-store.js +101 -101
  480. package/remote/config/image/remote-image-protocol.d.ts +4 -4
  481. package/remote/config/image/remote-image-store.d.ts +8 -8
  482. package/remote/config/image/remote-image-store.js +19 -19
  483. package/remote/config/view/remote-view-protocol.d.ts +8 -8
  484. package/remote/config/view/remote-view-store.d.ts +13 -13
  485. package/remote/config/view/remote-view-store.js +39 -39
  486. package/remote/config/view/view-result.d.ts +4 -4
  487. package/remote/index.d.ts +14 -14
  488. package/remote/index.js +4 -4
  489. package/security/index.d.ts +1 -1
  490. package/security/security-checker.d.ts +3 -3
  491. package/service/index.d.ts +8 -4
  492. package/service/index.js +1 -0
  493. package/service/index.metadata.json +1 -1
  494. package/service/language.service.d.ts +37 -0
  495. package/service/language.service.js +0 -0
  496. package/service/language.service.metadata.json +1 -0
  497. package/service/operation-record/create-operation-record-args.d.ts +5 -5
  498. package/service/operation-record/index.d.ts +3 -3
  499. package/service/operation-record/operation-record.service.d.ts +4 -4
  500. package/service/operation-record/variable-option.model.d.ts +5 -5
  501. package/service/permission-checker.d.ts +3 -3
  502. package/service/released-variable/index.d.ts +1 -0
  503. package/service/released-variable/index.js +0 -0
  504. package/service/released-variable/index.metadata.json +1 -0
  505. package/service/released-variable/released-variable.service.d.ts +4 -0
  506. package/service/released-variable/released-variable.service.js +0 -0
  507. package/service/released-variable/released-variable.service.metadata.json +1 -0
  508. package/service/system-text-library.service.d.ts +77 -0
  509. package/service/system-text-library.service.js +29 -0
  510. package/service/system-text-library.service.metadata.json +1 -0
  511. package/service/text-library.service.d.ts +49 -0
  512. package/service/text-library.service.js +0 -0
  513. package/service/text-library.service.metadata.json +1 -0
  514. package/service/video/index.d.ts +2 -2
  515. package/service/video/video-url.d.ts +4 -4
  516. package/service/video/video.service.d.ts +4 -4
  517. package/service/weather.service.d.ts +4 -3
  518. package/settings/display-mode.d.ts +10 -10
  519. package/settings/display-mode.js +11 -11
  520. package/settings/global-settings.d.ts +7 -7
  521. package/settings/global-settings.js +13 -13
  522. package/settings/index.d.ts +3 -3
  523. package/settings/index.js +3 -3
  524. package/settings/view-resize-mode.d.ts +10 -10
  525. package/settings/view-resize-mode.js +11 -11
  526. package/shared/config-is-empty-error.d.ts +3 -3
  527. package/shared/config-is-empty-error.js +7 -7
  528. package/shared/disposable.d.ts +3 -3
  529. package/shared/graph-extended-style.d.ts +4 -4
  530. package/shared/gui-consts.d.ts +33 -30
  531. package/shared/gui-consts.js +33 -30
  532. package/shared/gui-consts.metadata.json +1 -1
  533. package/shared/index.d.ts +5 -5
  534. package/shared/index.js +3 -3
  535. package/shared/operation-helper.d.ts +6 -6
  536. package/shared/operation-helper.js +38 -38
  537. package/utils/access-permission.d.ts +5 -5
  538. package/utils/access-permission.js +6 -6
  539. package/utils/access-permission.service.d.ts +11 -11
  540. package/utils/access-permission.service.js +30 -30
  541. package/utils/auto-focus.directive.d.ts +6 -6
  542. package/utils/auto-focus.directive.js +27 -27
  543. package/utils/bs-modal-drag.directive.d.ts +7 -7
  544. package/utils/bs-modal-drag.directive.js +38 -38
  545. package/utils/data-type/data-type.service.d.ts +57 -57
  546. package/utils/data-type/data-type.service.js +155 -155
  547. package/utils/data-type/fbox-data-type.service.d.ts +54 -54
  548. package/utils/data-type/fbox-data-type.service.js +300 -260
  549. package/utils/data-type/fcloud-data-type.service.d.ts +55 -55
  550. package/utils/data-type/fcloud-data-type.service.js +203 -203
  551. package/utils/fraction-digit.service.d.ts +41 -41
  552. package/utils/fraction-digit.service.js +133 -133
  553. package/utils/graph-util.d.ts +5 -5
  554. package/utils/graph-util.js +19 -19
  555. package/utils/guid.d.ts +6 -6
  556. package/utils/guid.js +27 -27
  557. package/utils/index.d.ts +7 -7
  558. package/utils/index.js +7 -7
  559. package/utils/numerical-operation-type.d.ts +4 -4
  560. package/utils/numerical-operation-type.js +5 -5
  561. package/utils/numerical-operation.service.d.ts +17 -17
  562. package/utils/numerical-operation.service.js +201 -177
  563. package/utils/variable-util.d.ts +5 -5
  564. package/utils/variable-util.js +11 -11
  565. package/view/popup-view.service.d.ts +7 -7
  566. package/view/view.service.d.ts +6 -6
  567. package/view/view.service.js +20 -20
@@ -1,364 +1,990 @@
1
- import * as d3 from 'd3';
2
- import { each, first, last } from 'lodash';
3
- import * as moment from 'moment';
4
- import * as nv from 'nvd3';
5
- import { GetHistoryDataArgs } from '../../config';
6
- import { HistoricalCurveTimeRange } from '../../config/history-data/historical-curve.time-range';
7
- import { LOCALIZATION } from '../../localization';
8
- import { ConditionalDisplayElement } from '../base/conditional-display-element';
9
- import { HistoricalCurveElementStatus } from './historical-curve-element-status';
10
- import { LOGGER_SERVICE_TOKEN } from '../../logger';
11
- import { GlobalSettings, DisplayMode } from '../../settings';
12
- import { CurveType } from '../../model/historical-curve/curve-type';
13
- export class HistoricalCurveElement extends ConditionalDisplayElement {
14
- constructor(element, injector, permissionChecker, variableCommunicator, variableStore, historyDataStore, signalRAppId) {
15
- super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
16
- this.historyDataStore = historyDataStore;
17
- this.displayOption = {
18
- dataLimit: 500,
19
- dataZoomHeight: 32,
20
- marginLeft: 40,
21
- marginRight: 20,
22
- mobileMinWidth: 450,
23
- operationAreaHeight: 32,
24
- operationAreaMarginTop: 10,
25
- operationSelectFontSize: '16px',
26
- operationButtonWidth: 24,
27
- operationButtonHeight: 24,
28
- operationButtonMargin: 4
29
- };
30
- this.elementStatus = HistoricalCurveElementStatus.Loading;
31
- this.logger = injector.get(LOGGER_SERVICE_TOKEN);
32
- this.localization = injector.get(LOCALIZATION);
33
- this.timePeriods = this.getValidTimePeriods();
34
- this.updateTimeRange(this.model.displaySetting.displayTimePeriod);
35
- this.refreshIntervalId = setInterval(() => {
36
- this.loadFirstPage();
37
- this.logger.debug(`[GUI]Refresh Histoical Curve:${d3.time.format('%x %X')(new Date())}`);
38
- }, this.model.displaySetting.refreshInterval * 1000);
39
- this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
40
- if (this.isMobileMode) {
41
- this.displayOption.operationAreaMarginTop = 20;
42
- if (this.model.displaySetting.size.width >= this.displayOption.mobileMinWidth) {
43
- this.displayOption.operationAreaHeight = 68;
44
- this.displayOption.operationSelectFontSize = '24px';
45
- this.displayOption.operationButtonWidth = 60;
46
- this.displayOption.operationButtonHeight = 60;
47
- this.displayOption.operationButtonMargin = 6;
48
- }
49
- }
50
- this.loadFirstPage();
51
- }
52
- dispose() {
53
- clearInterval(this.refreshIntervalId);
54
- if (this.chartElement) {
55
- this.chartElement.tooltip.hidden(true);
56
- }
57
- this.logger.debug(`[GUI]Dispose Histoical Curve Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
58
- }
59
- getValidTimePeriods() {
60
- const timePeriods = new Array();
61
- timePeriods.push({ key: 1, name: this.localization.lastOneHour });
62
- timePeriods.push({ key: 2, name: this.localization.lastTwentyFourHours });
63
- timePeriods.push({ key: 3, name: this.localization.lastSevenDays });
64
- timePeriods.push({ key: 4, name: this.localization.lastThirtyDays });
65
- timePeriods.push({ key: 5, name: this.localization.lastOneYear });
66
- return timePeriods;
67
- }
68
- updateTimeRange(timePeriodType) {
69
- this.currentTimePeriod = +timePeriodType;
70
- this.updateQueryTimeRange();
71
- }
72
- updateQueryTimeRange() {
73
- this.endTime = moment();
74
- switch (this.currentTimePeriod) {
75
- case 1:
76
- this.startTime = moment().subtract(1, 'hours');
77
- break;
78
- case 3:
79
- this.startTime = moment().subtract(7, 'days');
80
- break;
81
- case 4:
82
- this.startTime = moment().subtract(30, 'days');
83
- break;
84
- case 5:
85
- this.startTime = moment().subtract(1, 'years');
86
- break;
87
- default:
88
- this.startTime = moment().subtract(1, 'days');
89
- }
90
- }
91
- reRenderElement(startTime, endTime, limit, rangeType) {
92
- this.rootElement.selectAll('*').remove();
93
- this.chartElement = null;
94
- this.renderElement(startTime, endTime, limit, rangeType);
95
- }
96
- renderElement(startTime, endTime, limit, rangeType) {
97
- if (!this.model.dataSetting) {
98
- return;
99
- }
100
- const dataItemName = this.model.dataSetting.dataName;
101
- const dataSourceCode = this.model.dataSetting.dataSourceCode;
102
- const channelNames = this.model.dataSetting.channels.map(c => c.name);
103
- this.updateElementStatus(HistoricalCurveElementStatus.Loading);
104
- const input = new GetHistoryDataArgs(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType);
105
- this.historyDataStore.getHistoryData(input).subscribe(result => {
106
- if (result.error) {
107
- this.updateElementStatus(HistoricalCurveElementStatus.LoadFailed, result.error);
108
- }
109
- else {
110
- this.clearStatus();
111
- if (result.isUnbind) {
112
- this.updateElementStatus(HistoricalCurveElementStatus.Unbound);
113
- }
114
- else {
115
- this.updateElementStatus(HistoricalCurveElementStatus.Normal);
116
- }
117
- if (result.values.length) {
118
- this.currentStartTime = moment(first(result.values).time);
119
- this.currentEndTime = moment(last(result.values).time);
120
- }
121
- this.chartElement = this.renderChart(result.values);
122
- }
123
- });
124
- }
125
- renderChart(result) {
126
- const chartWidth = this.model.displaySetting.size.width;
127
- const chartHeight = this.model.displaySetting.size.height - this.displayOption.operationAreaHeight - this.displayOption.operationAreaMarginTop;
128
- const data = new Array();
129
- each(this.model.dataSetting.channels, (channel, key) => {
130
- const values = new Array();
131
- each(result, v => values.push({ x: moment(v.time).local().toDate().valueOf(), y: v.values[key] }));
132
- data.push({ key: channel.name, area: channel.projectEnabled, values: values });
133
- });
134
- nv.addGraph(() => {
135
- if (this.model.displaySetting.curveType === CurveType.BarGroup || this.model.displaySetting.curveType === CurveType.BarStack) {
136
- return this.getMultiBarWithFocusChart(chartWidth, chartHeight, data);
137
- }
138
- else {
139
- return this.getLineChart(chartWidth, chartHeight, data);
140
- }
141
- });
142
- }
143
- getLineChart(chartWidth, chartHeight, data) {
144
- const chart = nv.models.lineChart().showLegend(true)
145
- .margin({ top: 0, bottom: 0, left: this.displayOption.marginLeft, right: this.displayOption.marginRight })
146
- .noData(this.localization.chartNoData);
147
- if (!this.isMobileMode) {
148
- chart.focusEnable(true);
149
- chart.focus.margin({ top: 10, right: 0, bottom: 0, left: 0 });
150
- chart.focus.height(40);
151
- chart.focus.showXAxis(false);
152
- }
153
- this.renderCommonProperty(chart, chartWidth, chartHeight, data);
154
- this.renderOperationArea(chartWidth, chartHeight);
155
- return chart;
156
- }
157
- getMultiBarWithFocusChart(chartWidth, chartHeight, data) {
158
- const chart = nv.models.multiBarWithFocusChart()
159
- .margin({
160
- top: 0, bottom: 0, left: this.displayOption.marginLeft, right: this.displayOption.marginRight
161
- })
162
- .controlLabels({
163
- grouped: this.localization.grouped, stacked: this.localization.stacked
164
- })
165
- .noData(this.localization.chartNoData);
166
- if (this.model.displaySetting.curveType === CurveType.BarStack) {
167
- chart.stacked(true);
168
- chart.multibar.stacked(true);
169
- chart.multibar2.stacked(true);
170
- }
171
- if (!this.isMobileMode) {
172
- chart.focusEnable(true);
173
- chart.focusShowAxisX(false);
174
- }
175
- chart.xAxis.tickFormat(d => this.timeFormat(d, '%x %X'));
176
- this.renderCommonProperty(chart, chartWidth, chartHeight, data);
177
- this.renderOperationArea(chartWidth, chartHeight);
178
- const focusContext = this.rootElement.select('.nv-context');
179
- focusContext.select('.nv-barsWrap.nvd3-svg').attr('transform', 'translate(0,30)');
180
- focusContext.select('.nv-brushBackground').attr('transform', 'translate(0,30)');
181
- focusContext.select('.nv-x.nv-brush').attr('transform', 'translate(0,30)');
182
- if (!this.model.displaySetting.showAxis) {
183
- this.rootElement.select('.tick.zero').style('display', 'none');
184
- this.rootElement.select('.nv-x.nv-axis.nvd3-svg').style('display', 'none');
185
- this.rootElement.select('.nv-y.nv-axis.nvd3-svg').style('display', 'none');
186
- }
187
- chart.update();
188
- return chart;
189
- }
190
- renderCommonProperty(chart, chartWidth, chartHeight, data) {
191
- chart.tooltip.headerFormatter(d => this.timeFormat(d, '%x %X'));
192
- if (this.model.displaySetting.showAxis) {
193
- chart.xAxis.showMaxMin(true).tickFormat(d => this.timeFormat(d, '%X'));
194
- if (this.model.displaySetting.axisSetting) {
195
- if (this.model.displaySetting.axisSetting.showAxisLabel && this.model.displaySetting.axisSetting.axisLabelFont) {
196
- chart.xAxis.fontSize(this.model.displaySetting.axisSetting.axisLabelFont.fontSize);
197
- chart.yAxis.fontSize(this.model.displaySetting.axisSetting.axisLabelFont.fontSize).tickFormat(d => +d3.format('.9g')(d));
198
- }
199
- else {
200
- chart.xAxis.tickFormat(() => '');
201
- chart.yAxis.tickFormat(() => '');
202
- }
203
- }
204
- }
205
- else {
206
- chart.showXAxis(false);
207
- chart.showYAxis(false);
208
- }
209
- chart.width(chartWidth);
210
- chart.height(chartHeight);
211
- chart.color(this.model.dataSetting.channels.map(c => c.connectorColor));
212
- this.rootElement.append('g').datum(data).call(chart);
213
- this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
214
- nv.utils.windowResize(() => {
215
- chart.update();
216
- this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
217
- });
218
- this.rootElement.selectAll('.domain').style('stroke-opacity', 1);
219
- if (this.model.displaySetting.showAxis && this.model.displaySetting.axisSetting) {
220
- const axisColor = this.model.displaySetting.axisSetting.axisColor;
221
- this.rootElement.selectAll('.domain').style('stroke', axisColor);
222
- if (this.model.displaySetting.axisSetting.showAxisLabel) {
223
- const fontSize = this.model.displaySetting.axisSetting.axisLabelFont.fontSize;
224
- this.rootElement.selectAll('.nv-axisMaxMin').select('text').style('font-size', fontSize);
225
- }
226
- }
227
- }
228
- renderOperationArea(chartWidth, chartHeight) {
229
- const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop})`)
230
- .append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight).attr('fill', 'none')
231
- .append('xhtml:div').style('height', (this.displayOption.operationAreaHeight - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
232
- const selectElement = operationArea.append('select').style('margin-left', this.displayOption.marginLeft + 'px')
233
- .style('font-size', this.displayOption.operationSelectFontSize).on('change', () => {
234
- const displayTimePeriod = this.rootElement.select('select').property('value');
235
- this.updateTimeRange(displayTimePeriod);
236
- this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
237
- });
238
- const options = selectElement.selectAll('option').data(this.timePeriods).enter().append('option');
239
- options.text(d => d.name).attr('value', d => d.key).property('selected', d => d.key === Number(this.currentTimePeriod));
240
- const buttonWidth = this.displayOption.operationButtonWidth + 'px', buttonHeight = this.displayOption.operationButtonHeight + 'px';
241
- operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
242
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/last_page.svg)')
243
- .on('click', () => { this.loadLastPage(); });
244
- operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
245
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/next_page.svg)')
246
- .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
247
- .on('click', () => { this.loadNextPage(); });
248
- operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
249
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/previous_page.svg)')
250
- .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
251
- .on('click', () => { this.loadPreviousPage(); });
252
- operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
253
- .style('float', 'right').style('background', 'white').style('background-image', 'url(assets/img/first_page.svg)')
254
- .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
255
- .on('click', () => { this.loadFirstPage(); });
256
- }
257
- timeFormat(datetime, specifier) {
258
- return d3.time.format(specifier)(new Date(datetime));
259
- }
260
- loadFirstPage() {
261
- this.updateQueryTimeRange();
262
- this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
263
- }
264
- loadNextPage() {
265
- this.reRenderElement(this.currentEndTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndClose);
266
- }
267
- loadPreviousPage() {
268
- this.reRenderElement(this.startTime, this.currentStartTime, -this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginCloseEndOpen);
269
- }
270
- loadLastPage() {
271
- this.updateQueryTimeRange();
272
- this.reRenderElement(this.startTime, this.endTime, -this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
273
- }
274
- initElementStatus() {
275
- if (this.model.dataSetting && null != this.model.dataSetting.dataSourceCode) {
276
- this.updateElementStatus(HistoricalCurveElementStatus.Loading);
277
- }
278
- }
279
- updateElementStatus(status, error) {
280
- switch (status) {
281
- case HistoricalCurveElementStatus.Normal:
282
- if (this.elementStatus !== HistoricalCurveElementStatus.Normal) {
283
- this.elementStatus = HistoricalCurveElementStatus.Normal;
284
- }
285
- break;
286
- case HistoricalCurveElementStatus.Unbound:
287
- this.elementStatus = HistoricalCurveElementStatus.Unbound;
288
- this.setStatusAsUnbound();
289
- break;
290
- case HistoricalCurveElementStatus.Loading:
291
- if (this.elementStatus !== HistoricalCurveElementStatus.Unbound) {
292
- this.elementStatus = HistoricalCurveElementStatus.Loading;
293
- this.setStatusAsLoading();
294
- }
295
- break;
296
- case HistoricalCurveElementStatus.LoadFailed:
297
- if (this.elementStatus !== HistoricalCurveElementStatus.Unbound) {
298
- this.elementStatus = HistoricalCurveElementStatus.LoadFailed;
299
- this.setStatusAsLoadFailed(error ? error : this.localization.abnormal);
300
- }
301
- break;
302
- default:
303
- this.logger.error(`Invalid HistoricalCurveElementStatus:${status}`);
304
- break;
305
- }
306
- }
307
- setStatusAsUnbound() {
308
- this.renderStatus('assets/img/unbind.svg', this.localization.unbind, '#586e7c');
309
- }
310
- setStatusAsLoading() {
311
- this.renderStatus('assets/img/loading.svg', this.localization.loading, '#226abc');
312
- }
313
- setStatusAsLoadFailed(error) {
314
- this.logger.error(`[GUI]Failed to load historical curve:${error}`);
315
- this.renderStatus('assets/img/abnormal.svg', error, '#f6a520');
316
- }
317
- renderStatus(icon, tip, stroke) {
318
- if (this.elementStatus === HistoricalCurveElementStatus.Normal) {
319
- this.clearStatus();
320
- return;
321
- }
322
- this.rootElement.append('rect').attr('id', 'StateFrame').attr('fill', 'transparent')
323
- .attr('width', this.model.displaySetting.size.width)
324
- .attr('height', this.model.displaySetting.size.height);
325
- const document = this.$element[0].ownerDocument;
326
- const currentRect = this.$element.find('rect#StateFrame').first();
327
- if (!currentRect.length) {
328
- return;
329
- }
330
- this.$element.find('image#StateImage').remove();
331
- const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
332
- if (imgObj) {
333
- let x = Number(currentRect[0].getAttribute('width')) - 20;
334
- const currentRectX = currentRect[0].getAttribute('x');
335
- if (currentRectX !== null) {
336
- x += Number(currentRectX);
337
- }
338
- currentRect[0].setAttribute('stroke', stroke);
339
- currentRect[0].setAttribute('stroke-opacity', '0.5');
340
- imgObj.href.baseVal = icon;
341
- imgObj.setAttributeNS(null, 'id', 'StateImage');
342
- imgObj.setAttributeNS(null, 'x', x.toString());
343
- imgObj.setAttributeNS(null, 'y', '0');
344
- imgObj.setAttributeNS(null, 'height', '20px');
345
- imgObj.setAttributeNS(null, 'width', '20px');
346
- const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
347
- const text = document.createTextNode(tip);
348
- titleElement.appendChild(text);
349
- imgObj.appendChild(titleElement);
350
- this.$element.append(imgObj);
351
- }
352
- }
353
- clearStatus() {
354
- const currentRect = this.$element.find('rect#StateFrame').first();
355
- if (!currentRect.length) {
356
- return;
357
- }
358
- const stroke = currentRect[0].getAttribute('stroke');
359
- if (stroke) {
360
- currentRect[0].removeAttribute('stroke');
361
- }
362
- this.$element.find('image#StateImage').remove();
363
- }
364
- }
1
+ import * as d3 from 'd3';
2
+ import { each, first, last } from 'lodash';
3
+ import * as moment from 'moment';
4
+ import * as nv from 'nvd3';
5
+ import { GetHistoryDataArgs } from '../../config';
6
+ import { HistoricalCurveTimeRange } from '../../config/history-data/historical-curve.time-range';
7
+ import { LOCALIZATION } from '../../localization';
8
+ import { SYSTEM_TEXT_LIBRARY_TYPES, TIME_PERIOD_KEYS } from '../../service';
9
+ import { ConditionalDisplayElement } from '../base/conditional-display-element';
10
+ import { HistoricalCurveElementStatus } from './historical-curve-element-status';
11
+ import { LOGGER_SERVICE_TOKEN } from '../../logger';
12
+ import { GlobalSettings, DisplayMode } from '../../settings';
13
+ import { CurveType } from '../../model/historical-curve/curve-type';
14
+ import { AxisRangeType } from '../../model/historical-curve/historical-curve-axis-settings';
15
+ export class HistoricalCurveElement extends ConditionalDisplayElement {
16
+ constructor(element, injector, permissionChecker, variableCommunicator, variableStore, historyDataStore, signalRAppId, systemTextLibraryService, languageService, guiContext) {
17
+ super(element, permissionChecker, variableCommunicator, variableStore, signalRAppId);
18
+ this.historyDataStore = historyDataStore;
19
+ this.systemTextLibraryService = systemTextLibraryService;
20
+ this.languageService = languageService;
21
+ this.guiContext = guiContext;
22
+ this.displayOption = {
23
+ dataLimit: 500,
24
+ dataZoomHeight: 32,
25
+ marginLeft: 40,
26
+ marginRight: 20,
27
+ mobileMinWidth: 450,
28
+ operationAreaHeight: 32,
29
+ operationAreaMarginTop: 25,
30
+ operationSelectFontSize: '16px',
31
+ operationButtonWidth: 24,
32
+ operationButtonHeight: 24,
33
+ operationButtonMargin: 4
34
+ };
35
+ this.customStartTime = null;
36
+ this.customEndTime = null;
37
+ this.elementStatus = HistoricalCurveElementStatus.Loading;
38
+ this.data = [];
39
+ this.needResize = true;
40
+ this.dropdownListEl = null;
41
+ this.dropdownTriggerEl = null;
42
+ this.setNeedResize = () => {
43
+ this.needResize = false;
44
+ setTimeout(() => this.needResize = true, 500);
45
+ };
46
+ this.logger = injector.get(LOGGER_SERVICE_TOKEN);
47
+ this.localization = injector.get(LOCALIZATION);
48
+ this.updateTimeRange(this.model.displaySetting.displayTimePeriod);
49
+ this.refreshIntervalId = setInterval(() => {
50
+ this.loadFirstPage();
51
+ this.logger.debug(`[GUI]Refresh Histoical Curve:${d3.time.format('%x %X')(new Date())}`);
52
+ }, this.model.displaySetting.refreshInterval * 1000);
53
+ this.isMobileMode = DisplayMode.Mobile === injector.get(GlobalSettings).displayMode;
54
+ if (this.isMobileMode) {
55
+ this.displayOption.operationAreaMarginTop = 35;
56
+ if (this.model.displaySetting.size.width >= this.displayOption.mobileMinWidth) {
57
+ this.displayOption.operationAreaHeight = 68;
58
+ this.displayOption.operationSelectFontSize = '24px';
59
+ this.displayOption.operationButtonWidth = 60;
60
+ this.displayOption.operationButtonHeight = 60;
61
+ this.displayOption.operationButtonMargin = 6;
62
+ }
63
+ }
64
+ // 初始化时间段数据(此时文本库可能未加载,先填充空文本占位)
65
+ this.timePeriods = this.getValidTimePeriods();
66
+ this.loadFirstPage();
67
+ this.initKeyboardListener();
68
+ // 订阅语种变化事件 和 文本库缓存更新事件
69
+ this.subscribeLanguageChange();
70
+ }
71
+ dispose() {
72
+ clearInterval(this.refreshIntervalId);
73
+ if (this.chartElement) {
74
+ this.chartElement.tooltip.hidden(true);
75
+ }
76
+ if (this.resizeEventListener) {
77
+ this.resizeEventListener.clear();
78
+ }
79
+ if (this.isAndroid) {
80
+ window.removeEventListener('native.keyboardshow', this.setNeedResize);
81
+ window.removeEventListener('native.keyboardhide', this.setNeedResize);
82
+ }
83
+ // 取消语种变化订阅
84
+ if (this.languageChangeSubscription) {
85
+ this.languageChangeSubscription.unsubscribe();
86
+ this.languageChangeSubscription = undefined;
87
+ }
88
+ this.logger.debug(`[GUI]Dispose Histoical Curve Refresh Interval:${d3.time.format('%x %X')(new Date())}`);
89
+ }
90
+ initKeyboardListener() {
91
+ this.isAndroid = !!navigator.userAgent.match(/(Android)/i);
92
+ if (this.isAndroid) {
93
+ window.addEventListener('native.keyboardshow', this.setNeedResize);
94
+ window.addEventListener('native.keyboardhide', this.setNeedResize);
95
+ }
96
+ }
97
+ /**
98
+ * 订阅语种变化事件
99
+ */
100
+ subscribeLanguageChange() {
101
+ var _a;
102
+ if (this.guiContext && this.guiContext.languageChanged$) {
103
+ this.languageChangeSubscription = this.guiContext.languageChanged$.subscribe(() => {
104
+ // 只更新时间段选择器的文案,不重新查询数据
105
+ this.updateLanguageTexts();
106
+ });
107
+ }
108
+ // 订阅文本库缓存更新事件,解决首次加载时文本库未就绪导致下拉选项为空的问题
109
+ if ((_a = this.systemTextLibraryService) === null || _a === void 0 ? void 0 : _a.cacheUpdated) {
110
+ const cacheSubscription = this.systemTextLibraryService.cacheUpdated.subscribe(() => {
111
+ this.updateLanguageTexts();
112
+ });
113
+ if (this.languageChangeSubscription) {
114
+ this.languageChangeSubscription.add(cacheSubscription);
115
+ }
116
+ else {
117
+ this.languageChangeSubscription = cacheSubscription;
118
+ }
119
+ }
120
+ }
121
+ /**
122
+ * 更新语种相关的文案(时间段选择器)
123
+ */
124
+ updateLanguageTexts() {
125
+ const updatedTimePeriods = this.getValidTimePeriods();
126
+ this.timePeriods = updatedTimePeriods;
127
+ // 更新下拉列表各选项文字
128
+ if (this.dropdownListEl) {
129
+ const items = this.dropdownListEl.querySelectorAll('.hc-dropdown-item');
130
+ items.forEach((item, i) => {
131
+ if (i < updatedTimePeriods.length) {
132
+ item.textContent = updatedTimePeriods[i].name;
133
+ }
134
+ });
135
+ // 文字更新后重新测量宽度,修正首次加载时文字为空导致宽度过小的问题
136
+ const prevDisplay = this.dropdownListEl.style.display;
137
+ const prevVisibility = this.dropdownListEl.style.visibility;
138
+ this.dropdownListEl.style.display = 'block';
139
+ this.dropdownListEl.style.visibility = 'hidden';
140
+ this.dropdownListEl.style.width = '';
141
+ const newWidth = this.dropdownListEl.offsetWidth;
142
+ this.dropdownListEl.style.display = prevDisplay;
143
+ this.dropdownListEl.style.visibility = prevVisibility;
144
+ this.dropdownListEl.style.width = newWidth + 'px';
145
+ if (this.dropdownTriggerEl) {
146
+ this.dropdownTriggerEl.style.width = newWidth + 'px';
147
+ }
148
+ }
149
+ // 更新触发按钮文字(显示当前选中项的最新语言文案)
150
+ if (this.dropdownTriggerEl) {
151
+ const selected = updatedTimePeriods.find(p => p.key === Number(this.currentTimePeriod));
152
+ if (selected) {
153
+ const textNode = Array.from(this.dropdownTriggerEl.childNodes).find(n => n.nodeType === Node.TEXT_NODE);
154
+ if (textNode) {
155
+ textNode.textContent = selected.name;
156
+ }
157
+ else {
158
+ this.dropdownTriggerEl.insertBefore(document.createTextNode(selected.name), this.dropdownTriggerEl.firstChild);
159
+ }
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * 获取当前语种的 culture 代码
165
+ */
166
+ getCurrentCulture() {
167
+ var _a, _b, _c, _d, _e, _f;
168
+ // 获取当前语种ID
169
+ const currentLanguageId = (_c = (_b = (_a = this.guiContext) === null || _a === void 0 ? void 0 : _a.getCurrentLanguageId) === null || _b === void 0 ? void 0 : _b.call(_a)) !== null && _c !== void 0 ? _c : null;
170
+ // 确定要使用的语种代码(culture)
171
+ const defaultLanguage = ((_d = this.languageService) === null || _d === void 0 ? void 0 : _d.getDefaultLanguage()) || 'zh-CN';
172
+ if (currentLanguageId === null || currentLanguageId === undefined) {
173
+ // 设备未设置当前语种,使用默认语种
174
+ return defaultLanguage;
175
+ }
176
+ else {
177
+ // 设备已设置当前语种,获取对应的语种代码
178
+ const currentLanguage = (_f = (_e = this.guiContext) === null || _e === void 0 ? void 0 : _e.getLanguageCultureById) === null || _f === void 0 ? void 0 : _f.call(_e, currentLanguageId);
179
+ if (currentLanguage) {
180
+ return currentLanguage;
181
+ }
182
+ else {
183
+ // 无法获取语种代码,使用默认语种
184
+ return defaultLanguage;
185
+ }
186
+ }
187
+ }
188
+ getValidTimePeriods() {
189
+ const timePeriods = new Array();
190
+ timePeriods.push({ key: 6, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_MINUTES) });
191
+ timePeriods.push({ key: 1, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_HOUR) });
192
+ timePeriods.push({ key: 7, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_EIGHT_HOURS) });
193
+ timePeriods.push({ key: 2, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_TWENTY_FOUR_HOURS) });
194
+ timePeriods.push({ key: 3, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_SEVEN_DAYS) });
195
+ timePeriods.push({ key: 4, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_THIRTY_DAYS) });
196
+ timePeriods.push({ key: 5, name: this.getTimePeriodText(TIME_PERIOD_KEYS.LAST_ONE_YEAR) });
197
+ timePeriods.push({ key: 8, name: this.getTimePeriodText(TIME_PERIOD_KEYS.CUSTOM, this.localization.customTimeRange) });
198
+ return timePeriods;
199
+ }
200
+ /**
201
+ * 获取时间段文案(从系统文本库获取多语种翻译,fallback 到 localization)
202
+ */
203
+ getTimePeriodText(textKey, fallback = '') {
204
+ const currentCulture = this.getCurrentCulture();
205
+ const systemType = SYSTEM_TEXT_LIBRARY_TYPES.COMPONENT_BUILTIN;
206
+ if (this.systemTextLibraryService) {
207
+ const translation = this.systemTextLibraryService.getSystemTextValue(systemType, textKey, currentCulture);
208
+ if (translation) {
209
+ return translation;
210
+ }
211
+ }
212
+ return fallback;
213
+ }
214
+ updateTimeRange(timePeriodType) {
215
+ this.currentTimePeriod = +timePeriodType;
216
+ this.updateQueryTimeRange();
217
+ }
218
+ updateQueryTimeRange() {
219
+ if (this.currentTimePeriod === 8) {
220
+ if (this.customStartTime && this.customEndTime) {
221
+ this.startTime = this.customStartTime.clone();
222
+ this.endTime = this.customEndTime.clone();
223
+ }
224
+ return;
225
+ }
226
+ this.endTime = moment();
227
+ switch (this.currentTimePeriod) {
228
+ case 1:
229
+ this.startTime = moment().subtract(1, 'hours');
230
+ break;
231
+ case 3:
232
+ this.startTime = moment().subtract(7, 'days');
233
+ break;
234
+ case 4:
235
+ this.startTime = moment().subtract(30, 'days');
236
+ break;
237
+ case 5:
238
+ this.startTime = moment().subtract(1, 'years');
239
+ break;
240
+ case 6:
241
+ this.startTime = moment().subtract(30, 'minutes');
242
+ break;
243
+ case 7:
244
+ this.startTime = moment().subtract(8, 'hours');
245
+ break;
246
+ default:
247
+ this.startTime = moment().subtract(1, 'days');
248
+ }
249
+ }
250
+ reRenderElement(startTime, endTime, limit, rangeType) {
251
+ // 清理图表实例
252
+ if (this.chartElement) {
253
+ // 隐藏 tooltip
254
+ if (this.chartElement.tooltip) {
255
+ this.chartElement.tooltip.hidden(true);
256
+ }
257
+ // 清理图表引用
258
+ this.chartElement = null;
259
+ }
260
+ // 清除 DOM 元素
261
+ this.rootElement.selectAll('*').remove();
262
+ // 重新渲染
263
+ this.renderElement(startTime, endTime, limit, rangeType);
264
+ }
265
+ renderElement(startTime, endTime, limit, rangeType) {
266
+ if (!this.model.dataSetting) {
267
+ return;
268
+ }
269
+ const dataItemName = this.model.dataSetting.dataName;
270
+ const dataSourceCode = this.model.dataSetting.dataSourceCode;
271
+ const channelNames = this.model.dataSetting.channels.map(c => c.name);
272
+ this.updateElementStatus(HistoricalCurveElementStatus.Loading);
273
+ const input = new GetHistoryDataArgs(dataSourceCode, dataItemName, channelNames, startTime, endTime, limit, rangeType);
274
+ this.historyDataStore.getHistoryData(input).subscribe(result => {
275
+ if (result.error) {
276
+ this.updateElementStatus(HistoricalCurveElementStatus.LoadFailed, result.error);
277
+ }
278
+ else {
279
+ this.clearStatus();
280
+ if (result.isUnbind) {
281
+ this.updateElementStatus(HistoricalCurveElementStatus.Unbound);
282
+ }
283
+ else {
284
+ this.updateElementStatus(HistoricalCurveElementStatus.Normal);
285
+ }
286
+ if (result.values.length) {
287
+ this.currentStartTime = moment(first(result.values).time);
288
+ this.currentEndTime = moment(last(result.values).time);
289
+ }
290
+ this.chartElement = this.renderChart(result.values);
291
+ }
292
+ });
293
+ }
294
+ setupTooltipAutoHide(chart) {
295
+ const chartContainer = this.rootElement.select('.nv-focus').node();
296
+ if (!chartContainer || !chart)
297
+ return;
298
+ let timeoutId;
299
+ // 鼠标移入图表时显示 tooltip
300
+ chartContainer.addEventListener('mouseover', () => {
301
+ hideTooltipAfterDelay();
302
+ });
303
+ const clearTooltipTimeout = () => {
304
+ if (timeoutId) {
305
+ clearTimeout(timeoutId);
306
+ timeoutId = null;
307
+ }
308
+ };
309
+ const hideTooltipAfterDelay = () => {
310
+ clearTooltipTimeout();
311
+ timeoutId = setTimeout(() => {
312
+ chart.tooltip.hidden(true);
313
+ }, 2000); // 2秒延迟
314
+ };
315
+ }
316
+ renderChart(result) {
317
+ const chartWidth = this.model.displaySetting.size.width;
318
+ const chartHeight = this.model.displaySetting.size.height - this.displayOption.operationAreaHeight - this.displayOption.operationAreaMarginTop;
319
+ const data = new Array();
320
+ each(this.model.dataSetting.channels, (channel, key) => {
321
+ const values = new Array();
322
+ each(result, v => values.push({ x: moment(v.time).local().toDate().valueOf(), y: v.values[key] }));
323
+ data.push({ key: channel.name, area: channel.projectEnabled, values: values });
324
+ });
325
+ this.data = data;
326
+ let chart;
327
+ if (this.model.displaySetting.curveType === CurveType.BarGroup || this.model.displaySetting.curveType === CurveType.BarStack) {
328
+ chart = this.getMultiBarWithFocusChart(chartWidth, chartHeight, data);
329
+ }
330
+ else {
331
+ chart = this.getLineChart(chartWidth, chartHeight, data);
332
+ }
333
+ // 设置 tooltip 自动隐藏逻辑
334
+ this.setupTooltipAutoHide(chart);
335
+ return chart;
336
+ }
337
+ initPoint() {
338
+ try {
339
+ const legendList = this.$element
340
+ .find('.nv-legend')
341
+ .find('.nv-series');
342
+ let hiddenCount = 0;
343
+ for (let i = 0; i < this.data.length; i++) {
344
+ const channel = this.model.dataSetting.channels[i];
345
+ if (legendList.eq(i).children().eq(0).css('fill-opacity') === '1') {
346
+ const pointList = this.$element
347
+ .find('.nv-scatterWrap')
348
+ .find('.nv-series-' + (i - hiddenCount))
349
+ .find('.nv-point');
350
+ if (pointList && pointList.length) {
351
+ for (let j = 0; j < pointList.length; j++) {
352
+ const point = pointList.eq(j);
353
+ const previousPoint = pointList.eq(j - 1);
354
+ if (j && point.attr('transform').split(',')[1] !== previousPoint.attr('transform').split(',')[1]) {
355
+ if (channel.enablePoint && channel.pointColor) {
356
+ const pointStyle = {
357
+ 'stroke-opacity': 1,
358
+ 'stroke-width': '2px',
359
+ 'stroke': channel.pointColor,
360
+ 'fill-opacity': 1,
361
+ 'fill': channel.pointColor
362
+ };
363
+ point.addClass('nv-mark-point');
364
+ point.css(pointStyle);
365
+ previousPoint.addClass('nv-mark-point');
366
+ previousPoint.css(pointStyle);
367
+ }
368
+ }
369
+ }
370
+ }
371
+ }
372
+ else {
373
+ hiddenCount++;
374
+ }
375
+ }
376
+ }
377
+ catch (e) {
378
+ console.log(e);
379
+ }
380
+ }
381
+ getLineChart(chartWidth, chartHeight, data) {
382
+ const chart = nv.models.lineChart().showLegend(true)
383
+ .margin({ top: 0, bottom: 0, left: this.displayOption.marginLeft, right: this.displayOption.marginRight })
384
+ .noData(this.localization.chartNoData);
385
+ if (this.model.displaySetting.axisSetting.yAxisRangeType === AxisRangeType.Custom) {
386
+ chart.yDomain([this.model.displaySetting.axisSetting.yAxisMin, this.model.displaySetting.axisSetting.yAxisMax]);
387
+ }
388
+ if (!this.isMobileMode) {
389
+ chart.focusEnable(true);
390
+ chart.focus.margin({ top: 10, right: 0, bottom: 0, left: 0 });
391
+ chart.focus.height(40);
392
+ chart.focus.showXAxis(false);
393
+ }
394
+ this.renderCommonProperty(chart, chartWidth, chartHeight, data);
395
+ this.renderOperationArea(chartWidth, chartHeight);
396
+ this.initPoint();
397
+ chart.legend.dispatch.on('legendClick', () => {
398
+ setTimeout(() => {
399
+ this.$element.find('.nv-mark-point').css({
400
+ 'stroke-opacity': 0,
401
+ 'stroke-width': 0,
402
+ 'stroke': 'unset',
403
+ 'fill-opacity': 0,
404
+ 'fill': 'unset'
405
+ }).removeClass('nv-mark-point');
406
+ this.initPoint();
407
+ }, 1);
408
+ });
409
+ return chart;
410
+ }
411
+ getMultiBarWithFocusChart(chartWidth, chartHeight, data) {
412
+ const chart = nv.models.multiBarWithFocusChart()
413
+ .margin({
414
+ top: 0, bottom: 0, left: this.displayOption.marginLeft, right: this.displayOption.marginRight
415
+ })
416
+ .controlLabels({
417
+ grouped: this.localization.grouped, stacked: this.localization.stacked
418
+ })
419
+ .noData(this.localization.chartNoData);
420
+ if (this.model.displaySetting.curveType === CurveType.BarStack) {
421
+ chart.stacked(true);
422
+ chart.multibar.stacked(true);
423
+ chart.multibar2.stacked(true);
424
+ }
425
+ if (this.model.displaySetting.axisSetting.yAxisRangeType === AxisRangeType.Custom) {
426
+ chart.yDomain([this.model.displaySetting.axisSetting.yAxisMin, this.model.displaySetting.axisSetting.yAxisMax]);
427
+ }
428
+ if (!this.isMobileMode) {
429
+ chart.focusEnable(true);
430
+ chart.focusShowAxisX(false);
431
+ }
432
+ chart.xAxis.tickFormat(d => this.timeFormat(d, '%x %X'));
433
+ this.renderCommonProperty(chart, chartWidth, chartHeight, data);
434
+ this.renderOperationArea(chartWidth, chartHeight);
435
+ const focusContext = this.rootElement.select('.nv-context');
436
+ focusContext.select('.nv-barsWrap.nvd3-svg').attr('transform', 'translate(0,30)');
437
+ focusContext.select('.nv-brushBackground').attr('transform', 'translate(0,30)');
438
+ focusContext.select('.nv-x.nv-brush').attr('transform', 'translate(0,30)');
439
+ if (!this.model.displaySetting.showAxis) {
440
+ this.rootElement.select('.tick.zero').style('display', 'none');
441
+ this.rootElement.select('.nv-x.nv-axis.nvd3-svg').style('display', 'none');
442
+ this.rootElement.select('.nv-y.nv-axis.nvd3-svg').style('display', 'none');
443
+ }
444
+ chart.update();
445
+ return chart;
446
+ }
447
+ renderCommonProperty(chart, chartWidth, chartHeight, data) {
448
+ var _a, _b;
449
+ chart.tooltip.headerFormatter(d => this.timeFormat(d, '%x %X'));
450
+ if (this.model.displaySetting.showAxis) {
451
+ chart.xAxis.showMaxMin(true).tickFormat(d => {
452
+ this.$element.find('.nv-mark-point').css({
453
+ 'stroke-opacity': 0,
454
+ 'stroke-width': 0,
455
+ 'stroke': 'unset',
456
+ 'fill-opacity': 0,
457
+ 'fill': 'unset'
458
+ }).removeClass('nv-mark-point');
459
+ clearTimeout(this.timer);
460
+ this.timer = undefined;
461
+ this.timer = setTimeout(() => {
462
+ this.initPoint();
463
+ }, 100);
464
+ if (this.currentTimePeriod === 3 || this.currentTimePeriod === 4 || this.currentTimePeriod === 5) {
465
+ return this.timeFormat(d, '%y-%m-%d');
466
+ }
467
+ return this.timeFormat(Number(d), '%X');
468
+ });
469
+ if (this.model.displaySetting.axisSetting) {
470
+ if (this.model.displaySetting.axisSetting.showAxisLabel && this.model.displaySetting.axisSetting.axisLabelFont) {
471
+ chart.xAxis.fontSize(this.model.displaySetting.axisSetting.axisLabelFont.fontSize);
472
+ chart.yAxis.fontSize(this.model.displaySetting.axisSetting.axisLabelFont.fontSize).tickFormat(d => +d3.format('.9g')(d));
473
+ }
474
+ else {
475
+ chart.xAxis.tickFormat(() => '');
476
+ chart.yAxis.tickFormat(() => '');
477
+ }
478
+ }
479
+ }
480
+ else {
481
+ chart.showXAxis(false);
482
+ chart.showYAxis(false);
483
+ }
484
+ chart.width(chartWidth);
485
+ chart.height(chartHeight);
486
+ chart.color(this.model.dataSetting.channels.map(c => c.connectorColor));
487
+ this.rootElement.append('g').datum(data).call(chart);
488
+ this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
489
+ this.resizeEventListener = nv.utils.windowResize(() => {
490
+ if (!this.needResize)
491
+ return;
492
+ chart.update();
493
+ this.rootElement.selectAll('.nv-noData').attr('x', chartWidth / 2).attr('y', chartHeight / 2 + this.displayOption.operationAreaHeight);
494
+ });
495
+ const fontSize = (_b = (_a = this.model.displaySetting.axisSetting) === null || _a === void 0 ? void 0 : _a.axisLabelFont) === null || _b === void 0 ? void 0 : _b.fontSize;
496
+ this.rootElement.selectAll('.domain').style('stroke-opacity', 1);
497
+ if (this.model.displaySetting.showAxis && this.model.displaySetting.axisSetting) {
498
+ const axisColor = this.model.displaySetting.axisSetting.axisColor;
499
+ this.rootElement.selectAll('.domain').style('stroke', axisColor);
500
+ if (fontSize && this.model.displaySetting.axisSetting.showAxisLabel) {
501
+ this.rootElement.selectAll('.nv-axisMaxMin').select('text').style('font-size', fontSize);
502
+ }
503
+ }
504
+ let strokeWidth = 0;
505
+ if (this.model.displaySetting.axisSetting.showTick !== false) {
506
+ strokeWidth = 1;
507
+ }
508
+ this.rootElement
509
+ .selectAll('.nv-x')
510
+ .selectAll('.tick')
511
+ .selectAll('line')
512
+ .attr('style', `stroke:${this.model.displaySetting.axisSetting.xAxisTickColor || 'rgb(127, 147, 159)'};stroke-width:${strokeWidth};`);
513
+ this.rootElement
514
+ .selectAll('.nv-y')
515
+ .selectAll('.tick')
516
+ .selectAll('line')
517
+ .attr('style', `stroke:${this.model.displaySetting.axisSetting.yAxisTickColor || 'rgb(127, 147, 159)'};stroke-width:${strokeWidth};`);
518
+ if (fontSize && this.currentTimePeriod === 3 || this.currentTimePeriod === 4 || this.currentTimePeriod === 5) {
519
+ const self = this;
520
+ this.rootElement
521
+ .selectAll('.nv-x')
522
+ .selectAll('.tick')
523
+ .selectAll('text')
524
+ .data(function (d) {
525
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
526
+ })
527
+ .enter()
528
+ .append('text')
529
+ .attr('class', 'full-date')
530
+ .attr('x', 0)
531
+ .attr('y', 0)
532
+ .attr('dy', '2.3em')
533
+ .style('text-anchor', 'middle')
534
+ .style('font-size', fontSize)
535
+ .text((d) => d);
536
+ this.rootElement
537
+ .selectAll('.nv-axisMaxMin-x')
538
+ .selectAll('text')
539
+ .data(function (d) {
540
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
541
+ })
542
+ .enter()
543
+ .append('text')
544
+ .attr('class', 'full-date')
545
+ .attr('x', 0)
546
+ .attr('y', 0)
547
+ .attr('dy', '2.3em')
548
+ .style('text-anchor', 'middle')
549
+ .style('font-size', fontSize)
550
+ .text((d) => d);
551
+ const focusWrap = this.rootElement.selectAll('.nv-focusWrap');
552
+ if (focusWrap.size()) {
553
+ let h = focusWrap.attr('transform');
554
+ if (h && h.length && h.indexOf(',') !== -1) {
555
+ h = h.slice(0, -1).split(',')[1];
556
+ this.rootElement
557
+ .selectAll('.nv-focusWrap')
558
+ .attr('transform', `translate(0,${Number(h) + 15})`);
559
+ }
560
+ }
561
+ const resizeObserver = new window.MutationObserver(() => {
562
+ this.rootElement
563
+ .selectAll('.nv-x')
564
+ .selectAll('.tick')
565
+ .selectAll('.full-date')
566
+ .remove();
567
+ this.rootElement
568
+ .selectAll('.nv-x')
569
+ .selectAll('.tick')
570
+ .selectAll('text')
571
+ .data(function (d) {
572
+ return [self.timeFormat(Number(d), '%y-%m-%d'), self.timeFormat(Number(d), '%H:%M:%S')];
573
+ })
574
+ .enter()
575
+ .append('text')
576
+ .attr('class', 'full-date')
577
+ .attr('x', 0)
578
+ .attr('y', 0)
579
+ .attr('dy', '2.3em')
580
+ .style('text-anchor', 'middle')
581
+ .style('font-size', fontSize)
582
+ .text((d) => d);
583
+ });
584
+ const extent = document.getElementsByClassName('extent');
585
+ if (extent.length) {
586
+ resizeObserver.observe(extent[0], { attributes: true });
587
+ }
588
+ }
589
+ else {
590
+ this.rootElement
591
+ .selectAll('.full-date')
592
+ .remove();
593
+ }
594
+ }
595
+ renderOperationArea(chartWidth, chartHeight) {
596
+ const backgroundColor = this.model.displaySetting.axisSetting.filterBackgroudColor || 'inherit';
597
+ const operationArea = this.rootElement.append('g').attr('transform', `translate(0,${chartHeight + this.displayOption.operationAreaMarginTop})`)
598
+ .append('foreignObject').attr('width', chartWidth).attr('height', this.displayOption.operationAreaHeight).attr('fill', 'none')
599
+ .append('xhtml:div').style('height', (this.displayOption.operationAreaHeight - 4) + 'px').style('overflow', 'hidden').style('margin-top', '4px');
600
+ const rect = this.$element.parent().parent().find('rect');
601
+ const fillColor = rect.attr('fill');
602
+ const dropdownBg = this.model.displaySetting.axisSetting.filterBackgroudColor || fillColor || '#fff';
603
+ const dropdownWrapper = operationArea.append('div')
604
+ .style('display', 'inline-block')
605
+ .style('position', 'relative')
606
+ .style('margin-left', this.displayOption.marginLeft + 'px')
607
+ .style('vertical-align', 'middle');
608
+ const selectedText = this.timePeriods.find(t => t.key === Number(this.currentTimePeriod));
609
+ const dropdownTrigger = dropdownWrapper.append('div')
610
+ .attr('class', 'hc-dropdown-trigger')
611
+ .style('background-color', backgroundColor)
612
+ .style('font-size', this.displayOption.operationSelectFontSize)
613
+ .style('cursor', 'pointer')
614
+ .style('padding', '0 18px 0 4px')
615
+ .style('border', '1px solid #ccc')
616
+ .style('border-radius', '2px')
617
+ .style('position', 'relative')
618
+ .style('white-space', 'nowrap')
619
+ .style('line-height', (this.displayOption.operationAreaHeight - 8) + 'px')
620
+ .style('min-height', (this.displayOption.operationAreaHeight - 8) + 'px')
621
+ .text(selectedText ? selectedText.name : '');
622
+ dropdownTrigger.append('span')
623
+ .style('position', 'absolute')
624
+ .style('right', '4px')
625
+ .style('top', '50%')
626
+ .style('transform', 'translateY(-50%)')
627
+ .style('font-size', '10px')
628
+ .style('pointer-events', 'none')
629
+ .text('▼');
630
+ const dropdownListEl = document.createElement('div');
631
+ dropdownListEl.style.cssText = 'display:none;position:fixed;background:' + dropdownBg
632
+ + ';border:1px solid #ccc;border-radius:2px;z-index:9999;box-shadow:0 2px 6px rgba(0,0,0,0.15);';
633
+ document.body.appendChild(dropdownListEl);
634
+ this.dropdownListEl = dropdownListEl;
635
+ this.dropdownTriggerEl = dropdownTrigger.node();
636
+ const dropdownList = d3.select(dropdownListEl);
637
+ this.timePeriods.forEach(tp => {
638
+ dropdownList.append('div')
639
+ .attr('class', 'hc-dropdown-item')
640
+ .style('padding', '4px 8px')
641
+ .style('cursor', 'pointer')
642
+ .style('white-space', 'nowrap')
643
+ .style('font-size', this.displayOption.operationSelectFontSize)
644
+ .style('line-height', (this.displayOption.operationAreaHeight - 8) + 'px')
645
+ .style('min-height', (this.displayOption.operationAreaHeight - 8) + 'px')
646
+ .style('background', tp.key === Number(this.currentTimePeriod) ? '#1890ff' : 'transparent')
647
+ .style('color', tp.key === Number(this.currentTimePeriod) ? '#fff' : '#333')
648
+ .text(tp.name)
649
+ .on('mouseover', function () {
650
+ const el = d3.select(this);
651
+ if (!el.classed('hc-dropdown-selected')) {
652
+ el.style('background', '#e6f7ff').style('color', '#333');
653
+ }
654
+ })
655
+ .on('mouseout', function () {
656
+ const el = d3.select(this);
657
+ if (!el.classed('hc-dropdown-selected')) {
658
+ el.style('background', 'transparent').style('color', '#333');
659
+ }
660
+ })
661
+ .on('click', () => {
662
+ dropdownListEl.style.display = 'none';
663
+ // 从 this.timePeriods 实时查找,确保语种切换后显示最新文案
664
+ const currentPeriod = this.timePeriods.find(p => p.key === tp.key);
665
+ const currentName = currentPeriod ? currentPeriod.name : tp.name;
666
+ dropdownTrigger.text(currentName);
667
+ dropdownTrigger.append('span')
668
+ .style('position', 'absolute')
669
+ .style('right', '4px')
670
+ .style('top', '50%')
671
+ .style('transform', 'translateY(-50%)')
672
+ .style('font-size', '10px')
673
+ .style('pointer-events', 'none')
674
+ .text('▼');
675
+ // 更新选中状态
676
+ dropdownList.selectAll('.hc-dropdown-item')
677
+ .classed('hc-dropdown-selected', false)
678
+ .style('background', 'transparent')
679
+ .style('color', '#333');
680
+ d3.select(d3.event.currentTarget)
681
+ .classed('hc-dropdown-selected', true)
682
+ .style('background', '#1890ff')
683
+ .style('color', '#fff');
684
+ if (tp.key === 8) {
685
+ this.showCustomTimeRangeModal();
686
+ return;
687
+ }
688
+ this.updateTimeRange(tp.key);
689
+ this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
690
+ });
691
+ });
692
+ // 测量下拉列表最大宽度,让 trigger 和列表宽度一致
693
+ dropdownListEl.style.display = 'block';
694
+ dropdownListEl.style.visibility = 'hidden';
695
+ const listContentWidth = dropdownListEl.offsetWidth;
696
+ dropdownListEl.style.display = 'none';
697
+ dropdownListEl.style.visibility = '';
698
+ dropdownListEl.style.width = listContentWidth + 'px';
699
+ dropdownTrigger.node().style.width = listContentWidth + 'px';
700
+ dropdownTrigger.node().style.boxSizing = 'border-box';
701
+ const hideDropdown = () => { dropdownListEl.style.display = 'none'; };
702
+ dropdownTrigger.on('click', () => {
703
+ const isVisible = dropdownListEl.style.display !== 'none';
704
+ if (isVisible) {
705
+ hideDropdown();
706
+ }
707
+ else {
708
+ const triggerNode = dropdownTrigger.node();
709
+ const triggerRect = triggerNode.getBoundingClientRect();
710
+ // 设置宽度至少和 trigger 一样宽
711
+ dropdownListEl.style.minWidth = triggerRect.width + 'px';
712
+ dropdownListEl.style.left = triggerRect.left + 'px';
713
+ dropdownListEl.style.display = 'block';
714
+ const listHeight = dropdownListEl.offsetHeight;
715
+ const spaceBelow = window.innerHeight - triggerRect.bottom;
716
+ if (spaceBelow < listHeight) {
717
+ // 向上展开
718
+ dropdownListEl.style.top = '';
719
+ dropdownListEl.style.bottom = (window.innerHeight - triggerRect.top) + 'px';
720
+ }
721
+ else {
722
+ // 向下展开
723
+ dropdownListEl.style.bottom = '';
724
+ dropdownListEl.style.top = triggerRect.bottom + 'px';
725
+ }
726
+ }
727
+ });
728
+ // 点击外部收起
729
+ document.addEventListener('click', (event) => {
730
+ const triggerNode = dropdownTrigger.node();
731
+ if (!dropdownListEl.contains(event.target) && !triggerNode.contains(event.target)) {
732
+ hideDropdown();
733
+ }
734
+ });
735
+ // 滚动时收起
736
+ document.addEventListener('scroll', hideDropdown, true);
737
+ const buttonWidth = this.displayOption.operationButtonWidth + 'px', buttonHeight = this.displayOption.operationButtonHeight + 'px';
738
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
739
+ .style('float', 'right').style('background-image', 'url(assets/img/black_last_page.png)')
740
+ .style('background-color', backgroundColor).style('background-size', 'cover')
741
+ .on('click', () => { this.loadLastPage(); });
742
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
743
+ .style('float', 'right').style('background-image', 'url(assets/img/black_next_page.png)')
744
+ .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
745
+ .style('background-color', backgroundColor).style('background-size', 'cover')
746
+ .on('click', () => { this.loadNextPage(); });
747
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
748
+ .style('float', 'right').style('background-image', 'url(assets/img/black_previous_page.png)')
749
+ .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
750
+ .style('background-color', backgroundColor).style('background-size', 'cover')
751
+ .on('click', () => { this.loadPreviousPage(); });
752
+ operationArea.append('button').style('width', buttonWidth).style('height', buttonHeight).style('border', 'none')
753
+ .style('float', 'right').style('background-image', 'url(assets/img/black_first_page.png)')
754
+ .style('margin', `0 ${this.displayOption.operationButtonMargin}px 0 0`)
755
+ .style('background-color', backgroundColor).style('background-size', 'cover')
756
+ .on('click', () => { this.loadFirstPage(); });
757
+ }
758
+ timeFormat(datetime, specifier) {
759
+ return d3.time.format(specifier)(new Date(datetime));
760
+ }
761
+ fmtDatetimeLocal(d) {
762
+ const p2 = (n) => (n < 10 ? '0' : '') + n;
763
+ return d.getFullYear() + '-' + p2(d.getMonth() + 1) + '-' + p2(d.getDate())
764
+ + 'T' + p2(d.getHours()) + ':' + p2(d.getMinutes()) + ':' + p2(d.getSeconds());
765
+ }
766
+ showCustomTimeRangeModal() {
767
+ const now = new Date();
768
+ const defaultStart = this.customStartTime ? this.customStartTime.toDate()
769
+ : new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
770
+ const defaultEnd = this.customEndTime ? this.customEndTime.toDate()
771
+ : new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
772
+ if (this.guiContext && this.guiContext.showCustomTimeRangeModal) {
773
+ this.guiContext.showCustomTimeRangeModal({ startTime: defaultStart, endTime: defaultEnd }).then(result => {
774
+ if (result) {
775
+ const momentAny = moment;
776
+ this.customStartTime = momentAny(result.startTime);
777
+ this.customEndTime = momentAny(result.endTime);
778
+ this.updateTimeRange(8);
779
+ this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
780
+ }
781
+ });
782
+ return;
783
+ }
784
+ this.showCustomTimeRangeModalFallback();
785
+ }
786
+ showCustomTimeRangeModalFallback() {
787
+ const prevTimePeriod = this.currentTimePeriod;
788
+ const now = new Date();
789
+ const defaultStart = this.fmtDatetimeLocal(this.customStartTime ? this.customStartTime.toDate()
790
+ : new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0));
791
+ const defaultEnd = this.fmtDatetimeLocal(this.customEndTime ? this.customEndTime.toDate()
792
+ : new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59));
793
+ const overlay = document.createElement('div');
794
+ overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:9999;';
795
+ const modal = document.createElement('div');
796
+ const modalCss = 'position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);'
797
+ + 'background:#fff;border-radius:4px;min-width:460px;'
798
+ + 'box-shadow:0 4px 12px rgba(0,0,0,0.15);font-family:inherit;font-size:14px;';
799
+ modal.style.cssText = modalCss;
800
+ const header = document.createElement('div');
801
+ header.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #e8e8e8;';
802
+ const title = document.createElement('span');
803
+ title.style.cssText = 'font-size:16px;font-weight:500;color:#333;';
804
+ title.textContent = this.localization.customTimeRange || '自定义';
805
+ const closeBtn = document.createElement('span');
806
+ closeBtn.style.cssText = 'cursor:pointer;font-size:18px;color:#999;line-height:1;';
807
+ closeBtn.textContent = '×';
808
+ header.appendChild(title);
809
+ header.appendChild(closeBtn);
810
+ const body = document.createElement('div');
811
+ body.style.cssText = 'padding:20px 16px;display:flex;align-items:center;flex-wrap:wrap;gap:8px;';
812
+ const label = document.createElement('span');
813
+ label.style.cssText = 'color:#333;white-space:nowrap;';
814
+ label.textContent = '时间范围:';
815
+ const inputStyle = 'border:1px solid #d9d9d9;border-radius:4px;padding:4px 8px;font-size:14px;height:32px;outline:none;color:#333;';
816
+ const startInput = document.createElement('input');
817
+ startInput.type = 'datetime-local';
818
+ startInput.setAttribute('step', '1');
819
+ startInput.value = defaultStart;
820
+ startInput.style.cssText = inputStyle;
821
+ const separator = document.createElement('span');
822
+ separator.textContent = ' - ';
823
+ separator.style.cssText = 'color:#333;';
824
+ const endInput = document.createElement('input');
825
+ endInput.type = 'datetime-local';
826
+ endInput.setAttribute('step', '1');
827
+ endInput.value = defaultEnd;
828
+ endInput.style.cssText = inputStyle;
829
+ body.appendChild(label);
830
+ body.appendChild(startInput);
831
+ body.appendChild(separator);
832
+ body.appendChild(endInput);
833
+ const footer = document.createElement('div');
834
+ footer.style.cssText = 'display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid #e8e8e8;';
835
+ const cancelBtn = document.createElement('button');
836
+ cancelBtn.textContent = this.localization.cancel || '取消';
837
+ cancelBtn.style.cssText = 'padding:5px 16px;border:1px solid #d9d9d9;border-radius:4px;background:#fff;cursor:pointer;font-size:14px;color:#333;';
838
+ const saveBtn = document.createElement('button');
839
+ saveBtn.textContent = '保存';
840
+ saveBtn.style.cssText = 'padding:5px 16px;border:none;border-radius:4px;background:#1890ff;color:#fff;cursor:pointer;font-size:14px;';
841
+ footer.appendChild(cancelBtn);
842
+ footer.appendChild(saveBtn);
843
+ modal.appendChild(header);
844
+ modal.appendChild(body);
845
+ modal.appendChild(footer);
846
+ overlay.appendChild(modal);
847
+ document.body.appendChild(overlay);
848
+ const close = (revert) => {
849
+ document.body.removeChild(overlay);
850
+ if (revert) {
851
+ const selectEl = this.$element && this.$element.find('select');
852
+ if (selectEl && selectEl.length) {
853
+ selectEl.val(prevTimePeriod.toString());
854
+ }
855
+ }
856
+ };
857
+ closeBtn.addEventListener('click', () => close(true));
858
+ cancelBtn.addEventListener('click', () => close(true));
859
+ saveBtn.addEventListener('click', () => {
860
+ const startVal = startInput.value;
861
+ const endVal = endInput.value;
862
+ if (!startVal) {
863
+ startInput.style.borderColor = 'red';
864
+ return;
865
+ }
866
+ const startDate = new Date(startVal);
867
+ const endDate = endVal
868
+ ? new Date(endVal)
869
+ : new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate(), 23, 59, 59);
870
+ if (isNaN(startDate.getTime())) {
871
+ startInput.style.borderColor = 'red';
872
+ return;
873
+ }
874
+ if (endDate.getTime() <= startDate.getTime()) {
875
+ endInput.style.borderColor = 'red';
876
+ return;
877
+ }
878
+ const momentAny = moment;
879
+ this.customStartTime = momentAny(startDate);
880
+ this.customEndTime = momentAny(endDate);
881
+ close(false);
882
+ this.updateTimeRange(8);
883
+ this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
884
+ });
885
+ }
886
+ loadFirstPage() {
887
+ this.updateQueryTimeRange();
888
+ this.reRenderElement(this.startTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
889
+ }
890
+ loadNextPage() {
891
+ this.reRenderElement(this.currentEndTime, this.endTime, this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndClose);
892
+ }
893
+ loadPreviousPage() {
894
+ this.reRenderElement(this.startTime, this.currentStartTime, -this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginCloseEndOpen);
895
+ }
896
+ loadLastPage() {
897
+ this.updateQueryTimeRange();
898
+ this.reRenderElement(this.startTime, this.endTime, -this.displayOption.dataLimit, HistoricalCurveTimeRange.BeginOpenEndOpen);
899
+ }
900
+ initElementStatus() {
901
+ if (this.model.dataSetting && null != this.model.dataSetting.dataSourceCode) {
902
+ this.updateElementStatus(HistoricalCurveElementStatus.Loading);
903
+ }
904
+ }
905
+ updateElementStatus(status, error) {
906
+ switch (status) {
907
+ case HistoricalCurveElementStatus.Normal:
908
+ if (this.elementStatus !== HistoricalCurveElementStatus.Normal) {
909
+ this.elementStatus = HistoricalCurveElementStatus.Normal;
910
+ }
911
+ break;
912
+ case HistoricalCurveElementStatus.Unbound:
913
+ this.elementStatus = HistoricalCurveElementStatus.Unbound;
914
+ this.setStatusAsUnbound();
915
+ break;
916
+ case HistoricalCurveElementStatus.Loading:
917
+ if (this.elementStatus !== HistoricalCurveElementStatus.Unbound) {
918
+ this.elementStatus = HistoricalCurveElementStatus.Loading;
919
+ this.setStatusAsLoading();
920
+ }
921
+ break;
922
+ case HistoricalCurveElementStatus.LoadFailed:
923
+ if (this.elementStatus !== HistoricalCurveElementStatus.Unbound) {
924
+ this.elementStatus = HistoricalCurveElementStatus.LoadFailed;
925
+ this.setStatusAsLoadFailed(error ? error : this.localization.abnormal);
926
+ }
927
+ break;
928
+ default:
929
+ this.logger.error(`Invalid HistoricalCurveElementStatus:${status}`);
930
+ break;
931
+ }
932
+ }
933
+ setStatusAsUnbound() {
934
+ this.renderStatus('assets/img/unbind.svg', this.localization.unbind, '#586e7c');
935
+ }
936
+ setStatusAsLoading() {
937
+ this.renderStatus('assets/img/loading.svg', this.localization.loading, '#226abc');
938
+ }
939
+ setStatusAsLoadFailed(error) {
940
+ this.logger.error(`[GUI]Failed to load historical curve:${error}`);
941
+ this.renderStatus('assets/img/abnormal.svg', error, '#f6a520');
942
+ }
943
+ renderStatus(icon, tip, stroke) {
944
+ if (this.elementStatus === HistoricalCurveElementStatus.Normal) {
945
+ this.clearStatus();
946
+ return;
947
+ }
948
+ this.rootElement.append('rect').attr('id', 'StateFrame').attr('fill', 'transparent')
949
+ .attr('width', this.model.displaySetting.size.width)
950
+ .attr('height', this.model.displaySetting.size.height);
951
+ const document = this.$element[0].ownerDocument;
952
+ const currentRect = this.$element.find('rect#StateFrame').first();
953
+ if (!currentRect.length) {
954
+ return;
955
+ }
956
+ this.$element.find('image#StateImage').remove();
957
+ const imgObj = document.createElementNS('http://www.w3.org/2000/svg', 'image');
958
+ if (imgObj) {
959
+ let x = Number(currentRect[0].getAttribute('width')) - 20;
960
+ const currentRectX = currentRect[0].getAttribute('x');
961
+ if (currentRectX !== null) {
962
+ x += Number(currentRectX);
963
+ }
964
+ currentRect[0].setAttribute('stroke', stroke);
965
+ currentRect[0].setAttribute('stroke-opacity', '0.5');
966
+ imgObj.href.baseVal = icon;
967
+ imgObj.setAttributeNS(null, 'id', 'StateImage');
968
+ imgObj.setAttributeNS(null, 'x', x.toString());
969
+ imgObj.setAttributeNS(null, 'y', '0');
970
+ imgObj.setAttributeNS(null, 'height', '20px');
971
+ imgObj.setAttributeNS(null, 'width', '20px');
972
+ const titleElement = document.createElementNS('http://www.w3.org/2000/svg', 'title');
973
+ const text = document.createTextNode(tip);
974
+ titleElement.appendChild(text);
975
+ imgObj.appendChild(titleElement);
976
+ this.$element.append(imgObj);
977
+ }
978
+ }
979
+ clearStatus() {
980
+ const currentRect = this.$element.find('rect#StateFrame').first();
981
+ if (!currentRect.length) {
982
+ return;
983
+ }
984
+ const stroke = currentRect[0].getAttribute('stroke');
985
+ if (stroke) {
986
+ currentRect[0].removeAttribute('stroke');
987
+ }
988
+ this.$element.find('image#StateImage').remove();
989
+ }
990
+ }