Showing
5 changed files
with
832 additions
and
101 deletions
@@ -272,8 +272,12 @@ | @@ -272,8 +272,12 @@ | ||
272 | /** | 272 | /** |
273 | * @description 图片组件 | 273 | * @description 图片组件 |
274 | */ | 274 | */ |
275 | - IMAGE: 'image' | ||
276 | - | 275 | + IMAGE: 'image', |
276 | + | ||
277 | + /** | ||
278 | + * @description 流量计 | ||
279 | + */ | ||
280 | + FLOWMETER: 'flowmeter' | ||
277 | } | 281 | } |
278 | 282 | ||
279 | Sidebar.prototype.enumComponentTypeValue = { | 283 | Sidebar.prototype.enumComponentTypeValue = { |
@@ -364,7 +368,12 @@ | @@ -364,7 +368,12 @@ | ||
364 | /** | 368 | /** |
365 | * @description 运行于停止 | 369 | * @description 运行于停止 |
366 | */ | 370 | */ |
367 | - RUNNING_AND_STOP: 'runningAndStop' | 371 | + RUNNING_AND_STOP: 'runningAndStop', |
372 | + | ||
373 | + /** | ||
374 | + * @description 流量计 | ||
375 | + */ | ||
376 | + FLOWMETER_PANEL: 'flowmeter' | ||
368 | } | 377 | } |
369 | 378 | ||
370 | /** | 379 | /** |
@@ -721,8 +730,8 @@ | @@ -721,8 +730,8 @@ | ||
721 | //更多图形,显示出来的的标题跟id,同时包括图片 | 730 | //更多图形,显示出来的的标题跟id,同时包括图片 |
722 | 731 | ||
723 | // TODO thingsKit 设置数据绑定展示面板 | 732 | // TODO thingsKit 设置数据绑定展示面板 |
724 | - const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DASHBOARD_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT, RUNNING_AND_STOP } = this.enumPermissionPanel | ||
725 | - const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON, DASHBOARD_CHART, IMAGE } = this.enumComponentType | 733 | + const { LINE_CHART_EXPAND, BAR_CHART_EXPAND, DASHBOARD_CHART_EXPAND, DYNAMIC_EFFECT, DATA_SOURCE, VAR_IMAGE, INTERACTION, VIDEO: VIDEO_PANEL, SWITCH_STATE_SETTING, ONLY_SINGLE_EVENT, RUNNING_AND_STOP, FLOWMETER_PANEL } = this.enumPermissionPanel |
734 | + const { LINE, LINE_CHART, REAL_TIME, TITLE, VARIABLE, DEFAULT, BAR_CHART, VIDEO, SWITCH, PARAMS_SETTING_BUTTON, DASHBOARD_CHART, IMAGE, FLOWMETER } = this.enumComponentType | ||
726 | this.setComponentPermission(LINE, [RUNNING_AND_STOP, DYNAMIC_EFFECT]) | 735 | this.setComponentPermission(LINE, [RUNNING_AND_STOP, DYNAMIC_EFFECT]) |
727 | this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT]) | 736 | this.setComponentPermission(DEFAULT, [DYNAMIC_EFFECT]) |
728 | this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT]) | 737 | this.setComponentPermission(REAL_TIME, [DYNAMIC_EFFECT]) |
@@ -736,6 +745,7 @@ | @@ -736,6 +745,7 @@ | ||
736 | this.setComponentPermission(SWITCH, [DATA_SOURCE, SWITCH_STATE_SETTING]) | 745 | this.setComponentPermission(SWITCH, [DATA_SOURCE, SWITCH_STATE_SETTING]) |
737 | this.setComponentPermission(PARAMS_SETTING_BUTTON, [DATA_SOURCE, ONLY_SINGLE_EVENT]) | 746 | this.setComponentPermission(PARAMS_SETTING_BUTTON, [DATA_SOURCE, ONLY_SINGLE_EVENT]) |
738 | this.setComponentPermission(IMAGE, [DATA_SOURCE]) | 747 | this.setComponentPermission(IMAGE, [DATA_SOURCE]) |
748 | + this.setComponentPermission(FLOWMETER, [DATA_SOURCE, FLOWMETER_PANEL]) | ||
739 | 749 | ||
740 | var thingskitEntries = [ | 750 | var thingskitEntries = [ |
741 | { title: mxResources.get('general'), id: 'general', image: IMAGE_PATH + '/sidebar-general.png' }, | 751 | { title: mxResources.get('general'), id: 'general', image: IMAGE_PATH + '/sidebar-general.png' }, |
@@ -42,10 +42,29 @@ | @@ -42,10 +42,29 @@ | ||
42 | CHART_IMG_PLACEHOLDER_SIZE: 30, | 42 | CHART_IMG_PLACEHOLDER_SIZE: 30, |
43 | } | 43 | } |
44 | 44 | ||
45 | + Sidebar.prototype.enumFlowmeterAttr = { | ||
46 | + WIDTH: 'width', | ||
47 | + HEIGHT: 'height', | ||
48 | + VALUE: 'value', | ||
49 | + TYPE: 'type', | ||
50 | + UUID: 'uuid', | ||
51 | + BG_COLOR: 'bgColor', | ||
52 | + WAVE_FIRST_COLOR: 'waveFirstColor', | ||
53 | + WAVE_SECOND_COLOR: 'waveSecondColor', | ||
54 | + WAVE_THIRD_COLOR: 'waveThirdColor', | ||
55 | + } | ||
56 | + | ||
57 | + Sidebar.prototype.enumFlowmeterType = { | ||
58 | + RECT: 'rect', | ||
59 | + CIRCLE: 'circle', | ||
60 | + THERMOMETER: 'thermometer' | ||
61 | + } | ||
62 | + | ||
45 | // Adds Atlassian shapes | 63 | // Adds Atlassian shapes |
46 | // 图表 | 64 | // 图表 |
47 | Sidebar.prototype.addChartsPalette = function () { | 65 | Sidebar.prototype.addChartsPalette = function () { |
48 | this.chartsComponentInit() | 66 | this.chartsComponentInit() |
67 | + | ||
49 | const self = this | 68 | const self = this |
50 | const componentType = this.enumComponentType | 69 | const componentType = this.enumComponentType |
51 | const { DATA_SOURCE, DYNAMIC_EFFECT, DISPLAY_TYPE } = this.enumPermissionPanel | 70 | const { DATA_SOURCE, DYNAMIC_EFFECT, DISPLAY_TYPE } = this.enumPermissionPanel |
@@ -74,7 +93,19 @@ | @@ -74,7 +93,19 @@ | ||
74 | const id = self.generatorChartsId() | 93 | const id = self.generatorChartsId() |
75 | const cell = self.generatorCell(id, enumConst.CHART_IMG_PLACEHOLDER_SIZE, enumConst.CHART_IMG_PLACEHOLDER_SIZE, componentType.DASHBOARD_CHART, `${Proxy_Prefix}/images/thingskit/dashboard-chart.png`) | 94 | const cell = self.generatorCell(id, enumConst.CHART_IMG_PLACEHOLDER_SIZE, enumConst.CHART_IMG_PLACEHOLDER_SIZE, componentType.DASHBOARD_CHART, `${Proxy_Prefix}/images/thingskit/dashboard-chart.png`) |
76 | return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '仪表盘'); | 95 | return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '仪表盘'); |
77 | - })) | 96 | + })), |
97 | + this.addEntry('flowmeter-circle', mxUtils.bind(this, function () { | ||
98 | + const cell = self.generateFlowmeterCell(100, 100, Sidebar.prototype.enumFlowmeterType.CIRCLE) | ||
99 | + return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '流量计'); | ||
100 | + })), | ||
101 | + this.addEntry('flowmeter-rect', mxUtils.bind(this, function () { | ||
102 | + const cell = self.generateFlowmeterCell(100, 100, Sidebar.prototype.enumFlowmeterType.RECT) | ||
103 | + return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '流量计'); | ||
104 | + })), | ||
105 | + this.addEntry('flowmeter-thermometer', mxUtils.bind(this, function () { | ||
106 | + const cell = self.generateFlowmeterCell(100, 100, Sidebar.prototype.enumFlowmeterType.THERMOMETER) | ||
107 | + return this.createVertexTemplateFromCells([cell], cell.geometry.width, cell.geometry.height, '流量计'); | ||
108 | + })), | ||
78 | ]; | 109 | ]; |
79 | 110 | ||
80 | this.addPaletteFunctions('charts', '图表', false, fns); | 111 | this.addPaletteFunctions('charts', '图表', false, fns); |
@@ -210,7 +241,8 @@ | @@ -210,7 +241,8 @@ | ||
210 | Sidebar.prototype.addClickHandler = function (elt, ds, cells) { | 241 | Sidebar.prototype.addClickHandler = function (elt, ds, cells) { |
211 | const cell = cells[0] | 242 | const cell = cells[0] |
212 | const cellValue = cell.value | 243 | const cellValue = cell.value |
213 | - const validate = cellValue && cellValue.nodeName === 'UserObject' && this.isChartCell(cell) | 244 | + const validateChart = cellValue && cellValue.nodeName === 'UserObject' && this.isChartCell(cell) |
245 | + const validateFlowmeter = cellValue && cellValue.nodeName === 'UserObject' && this.isFlowmeter(cell) | ||
214 | 246 | ||
215 | /** | 247 | /** |
216 | * @description 拓展Sidebar鼠标按下 | 248 | * @description 拓展Sidebar鼠标按下 |
@@ -218,7 +250,7 @@ | @@ -218,7 +250,7 @@ | ||
218 | */ | 250 | */ |
219 | const mouseDown = ds.mouseDown | 251 | const mouseDown = ds.mouseDown |
220 | ds.mouseDown = function (evt) { | 252 | ds.mouseDown = function (evt) { |
221 | - if (validate) { | 253 | + if (validateChart) { |
222 | const id = self.generatorChartsId() | 254 | const id = self.generatorChartsId() |
223 | const geo = Object.assign(graph.model.getGeometry(cell), { width: 400, height: 400 }) | 255 | const geo = Object.assign(graph.model.getGeometry(cell), { width: 400, height: 400 }) |
224 | cell.setGeometry(geo) | 256 | cell.setGeometry(geo) |
@@ -227,6 +259,14 @@ | @@ -227,6 +259,14 @@ | ||
227 | self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT, enumConst.CHART_CELL_DEFAULT_HEIGHT); | 259 | self.graph.setAttributeForCell(cell, enumConst.CHART_CELL_HEIGHT, enumConst.CHART_CELL_DEFAULT_HEIGHT); |
228 | self.graph.setAttributeForCell(cell, 'label', self.createChartsNode(id)) | 260 | self.graph.setAttributeForCell(cell, 'label', self.createChartsNode(id)) |
229 | } | 261 | } |
262 | + | ||
263 | + if (validateFlowmeter) { | ||
264 | + const { UUID, TYPE } = getFlowmeterAttrKey() | ||
265 | + const id = uuid() | ||
266 | + const type = self.graph.getAttributeForCell(cell, TYPE) | ||
267 | + self.graph.setAttributeForCell(cell, UUID, id); | ||
268 | + self.graph.setAttributeForCell(cell, 'label', Sidebar.prototype.generateFlowmeterTemplate(id, type)); | ||
269 | + } | ||
230 | mouseDown.apply(this, arguments) | 270 | mouseDown.apply(this, arguments) |
231 | }; | 271 | }; |
232 | 272 | ||
@@ -239,7 +279,7 @@ | @@ -239,7 +279,7 @@ | ||
239 | try { | 279 | try { |
240 | mouseUp.apply(this, arguments) | 280 | mouseUp.apply(this, arguments) |
241 | } finally { | 281 | } finally { |
242 | - if (validate) { | 282 | + if (validateChart) { |
243 | const id = self.getCellId(cell) | 283 | const id = self.getCellId(cell) |
244 | const chartType = cell.getAttribute(basicAttr.COMPONENT_TYPE) | 284 | const chartType = cell.getAttribute(basicAttr.COMPONENT_TYPE) |
245 | self.generatorEChartInstance(id, enumConst.CHART_CELL_DEFAULT_WIDTH, enumConst.CHART_CELL_DEFAULT_HEIGHT, chartType) | 285 | self.generatorEChartInstance(id, enumConst.CHART_CELL_DEFAULT_WIDTH, enumConst.CHART_CELL_DEFAULT_HEIGHT, chartType) |
@@ -332,6 +372,7 @@ | @@ -332,6 +372,7 @@ | ||
332 | const { width, height, chartType } = domIdMapping.get(id) | 372 | const { width, height, chartType } = domIdMapping.get(id) |
333 | Sidebar.prototype.generatorEChartInstance(id, width, height, chartType) | 373 | Sidebar.prototype.generatorEChartInstance(id, width, height, chartType) |
334 | } | 374 | } |
375 | + // Sidebar.prototype.initFlowmeter(graph) | ||
335 | } | 376 | } |
336 | 377 | ||
337 | /** | 378 | /** |
@@ -357,6 +398,7 @@ | @@ -357,6 +398,7 @@ | ||
357 | refresh.apply(this, arguments) | 398 | refresh.apply(this, arguments) |
358 | if (!arguments.length) { | 399 | if (!arguments.length) { |
359 | Sidebar.prototype.initChartInstance(this) | 400 | Sidebar.prototype.initChartInstance(this) |
401 | + Sidebar.prototype.resetFlowmeter(this) | ||
360 | } | 402 | } |
361 | } | 403 | } |
362 | 404 | ||
@@ -367,6 +409,7 @@ | @@ -367,6 +409,7 @@ | ||
367 | EditorUi.prototype.setFileData = function () { | 409 | EditorUi.prototype.setFileData = function () { |
368 | setFileData.apply(this, arguments) | 410 | setFileData.apply(this, arguments) |
369 | Sidebar.prototype.initChartInstance(this.editor.graph) | 411 | Sidebar.prototype.initChartInstance(this.editor.graph) |
412 | + Sidebar.prototype.resetFlowmeter(this.editor.graph) | ||
370 | } | 413 | } |
371 | 414 | ||
372 | // const selectPage = EditorUi.prototype.selectPage | 415 | // const selectPage = EditorUi.prototype.selectPage |
@@ -496,5 +539,419 @@ | @@ -496,5 +539,419 @@ | ||
496 | } | 539 | } |
497 | } | 540 | } |
498 | 541 | ||
542 | + function uuid() { | ||
543 | + return Number(Math.random().toString().substring(2)).toString(32) | ||
544 | + } | ||
545 | + | ||
546 | + /** | ||
547 | + * @description 生成流量计模版 | ||
548 | + */ | ||
549 | + Sidebar.prototype.generateFlowmeterTemplate = function (id = uuid(), type) { | ||
550 | + const flowmeterType = Sidebar.prototype.enumFlowmeterType | ||
551 | + const typeGenFn = { | ||
552 | + [flowmeterType.CIRCLE]: Sidebar.prototype.generateFlowmeterCircle, | ||
553 | + [flowmeterType.RECT]: Sidebar.prototype.generateFlowmeterRect, | ||
554 | + [flowmeterType.THERMOMETER]: Sidebar.prototype.generateFlowmeterThermometer, | ||
555 | + } | ||
556 | + const template = `<div class="flowmeter" style="transform: scale(0.9);font-size: 0;" id="${id}">${typeGenFn[type] && typeGenFn[type]()}</div>` | ||
557 | + return template | ||
558 | + } | ||
559 | + | ||
560 | + Sidebar.prototype.generateFlowmeterCell = function (width = 100, height = 100, type) { | ||
561 | + const id = uuid() | ||
562 | + const template = Sidebar.prototype.generateFlowmeterTemplate(id, type) | ||
563 | + const cell = new mxCell(template, new mxGeometry(0, 0, width, height), 'text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;overflow=hidden;'); | ||
564 | + cell.setVertex(true) | ||
565 | + const componentType = Sidebar.prototype.enumComponentType | ||
566 | + const { WIDTH, HEIGHT, VALUE, TYPE, COMPONENT_TYPE, UUID } = getFlowmeterAttrKey() | ||
567 | + this.graph.setAttributeForCell(cell, WIDTH, width); | ||
568 | + this.graph.setAttributeForCell(cell, HEIGHT, height); | ||
569 | + this.graph.setAttributeForCell(cell, VALUE, 20); | ||
570 | + this.graph.setAttributeForCell(cell, TYPE, type); | ||
571 | + this.graph.setAttributeForCell(cell, UUID, id); | ||
572 | + this.graph.setAttributeForCell(cell, COMPONENT_TYPE, componentType.FLOWMETER); | ||
573 | + return cell | ||
574 | + } | ||
575 | + | ||
576 | + Sidebar.prototype.generateFlowmeterRect = function () { | ||
577 | + return ` | ||
578 | + <svg class="waves-rect" viewBox="0 0 100 100" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" | ||
579 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
580 | + style="--width: 100; --height: 100; --value: 20; --play-state: running; --full-flag: clamp(0, calc(100 - var(--value)), 1); --over-min-flag: clamp(0, calc(calc(var(--value) - 1) * -1), 1);"> | ||
581 | + <defs> | ||
582 | + <style> | ||
583 | + .waves-rect { | ||
584 | + width: calc(var(--width) * 1px); | ||
585 | + height: calc(var(--height) * 1px); | ||
586 | + } | ||
587 | + | ||
588 | + @keyframes move { | ||
589 | + from { | ||
590 | + transform: translate(-90px, 0%); | ||
591 | + } | ||
592 | + | ||
593 | + to { | ||
594 | + transform: translate(85px, 0%); | ||
595 | + } | ||
596 | + } | ||
597 | + | ||
598 | + .wave { | ||
599 | + animation: move 3s linear infinite; | ||
600 | + animation-play-state: running; | ||
601 | + } | ||
602 | + | ||
603 | + .wave:nth-child(1) { | ||
604 | + animation-delay: -2s; | ||
605 | + animation-duration: 9s; | ||
606 | + } | ||
607 | + | ||
608 | + .wave:nth-child(2) { | ||
609 | + animation-delay: -4s; | ||
610 | + animation-duration: 6s; | ||
611 | + } | ||
612 | + | ||
613 | + .wave:nth-child(3) { | ||
614 | + animation-delay: -6s; | ||
615 | + animation-duration: 3s; | ||
616 | + } | ||
617 | + | ||
618 | + .waves-rect>g+rect { | ||
619 | + transform: translateY(calc(calc(100 - var(--value)) * var(--full-flag) * 1% + var(--full-flag) * 15%)); | ||
620 | + transition: transform linear 1s; | ||
621 | + } | ||
622 | + | ||
623 | + .height { | ||
624 | + transform: translateY(calc(var(--value) * -1% - 10% + var(--over-min-flag) * 10%)); | ||
625 | + transition: transform linear 1s; | ||
626 | + } | ||
627 | + | ||
628 | + .waves-rect .text { | ||
629 | + display: flex; | ||
630 | + justify-content: center; | ||
631 | + align-items: center; | ||
632 | + width: 100%; | ||
633 | + height: 100%; | ||
634 | + color: #fff; | ||
635 | + font-size: 18px; | ||
636 | + font-weight: 700; | ||
637 | + } | ||
638 | + | ||
639 | + .waves-rect .text::after { | ||
640 | + counter-reset: value var(--value); | ||
641 | + content: counter(value) ' %'; | ||
642 | + } | ||
643 | + </style> | ||
644 | + <path id="wave" d="M-160 118c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v100h-352z" /> | ||
645 | + </defs> | ||
646 | + <rect class="bgColor" x="0" y="0" width="100" height="100" fill="#8badcb"></rect> | ||
647 | + <g class="height"> | ||
648 | + <use class="wave waveFirst" xlink:href="#wave" fill="#4579e2" x="0" y="0"></use> | ||
649 | + <use class="wave waveSecond" xlink:href="#wave" fill="#3461c1" x="0" y="2"></use> | ||
650 | + <use class="wave waveThird" xlink:href="#wave" fill="#2d55aa" x="0" y="4"></use> | ||
651 | + </g> | ||
652 | + <rect class="waveThird" x="0" y="0" width="100" height="100" fill="#2d55aa"></rect> | ||
653 | + <foreignObject x="0" y="0" width="100" height="100" text-anchor="middle" dominant-baseline="middle"> | ||
654 | + <div xmlns="http://www.w3.org/1999/xhtml" class="text"></div> | ||
655 | + </foreignObject> | ||
656 | +</svg> | ||
657 | + `.replace(/\n/g, '') | ||
658 | + } | ||
659 | + | ||
660 | + Sidebar.prototype.generateFlowmeterCircle = function () { | ||
661 | + return ` | ||
662 | + <svg class="waves-circle" viewBox="0 0 100 100" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" | ||
663 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
664 | + style="--width: 100; --height: 100; --value: 20; --play-state: running; --full-flag: clamp(0, calc(100 - var(--value)), 1); --over-min-flag: clamp(0, calc(calc(var(--value) - 1) * -1), 1)"> | ||
665 | + <style> | ||
666 | + .waves-circle { | ||
667 | + width: calc(min(var(--width), var(--height)) * 1px); | ||
668 | + height: calc(min(var(--width), var(--height)) * 1px); | ||
669 | + clip-path: circle(calc(min(var(--width), var(--height)) / 2 * 1px)); | ||
670 | + } | ||
671 | + | ||
672 | + @keyframes move { | ||
673 | + from { | ||
674 | + transform: translate(-90px, 0%); | ||
675 | + } | ||
676 | + | ||
677 | + to { | ||
678 | + transform: translate(85px, 0%); | ||
679 | + } | ||
680 | + } | ||
681 | + | ||
682 | + .wave { | ||
683 | + animation: move 3s linear infinite; | ||
684 | + animation-play-state: var(--play-state); | ||
685 | + } | ||
686 | + | ||
687 | + .wave:nth-child(1) { | ||
688 | + animation-delay: -2s; | ||
689 | + animation-duration: 9s; | ||
690 | + } | ||
691 | + | ||
692 | + .wave:nth-child(2) { | ||
693 | + animation-delay: -4s; | ||
694 | + animation-duration: 6s; | ||
695 | + } | ||
696 | + | ||
697 | + .wave:nth-child(3) { | ||
698 | + animation-delay: -6s; | ||
699 | + animation-duration: 3s; | ||
700 | + } | ||
701 | + | ||
702 | + .height { | ||
703 | + transform: translateY(calc(var(--value) * -1% - 10% + var(--over-min-flag) * 10%)); | ||
704 | + transition: transform linear 1s; | ||
705 | + } | ||
706 | + | ||
707 | + .waves-circle>g+rect { | ||
708 | + transform: translateY(calc(calc(100 - var(--value)) * var(--full-flag) * 1% + var(--full-flag) * 15%)); | ||
709 | + transition: transform linear 1s; | ||
710 | + } | ||
711 | + | ||
712 | + .waves-circle .text { | ||
713 | + display: flex; | ||
714 | + justify-content: center; | ||
715 | + align-items: center; | ||
716 | + width: 100%; | ||
717 | + height: 100%; | ||
718 | + color: #fff; | ||
719 | + font-size: 18px; | ||
720 | + font-weight: 700; | ||
721 | + } | ||
722 | + | ||
723 | + .waves-circle .text::after { | ||
724 | + counter-reset: value var(--value); | ||
725 | + content: counter(value) ' %'; | ||
726 | + } | ||
727 | + </style> | ||
728 | + <defs> | ||
729 | + <path id="wave" d="M-160 118c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v100h-352z" /> | ||
730 | + </defs> | ||
731 | + <circle class="bgColor" cx="50" cy="50" r="50" fill="#8badcb" /> | ||
732 | + <g class="height"> | ||
733 | + <use class="wave waveFirst" xlink:href="#wave" fill="#4579e2" x="0" y="0"></use> | ||
734 | + <use class="wave waveSecond" xlink:href="#wave" fill="#3461c1" x="0" y="2"></use> | ||
735 | + <use class="wave waveThird" xlink:href="#wave" fill="#2d55aa" x="0" y="4"></use> | ||
736 | + </g> | ||
737 | + <rect class="waveThird" x="0" y="0" width="100" height="100" fill="#2d55aa"></rect> | ||
738 | + <foreignObject x="0" y="0" width="100" height="100" text-anchor="middle" dominant-baseline="middle"> | ||
739 | + <div xmlns="http://www.w3.org/1999/xhtml" class="text"></div> | ||
740 | + </foreignObject> | ||
741 | + </svg> | ||
742 | + `.replace(/\n/g, '') | ||
743 | + } | ||
744 | + | ||
745 | + Sidebar.prototype.generateFlowmeterThermometer = function () { | ||
746 | + return ` | ||
747 | + <svg class="flowmeter-thermometer" viewBox="0 0 200 250" xmlns="http://www.w3.org/2000/svg" | ||
748 | + style="--range: 4; --min: 50; --max: 70; --width: 100; --height: 100; --value: 50;"> | ||
749 | + <style> | ||
750 | + .flowmeter-thermometer { | ||
751 | + width: calc(min(var(--width), var(--height)) * 1px); | ||
752 | + height: calc(min(var(--width), var(--height)) * 1px); | ||
753 | + } | ||
754 | + | ||
755 | + .thermometer-mercury-column { | ||
756 | + y: var(--value); | ||
757 | + } | ||
758 | + | ||
759 | + .tick-label { | ||
760 | + font-size: 12px; | ||
761 | + text-align: right; | ||
762 | + overflow: hidden; | ||
763 | + text-overflow: ellipsis; | ||
764 | + color: #5b6b73; | ||
765 | + } | ||
766 | + | ||
767 | + .thermometer-mercury-column { | ||
768 | + transition: y .5s cubic-bezier(0.52, 0.05, 0.47, 0.99); | ||
769 | + } | ||
770 | + </style> | ||
771 | + <defs> | ||
772 | + <radialGradient id="thermometerdiv_meter_2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"> | ||
773 | + <stop offset="0%" style="stop-color: rgb(230, 200, 200);"></stop> | ||
774 | + <stop offset="90%" style="stop-color: rgb(230, 0, 0);"></stop> | ||
775 | + </radialGradient> | ||
776 | + <clipPath id="over"> | ||
777 | + <rect width="100" height="190" x="100" y="10" /> | ||
778 | + </clipPath> | ||
779 | + </defs> | ||
780 | + <circle r="9.25" cx="109" cy="14.25" style="fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136); stroke-width: 1px;"> | ||
781 | + </circle> | ||
782 | + <rect x="99.75" y="14.25" height="192.75" width="18.5" | ||
783 | + style="shape-rendering: crispedges; fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136); stroke-width: 1px;"> | ||
784 | + </rect> | ||
785 | + <circle r="8.75" cx="109" cy="14.25" style="fill: rgb(255, 255, 255); stroke: none;"></circle> | ||
786 | + <circle r="18" cx="109" cy="207" style="fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136);"></circle> | ||
787 | + <rect x="100.25" y="14.25" height="192.75" width="17.5" | ||
788 | + style="shape-rendering: crispedges; fill: rgb(255, 255, 255); stroke: none;"></rect> | ||
789 | + <line class="thermometer-min-line" x1="99.75" x2="140.25" y1="165" y2="165" | ||
790 | + style="stroke: rgb(136, 136, 136); stroke-width: 1px; shape-rendering: crispedges;"></line> | ||
791 | + <text class="thermometer-min-label" x="120.25" y="168.46428571428572" dy="0.72em" | ||
792 | + style="fill: rgb(0, 0, 230); font-size: 10px;">min</text> | ||
793 | + <line class="thermometer-max-line" x1="99.75" x2="140.25" y1="40" y2="40" | ||
794 | + style="stroke: rgb(136, 136, 136); stroke-width: 1px; shape-rendering: crispedges;"></line> | ||
795 | + <text class="thermometer-max-label" x="120.25" y="35.285714285714306" | ||
796 | + style="fill: rgb(230, 0, 0); font-size: 10px;">max</text> | ||
797 | + <rect class="thermometer-mercury-column" x="104" y="15" width="10.5" height="190" | ||
798 | + style="shape-rendering: crispedges; fill: rgb(230, 0, 0);" clip-path="url(#over)"></rect> | ||
799 | + <circle r="13" cx="109" cy="207" | ||
800 | + style="fill: url("#thermometerdiv_meter_2"); stroke: rgb(230, 0, 0); stroke-width: 2px;"></circle> | ||
801 | + <g class="thermometer-temperature-axis" transform="translate(99.75,0)" fill="none" font-size="10" | ||
802 | + font-family="sans-serif" text-anchor="end"> | ||
803 | + <g class="tick" opacity="1" transform="translate(0,190)"> | ||
804 | + <line stroke="currentColor" x2="-7" | ||
805 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
806 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
807 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">-20</div> | ||
808 | + </foreignObject> | ||
809 | + </g> | ||
810 | + <g class="tick" opacity="1" transform="translate(0,165)"> | ||
811 | + <line stroke="currentColor" x2="-7" | ||
812 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
813 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
814 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">0</div> | ||
815 | + </foreignObject> | ||
816 | + </g> | ||
817 | + <g class="tick" opacity="1" transform="translate(0,140)"> | ||
818 | + <line stroke="currentColor" x2="-7" | ||
819 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
820 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
821 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">20</div> | ||
822 | + </foreignObject> | ||
823 | + </g> | ||
824 | + <g class="tick" opacity="1" transform="translate(0,115)"> | ||
825 | + <line stroke="currentColor" x2="-7" | ||
826 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
827 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
828 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">40</div> | ||
829 | + </foreignObject> | ||
830 | + </g> | ||
831 | + <g class="tick" opacity="1" transform="translate(0,90)"> | ||
832 | + <line stroke="currentColor" x2="-7" | ||
833 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
834 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
835 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">60</div> | ||
836 | + </foreignObject> | ||
837 | + </g> | ||
838 | + <g class="tick" opacity="1" transform="translate(0,65)"> | ||
839 | + <line stroke="currentColor" x2="-7" | ||
840 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
841 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
842 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">80</div> | ||
843 | + </foreignObject> | ||
844 | + </g> | ||
845 | + <g class="tick" opacity="1" transform="translate(0,40)"> | ||
846 | + <line stroke="currentColor" x2="-7" | ||
847 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
848 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
849 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">100</div> | ||
850 | + </foreignObject> | ||
851 | + </g> | ||
852 | + <g class="tick" opacity="1" transform="translate(0,15)"> | ||
853 | + <line stroke="currentColor" x2="-7" | ||
854 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
855 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
856 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">120</div> | ||
857 | + </foreignObject> | ||
858 | + </g> | ||
859 | + </g> | ||
860 | + </svg> | ||
861 | + `.replace(/\n/g, '') | ||
862 | + } | ||
863 | + | ||
864 | + Sidebar.prototype.resetFlowmeter = function (graph) { | ||
865 | + const { COMPONENT_TYPE, UUID, WIDTH, HEIGHT } = getFlowmeterAttrKey() | ||
866 | + const componentType = Sidebar.prototype.enumComponentType | ||
867 | + const cells = Object.entries(graph?.getModel()?.cells || {}).map(([_, item]) => item) || [] | ||
868 | + const needReset = cells.filter(item => item.value && item.getAttribute(COMPONENT_TYPE) === componentType.FLOWMETER) | ||
869 | + | ||
870 | + needReset.forEach(item => { | ||
871 | + const id = item.getAttribute(UUID) | ||
872 | + const element = document.getElementById(id).querySelector('svg') | ||
873 | + if (element) { | ||
874 | + const width = item.getAttribute(WIDTH) | ||
875 | + const height = item.getAttribute(HEIGHT) | ||
876 | + | ||
877 | + element.style.setProperty('--width', width) | ||
878 | + element.style.setProperty('--height', height) | ||
879 | + } | ||
880 | + }) | ||
881 | + } | ||
882 | + | ||
883 | + Sidebar.prototype.isFlowmeter = function (cell) { | ||
884 | + const basicAttr = Sidebar.prototype.enumCellBasicAttribute | ||
885 | + const componentType = Sidebar.prototype.enumComponentType | ||
886 | + return cell.getAttribute(basicAttr.COMPONENT_TYPE) === componentType.FLOWMETER | ||
887 | + } | ||
888 | + | ||
889 | + Sidebar.prototype.updateFlowmeterCell = function (cell, { width, height, value, type }) { | ||
890 | + const { WIDTH, HEIGHT, VALUE, TYPE, UUID } = getFlowmeterAttrKey() | ||
891 | + const id = cell.getAttribute(UUID) | ||
892 | + const element = document.getElementById(id).querySelector('svg') | ||
893 | + if (element) { | ||
894 | + width && element.style.setProperty('--width', width) | ||
895 | + height && element.style.setProperty('--height', height) | ||
896 | + value && element.style.setProperty('--value', value) | ||
897 | + width && cell.setAttribute(WIDTH, width) | ||
898 | + height && cell.setAttribute(HEIGHT, height) | ||
899 | + value && cell.setAttribute(VALUE, value) | ||
900 | + type && cell.setAttribute(TYPE, type) | ||
901 | + } | ||
902 | + } | ||
903 | + | ||
904 | + /** | ||
905 | + * @description charts cell发生resize时改变charts size | ||
906 | + * @type {Function} | ||
907 | + */ | ||
908 | + const cellResized = mxGraph.prototype.cellResized | ||
909 | + mxGraph.prototype.cellResized = function (cell, rect) { | ||
910 | + | ||
911 | + if (Sidebar.prototype.isFlowmeter(cell)) { | ||
912 | + const { width, height } = rect | ||
913 | + Sidebar.prototype.updateFlowmeterCell(cell, { width, height }) | ||
914 | + } | ||
915 | + cellResized.apply(this, arguments) | ||
916 | + } | ||
499 | })(); | 917 | })(); |
500 | 918 | ||
919 | +/** | ||
920 | + * @description 获取流量计属性key | ||
921 | + * @returns {{WIDTH: 'width', HEIGHT: 'height', VALUE: 'value', TYPE: 'type', UUID: 'uuid', COMPONENT_TYPE: 'componentType', BG_COLOR: 'bgColor', WAVE_FIRST_COLOR: 'waveFirstColor', WAVE_SECOND_COLOR: 'waveSecondColor', WAVE_THIRD_COLOR: 'waveThirdColor'}} | ||
922 | + */ | ||
923 | +function getFlowmeterAttrKey() { | ||
924 | + const basicAttr = Sidebar.prototype.enumCellBasicAttribute | ||
925 | + const flowmeterAttr = Sidebar.prototype.enumFlowmeterAttr | ||
926 | + return { | ||
927 | + WIDTH: flowmeterAttr.WIDTH, | ||
928 | + HEIGHT: flowmeterAttr.HEIGHT, | ||
929 | + VALUE: flowmeterAttr.VALUE, | ||
930 | + TYPE: flowmeterAttr.TYPE, | ||
931 | + UUID: flowmeterAttr.UUID, | ||
932 | + BG_COLOR: flowmeterAttr.BG_COLOR, | ||
933 | + WAVE_FIRST_COLOR: flowmeterAttr.WAVE_FIRST_COLOR, | ||
934 | + WAVE_SECOND_COLOR: flowmeterAttr.WAVE_SECOND_COLOR, | ||
935 | + WAVE_THIRD_COLOR: flowmeterAttr.WAVE_THIRD_COLOR, | ||
936 | + UUID: flowmeterAttr.UUID, | ||
937 | + COMPONENT_TYPE: basicAttr.COMPONENT_TYPE, | ||
938 | + } | ||
939 | +} | ||
940 | + | ||
941 | +/** | ||
942 | + * @description 获取流量计类型 | ||
943 | + * @returns {{RECT: 'rect', CIRCLE: 'circle'}} | ||
944 | + */ | ||
945 | +function getFlowmeterType() { | ||
946 | + const type = Sidebar.prototype.enumFlowmeterType | ||
947 | + return { | ||
948 | + RECT: type.RECT, | ||
949 | + CIRCLE: type.CIRCLE | ||
950 | + } | ||
951 | +} | ||
952 | + | ||
953 | + | ||
954 | +function getComponentType() { | ||
955 | + const componentType = Sidebar.prototype.enumComponentType | ||
956 | + return | ||
957 | +} |
@@ -5132,7 +5132,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -5132,7 +5132,8 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
5132 | [permissionKey.VIDEO]: createVideoBindPanel, | 5132 | [permissionKey.VIDEO]: createVideoBindPanel, |
5133 | [permissionKey.SWITCH_STATE_SETTING]: createSwitchStateSettingPanel, | 5133 | [permissionKey.SWITCH_STATE_SETTING]: createSwitchStateSettingPanel, |
5134 | [permissionKey.ONLY_SINGLE_EVENT]: createParamsSettingButtonPanel, | 5134 | [permissionKey.ONLY_SINGLE_EVENT]: createParamsSettingButtonPanel, |
5135 | - [permissionKey.RUNNING_AND_STOP]: createRunningAndStopPanel | 5135 | + [permissionKey.RUNNING_AND_STOP]: createRunningAndStopPanel, |
5136 | + [permissionKey.FLOWMETER_PANEL]: createFlowmeterPanel | ||
5136 | } | 5137 | } |
5137 | 5138 | ||
5138 | 5139 | ||
@@ -5241,6 +5242,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -5241,6 +5242,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
5241 | * @type {Function} | 5242 | * @type {Function} |
5242 | */ | 5243 | */ |
5243 | const refreshFn = echoRefreshFn | 5244 | const refreshFn = echoRefreshFn |
5245 | + | ||
5244 | echoRefreshFn = function () { | 5246 | echoRefreshFn = function () { |
5245 | refreshFn.apply(this) | 5247 | refreshFn.apply(this) |
5246 | const { dataSources: [dataSource] = [] } = currentNodeData || {} | 5248 | const { dataSources: [dataSource] = [] } = currentNodeData || {} |
@@ -5428,6 +5430,70 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -5428,6 +5430,70 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
5428 | } | 5430 | } |
5429 | 5431 | ||
5430 | /** | 5432 | /** |
5433 | + * @description 创建流量计面板 | ||
5434 | + */ | ||
5435 | + function createFlowmeterPanel() { | ||
5436 | + | ||
5437 | + const enumConst = { | ||
5438 | + MAX_VALUE: 'maxValue', | ||
5439 | + MIN_VALUE: 'minValue', | ||
5440 | + BG_COLOR: 'bgColor', | ||
5441 | + WAVE_FIRST: 'waveFirst', | ||
5442 | + WAVE_SECOND: 'waveSecond', | ||
5443 | + WAVE_THIRD: 'waveThird', | ||
5444 | + COMPONENT_TYPE: 'componentType' | ||
5445 | + } | ||
5446 | + | ||
5447 | + const enumEl = { | ||
5448 | + BG_COLOR_PICKER_EL: 'bgColorPickerEl', | ||
5449 | + WAVE_FIRST: 'waveFirstEl', | ||
5450 | + WAVE_SECOND: 'waveSecondEl', | ||
5451 | + WAVE_THIRD: 'waveThirdEl', | ||
5452 | + } | ||
5453 | + | ||
5454 | + const componentType = Sidebar.prototype.enumComponentType | ||
5455 | + const flowmeterType = Sidebar.prototype.enumFlowmeterType | ||
5456 | + const { TYPE } = getFlowmeterAttrKey() | ||
5457 | + const cell = vertices[0] | ||
5458 | + const isThemometerComponent = cell.getAttribute(TYPE) === flowmeterType.THERMOMETER | ||
5459 | + | ||
5460 | + if (isThemometerComponent) return | ||
5461 | + | ||
5462 | + const fragment = document.createDocumentFragment() | ||
5463 | + const title = createTitle('流量计配置') | ||
5464 | + $(title).addClass('override__title--default') | ||
5465 | + | ||
5466 | + const defaultPanel = createPanel() | ||
5467 | + $(defaultPanel).addClass('override__panel--default') | ||
5468 | + $(defaultPanel).append(`<div style="display: none;" class="layui-form-item data-source__component-select"><label class="layui-form-label">最小值</label><div class="layui-input-block"><input class="layui-input" name="${enumConst.COMPONENT_TYPE}" value="${componentType.FLOWMETER}" placeholder="组件类型"></div></div>`) | ||
5469 | + // $(defaultPanel).append(`<div class="layui-form-item data-source__component-select"><label class="layui-form-label">最小值</label><div class="layui-input-block"><input class="layui-input" name="${enumConst.MIN_VALUE}" value="0" placeholder="请输入最小值"></div></div>`) | ||
5470 | + // $(defaultPanel).append(`<div class="layui-form-item data-source__component-select"><label class="layui-form-label">最大值</label><div class="layui-input-block"><input class="layui-input" name="${enumConst.MAX_VALUE}" value="100" placeholder="请输入最大值"></div></div>`) | ||
5471 | + $(defaultPanel).append(`<div style="display: ${isThemometerComponent ? 'none' : 'block'}" class="layui-form-item data-source__component-select"><label class="layui-form-label">背景色</label><div class="layui-input-block" style="display: flex; align-items: center;"><input style="border: none;" id="${enumEl.BG_COLOR_PICKER_EL}" type="color" name="${enumConst.BG_COLOR}" value="#8badcb" /></div></div>`) | ||
5472 | + $(defaultPanel).append(`<div style="display: ${isThemometerComponent ? 'none' : 'block'}" class="layui-form-item data-source__component-select"><label class="layui-form-label">颜色一</label><div class="layui-input-block" style="display: flex; align-items: center;"><input style="border: none;" id="${enumEl.WAVE_FIRST}" type="color" name="${enumConst.WAVE_FIRST}" value="#4579e2" /></div></div>`) | ||
5473 | + $(defaultPanel).append(`<div style="display: ${isThemometerComponent ? 'none' : 'block'}" class="layui-form-item data-source__component-select"><label class="layui-form-label">颜色二</label><div class="layui-input-block" style="display: flex; align-items: center;"><input style="border: none;" id="${enumEl.WAVE_SECOND}" type="color" name="${enumConst.WAVE_SECOND}" value="#3461c1" /></div></div>`) | ||
5474 | + $(defaultPanel).append(`<div style="display: ${isThemometerComponent ? 'none' : 'block'}" class="layui-form-item data-source__component-select"><label class="layui-form-label">颜色三</label><div class="layui-input-block" style="display: flex; align-items: center;"><input style="border: none;" id="${enumEl.WAVE_THIRD}" type="color" name="${enumConst.WAVE_THIRD}" value="#2d55aa" /></div></div>`) | ||
5475 | + | ||
5476 | + | ||
5477 | + fragment.append(title) | ||
5478 | + fragment.append(defaultPanel) | ||
5479 | + $(container).append(fragment) | ||
5480 | + | ||
5481 | + function init() { | ||
5482 | + | ||
5483 | + const refreshFn = echoRefreshFn | ||
5484 | + echoRefreshFn = function () { | ||
5485 | + refreshFn.apply(this) | ||
5486 | + const { dataSources: [dataSource] = [] } = currentNodeData || {} | ||
5487 | + form.val(CONTAINER_FILTER, dataSource?.additional || {}) | ||
5488 | + } | ||
5489 | + | ||
5490 | + form.render() | ||
5491 | + } | ||
5492 | + | ||
5493 | + init() | ||
5494 | + } | ||
5495 | + | ||
5496 | + /** | ||
5431 | * @description 是否是折线图 | 5497 | * @description 是否是折线图 |
5432 | * @param {boolean} isLineChart | 5498 | * @param {boolean} isLineChart |
5433 | */ | 5499 | */ |
@@ -5900,6 +5966,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -5900,6 +5966,7 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
5900 | } | 5966 | } |
5901 | const { field } = data | 5967 | const { field } = data |
5902 | const value = getValueOnSubmit(field) | 5968 | const value = getValueOnSubmit(field) |
5969 | + if (!value) return | ||
5903 | await to(autoSaveGraphInfo()) | 5970 | await to(autoSaveGraphInfo()) |
5904 | const [err, res] = await to(ConfigurationNodeApi.updateNodeInfo(value)) | 5971 | const [err, res] = await to(ConfigurationNodeApi.updateNodeInfo(value)) |
5905 | if (err) return | 5972 | if (err) return |
@@ -5927,12 +5994,13 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -5927,12 +5994,13 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
5927 | [componentType.VIDEO]: getVideoSubmitValue, | 5994 | [componentType.VIDEO]: getVideoSubmitValue, |
5928 | [componentType.SWITCH]: getSwitchSubmitValue, | 5995 | [componentType.SWITCH]: getSwitchSubmitValue, |
5929 | [componentType.PARAMS_SETTING_BUTTON]: getSwitchSubmitValue, | 5996 | [componentType.PARAMS_SETTING_BUTTON]: getSwitchSubmitValue, |
5930 | - [componentType.IMAGE]: getSubmitValue | 5997 | + [componentType.IMAGE]: getSubmitValue, |
5998 | + [componentType.FLOWMETER]: getFlowmeterSubmitValue, | ||
5931 | } | 5999 | } |
5932 | 6000 | ||
5933 | const cell = vertices[0] | 6001 | const cell = vertices[0] |
5934 | const type = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE) | 6002 | const type = graph.getAttributeForCell(cell, basicAttr.COMPONENT_TYPE) |
5935 | - return renderMapping[type]?.(field) || {} | 6003 | + return renderMapping[type]?.(field) || false |
5936 | 6004 | ||
5937 | function getSubmitValue(field) { | 6005 | function getSubmitValue(field) { |
5938 | const ENABLED_FLAG = 'on' | 6006 | const ENABLED_FLAG = 'on' |
@@ -6062,6 +6130,47 @@ DataFormatPanel.prototype.addDataFont = function (container) { | @@ -6062,6 +6130,47 @@ DataFormatPanel.prototype.addDataFont = function (container) { | ||
6062 | } | 6130 | } |
6063 | return value | 6131 | return value |
6064 | } | 6132 | } |
6133 | + | ||
6134 | + function getFlowmeterSubmitValue(field = {}) { | ||
6135 | + const additionalKey = HandleDataSource.enumConst | ||
6136 | + const minValue = field[additionalKey.MIN_VALUE] | ||
6137 | + const maxValue = field[additionalKey.MAX_VALUE] | ||
6138 | + | ||
6139 | + if ([minValue, maxValue].some(item => isNaN(item))) { | ||
6140 | + UseLayUi.topErrorMsg('最大值或最小值不是一个数字!') | ||
6141 | + return false | ||
6142 | + } | ||
6143 | + | ||
6144 | + if (Number(minValue) > Number(maxValue)) { | ||
6145 | + UseLayUi.topErrorMsg('最小值大于最大值!') | ||
6146 | + return false | ||
6147 | + } | ||
6148 | + | ||
6149 | + const value = { | ||
6150 | + configurationId, | ||
6151 | + contentId: currentPageId.id, | ||
6152 | + nodeId: graphId, | ||
6153 | + [enumCategory.ACT]: [], | ||
6154 | + [enumCategory.EVENT]: [], | ||
6155 | + [enumCategory.DATA_SOURCE]: { | ||
6156 | + [enumDataSourceConst.ORG_ID]: field[enumDataSourceConst.ORG_ID], | ||
6157 | + [enumDataSourceConst.DEVICE_ID]: field[enumDataSourceConst.DEVICE_ID], | ||
6158 | + [enumDataSourceConst.DEVICE_TYPE]: field[enumDataSourceConst.DEVICE_TYPE], | ||
6159 | + [enumDataSourceConst.DEVICE_PROFILE_ID]: field[enumDataSourceConst.DEVICE_PROFILE_ID], | ||
6160 | + [enumDataSourceConst.ATTR]: field[enumDataSourceConst.ATTR], | ||
6161 | + [enumDataSourceConst.ADDITIONAL]: { | ||
6162 | + [additionalKey.COMPONENT_TYPE]: field[additionalKey.COMPONENT_TYPE], | ||
6163 | + [additionalKey.MIN_VALUE]: field[additionalKey.MIN_VALUE], | ||
6164 | + [additionalKey.MAX_VALUE]: field[additionalKey.MAX_VALUE], | ||
6165 | + [additionalKey.BG_COLOR]: field[additionalKey.BG_COLOR], | ||
6166 | + [additionalKey.WAVE_FIRST_COLOR]: field[additionalKey.WAVE_FIRST_COLOR], | ||
6167 | + [additionalKey.WAVE_SECOND_COLOR]: field[additionalKey.WAVE_SECOND_COLOR], | ||
6168 | + [additionalKey.WAVE_THIRD_COLOR]: field[additionalKey.WAVE_THIRD_COLOR], | ||
6169 | + } | ||
6170 | + }, | ||
6171 | + } | ||
6172 | + return value | ||
6173 | + } | ||
6065 | } | 6174 | } |
6066 | 6175 | ||
6067 | /** | 6176 | /** |
@@ -13660,7 +13769,7 @@ class DispatchCenter { | @@ -13660,7 +13769,7 @@ class DispatchCenter { | ||
13660 | subList.forEach(item => { | 13769 | subList.forEach(item => { |
13661 | const { dataOrigin, additional } = item | 13770 | const { dataOrigin, additional } = item |
13662 | if (dataOrigin === 'dataSources') { | 13771 | if (dataOrigin === 'dataSources') { |
13663 | - if (additional) { | 13772 | + if (additional && (additional || {})?.dataType ) { |
13664 | const { dataType } = additional || {} | 13773 | const { dataType } = additional || {} |
13665 | if (dataType === HandleDataSource.enumDataBindType.REAL) { | 13774 | if (dataType === HandleDataSource.enumDataBindType.REAL) { |
13666 | this.dataSourceHandlerInstance.updateRealTimeDataSource(message, item) | 13775 | this.dataSourceHandlerInstance.updateRealTimeDataSource(message, item) |
@@ -13678,10 +13787,6 @@ class DispatchCenter { | @@ -13678,10 +13787,6 @@ class DispatchCenter { | ||
13678 | handleFunction(message, item) | 13787 | handleFunction(message, item) |
13679 | } | 13788 | } |
13680 | }) | 13789 | }) |
13681 | - // this.subscribeEvent(cmdId, this.updateCommonDataSource.bind(this)) | ||
13682 | - return | ||
13683 | - // const { subscriptionId, data } = message | ||
13684 | - // DispatchCenter.instance.publishEvent(subscriptionId, data, message, event, ws) | ||
13685 | } | 13790 | } |
13686 | 13791 | ||
13687 | /** | 13792 | /** |
@@ -13712,6 +13817,40 @@ class DispatchCenter { | @@ -13712,6 +13817,40 @@ class DispatchCenter { | ||
13712 | if (!id) return | 13817 | if (!id) return |
13713 | const [err, res] = await to(ConfigurationNodeApi.getConfigurationInfo('CONTENT', id)) | 13818 | const [err, res] = await to(ConfigurationNodeApi.getConfigurationInfo('CONTENT', id)) |
13714 | this.contentData = res | 13819 | this.contentData = res |
13820 | + this.afterGetContentDataNode() | ||
13821 | + } | ||
13822 | + | ||
13823 | + afterGetContentDataNode() { | ||
13824 | + setTimeout(() => { | ||
13825 | + const componentType = Sidebar.prototype.enumComponentType | ||
13826 | + const flowmeterComponent = this.contentData.dataSources.filter(item => item.additional && (item.additional || {}).componentType === componentType.FLOWMETER) | ||
13827 | + const { MIN_VALUE, MAX_VALUE, BG_COLOR, WAVE_FIRST_COLOR, WAVE_SECOND_COLOR, WAVE_THIRD_COLOR } = HandleDataSource.enumConst | ||
13828 | + flowmeterComponent.forEach(item => { | ||
13829 | + const { nodeId, additional } = item | ||
13830 | + const { bgColor, maxValue, minValue, waveFirst, waveSecond, waveThird } = additional || {} | ||
13831 | + const cell = this.graph?.getCellsById([nodeId])?.[0] | ||
13832 | + if (cell) { | ||
13833 | + cell.setAttribute(BG_COLOR, bgColor) | ||
13834 | + cell.setAttribute(MIN_VALUE, minValue) | ||
13835 | + cell.setAttribute(MAX_VALUE, maxValue) | ||
13836 | + cell.setAttribute(WAVE_FIRST_COLOR, waveFirst) | ||
13837 | + cell.setAttribute(WAVE_SECOND_COLOR, waveSecond) | ||
13838 | + cell.setAttribute(WAVE_THIRD_COLOR, waveThird) | ||
13839 | + | ||
13840 | + const { UUID } = getFlowmeterAttrKey() | ||
13841 | + const id = cell.getAttribute(UUID) | ||
13842 | + | ||
13843 | + const element = document.getElementById(id) | ||
13844 | + | ||
13845 | + if (element) { | ||
13846 | + element.querySelectorAll(`.${BG_COLOR}`).forEach(item => item.style.fill = bgColor) | ||
13847 | + element.querySelectorAll(`.${WAVE_FIRST_COLOR}`).forEach(item => item.style.fill = waveFirst) | ||
13848 | + element.querySelectorAll(`.${WAVE_SECOND_COLOR}`).forEach(item => item.style.fill = waveSecond) | ||
13849 | + element.querySelectorAll(`.${WAVE_THIRD_COLOR}`).forEach(item => item.style.fill = waveThird) | ||
13850 | + } | ||
13851 | + } | ||
13852 | + }) | ||
13853 | + }, 10); | ||
13715 | } | 13854 | } |
13716 | 13855 | ||
13717 | sendSubscribeMessage() { | 13856 | sendSubscribeMessage() { |
@@ -14043,7 +14182,42 @@ class HandleDataSource { | @@ -14043,7 +14182,42 @@ class HandleDataSource { | ||
14043 | /** | 14182 | /** |
14044 | * @description 属性名称 | 14183 | * @description 属性名称 |
14045 | */ | 14184 | */ |
14046 | - ATTR_NAME: 'attrName' | 14185 | + ATTR_NAME: 'attrName', |
14186 | + | ||
14187 | + /** | ||
14188 | + * @description 组件类型 | ||
14189 | + */ | ||
14190 | + COMPONENT_TYPE: 'componentType', | ||
14191 | + | ||
14192 | + /** | ||
14193 | + * @description 流量计最大值 | ||
14194 | + */ | ||
14195 | + MAX_VALUE: 'maxValue', | ||
14196 | + | ||
14197 | + /** | ||
14198 | + * @description 流量计最小值 | ||
14199 | + */ | ||
14200 | + MIN_VALUE: 'minValue', | ||
14201 | + | ||
14202 | + /** | ||
14203 | + * @description 流量计背景颜色 | ||
14204 | + */ | ||
14205 | + BG_COLOR: 'bgColor', | ||
14206 | + | ||
14207 | + /** | ||
14208 | + * @description 流量计颜色一 | ||
14209 | + */ | ||
14210 | + WAVE_FIRST_COLOR: 'waveFirst', | ||
14211 | + | ||
14212 | + /** | ||
14213 | + * @description 流量计颜色二 | ||
14214 | + */ | ||
14215 | + WAVE_SECOND_COLOR: 'waveSecond', | ||
14216 | + | ||
14217 | + /** | ||
14218 | + * @description 流量计颜色三 | ||
14219 | + */ | ||
14220 | + WAVE_THIRD_COLOR: 'waveThird', | ||
14047 | } | 14221 | } |
14048 | 14222 | ||
14049 | 14223 | ||
@@ -14074,8 +14248,6 @@ class HandleDataSource { | @@ -14074,8 +14248,6 @@ class HandleDataSource { | ||
14074 | 14248 | ||
14075 | constructor(DispatchInstance) { | 14249 | constructor(DispatchInstance) { |
14076 | this.DispatchInstance = DispatchInstance | 14250 | this.DispatchInstance = DispatchInstance |
14077 | - // this.generatorCommonDataSourceMapping() | ||
14078 | - // this.generatorChartDataSourceMapping() | ||
14079 | } | 14251 | } |
14080 | 14252 | ||
14081 | get graph() { | 14253 | get graph() { |
@@ -14114,76 +14286,6 @@ class HandleDataSource { | @@ -14114,76 +14286,6 @@ class HandleDataSource { | ||
14114 | } | 14286 | } |
14115 | 14287 | ||
14116 | /** | 14288 | /** |
14117 | - * @description 生成普通数据源绑定映射关系 | ||
14118 | - * @param dataSources | ||
14119 | - * @return {{cmdId: number, entityType: string, keys: *, scope: string, entityId: *}[]} | ||
14120 | - */ | ||
14121 | - generatorCommonDataSourceMapping() { | ||
14122 | - const msg = this.commonDataSourceBindList.map((datum) => { | ||
14123 | - const { deviceId, attr, nodeId, slaveDeviceId } = datum | ||
14124 | - const cmdId = this.getCmdId(nodeId) | ||
14125 | - const sendMsgTemplate = { | ||
14126 | - entityType: "DEVICE", | ||
14127 | - entityId: slaveDeviceId ? slaveDeviceId : deviceId, | ||
14128 | - scope: "LATEST_TELEMETRY", | ||
14129 | - cmdId, | ||
14130 | - keys: attr, | ||
14131 | - } | ||
14132 | - this.dataSourceNodeMapping.set(nodeId, datum) | ||
14133 | - this.subscribeEvent(cmdId, this.updateCommonDataSource.bind(this)) | ||
14134 | - return sendMsgTemplate | ||
14135 | - }) | ||
14136 | - const { REAL } = HandleDataSource.enumDataBindType | ||
14137 | - if (msg.length) this.sendMsg({ [REAL]: msg }) | ||
14138 | - } | ||
14139 | - | ||
14140 | - | ||
14141 | - /** | ||
14142 | - * @description 图表数据源绑定关系 | ||
14143 | - * @param {any[]} dataSource | ||
14144 | - */ | ||
14145 | - generatorChartDataSourceMapping() { | ||
14146 | - const realList = [] | ||
14147 | - const historyList = [] | ||
14148 | - const { HISTORY, REAL } = HandleDataSource.enumDataBindType | ||
14149 | - const { STARTTs, ENDTs } = HandleDataSource.enumConst | ||
14150 | - for (const item of this.chartDataSourceBindList) { | ||
14151 | - const { additional = {}, deviceId, attr, nodeId, slaveDeviceId } = item | ||
14152 | - if (!attr) continue | ||
14153 | - const { agg, interval = 1000, dataType, effectScope = 0 } = additional | ||
14154 | - const cmdId = this.getCmdId(nodeId) | ||
14155 | - const template = { | ||
14156 | - entityType: "DEVICE", | ||
14157 | - entityId: slaveDeviceId ? slaveDeviceId : deviceId, | ||
14158 | - cmdId, | ||
14159 | - interval: Number(interval), | ||
14160 | - agg, | ||
14161 | - keys: attr, | ||
14162 | - } | ||
14163 | - let scope = isNaN(effectScope) ? 0 : Number(effectScope) | ||
14164 | - if (dataType === HISTORY) { | ||
14165 | - template[STARTTs] = Date.now() - scope | ||
14166 | - template[ENDTs] = Date.now() | ||
14167 | - historyList.push(template) | ||
14168 | - this.subscribeEvent(cmdId, (message) => { | ||
14169 | - this.updateHistoryDataSource(message, agg) | ||
14170 | - }) | ||
14171 | - } | ||
14172 | - else if (dataType === REAL) { | ||
14173 | - template[STARTTs] = Date.now() - scope | ||
14174 | - // template['timeWindow'] = interval | ||
14175 | - realList.push(template) | ||
14176 | - this.subscribeEvent(cmdId, (message) => { | ||
14177 | - this.updateRealTimeDataSource(message, agg) | ||
14178 | - }) | ||
14179 | - } | ||
14180 | - this.dataSourceNodeMapping.set(nodeId, item) | ||
14181 | - } | ||
14182 | - | ||
14183 | - if (historyList.length || realList.length) this.sendMsg({ [HISTORY]: historyList, [REAL]: realList }) | ||
14184 | - } | ||
14185 | - | ||
14186 | - /** | ||
14187 | * @description 订阅事件 绑定回调 | 14289 | * @description 订阅事件 绑定回调 |
14188 | * @param eventName | 14290 | * @param eventName |
14189 | * @param callback | 14291 | * @param callback |
@@ -14197,12 +14299,20 @@ class HandleDataSource { | @@ -14197,12 +14299,20 @@ class HandleDataSource { | ||
14197 | * @param {} message | 14299 | * @param {} message |
14198 | */ | 14300 | */ |
14199 | updateCommonDataSource(message, record) { | 14301 | updateCommonDataSource(message, record) { |
14302 | + console.log('enter') | ||
14200 | const { nodeId, attr } = record | 14303 | const { nodeId, attr } = record |
14201 | - const node = this.getNodeByCmdId(nodeId) | 14304 | + const node = this.getNodeByNodeId(nodeId) |
14305 | + const { data } = message | ||
14306 | + const type = this.getComponentType(node) | ||
14307 | + | ||
14308 | + if (node && type === this.componentType.FLOWMETER) { | ||
14309 | + this.handleFlowmeterComponent(message, record) | ||
14310 | + return | ||
14311 | + } | ||
14202 | 14312 | ||
14313 | + // 需要刷新页面 | ||
14203 | node && this.updatePage(() => { | 14314 | node && this.updatePage(() => { |
14204 | - const { data } = message | ||
14205 | - const type = this.getComponentType(node) | 14315 | + |
14206 | if (type === this.componentType.SWITCH) { | 14316 | if (type === this.componentType.SWITCH) { |
14207 | this.handleSwitchComponent(message, record) | 14317 | this.handleSwitchComponent(message, record) |
14208 | return | 14318 | return |
@@ -14232,7 +14342,7 @@ class HandleDataSource { | @@ -14232,7 +14342,7 @@ class HandleDataSource { | ||
14232 | handleSwitchComponent(message, record) { | 14342 | handleSwitchComponent(message, record) { |
14233 | const { data = {} } = message | 14343 | const { data = {} } = message |
14234 | const { nodeId, attr } = record | 14344 | const { nodeId, attr } = record |
14235 | - const node = this.getNodeByCmdId(nodeId) | 14345 | + const node = this.getNodeByNodeId(nodeId) |
14236 | const [[_timespan, receiveValue] = []] = data[attr] || [] | 14346 | const [[_timespan, receiveValue] = []] = data[attr] || [] |
14237 | const switchConfig = this.DispatchInstance.contentData.act.find(item => item.id === nodeId && item.type === 'SWITCH') | 14347 | const switchConfig = this.DispatchInstance.contentData.act.find(item => item.id === nodeId && item.type === 'SWITCH') |
14238 | const { condition = [] } = switchConfig || {} | 14348 | const { condition = [] } = switchConfig || {} |
@@ -14273,11 +14383,46 @@ class HandleDataSource { | @@ -14273,11 +14383,46 @@ class HandleDataSource { | ||
14273 | 14383 | ||
14274 | } | 14384 | } |
14275 | 14385 | ||
14386 | + handleFlowmeterComponent(message, record) { | ||
14387 | + const { data = {} } = message | ||
14388 | + if (!data) return | ||
14389 | + const { nodeId, attr } = record | ||
14390 | + const node = this.getNodeByNodeId(nodeId) | ||
14391 | + | ||
14392 | + let [[_timespan, receiveValue] = []] = data[attr] || [] | ||
14393 | + const { UUID, TYPE } = getFlowmeterAttrKey() | ||
14394 | + const type = node.getAttribute(TYPE) | ||
14395 | + const flowmeterType = Sidebar.prototype.enumFlowmeterType | ||
14396 | + const id = node.getAttribute(UUID) | ||
14397 | + const element = document.getElementById(id) | ||
14398 | + const bindData = this.getBindData(nodeId) | ||
14399 | + const { additional } = bindData || {} | ||
14400 | + const { maxValue, minValue } = additional || {} | ||
14401 | + | ||
14402 | + receiveValue = isNaN(receiveValue) ? 0 : Number(receiveValue) | ||
14403 | + console.log('enter') | ||
14404 | + if (element) { | ||
14405 | + if (type === flowmeterType.CIRCLE || type === flowmeterType.RECT) { | ||
14406 | + const element = document.getElementById(id).querySelector('svg') | ||
14407 | + element.style.setProperty('--value', receiveValue) | ||
14408 | + } | ||
14409 | + if (type === flowmeterType.THERMOMETER) { | ||
14410 | + const element = document.getElementById(id).querySelector('svg') | ||
14411 | + const range = 140 | ||
14412 | + const ratio = (190 - 15) / range | ||
14413 | + receiveValue = receiveValue >= 0 ? receiveValue + 20 : 20 - Math.abs(receiveValue) | ||
14414 | + receiveValue = 190 - receiveValue * ratio | ||
14415 | + receiveValue = receiveValue < 15 ? 15 : receiveValue | ||
14416 | + element.style.setProperty('--value', receiveValue) | ||
14417 | + } | ||
14418 | + } | ||
14419 | + } | ||
14420 | + | ||
14276 | handleParamSettingButton(message, record) { | 14421 | handleParamSettingButton(message, record) { |
14277 | const { data = {} } = message | 14422 | const { data = {} } = message |
14278 | if (!data) return | 14423 | if (!data) return |
14279 | const { nodeId, attr } = record | 14424 | const { nodeId, attr } = record |
14280 | - const node = this.getNodeByCmdId(nodeId) | 14425 | + const node = this.getNodeByNodeId(nodeId) |
14281 | const [[_timespan, receiveValue] = []] = data[attr] || [] | 14426 | const [[_timespan, receiveValue] = []] = data[attr] || [] |
14282 | this.updatePage(() => { | 14427 | this.updatePage(() => { |
14283 | node.setAttribute('label', `<button class="param-setting-button">${receiveValue}</button>`) | 14428 | node.setAttribute('label', `<button class="param-setting-button">${receiveValue}</button>`) |
@@ -14287,7 +14432,7 @@ class HandleDataSource { | @@ -14287,7 +14432,7 @@ class HandleDataSource { | ||
14287 | handleImageComponent(message, record) { | 14432 | handleImageComponent(message, record) { |
14288 | const { data = {} } = message | 14433 | const { data = {} } = message |
14289 | const { nodeId, attr } = record | 14434 | const { nodeId, attr } = record |
14290 | - const node = this.getNodeByCmdId(nodeId) | 14435 | + const node = this.getNodeByNodeId(nodeId) |
14291 | const [[_timespan, receiveValue] = []] = data[attr] || [] | 14436 | const [[_timespan, receiveValue] = []] = data[attr] || [] |
14292 | this.updatePage(() => { | 14437 | this.updatePage(() => { |
14293 | node.setAttribute('label', `<img class="basic-component__image" alt="图片" src="${receiveValue}" />`) | 14438 | node.setAttribute('label', `<img class="basic-component__image" alt="图片" src="${receiveValue}" />`) |
@@ -14303,7 +14448,7 @@ class HandleDataSource { | @@ -14303,7 +14448,7 @@ class HandleDataSource { | ||
14303 | const { data = {} } = message | 14448 | const { data = {} } = message |
14304 | const { nodeId, attr, additional = {} } = record | 14449 | const { nodeId, attr, additional = {} } = record |
14305 | const { agg } = additional | 14450 | const { agg } = additional |
14306 | - const node = this.getNodeByCmdId(nodeId) | 14451 | + const node = this.getNodeByNodeId(nodeId) |
14307 | if (!node) return | 14452 | if (!node) return |
14308 | const enumConst = Sidebar.prototype.enumCellBasicAttribute | 14453 | const enumConst = Sidebar.prototype.enumCellBasicAttribute |
14309 | const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping | 14454 | const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping |
@@ -14334,7 +14479,7 @@ class HandleDataSource { | @@ -14334,7 +14479,7 @@ class HandleDataSource { | ||
14334 | const { data = {} } = message | 14479 | const { data = {} } = message |
14335 | const { nodeId, attr, additional = {} } = record | 14480 | const { nodeId, attr, additional = {} } = record |
14336 | const { agg } = additional | 14481 | const { agg } = additional |
14337 | - const node = this.getNodeByCmdId(nodeId) | 14482 | + const node = this.getNodeByNodeId(nodeId) |
14338 | if (!node) return | 14483 | if (!node) return |
14339 | const enumConst = Sidebar.prototype.enumCellBasicAttribute | 14484 | const enumConst = Sidebar.prototype.enumCellBasicAttribute |
14340 | const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping | 14485 | const chartInstanceMap = Sidebar.prototype.chartsInstanceMapping |
@@ -14703,7 +14848,7 @@ class HandleDataSource { | @@ -14703,7 +14848,7 @@ class HandleDataSource { | ||
14703 | * @param subscriptionId | 14848 | * @param subscriptionId |
14704 | * @return {*} | 14849 | * @return {*} |
14705 | */ | 14850 | */ |
14706 | - getNodeByCmdId(nodeId) { | 14851 | + getNodeByNodeId(nodeId) { |
14707 | // const nodeId = this.getNodeIdByCmdId(subscriptionId) | 14852 | // const nodeId = this.getNodeIdByCmdId(subscriptionId) |
14708 | return this.contentAllCell.find(item => item.id === nodeId) | 14853 | return this.contentAllCell.find(item => item.id === nodeId) |
14709 | } | 14854 | } |
@@ -1682,8 +1682,10 @@ Graph.sanitizeHtml = function(value, editing) | @@ -1682,8 +1682,10 @@ Graph.sanitizeHtml = function(value, editing) | ||
1682 | return null; | 1682 | return null; |
1683 | }; | 1683 | }; |
1684 | function idX(id) { return id }; | 1684 | function idX(id) { return id }; |
1685 | - | ||
1686 | - return html_sanitize(value, urlX, idX); | 1685 | + // console.log(html_sanitize(value, urlX, idX)) |
1686 | + // TODO THINGS_KIT 取消html标签限制 | ||
1687 | + return value | ||
1688 | + // return html_sanitize(value, urlX, idX); | ||
1687 | }; | 1689 | }; |
1688 | 1690 | ||
1689 | /** | 1691 | /** |
thermometer.svg
0 → 100644
1 | +<svg class="flowmeter-thermometer" viewBox="0 0 200 250" xmlns="http://www.w3.org/2000/svg" | ||
2 | + style="--range: 4; --min: 50; --max: 70; --width: 500; --height: 500; --value: 50;"> | ||
3 | + <style> | ||
4 | + .flowmeter-thermometer { | ||
5 | + width: calc(min(var(--width), var(--height)) * 1px); | ||
6 | + height: calc(min(var(--width), var(--height)) * 1px); | ||
7 | + } | ||
8 | + | ||
9 | + .thermometer-mercury-column { | ||
10 | + y: var(--value); | ||
11 | + } | ||
12 | + | ||
13 | + .tick-label { | ||
14 | + font-size: 12px; | ||
15 | + text-align: right; | ||
16 | + overflow: hidden; | ||
17 | + text-overflow: ellipsis; | ||
18 | + color: #5b6b73; | ||
19 | + } | ||
20 | + | ||
21 | + .thermometer-mercury-column { | ||
22 | + transition: y .5s cubic-bezier(0.19, 1, 0.22, 1); | ||
23 | + } | ||
24 | + </style> | ||
25 | + <defs> | ||
26 | + <radialGradient id="thermometerdiv_meter_2" cx="50%" cy="50%" r="50%" fx="50%" fy="50%"> | ||
27 | + <stop offset="0%" style="stop-color: rgb(230, 200, 200);"></stop> | ||
28 | + <stop offset="90%" style="stop-color: rgb(230, 0, 0);"></stop> | ||
29 | + </radialGradient> | ||
30 | + <clipPath id="over"> | ||
31 | + <rect width="100" height="190" x="100" y="10" /> | ||
32 | + </clipPath> | ||
33 | + </defs> | ||
34 | + <circle r="9.25" cx="109" cy="14.25" style="fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136); stroke-width: 1px;"> | ||
35 | + </circle> | ||
36 | + <rect x="99.75" y="14.25" height="192.75" width="18.5" | ||
37 | + style="shape-rendering: crispedges; fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136); stroke-width: 1px;"> | ||
38 | + </rect> | ||
39 | + <circle r="8.75" cx="109" cy="14.25" style="fill: rgb(255, 255, 255); stroke: none;"></circle> | ||
40 | + <circle r="18" cx="109" cy="207" style="fill: rgb(255, 255, 255); stroke: rgb(136, 136, 136);"></circle> | ||
41 | + <rect x="100.25" y="14.25" height="192.75" width="17.5" | ||
42 | + style="shape-rendering: crispedges; fill: rgb(255, 255, 255); stroke: none;"></rect> | ||
43 | + <line class="thermometer-min-line" x1="99.75" x2="140.25" y1="165" y2="165" | ||
44 | + style="stroke: rgb(136, 136, 136); stroke-width: 1px; shape-rendering: crispedges;"></line> | ||
45 | + <text class="thermometer-min-label" x="120.25" y="168.46428571428572" dy="0.72em" | ||
46 | + style="fill: rgb(0, 0, 230); font-size: 10px;">min</text> | ||
47 | + <line class="thermometer-max-line" x1="99.75" x2="140.25" y1="40" y2="40" | ||
48 | + style="stroke: rgb(136, 136, 136); stroke-width: 1px; shape-rendering: crispedges;"></line> | ||
49 | + <text class="thermometer-max-label" x="120.25" y="35.285714285714306" | ||
50 | + style="fill: rgb(230, 0, 0); font-size: 10px;">max</text> | ||
51 | + <rect class="thermometer-mercury-column" x="104" y="15" width="10.5" height="190" | ||
52 | + style="shape-rendering: crispedges; fill: rgb(230, 0, 0);" clip-path="url(#over)"></rect> | ||
53 | + <circle r="13" cx="109" cy="207" | ||
54 | + style="fill: url("#thermometerdiv_meter_2"); stroke: rgb(230, 0, 0); stroke-width: 2px;"></circle> | ||
55 | + <foreignObject> | ||
56 | + <div></div> | ||
57 | + </foreignObject> | ||
58 | + <g class="thermometer-temperature-axis" transform="translate(99.75,0)" fill="none" font-size="10" | ||
59 | + font-family="sans-serif" text-anchor="end"> | ||
60 | + <g class="tick" opacity="1" transform="translate(0,190)"> | ||
61 | + <line stroke="currentColor" x2="-7" | ||
62 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
63 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
64 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">-20</div> | ||
65 | + </foreignObject> | ||
66 | + </g> | ||
67 | + <g class="tick" opacity="1" transform="translate(0,165)"> | ||
68 | + <line stroke="currentColor" x2="-7" | ||
69 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
70 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
71 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">0</div> | ||
72 | + </foreignObject> | ||
73 | + </g> | ||
74 | + <g class="tick" opacity="1" transform="translate(0,140)"> | ||
75 | + <line stroke="currentColor" x2="-7" | ||
76 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
77 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
78 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">20</div> | ||
79 | + </foreignObject> | ||
80 | + </g> | ||
81 | + <g class="tick" opacity="1" transform="translate(0,115)"> | ||
82 | + <line stroke="currentColor" x2="-7" | ||
83 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
84 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
85 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">40</div> | ||
86 | + </foreignObject> | ||
87 | + </g> | ||
88 | + <g class="tick" opacity="1" transform="translate(0,90)"> | ||
89 | + <line stroke="currentColor" x2="-7" | ||
90 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
91 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
92 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">60</div> | ||
93 | + </foreignObject> | ||
94 | + </g> | ||
95 | + <g class="tick" opacity="1" transform="translate(0,65)"> | ||
96 | + <line stroke="currentColor" x2="-7" | ||
97 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
98 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
99 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">80</div> | ||
100 | + </foreignObject> | ||
101 | + </g> | ||
102 | + <g class="tick" opacity="1" transform="translate(0,40)"> | ||
103 | + <line stroke="currentColor" x2="-7" | ||
104 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
105 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
106 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">100</div> | ||
107 | + </foreignObject> | ||
108 | + </g> | ||
109 | + <g class="tick" opacity="1" transform="translate(0,15)"> | ||
110 | + <line stroke="currentColor" x2="-7" | ||
111 | + style="stroke: rgb(136, 136, 136); shape-rendering: crispedges; stroke-width: 1px;"></line> | ||
112 | + <foreignObject xmlns="http://www.w3.org/2000/svg" x="-55" y="-10" width="45" height="20"> | ||
113 | + <div class="tick-label" xmlns="http://www.w3.org/1999/xhtml">120</div> | ||
114 | + </foreignObject> | ||
115 | + </g> | ||
116 | + </g> | ||
117 | +</svg> |