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.
@@ -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: [], timestamp: Date.now() },
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
- const REFRESH_OPTIONS: IOption[] = [
27
- { id: "RefreshOption-AUTO", name: "AUTO", value: 0, class: "" },
28
- { id: "RefreshOption-10", name: "10", value: 10, class: "" },
29
- { id: "RefreshOption-25", name: "25", value: 25, class: "" },
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 previousDataTimestamp: number = $state(0)
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
- if (previousDataTimestamp < (streamingData.timestamp ?? Date.now())) {
112
- let newValues = (streamingData.data as IGraphDataObject[]).map((dataset) => dataset.value)
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
- newValues.forEach((value, i) => {
115
- if (!graphData[i]) return
116
- graphData[i].points.push({ x: streamingData.timestamp ?? Date.now(), y: value })
117
- if (graphData[i].points.length > maxDataPoints) {
118
- graphData[i].points.shift()
119
- }
120
- currentValues[i] = value
121
- })
122
- drawAllGraphs()
123
- previousDataTimestamp = streamingData.timestamp ?? Date.now()
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "poe-svelte-ui-lib",
3
- "version": "1.10.5",
3
+ "version": "1.10.6",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {