poe-svelte-ui-lib 1.10.5 → 1.10.6
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.
package/dist/Graph/Graph.svelte
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
<!-- $lib/ElementsUI/Graph.svelte -->
|
|
2
|
+
<script module lang="ts">
|
|
3
|
+
import type { IOption } from "../types"
|
|
4
|
+
|
|
5
|
+
/* Константы и настройки — экспортируются для переиспользования в GraphProps.svelte (редактор конструктора) */
|
|
6
|
+
export const REFRESH_OPTIONS: IOption[] = [
|
|
7
|
+
{ id: "RefreshOption-AUTO", name: "AUTO", value: 0, class: "" },
|
|
8
|
+
{ id: "RefreshOption-10", name: "10", value: 10, class: "" },
|
|
9
|
+
{ id: "RefreshOption-25", name: "25", value: 25, class: "" },
|
|
10
|
+
{ id: "RefreshOption-50", name: "50", value: 50, class: "" },
|
|
11
|
+
{ id: "RefreshOption-100", name: "100", value: 100, class: "" },
|
|
12
|
+
{ id: "RefreshOption-250", name: "250", value: 250, class: "" },
|
|
13
|
+
{ id: "RefreshOption-500", name: "500", value: 500, class: "" },
|
|
14
|
+
{ id: "RefreshOption-1000", name: "1000", value: 1000, class: "" },
|
|
15
|
+
{ id: "RefreshOption-5000", name: "5000", value: 5000, class: "" },
|
|
16
|
+
]
|
|
17
|
+
export const SCALE_OPTIONS: IOption[] = [
|
|
18
|
+
{ id: "ScaleOption-50", name: "50", value: 50, class: "" },
|
|
19
|
+
{ id: "ScaleOption-100", name: "100", value: 100, class: "" },
|
|
20
|
+
{ id: "ScaleOption-500", name: "500", value: 500, class: "" },
|
|
21
|
+
{ id: "ScaleOption-1000", name: "1000", value: 1000, class: "" },
|
|
22
|
+
{ id: "ScaleOption-2000", name: "2000", value: 2000, class: "" },
|
|
23
|
+
]
|
|
24
|
+
</script>
|
|
25
|
+
|
|
2
26
|
<script lang="ts">
|
|
3
27
|
import { onMount } from "svelte"
|
|
4
28
|
import Select from "../Select/Select.svelte"
|
|
@@ -9,8 +33,10 @@
|
|
|
9
33
|
id = crypto.randomUUID(),
|
|
10
34
|
wrapperClass = "",
|
|
11
35
|
label = { name: "", class: "" },
|
|
12
|
-
streamingData = { data: []
|
|
36
|
+
streamingData = { data: [] },
|
|
13
37
|
isTest = false,
|
|
38
|
+
refreshRate = 0,
|
|
39
|
+
scale = 100,
|
|
14
40
|
}: IGraphProps = $props()
|
|
15
41
|
|
|
16
42
|
/* Состояние компонента */
|
|
@@ -22,31 +48,15 @@
|
|
|
22
48
|
let width = $state(600)
|
|
23
49
|
let height = $state(125)
|
|
24
50
|
|
|
25
|
-
/*
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{ id: "RefreshOption-50", name: "50", value: 50, class: "" },
|
|
31
|
-
{ id: "RefreshOption-100", name: "100", value: 100, class: "" },
|
|
32
|
-
{ id: "RefreshOption-250", name: "250", value: 250, class: "" },
|
|
33
|
-
{ id: "RefreshOption-500", name: "500", value: 500, class: "" },
|
|
34
|
-
{ id: "RefreshOption-1000", name: "1000", value: 1000, class: "" },
|
|
35
|
-
{ id: "RefreshOption-5000", name: "5000", value: 5000, class: "" },
|
|
36
|
-
]
|
|
37
|
-
const SCALE_OPTIONS: IOption[] = [
|
|
38
|
-
{ id: "ScaleOption-50", name: "50", value: 50, class: "" },
|
|
39
|
-
{ id: "ScaleOption-100", name: "100", value: 100, class: "" },
|
|
40
|
-
{ id: "ScaleOption-500", name: "500", value: 500, class: "" },
|
|
41
|
-
{ id: "ScaleOption-1000", name: "1000", value: 1000, class: "" },
|
|
42
|
-
{ id: "ScaleOption-2000", name: "2000", value: 2000, class: "" },
|
|
43
|
-
]
|
|
44
|
-
let selectedRefreshRate = $derived(isTest ? 50 : 0)
|
|
45
|
-
let selectedScale = $state(100)
|
|
51
|
+
/* selectedRefreshRate/selectedScale изначально берутся из пропов (сохраняются вместе с компонентом в конструкторе),
|
|
52
|
+
но остаются локально переключаемыми через Select ниже — присвоение этим $derived временно
|
|
53
|
+
переопределяет значение, пока не изменится refreshRate/scale/isTest (проп) */
|
|
54
|
+
let selectedRefreshRate = $derived(isTest ? 50 : (refreshRate ?? 0))
|
|
55
|
+
let selectedScale = $derived(scale ?? 100)
|
|
46
56
|
const maxDataPoints = $derived(selectedRefreshRate == 0 ? 20 : 100)
|
|
47
57
|
const defaultColors = ["#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6", "#ec4899"]
|
|
48
58
|
|
|
49
|
-
let
|
|
59
|
+
let previousValues: number[] = $state([])
|
|
50
60
|
|
|
51
61
|
/* Инициализация данных графиков */
|
|
52
62
|
const initializeGraphData = () => {
|
|
@@ -56,6 +66,7 @@
|
|
|
56
66
|
if (!streamingData.data || streamingData.data.length === 0) {
|
|
57
67
|
graphData = []
|
|
58
68
|
currentValues = []
|
|
69
|
+
previousValues = []
|
|
59
70
|
return
|
|
60
71
|
}
|
|
61
72
|
const newGraphData = (streamingData.data as IGraphDataObject[]).slice(0, 6).map((d, i) => {
|
|
@@ -106,22 +117,25 @@
|
|
|
106
117
|
drawAllGraphs()
|
|
107
118
|
}, selectedRefreshRate)
|
|
108
119
|
} else if (selectedRefreshRate == 0 && !isTest) {
|
|
120
|
+
/* AUTO: streamingData не несёт признак "это новый пакет" (timestamp никем не передаётся —
|
|
121
|
+
DeviceStore хранит только последнее значение), поэтому опрашиваем каждые 10мс и рисуем
|
|
122
|
+
точку только когда сами значения реально изменились, а не на каждый тик поллинга. */
|
|
109
123
|
intervalId = setInterval(() => {
|
|
110
124
|
if (!streamingData.data || streamingData.data.length === 0) return
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
const newValues = (streamingData.data as IGraphDataObject[]).map((dataset) => dataset.value)
|
|
126
|
+
if (JSON.stringify(newValues) === JSON.stringify(previousValues)) return
|
|
127
|
+
previousValues = newValues
|
|
113
128
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
129
|
+
const now = Date.now()
|
|
130
|
+
newValues.forEach((value, i) => {
|
|
131
|
+
if (!graphData[i]) return
|
|
132
|
+
graphData[i].points.push({ x: now, y: value })
|
|
133
|
+
if (graphData[i].points.length > maxDataPoints) {
|
|
134
|
+
graphData[i].points.shift()
|
|
135
|
+
}
|
|
136
|
+
currentValues[i] = value
|
|
137
|
+
})
|
|
138
|
+
drawAllGraphs()
|
|
125
139
|
}, 10)
|
|
126
140
|
}
|
|
127
141
|
return () => clearInterval(intervalId)
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { IOption } from "../types";
|
|
2
|
+
export declare const REFRESH_OPTIONS: IOption[];
|
|
3
|
+
export declare const SCALE_OPTIONS: IOption[];
|
|
1
4
|
import type { IGraphProps } from "../types";
|
|
2
5
|
declare const Graph: import("svelte").Component<IGraphProps, {}, "">;
|
|
3
6
|
type Graph = ReturnType<typeof Graph>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getContext } from "svelte"
|
|
3
3
|
import { T } from "../locales/i18n"
|
|
4
|
-
import { type UIComponent, type IGraphProps, updateProperty, type IUIComponentHandler } from "../types"
|
|
4
|
+
import { type UIComponent, type IGraphProps, type IOption, updateProperty, type IUIComponentHandler } from "../types"
|
|
5
5
|
import * as UI from ".."
|
|
6
6
|
import { optionsStore } from "../options"
|
|
7
7
|
import { twMerge } from "tailwind-merge"
|
|
8
8
|
import CommonSnippets from "../CommonSnippets.svelte"
|
|
9
|
+
import { REFRESH_OPTIONS, SCALE_OPTIONS } from "./Graph.svelte"
|
|
9
10
|
|
|
10
11
|
const {
|
|
11
12
|
component,
|
|
@@ -37,6 +38,21 @@
|
|
|
37
38
|
/>
|
|
38
39
|
{/snippet}
|
|
39
40
|
|
|
41
|
+
{#snippet GraphSettings()}
|
|
42
|
+
<UI.Select
|
|
43
|
+
label={{ name: $T("constructor.props.refreshrate") }}
|
|
44
|
+
options={REFRESH_OPTIONS}
|
|
45
|
+
value={REFRESH_OPTIONS.find((o) => o.value == (component.properties.refreshRate ?? 0))}
|
|
46
|
+
onUpdate={(value) => updateProperty("refreshRate", (value as IOption).value as number, component, onPropertyChange)}
|
|
47
|
+
/>
|
|
48
|
+
<UI.Select
|
|
49
|
+
label={{ name: $T("constructor.props.scale") }}
|
|
50
|
+
options={SCALE_OPTIONS}
|
|
51
|
+
value={SCALE_OPTIONS.find((o) => o.value == (component.properties.scale ?? 100))}
|
|
52
|
+
onUpdate={(value) => updateProperty("scale", (value as IOption).value as number, component, onPropertyChange)}
|
|
53
|
+
/>
|
|
54
|
+
{/snippet}
|
|
55
|
+
|
|
40
56
|
{#if forConstructor}
|
|
41
57
|
<div class="relative flex flex-row items-start justify-center">
|
|
42
58
|
<div class="flex w-1/3 flex-col px-2">
|
|
@@ -49,6 +65,7 @@
|
|
|
49
65
|
</div>
|
|
50
66
|
<div class="flex w-1/3 flex-col px-2">
|
|
51
67
|
{@render GraphIsTest()}
|
|
68
|
+
{@render GraphSettings()}
|
|
52
69
|
</div>
|
|
53
70
|
</div>
|
|
54
71
|
{:else}
|
|
@@ -64,6 +81,7 @@
|
|
|
64
81
|
<div class="flex w-1/3 flex-col px-2">
|
|
65
82
|
<CommonSnippets snippet="WrapperClass" {component} {onPropertyChange} />
|
|
66
83
|
{@render GraphIsTest()}
|
|
84
|
+
{@render GraphSettings()}
|
|
67
85
|
</div>
|
|
68
86
|
</div>
|
|
69
87
|
{/if}
|
|
@@ -140,6 +140,8 @@ const translations = {
|
|
|
140
140
|
"constructor.props.disabled": "Отключить",
|
|
141
141
|
"constructor.props.readonly": "Только чтение",
|
|
142
142
|
"constructor.props.istest": "Тестовые данные",
|
|
143
|
+
"constructor.props.refreshrate": "Скорость обновления",
|
|
144
|
+
"constructor.props.scale": "Масштаб",
|
|
143
145
|
"constructor.props.variable": "Имя переменной",
|
|
144
146
|
"constructor.props.widthMode": "Ширина кнопок",
|
|
145
147
|
"constructor.props.graphdata.title": "Начальные данные ",
|
|
@@ -303,6 +305,8 @@ const translations = {
|
|
|
303
305
|
"common.select_tag": "Make a choice",
|
|
304
306
|
"constructor.props.file.select": "Select a file",
|
|
305
307
|
"constructor.props.file.notselected": "File is not selected",
|
|
308
|
+
"constructor.props.refreshrate": "Refresh rate",
|
|
309
|
+
"constructor.props.scale": "Scale",
|
|
306
310
|
},
|
|
307
311
|
zh: {},
|
|
308
312
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -144,9 +144,10 @@ export interface IGraphProps {
|
|
|
144
144
|
};
|
|
145
145
|
streamingData?: {
|
|
146
146
|
data: IGraphDataObject[] | null;
|
|
147
|
-
timestamp?: number;
|
|
148
147
|
};
|
|
149
148
|
isTest?: boolean;
|
|
149
|
+
refreshRate?: number;
|
|
150
|
+
scale?: number;
|
|
150
151
|
}
|
|
151
152
|
export interface IInputProps {
|
|
152
153
|
id?: string;
|