@ledvance/group-ui-biz-bundle 1.0.140 → 1.0.142

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 (22) hide show
  1. package/package.json +1 -1
  2. package/src/modules/biorhythm/IconSelect.tsx +92 -29
  3. package/src/modules/energyConsumption/EnergyConsumptionActions.ts +42 -16
  4. package/src/modules/energyConsumption/EnergyConsumptionCard.tsx +3 -3
  5. package/src/modules/energyConsumption/EnergyConsumptionChart/ChartSection.tsx +103 -15
  6. package/src/modules/energyConsumption/EnergyConsumptionChart/LandscapeView.tsx +1 -0
  7. package/src/modules/energyConsumption/EnergyConsumptionChart/PortraitView.tsx +3 -27
  8. package/src/modules/energyConsumption/EnergyConsumptionChart/styles.ts +13 -4
  9. package/src/modules/energyConsumption/EnergyConsumptionChart/useEnergyData.ts +28 -12
  10. package/src/modules/energyConsumption/EnergyConsumptionChart.tsx +4 -0
  11. package/src/modules/energyConsumption/EnergyConsumptionDetail.tsx +41 -31
  12. package/src/modules/energyConsumption/EnergyConsumptionPage.tsx +52 -3
  13. package/src/modules/energyConsumption/component/DateSelectedItem.tsx +1 -1
  14. package/src/modules/energyConsumption/component/DateSwitch.tsx +10 -8
  15. package/src/modules/energyConsumption/component/DateTypeItem.tsx +1 -1
  16. package/src/modules/energyConsumption/component/EnergyModal.tsx +2 -2
  17. package/src/modules/energyConsumption/component/NewBarChart.tsx +221 -153
  18. package/src/modules/energyConsumption/component/Overview.tsx +1 -1
  19. package/src/modules/flags/FlagInfo.tsx +1204 -1054
  20. package/src/modules/flags/FlagItem.tsx +1 -2
  21. package/src/modules/flags/FlagPage.tsx +19 -15
  22. package/src/modules/mood_new/MoodItem.tsx +0 -1
@@ -1,182 +1,250 @@
1
1
  import ThemeType from '@ledvance/base/src/config/themeType'
2
2
  import I18n from '@ledvance/base/src/i18n'
3
+ import { xLog } from '@ledvance/base/src/utils'
3
4
  import ECharts from '@ledvance/react-native-echarts-pro'
4
5
  import React, { useMemo, useRef } from 'react'
5
6
  import { View } from 'react-native'
6
7
  import { Utils } from 'tuya-panel-kit'
7
8
  import { OverviewItem } from '../EnergyConsumptionPage'
9
+ import { EnergyDisplayMode } from '../EnergyConsumptionChart/useEnergyData'
8
10
 
9
11
  const { withTheme } = Utils.ThemeUtils
10
- const cx = Utils.RatioUtils.convertX
11
-
12
12
  interface BarChartProps {
13
- theme?: ThemeType
14
- data: OverviewItem[],
15
- price: number,
16
- unit: string,
17
- height: number
13
+ theme?: ThemeType;
14
+ consumedData: OverviewItem[];
15
+ generatedData: OverviewItem[];
16
+ consumedName?: string;
17
+ generatedName?: string;
18
+ price: number;
19
+ unit: string;
20
+ height: number;
21
+ displayMode?: EnergyDisplayMode;
18
22
  }
19
23
 
20
24
  const BarChartWithTouch = (props: BarChartProps) => {
21
- const echarts = useRef()
22
- const { data, height, price, unit, theme } = props
23
- const dataX = data?.map(item => {
24
- return item.chartTitle
25
- })
26
- const dataKwhY = data?.map(item => {
27
- return Number(item.value)
28
- })
29
- const dataPriceY = data?.map(item => {
30
- return ((isNaN(Number(item.value)) ? 0 : Number(item.value)) * price).toFixed(2)
31
- })
32
- const maxValue = useMemo(() => {
33
- let max = Math.max(...dataKwhY)
34
- if (max < 0.1) {
35
- max += 0.02
36
- max = max - (max % 0.02)
37
- } else if (max < 1) {
38
- max += 0.2
39
- max = max - (max % 0.2)
40
- } else if (max < 10) {
41
- max = Math.ceil(max) + 2
42
- max = max - (max % 2)
43
- }
44
- return max
45
- }, [dataKwhY])
46
- const gridRight = useMemo(() => {
47
- const max = Math.max(...dataPriceY.map(it => Number(it)))
48
- return max > 999 ? '15%' : '10%'
49
- }, [dataPriceY])
50
- const option = {
51
- tooltip: {
52
- show: true,
53
- triggerOn: 'click',
54
- trigger: 'axis',
55
- },
56
- legend: {
57
- show: true,
58
- data: ['kWh', unit],
59
- textStyle: {
60
- color: theme?.global.fontColor,
25
+ const echarts = useRef<ECharts>(null)
26
+ const {
27
+ consumedData,
28
+ generatedData,
29
+ consumedName = I18n.getLang('chart_legend_consumption'),
30
+ generatedName = I18n.getLang('chart_legend_generation'),
31
+ price,
32
+ unit,
33
+ height,
34
+ theme,
35
+ displayMode = 'consumption',
36
+ } = props
37
+
38
+ const chartKey = useMemo(() => {
39
+ return `chart-${displayMode}-${price}-${unit}`
40
+ }, [displayMode, price, unit])
41
+
42
+ // 数据对齐(不变)
43
+ const { dataX, alignedConsumed, alignedGenerated, alignedConsumedPrice, alignedGeneratedPrice } = useMemo(() => {
44
+ const combinedDataMap = new Map<string, { title: string; consumed?: number; generated?: number }>()
45
+
46
+ consumedData?.forEach(item => {
47
+ const key = item.headlineText
48
+ if (!combinedDataMap.has(key)) {
49
+ combinedDataMap.set(key, { title: item.chartTitle })
61
50
  }
62
- },
63
- grid: {
64
- right: gridRight,
65
- },
66
- xAxis: {
67
- data: dataX,
68
- axisTick: {
69
- show: false,
70
- },
71
- axisLabel: {
72
- show: true,
73
- color: props.theme?.global.secondFontColor,
74
- interval: 'auto',
75
- rotate: 45,
76
- align: 'right',
77
- verticalAlign: 'top',
78
- showMinLabel: true,
79
- showMaxLabel: true,
51
+ combinedDataMap.get(key)!.consumed = Number(item.value)
52
+ })
53
+
54
+ generatedData?.forEach(item => {
55
+ const key = item.headlineText
56
+ if (!combinedDataMap.has(key)) {
57
+ combinedDataMap.set(key, { title: item.chartTitle })
80
58
  }
81
- },
82
- yAxis: [{
83
- type: 'value',
84
- name: I18n.getLang('consumption_data_annual_bar_chart_text'),
85
- max: Math.max(maxValue, 0.02),
86
- min: 0,
87
- position: 'left',
88
- axisLabel: {
89
- formatter: function (value) {
90
- const kwh = parseFloat(value)
91
- let toFixed = 2
92
- if (kwh >= 100) {
93
- toFixed = 0
94
- } else if (kwh >= 10) {
95
- toFixed = 1
96
- }
97
- return kwh.toFixed(toFixed)
59
+ combinedDataMap.get(key)!.generated = Number(item.value)
60
+ })
61
+
62
+ const sortedKeys = Array.from(combinedDataMap.keys()).sort((a, b) => {
63
+ // 1. 移除非数字字符
64
+ // 2. 转换为整数
65
+ // 3. 进行数字比较
66
+ const numA = parseInt(a.replace(/\D/g, ''), 10);
67
+ const numB = parseInt(b.replace(/\D/g, ''), 10);
68
+
69
+ return numA - numB;
70
+ })
71
+
72
+ const finalDataX: string[] = []
73
+ const finalAlignedConsumed: number[] = []
74
+ const finalAlignedGenerated: number[] = []
75
+ const finalAlignedConsumedPrice: string[] = []
76
+ const finalAlignedGeneratedPrice: string[] = []
77
+
78
+ sortedKeys.forEach(key => {
79
+ const dataPoint = combinedDataMap.get(key)!
80
+ const consumedVal = dataPoint.consumed || 0
81
+ const generatedVal = dataPoint.generated || 0
82
+
83
+ finalDataX.push(dataPoint.title)
84
+ finalAlignedConsumed.push(consumedVal)
85
+ finalAlignedGenerated.push(generatedVal)
86
+ finalAlignedConsumedPrice.push((consumedVal * price).toFixed(2))
87
+ finalAlignedGeneratedPrice.push((generatedVal * price).toFixed(2))
88
+ })
89
+
90
+ return {
91
+ dataX: finalDataX,
92
+ alignedConsumed: finalAlignedConsumed,
93
+ alignedGenerated: finalAlignedGenerated,
94
+ alignedConsumedPrice: finalAlignedConsumedPrice,
95
+ alignedGeneratedPrice: finalAlignedGeneratedPrice,
96
+ }
97
+ }, [consumedData, generatedData, price])
98
+
99
+ // 图例 & series 动态生成
100
+ const { legendData, seriesData } = useMemo(() => {
101
+ const finalLegend: string[] = []
102
+ const finalSeries: any[] = []
103
+
104
+ if (displayMode === 'consumption' || displayMode === 'both') {
105
+ finalLegend.push(consumedName, `${consumedName} ${unit}`)
106
+ finalSeries.push(
107
+ {
108
+ name: consumedName,
109
+ type: 'bar',
110
+ yAxisIndex: 0,
111
+ data: alignedConsumed,
112
+ itemStyle: { color: '#FFC2A9', borderRadius: 2 },
113
+ barMaxWidth: 10,
114
+ },
115
+ {
116
+ name: `${consumedName} ${unit}`,
117
+ type: 'line',
118
+ yAxisIndex: 1,
119
+ data: alignedConsumedPrice,
120
+ smooth: true,
121
+ showSymbol: false,
122
+ color: '#F49431',
123
+ }
124
+ )
125
+ }
126
+
127
+ if (displayMode === 'generation' || displayMode === 'both') {
128
+ finalLegend.push(generatedName, `${generatedName} ${unit}`)
129
+ finalSeries.push(
130
+ {
131
+ name: generatedName,
132
+ type: 'bar',
133
+ yAxisIndex: 0,
134
+ data: alignedGenerated,
135
+ itemStyle: { color: '#A7D7A7', borderRadius: 2 },
136
+ barMaxWidth: 10,
98
137
  },
99
- color: props.theme?.global.secondFontColor,
138
+ {
139
+ name: `${generatedName} ${unit}`,
140
+ type: 'line',
141
+ yAxisIndex: 1,
142
+ data: alignedGeneratedPrice,
143
+ smooth: true,
144
+ showSymbol: false,
145
+ color: '#5A9C5A',
146
+ }
147
+ )
148
+ }
149
+
150
+ return { legendData: finalLegend, seriesData: finalSeries }
151
+ }, [displayMode, unit, consumedName, generatedName, alignedConsumed, alignedGenerated, alignedConsumedPrice, alignedGeneratedPrice])
152
+
153
+ // yAxis 动态
154
+ const maxKwhValue = useMemo(() => {
155
+ const valuesToConsider: number[] = [];
156
+ if (displayMode === 'consumption' || displayMode === 'both') valuesToConsider.push(...alignedConsumed);
157
+ if (displayMode === 'generation' || displayMode === 'both') valuesToConsider.push(...alignedGenerated);
158
+
159
+ if (valuesToConsider.length === 0) return 0.2; // 默认值
160
+ let max = Math.max(...valuesToConsider);
161
+ if (max < 1) max += 0.2;
162
+ else if (max < 10) max = Math.ceil(max) + 2;
163
+ else max = Math.ceil(max * 1.2);
164
+ return max;
165
+ }, [displayMode, alignedConsumed, alignedGenerated]);
166
+ const maxPriceValue = useMemo(() => {
167
+ const valuesToConsider: number[] = [];
168
+ if (displayMode === 'consumption' || displayMode === 'both') valuesToConsider.push(...alignedConsumedPrice.map(Number));
169
+ if (displayMode === 'generation' || displayMode === 'both') valuesToConsider.push(...alignedGeneratedPrice.map(Number));
170
+ if (valuesToConsider.length === 0) return 1; // 默认值
171
+ const max = Math.max(...valuesToConsider);
172
+ return Math.ceil(max * 1.4);
173
+ }, [displayMode, alignedConsumedPrice, alignedGeneratedPrice]);
174
+
175
+ const option = useMemo(
176
+ () => ({
177
+ tooltip: { show: true, triggerOn: 'click', trigger: 'axis' },
178
+ legend: {
179
+ show: true,
180
+ data: legendData,
181
+ top: '5%',
182
+ textStyle: { color: theme?.global.fontColor },
100
183
  },
101
- nameTextStyle: {
102
- fontSize: 14,
103
- align: 'left',
104
- padding: [0, 0, 0, cx(-30)],
105
- color: props.theme?.global.secondFontColor,
184
+ grid: {
185
+ top: '25%',
186
+ right: '15%',
187
+ left: '15%',
106
188
  },
107
- }, {
108
- type: 'value',
109
- name: I18n.formatValue('format_unit', unit),
110
- position: 'right',
111
- alignTicks: true,
112
- max: Math.ceil(price ? maxValue * price * 1.4 : 0),
113
- min: 0,
114
- minInterval: 1,
115
- axisLabel: {
116
- formatter: function (value) {
117
- const price = parseFloat(value)
118
- let toFixed = 2
119
- if (price >= 100) {
120
- toFixed = 0
121
- } else if (price >= 10) {
122
- toFixed = 1
123
- }
124
- return price.toFixed(toFixed)
189
+ xAxis: {
190
+ data: dataX,
191
+ axisTick: { show: false },
192
+ axisLabel: {
193
+ show: true,
194
+ color: theme?.global.secondFontColor,
195
+ rotate: 45,
196
+ align: 'right',
125
197
  },
126
- color: props.theme?.global.secondFontColor,
127
198
  },
128
- nameTextStyle: {
129
- fontSize: 14,
130
- align: 'right',
131
- padding: [0, cx(-30), 0, 0],
132
- color: props.theme?.global.secondFontColor,
133
- },
134
- }],
135
- series: [
136
- {
137
- name: 'kWh',
138
- type: 'bar',
139
- data: dataKwhY,
140
- itemStyle: {
141
- emphasis: {
142
- color: '#FFC2A9', // Color when bar is clicked
199
+ yAxis: [
200
+ {
201
+ type: 'value',
202
+ name: I18n.getLang('consumption_data_annual_bar_chart_text'),
203
+ max: maxKwhValue,
204
+ min: 0,
205
+ axisLabel: {
206
+ formatter: function (value) {
207
+ return parseFloat(value).toFixed(2);
208
+ },
209
+ color: theme?.global.secondFontColor
143
210
  },
144
- color: '#FFC2A9',
145
- borderRadius: 2,
146
211
  },
147
- barMaxWidth: 10,
148
- select: {
149
- itemStyle: {
150
- borderColor: '#FFC2A9',
151
- }
212
+ {
213
+ type: 'value',
214
+ name: I18n.formatValue('format_unit', unit),
215
+ position: 'right',
216
+ max: maxPriceValue,
217
+ min: 0,
218
+ minInterval: 1,
219
+ axisLabel: {
220
+ formatter: function (value) {
221
+ return parseFloat(value).toFixed(1);
222
+ },
223
+ color: theme?.global.secondFontColor
224
+ },
152
225
  },
153
- selectedMode: 'single',
226
+ ],
227
+ series: seriesData,
228
+ dataZoom: {
229
+ start: 0,
230
+ type: 'inside',
231
+ zoomLock: true,
154
232
  },
155
- {
156
- name: unit,
157
- type: 'line',
158
- data: dataPriceY,
159
- yAxisIndex: 1,
160
- smooth: true,
161
- showSymbol: false,
162
- color: '#F49431',
163
- selectedMode: 'single',
164
- }
165
- ],
166
- dataZoom: {
167
- start: 0,
168
- type: 'inside',
169
- zoomLock: true,
170
- },
171
- customMapData: {}
172
- }
233
+ }),
234
+ [
235
+ legendData,
236
+ seriesData,
237
+ dataX,
238
+ maxKwhValue,
239
+ maxPriceValue,
240
+ unit,
241
+ theme,
242
+ ]
243
+ )
244
+
173
245
  return (
174
246
  <View style={{ flex: 1 }}>
175
- <ECharts
176
- option={option}
177
- ref={echarts}
178
- height={height}
179
- />
247
+ <ECharts key={chartKey} option={option} ref={echarts} height={height}/>
180
248
  </View>
181
249
  )
182
250
  }
@@ -40,7 +40,7 @@ const OverView = (props: OverViewProps) => {
40
40
  listEmptyText: {
41
41
  color: props.theme?.global.fontColor,
42
42
  fontSize: cx(12),
43
- fontFamily: 'helvetica_neue_lt_std_roman',
43
+ // fontFamily: 'helvetica_neue_lt_std_roman',
44
44
  },
45
45
  overviewItemText: {
46
46
  color: props.theme?.global.fontColor,