@eturnity/eturnity_reusable_components 8.16.9-EPDM-14690.4 → 8.16.9-EPDM-11600.8
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/package.json +1 -1
- package/src/assets/svgIcons/erase.svg +2 -3
- package/src/assets/theme.js +1 -1
- package/src/components/barchart/BottomFields.vue +37 -125
- package/src/components/barchart/composables/useAxisCalculations.js +1 -1
- package/src/components/barchart/composables/useChartData.js +1 -1
- package/src/components/barchart/composables/useTooltip.js +3 -28
- package/src/components/barchart/index.vue +16 -54
- package/src/components/barchart/styles/bottomFields.js +4 -18
- package/src/components/barchart/styles/chart.js +12 -15
- package/src/components/errorMessage/index.vue +1 -1
- package/src/components/infoCard/index.vue +10 -18
- package/src/components/infoCard/infoCard.spec.js +3 -3
- package/src/components/inputs/inputNumber/InputNumber.stories.js +19 -5
- package/src/components/inputs/inputNumber/index.vue +19 -25
- package/src/components/pageSubtitle/index.vue +7 -1
- package/src/components/pageTitle/index.vue +4 -3
- package/src/TestChart.vue +0 -229
package/package.json
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
<svg
|
2
|
-
<
|
3
|
-
<path d="M24.9592 15.0408C22.2382 12.3197 17.7618 12.3197 15.0408 15.0408C12.3197 17.7618 12.3197 22.2382 15.0408 24.9592C17.7618 27.6803 22.2382 27.6803 24.9592 24.9592C27.6803 22.2382 27.6803 17.8495 24.9592 15.0408ZM23.6426 22.5016L22.4138 23.7304L19.9561 21.2727L17.4984 23.7304L16.2696 22.5016L18.7273 20.0439L16.2696 17.5862L17.4984 16.3574L19.9561 18.815L22.4138 16.3574L23.6426 17.5862L21.185 20.0439L23.6426 22.5016Z" fill="#FF5656"></path>
|
1
|
+
<svg width="22" height="21" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2
|
+
<path d="M18.4389 3.06113C14.3574 -1.02038 7.64263 -1.02038 3.56113 3.06113C-0.520376 7.14263 -0.520376 13.8574 3.56113 17.9389C7.64263 22.0204 14.3574 22.0204 18.4389 17.9389C22.5204 13.8574 22.5204 7.2743 18.4389 3.06113ZM16.464 14.2524L14.6207 16.0956L10.9342 12.4091L7.24765 16.0956L5.40439 14.2524L9.09091 10.5658L5.40439 6.87931L7.24765 5.03605L10.9342 8.72257L14.6207 5.03605L16.464 6.87931L12.7774 10.5658L16.464 14.2524Z" fill="#FF5656"/>
|
4
3
|
</svg>
|
package/src/assets/theme.js
CHANGED
@@ -333,7 +333,7 @@ const theme = (() => {
|
|
333
333
|
borderColor: semanticColors.grey[300],
|
334
334
|
},
|
335
335
|
active: {
|
336
|
-
backgroundColor: semanticColors.
|
336
|
+
backgroundColor: semanticColors.purple[50],
|
337
337
|
textColor: semanticColors.purple[600],
|
338
338
|
borderColor: semanticColors.grey[600],
|
339
339
|
},
|
@@ -1,14 +1,14 @@
|
|
1
1
|
<template>
|
2
2
|
<Container :is-chart-controls-shown-in-bottom="isChartControlsShownInBottom">
|
3
3
|
<LabelsColumn :width="yAxisWidth">
|
4
|
-
<LabelRow v-for="series in
|
4
|
+
<LabelRow v-for="series in props.series" :key="series.name">
|
5
5
|
{{ series.name }}
|
6
6
|
</LabelRow>
|
7
|
-
<TotalRow v-if="
|
8
|
-
{{ $gettext ?
|
7
|
+
<TotalRow v-if="props.series.length && fieldMode === 'percentage'">
|
8
|
+
{{ $gettext ? $gettext('Total (%)') : 'Total (%)' }}
|
9
9
|
</TotalRow>
|
10
|
-
<TotalRow v-if="
|
11
|
-
{{ $gettext ?
|
10
|
+
<TotalRow v-if="props.series.length">
|
11
|
+
{{ $gettext ? $gettext('Total (kWh)') : 'Total (kWh)' }}
|
12
12
|
</TotalRow>
|
13
13
|
</LabelsColumn>
|
14
14
|
|
@@ -18,35 +18,27 @@
|
|
18
18
|
>
|
19
19
|
<FieldsWrapper>
|
20
20
|
<!-- For stacked bar chart -->
|
21
|
-
<template v-if="
|
21
|
+
<template v-if="props.series.length">
|
22
22
|
<InputRow
|
23
|
-
v-for="series in
|
23
|
+
v-for="series in props.series"
|
24
24
|
:key="series.name"
|
25
25
|
:data-series-name="series.name"
|
26
26
|
>
|
27
27
|
<InputGroup
|
28
28
|
v-for="(item, index) in props.data"
|
29
|
-
:key="index"
|
30
29
|
:bar-width="barWidth"
|
31
30
|
:is-scrollable="isScrollable"
|
31
|
+
:key="index"
|
32
32
|
>
|
33
33
|
<InputNumber
|
34
34
|
:allow-negative="false"
|
35
|
-
:disabled="isInputsDisabled"
|
36
35
|
input-height="36px"
|
37
|
-
:
|
38
|
-
fieldMode === 'percentage'
|
39
|
-
? calculatePercentageTotal(item.label) !== 100
|
40
|
-
: false
|
41
|
-
"
|
36
|
+
:number-precision="0"
|
42
37
|
:min-decimals="0"
|
43
|
-
:number-precision="fieldMode === 'percentage' ? 2 : 0"
|
44
38
|
text-align="center"
|
45
39
|
:unit-name="fieldMode === 'percentage' ? '%' : ''"
|
46
40
|
:value="getDisplayValue(series.data, item.label)"
|
47
|
-
@input-blur="
|
48
|
-
handleInputBlur($event, series.name, item.label, series.data)
|
49
|
-
"
|
41
|
+
@input-blur="handleInputBlur($event, series.name, item.label)"
|
50
42
|
@input-focus="handleInputFocus(series.name, item.label)"
|
51
43
|
/>
|
52
44
|
</InputGroup>
|
@@ -55,17 +47,16 @@
|
|
55
47
|
<TotalInputRow v-if="fieldMode === 'percentage'">
|
56
48
|
<InputGroup
|
57
49
|
v-for="(item, index) in props.data"
|
58
|
-
:key="index"
|
59
50
|
:bar-width="barWidth"
|
60
51
|
:is-scrollable="isScrollable"
|
52
|
+
:key="index"
|
61
53
|
>
|
62
54
|
<InputNumber
|
63
55
|
:allow-negative="false"
|
64
|
-
:disabled="isInputsDisabled"
|
65
56
|
input-height="36px"
|
66
57
|
:is-read-only="true"
|
58
|
+
:number-precision="0"
|
67
59
|
:min-decimals="0"
|
68
|
-
:number-precision="fieldMode === 'percentage' ? 2 : 0"
|
69
60
|
text-align="center"
|
70
61
|
:unit-name="fieldMode === 'percentage' ? '%' : ''"
|
71
62
|
:value="calculatePercentageTotal(item.label)"
|
@@ -76,23 +67,17 @@
|
|
76
67
|
<TotalInputRow>
|
77
68
|
<InputGroup
|
78
69
|
v-for="(item, index) in props.data"
|
79
|
-
:key="index"
|
80
70
|
:bar-width="barWidth"
|
81
71
|
:is-scrollable="isScrollable"
|
72
|
+
:key="index"
|
82
73
|
>
|
83
74
|
<InputNumber
|
84
75
|
input-height="36px"
|
85
|
-
:is-border-error-only="true"
|
86
|
-
:is-info-border="
|
87
|
-
fieldMode === 'percentage'
|
88
|
-
? calculatePercentageTotal(item.label) !== 100
|
89
|
-
: false
|
90
|
-
"
|
91
76
|
:is-read-only="true"
|
77
|
+
:number-precision="2"
|
92
78
|
:min-decimals="0"
|
93
|
-
:number-precision="0"
|
94
79
|
text-align="center"
|
95
|
-
:value="
|
80
|
+
:value="calculateTotal(item.label)"
|
96
81
|
/>
|
97
82
|
</InputGroup>
|
98
83
|
</TotalInputRow>
|
@@ -103,19 +88,17 @@
|
|
103
88
|
<InputRow>
|
104
89
|
<InputGroup
|
105
90
|
v-for="(item, index) in props.data"
|
106
|
-
:key="index"
|
107
91
|
:bar-width="barWidth"
|
108
92
|
:is-scrollable="isScrollable"
|
93
|
+
:key="index"
|
109
94
|
>
|
110
95
|
<InputNumber
|
111
|
-
:allow-negative="false"
|
112
|
-
:disabled="isInputsDisabled"
|
113
96
|
input-height="36px"
|
114
97
|
:min-decimals="0"
|
115
|
-
:number-precision="
|
98
|
+
:number-precision="2"
|
116
99
|
text-align="center"
|
117
100
|
:value="item.value"
|
118
|
-
@input-blur="handleInputBlur($event, null, item.label
|
101
|
+
@input-blur="handleInputBlur($event, null, item.label)"
|
119
102
|
@input-focus="handleInputFocus(null, item.label)"
|
120
103
|
/>
|
121
104
|
</InputGroup>
|
@@ -124,22 +107,11 @@
|
|
124
107
|
</FieldsWrapper>
|
125
108
|
</FieldsContainer>
|
126
109
|
</Container>
|
127
|
-
<InfoCardContainer
|
128
|
-
v-if="hasAnySegmentNotTotatTo100Percent && fieldMode === 'percentage'"
|
129
|
-
:yAxisWidth="yAxisWidth"
|
130
|
-
>
|
131
|
-
<InfoCard align-items="center" type="info">
|
132
|
-
<InfoCardBody>
|
133
|
-
{{ $gettext('load_profile_not_add_up_to_100') }}
|
134
|
-
</InfoCardBody>
|
135
|
-
</InfoCard>
|
136
|
-
</InfoCardContainer>
|
137
110
|
</template>
|
138
111
|
|
139
112
|
<script setup>
|
140
|
-
import { ref
|
113
|
+
import { ref } from 'vue'
|
141
114
|
import InputNumber from '../inputs/inputNumber'
|
142
|
-
import InfoCard from '../infoCard'
|
143
115
|
|
144
116
|
import {
|
145
117
|
Container,
|
@@ -151,8 +123,6 @@
|
|
151
123
|
InputRow,
|
152
124
|
TotalInputRow,
|
153
125
|
InputGroup,
|
154
|
-
InfoCardContainer,
|
155
|
-
InfoCardBody,
|
156
126
|
} from './styles/bottomFields'
|
157
127
|
|
158
128
|
const props = defineProps({
|
@@ -189,47 +159,6 @@
|
|
189
159
|
default: 'absolute',
|
190
160
|
validator: (value) => ['absolute', 'percentage'].includes(value),
|
191
161
|
},
|
192
|
-
isInputsDisabled: {
|
193
|
-
type: Boolean,
|
194
|
-
default: false,
|
195
|
-
},
|
196
|
-
})
|
197
|
-
|
198
|
-
const seriesData = ref([])
|
199
|
-
|
200
|
-
watchEffect(() => {
|
201
|
-
let isNewSetOfSeries = false
|
202
|
-
const seriesDataCopy = [...seriesData.value]
|
203
|
-
if (
|
204
|
-
!seriesDataCopy.length ||
|
205
|
-
!props.series.length ||
|
206
|
-
seriesDataCopy.length !== props.series.length ||
|
207
|
-
!seriesDataCopy.some((item) => {
|
208
|
-
return props.series.map((s) => s.name).includes(item.name)
|
209
|
-
})
|
210
|
-
) {
|
211
|
-
isNewSetOfSeries = true
|
212
|
-
}
|
213
|
-
const currentSeriesData = !isNewSetOfSeries ? seriesDataCopy : []
|
214
|
-
const newSeriesData = []
|
215
|
-
|
216
|
-
props.series.forEach((item, itemIndex) => {
|
217
|
-
const data = item.data.map((d, dIndex) => ({
|
218
|
-
label: d.label,
|
219
|
-
value: d.value,
|
220
|
-
percentage: d.percentage,
|
221
|
-
originalValue: currentSeriesData.length
|
222
|
-
? currentSeriesData[itemIndex].data[dIndex].originalValue
|
223
|
-
: d.value,
|
224
|
-
}))
|
225
|
-
|
226
|
-
newSeriesData.push({
|
227
|
-
name: item.name,
|
228
|
-
data,
|
229
|
-
})
|
230
|
-
})
|
231
|
-
|
232
|
-
seriesData.value = [...newSeriesData]
|
233
162
|
})
|
234
163
|
|
235
164
|
const emit = defineEmits([
|
@@ -246,13 +175,11 @@
|
|
246
175
|
emit('input-focus', { seriesName, label })
|
247
176
|
}
|
248
177
|
|
249
|
-
const
|
250
|
-
|
178
|
+
const calculateTotal = (label) => {
|
179
|
+
return props.series.reduce((sum, series) => {
|
251
180
|
const value = series.data.find((d) => d.label === label)?.value || 0
|
252
181
|
return sum + value
|
253
182
|
}, 0)
|
254
|
-
|
255
|
-
return Math.round(total)
|
256
183
|
}
|
257
184
|
|
258
185
|
const syncScroll = (scrollLeft) => {
|
@@ -263,43 +190,34 @@
|
|
263
190
|
container.scrollLeft = scrollLeft
|
264
191
|
}
|
265
192
|
}
|
266
|
-
|
267
|
-
const calculateTotalOriginalValue = (label) => {
|
268
|
-
return seriesData.value.reduce((sum, series) => {
|
269
|
-
const value =
|
270
|
-
series.data.find((d) => d.label === label)?.originalValue || 0
|
271
|
-
return sum + value
|
272
|
-
}, 0)
|
273
|
-
}
|
274
|
-
|
275
|
-
const getDisplayValue = (data, label, shouldRound = true) => {
|
193
|
+
const getDisplayValue = (seriesData, label) => {
|
276
194
|
if (props.fieldMode === 'absolute') {
|
277
|
-
return
|
195
|
+
return seriesData.find((d) => d.label === label)?.value || ''
|
278
196
|
}
|
279
197
|
|
280
|
-
|
198
|
+
const value = seriesData.find((d) => d.label === label)?.value || 0
|
199
|
+
const total = calculateTotal(label)
|
200
|
+
return total ? Number(((value / total) * 100).toFixed(0)) : 0
|
281
201
|
}
|
282
202
|
|
283
203
|
const calculatePercentageTotal = (label) => {
|
284
|
-
|
285
|
-
const
|
286
|
-
|
204
|
+
return props.series.reduce((sum, series) => {
|
205
|
+
const value = series.data.find((d) => d.label === label)?.value || 0
|
206
|
+
const total = calculateTotal(label)
|
207
|
+
const percentage = total ? Number(((value / total) * 100).toFixed(0)) : 0
|
287
208
|
return sum + percentage
|
288
209
|
}, 0)
|
289
|
-
|
290
|
-
return Math.round(percentageTotal)
|
291
210
|
}
|
292
211
|
|
293
|
-
const handleInputBlur = (_value, seriesName, label
|
212
|
+
const handleInputBlur = (_value, seriesName, label) => {
|
294
213
|
let value = Number(_value)
|
295
214
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
: { label, value }
|
215
|
+
if (props.fieldMode === 'percentage') {
|
216
|
+
const total = calculateTotal(label)
|
217
|
+
value = (value / 100) * total
|
218
|
+
}
|
219
|
+
|
220
|
+
const payload = seriesName ? { seriesName, label, value } : { label, value }
|
303
221
|
emit('input-blur', payload)
|
304
222
|
focusedInput.value = null
|
305
223
|
|
@@ -325,12 +243,6 @@
|
|
325
243
|
}
|
326
244
|
}
|
327
245
|
|
328
|
-
const hasAnySegmentNotTotatTo100Percent = computed(() => {
|
329
|
-
return props.data.some((d) => {
|
330
|
-
return calculatePercentageTotal(d.label) !== 100
|
331
|
-
})
|
332
|
-
})
|
333
|
-
|
334
246
|
const handleFieldsScroll = (event) => {
|
335
247
|
emit('sync-scroll', event.target.scrollLeft)
|
336
248
|
}
|
@@ -84,7 +84,7 @@ export function useAxisCalculations(props, maxValue) {
|
|
84
84
|
})
|
85
85
|
|
86
86
|
const yAxisWidth = computed(() => {
|
87
|
-
return !!props.yAxisTitle || props.isBottomFieldsShown ? '
|
87
|
+
return !!props.yAxisTitle || props.isBottomFieldsShown ? '70px' : '60px'
|
88
88
|
})
|
89
89
|
|
90
90
|
const isChartControlsShown = (position) => {
|
@@ -66,7 +66,7 @@ export function useChartData(props, paddedMaxValue) {
|
|
66
66
|
let accumulated = 0
|
67
67
|
return {
|
68
68
|
label: item.label,
|
69
|
-
segments: [...props.series].map((series, index) => {
|
69
|
+
segments: [...props.series].reverse().map((series, index) => {
|
70
70
|
const value =
|
71
71
|
series.data.find((d) => d.label === item.label)?.value || 0
|
72
72
|
accumulated += value
|
@@ -16,21 +16,7 @@ export function useTooltip(chartId, normalizedData) {
|
|
16
16
|
if (!showTooltipContent.value) {
|
17
17
|
showTooltipContent.value = true
|
18
18
|
}
|
19
|
-
if (isObjectEqual(item, tooltipData.value))
|
20
|
-
return
|
21
|
-
}
|
22
|
-
|
23
|
-
const totalValue = item.segments.reduce((acc, segment) => {
|
24
|
-
return acc + segment.value
|
25
|
-
}, 0)
|
26
|
-
|
27
|
-
const segments = item.segments.map((segment) => {
|
28
|
-
let valuePercentage = (segment.value / totalValue) * 100
|
29
|
-
segment.valuePercentage = Math.round(valuePercentage)
|
30
|
-
|
31
|
-
return segment
|
32
|
-
})
|
33
|
-
item.segments = segments
|
19
|
+
if (isObjectEqual(item, tooltipData.value)) return
|
34
20
|
|
35
21
|
tooltipData.value = { ...item }
|
36
22
|
|
@@ -55,27 +41,16 @@ export function useTooltip(chartId, normalizedData) {
|
|
55
41
|
|
56
42
|
isInputFocused.value = true
|
57
43
|
const barData = normalizedData.value.find((item) => item.label === label)
|
58
|
-
if (!barData) return
|
59
44
|
|
60
|
-
|
61
|
-
return acc + segment.value
|
62
|
-
}, 0)
|
63
|
-
const segments = barData.segments.map((segment) => {
|
64
|
-
let valuePercentage = (segment.value / totalValue) * 100
|
65
|
-
segment.valuePercentage = Math.round(valuePercentage)
|
66
|
-
|
67
|
-
return segment
|
68
|
-
})
|
69
|
-
barData.segments = segments
|
45
|
+
if (!barData) return
|
70
46
|
focusedBarData.value = barData
|
71
|
-
|
72
47
|
const barElement = document.querySelector(
|
73
48
|
`.barchart-${chartId} .bar-group:nth-child(${
|
74
49
|
normalizedData.value.indexOf(barData) + 1
|
75
50
|
})`
|
76
51
|
)
|
77
|
-
if (!barElement) return
|
78
52
|
|
53
|
+
if (!barElement) return
|
79
54
|
// Get the last bar segment, samee as hover behavior
|
80
55
|
const targetElement = barElement.querySelector('.bar-segment:last-child')
|
81
56
|
const rect = targetElement.getBoundingClientRect()
|
@@ -17,8 +17,8 @@
|
|
17
17
|
/>
|
18
18
|
</ChartControlsWrapper>
|
19
19
|
<GraphSection :height="height" :width="width">
|
20
|
-
<YAxis :
|
21
|
-
<YAxisTitleWrapper v-if="yAxisTitle"
|
20
|
+
<YAxis :width="yAxisWidth">
|
21
|
+
<YAxisTitleWrapper v-if="yAxisTitle">
|
22
22
|
{{ yAxisTitle }}
|
23
23
|
</YAxisTitleWrapper>
|
24
24
|
<YAxisRow
|
@@ -30,15 +30,15 @@
|
|
30
30
|
)
|
31
31
|
"
|
32
32
|
>
|
33
|
-
<YAxisLabel>{{
|
33
|
+
<YAxisLabel>{{ label }}</YAxisLabel>
|
34
34
|
<YAxisLine :y-axis-width="yAxisWidth" />
|
35
35
|
</YAxisRow>
|
36
36
|
</YAxis>
|
37
37
|
|
38
38
|
<ScrollContainer
|
39
39
|
:class="`chart-scroll-container-${chartId}`"
|
40
|
-
:height="height"
|
41
40
|
:is-scrollable="isScrollable"
|
41
|
+
:height="height"
|
42
42
|
@scroll="handleChartScroll"
|
43
43
|
>
|
44
44
|
<ChartContent
|
@@ -64,19 +64,19 @@
|
|
64
64
|
<BarsContainer>
|
65
65
|
<BarGroup
|
66
66
|
v-for="(item, index) in normalizedData"
|
67
|
-
:key="index"
|
68
67
|
:bar-width="barWidth"
|
69
68
|
class="bar-group"
|
70
69
|
:is-scrollable="isScrollable"
|
70
|
+
:key="index"
|
71
71
|
>
|
72
72
|
<BarWrapper>
|
73
73
|
<BarSegment
|
74
74
|
v-for="(segment, segIndex) in item.segments"
|
75
|
-
:key="segIndex"
|
76
75
|
class="bar-segment"
|
77
76
|
:gradient-from="getSegmentGradient(index, segment).from"
|
78
77
|
:gradient-to="getSegmentGradient(index, segment).to"
|
79
78
|
:height="`${segment.percentage}%`"
|
79
|
+
:key="segIndex"
|
80
80
|
:z-index="item.segments.length - segIndex"
|
81
81
|
@mouseenter="showTooltip(item, $event, series)"
|
82
82
|
@mouseleave="hideTooltip"
|
@@ -96,7 +96,7 @@
|
|
96
96
|
:left="tooltipStyle.left"
|
97
97
|
:top="tooltipStyle.top"
|
98
98
|
>
|
99
|
-
<slot :item="tooltipData" name="tooltip"
|
99
|
+
<slot :item="tooltipData" name="tooltip" />
|
100
100
|
<TooltipTextWrapper v-if="!slots.tooltip && tooltipData">
|
101
101
|
<template v-if="!series.length">
|
102
102
|
<TooltipText font-weight="500">{{ tooltipData.label }}</TooltipText>
|
@@ -128,11 +128,7 @@
|
|
128
128
|
:gradient-to="segment.gradientTo"
|
129
129
|
/>
|
130
130
|
<TooltipText>
|
131
|
-
{{
|
132
|
-
fieldMode === 'absolute' && showPercentageOnTooltip
|
133
|
-
? `${segment.valuePercentage}%`
|
134
|
-
: handleValueFormatter(segment.value)
|
135
|
-
}}
|
131
|
+
{{ handleValueFormatter(segment.value) }}
|
136
132
|
</TooltipText>
|
137
133
|
</TooltipRow>
|
138
134
|
</template>
|
@@ -163,7 +159,6 @@
|
|
163
159
|
:data="data"
|
164
160
|
:field-mode="fieldMode"
|
165
161
|
:is-chart-controls-shown-in-bottom="isChartControlsShown('bottom')"
|
166
|
-
:is-inputs-disabled="isLoading"
|
167
162
|
:is-scrollable="isScrollable"
|
168
163
|
:series="series"
|
169
164
|
:y-axis-width="yAxisWidth"
|
@@ -176,13 +171,12 @@
|
|
176
171
|
</template>
|
177
172
|
|
178
173
|
<script setup>
|
179
|
-
import { useSlots, computed
|
174
|
+
import { useSlots, computed } from 'vue'
|
180
175
|
|
181
176
|
import ChartControls from './ChartControls'
|
182
177
|
import BottomFields from './BottomFields'
|
183
178
|
import SelectionBox from './SelectionBox'
|
184
179
|
import Spinner from '../spinner'
|
185
|
-
import { numberToString } from '../../helpers/numberConverter'
|
186
180
|
|
187
181
|
import {
|
188
182
|
useTooltip,
|
@@ -252,6 +246,10 @@
|
|
252
246
|
type: String,
|
253
247
|
default: '',
|
254
248
|
},
|
249
|
+
valueFormatter: {
|
250
|
+
type: Function,
|
251
|
+
default: null,
|
252
|
+
},
|
255
253
|
isLegendShown: {
|
256
254
|
type: Boolean,
|
257
255
|
default: false,
|
@@ -298,10 +296,6 @@
|
|
298
296
|
type: Boolean,
|
299
297
|
default: false,
|
300
298
|
},
|
301
|
-
showPercentageOnTooltip: {
|
302
|
-
type: Boolean,
|
303
|
-
default: false,
|
304
|
-
},
|
305
299
|
})
|
306
300
|
|
307
301
|
const generateChartId = () =>
|
@@ -384,40 +378,8 @@
|
|
384
378
|
}
|
385
379
|
|
386
380
|
const handleValueFormatter = (value) => {
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
value: formattedValue,
|
391
|
-
numberPrecision: 0,
|
392
|
-
minDecimals: 0,
|
393
|
-
})
|
394
|
-
} else if (value < 1000000) {
|
395
|
-
formattedValue = numberToString({
|
396
|
-
value: Number(formattedValue / 1000),
|
397
|
-
numberPrecision: 2,
|
398
|
-
minDecimals: 2,
|
399
|
-
})
|
400
|
-
} else {
|
401
|
-
formattedValue = numberToString({
|
402
|
-
value: Number(formattedValue / 1000000),
|
403
|
-
numberPrecision: 2,
|
404
|
-
minDecimals: 2,
|
405
|
-
})
|
406
|
-
}
|
407
|
-
if (value < 1000) {
|
408
|
-
return `${formattedValue} kWh`
|
409
|
-
} else if (value < 1000000) {
|
410
|
-
return `${formattedValue} MWh`
|
411
|
-
} else {
|
412
|
-
return `${formattedValue} GWh`
|
413
|
-
}
|
414
|
-
}
|
415
|
-
|
416
|
-
const getYAxisLabel = (label) => {
|
417
|
-
return numberToString({
|
418
|
-
value: label,
|
419
|
-
numberPrecision: 0,
|
420
|
-
minDecimals: 0,
|
421
|
-
})
|
381
|
+
return props.valueFormatter
|
382
|
+
? props.valueFormatter(Math.round(value))
|
383
|
+
: value
|
422
384
|
}
|
423
385
|
</script>
|
@@ -17,18 +17,18 @@ export const LabelsColumn = styled('div', { width: String })`
|
|
17
17
|
|
18
18
|
export const LabelRow = styled.div`
|
19
19
|
height: 32px;
|
20
|
-
padding-top: 5px;
|
21
20
|
font-size: 12px;
|
22
21
|
font-weight: 500;
|
23
22
|
color: ${(props) => props.theme.semanticColors.teal[600]};
|
24
23
|
display: flex;
|
25
|
-
align-items:
|
24
|
+
align-items: flex-start;
|
26
25
|
`
|
27
26
|
|
28
27
|
export const TotalRow = styled(LabelRow)``
|
29
28
|
|
30
29
|
export const FieldsContainer = styled.div`
|
31
30
|
flex: 1;
|
31
|
+
overflow-x: auto;
|
32
32
|
scrollbar-width: none;
|
33
33
|
|
34
34
|
&::-webkit-scrollbar {
|
@@ -59,22 +59,8 @@ export const InputGroup = styled('div', {
|
|
59
59
|
barWidth: Number,
|
60
60
|
isScrollable: Boolean,
|
61
61
|
})`
|
62
|
-
${(props) => (props.isScrollable ? 'min-width' : 'width')}
|
62
|
+
${(props) => (props.isScrollable ? 'min-width' : 'width')}:${(props) =>
|
63
|
+
props.barWidth}px;
|
63
64
|
display: flex;
|
64
65
|
justify-content: center;
|
65
|
-
position: relative;
|
66
|
-
|
67
|
-
input[readonly] {
|
68
|
-
border: 1px solid ${(props) => props.theme.colors.grey4} !important;
|
69
|
-
}
|
70
|
-
`
|
71
|
-
|
72
|
-
export const InfoCardContainer = styled('div', { yAxisWidth: String })`
|
73
|
-
margin-left: ${(props) => props.yAxisWidth};
|
74
|
-
padding: 12px;
|
75
|
-
margin-top: 12px;
|
76
|
-
`
|
77
|
-
|
78
|
-
export const InfoCardBody = styled.div`
|
79
|
-
padding: 8px 0;
|
80
66
|
`
|
@@ -16,12 +16,9 @@ export const GraphSection = styled('div', { width: String, height: String })`
|
|
16
16
|
display: flex;
|
17
17
|
`
|
18
18
|
|
19
|
-
export const YAxis = styled('div', { width: String
|
19
|
+
export const YAxis = styled('div', { width: String })`
|
20
20
|
width: ${(props) => props.width};
|
21
|
-
display: flex;
|
22
|
-
flex-direction: column;
|
23
21
|
position: relative;
|
24
|
-
height: ${(props) => props.height};
|
25
22
|
`
|
26
23
|
|
27
24
|
export const YAxisRow = styled('div', { percentage: Number })`
|
@@ -57,18 +54,19 @@ export const YAxisLine = styled('div', { yAxisWidth: String })`
|
|
57
54
|
transform: translateY(-50%);
|
58
55
|
`
|
59
56
|
|
60
|
-
export const YAxisTitleWrapper = styled('div'
|
61
|
-
position: absolute;
|
62
|
-
left: -66px;
|
63
|
-
top: ${(props) => props.height};
|
64
|
-
transform: rotate(-90deg) translateX(50%);
|
65
|
-
transform-origin: right;
|
57
|
+
export const YAxisTitleWrapper = styled('div')`
|
66
58
|
font-size: 12px;
|
67
|
-
|
68
|
-
|
69
|
-
align-items: center;
|
59
|
+
font-weight: 500;
|
60
|
+
color: ${(props) => props.theme.semanticColors.grey[700]};
|
70
61
|
white-space: nowrap;
|
71
|
-
|
62
|
+
height: 0;
|
63
|
+
width: 0;
|
64
|
+
display: flex;
|
65
|
+
align-items: flex-start;
|
66
|
+
justify-content: center;
|
67
|
+
position: absolute;
|
68
|
+
top: 50%;
|
69
|
+
transform: rotate(-90deg);
|
72
70
|
`
|
73
71
|
|
74
72
|
export const ScrollContainer = styled('div', {
|
@@ -127,7 +125,6 @@ export const BarWrapper = styled.div`
|
|
127
125
|
height: 100%;
|
128
126
|
width: 100%;
|
129
127
|
position: relative;
|
130
|
-
overflow: hidden;
|
131
128
|
`
|
132
129
|
|
133
130
|
export const BarSegment = styled('div', {
|
@@ -73,12 +73,7 @@
|
|
73
73
|
type: {
|
74
74
|
required: false,
|
75
75
|
type: String,
|
76
|
-
default: '
|
77
|
-
validator(value) {
|
78
|
-
return ['info_simple', 'warning', 'error_minor', 'info'].includes(
|
79
|
-
value
|
80
|
-
)
|
81
|
-
},
|
76
|
+
default: 'info',
|
82
77
|
},
|
83
78
|
minWidth: {
|
84
79
|
required: false,
|
@@ -117,11 +112,8 @@
|
|
117
112
|
},
|
118
113
|
},
|
119
114
|
computed: {
|
120
|
-
isInfoSimple() {
|
121
|
-
// this property is used for tests
|
122
|
-
return this.type === 'info_simple'
|
123
|
-
},
|
124
115
|
isInfo() {
|
116
|
+
// this property is used for tests
|
125
117
|
return this.type === 'info'
|
126
118
|
},
|
127
119
|
isWarning() {
|
@@ -131,7 +123,11 @@
|
|
131
123
|
return this.type === 'error_minor'
|
132
124
|
},
|
133
125
|
iconName() {
|
134
|
-
return this.type === 'warning'
|
126
|
+
return this.type === 'warning'
|
127
|
+
? 'warning_triangle'
|
128
|
+
: this.isErrorMinor
|
129
|
+
? 'erase'
|
130
|
+
: 'info'
|
135
131
|
},
|
136
132
|
presetStyles() {
|
137
133
|
// the types that doesn't have explicit border anyway have it transparent
|
@@ -149,16 +145,12 @@
|
|
149
145
|
stylesCollection.backgroundColor = theme.semanticColors.yellow[300]
|
150
146
|
stylesCollection.iconColor = theme.semanticColors.teal[800]
|
151
147
|
} else if (this.isErrorMinor) {
|
152
|
-
stylesCollection.borderStyle = 'dashed'
|
153
|
-
stylesCollection.borderColor = theme.colors.pureRed
|
154
|
-
stylesCollection.iconColor = theme.colors.pureRed
|
155
|
-
} else if (this.isInfoSimple) {
|
156
148
|
stylesCollection.borderStyle = 'dashed'
|
157
149
|
stylesCollection.borderColor = theme.colors.grey4
|
150
|
+
stylesCollection.iconColor = theme.colors.red
|
158
151
|
} else {
|
159
|
-
stylesCollection.
|
160
|
-
stylesCollection.
|
161
|
-
stylesCollection.iconColor = theme.semanticColors.teal[800]
|
152
|
+
stylesCollection.borderStyle = 'dashed'
|
153
|
+
stylesCollection.borderColor = theme.colors.grey4
|
162
154
|
}
|
163
155
|
|
164
156
|
return stylesCollection
|
@@ -45,19 +45,19 @@ describe('RCInfoCard.vue', () => {
|
|
45
45
|
},
|
46
46
|
})
|
47
47
|
|
48
|
-
expect(wrapper.vm.
|
48
|
+
expect(wrapper.vm.isInfo).toBe(true)
|
49
49
|
expect(wrapper.vm.isWarning).toBe(false)
|
50
50
|
expect(wrapper.vm.isErrorMinor).toBe(false)
|
51
51
|
|
52
52
|
await wrapper.setProps({ type: 'warning' })
|
53
53
|
|
54
|
-
expect(wrapper.vm.
|
54
|
+
expect(wrapper.vm.isInfo).toBe(false)
|
55
55
|
expect(wrapper.vm.isWarning).toBe(true)
|
56
56
|
expect(wrapper.vm.isErrorMinor).toBe(false)
|
57
57
|
|
58
58
|
await wrapper.setProps({ type: 'error_minor' })
|
59
59
|
|
60
|
-
expect(wrapper.vm.
|
60
|
+
expect(wrapper.vm.isInfo).toBe(false)
|
61
61
|
expect(wrapper.vm.isWarning).toBe(false)
|
62
62
|
expect(wrapper.vm.isErrorMinor).toBe(true)
|
63
63
|
})
|
@@ -3,15 +3,15 @@ import InputNumber from './index.vue'
|
|
3
3
|
export default {
|
4
4
|
title: 'InputNumber',
|
5
5
|
component: InputNumber,
|
6
|
-
// argTypes: {},
|
7
6
|
}
|
8
7
|
|
9
|
-
const Template = (args
|
8
|
+
const Template = (args) => ({
|
10
9
|
// Components used in your story `template` are defined in the `components` object
|
11
10
|
components: { InputNumber },
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
setup() {
|
12
|
+
return { args: args }
|
13
|
+
},
|
14
|
+
template: `<InputNumber v-bind="args" />`,
|
15
15
|
|
16
16
|
// import InputNumber from "@eturnity/eturnity_reusable_components/src/components/inputs/inputNumber"
|
17
17
|
// How to use:
|
@@ -73,6 +73,20 @@ Disabled.args = {
|
|
73
73
|
showLinearUnitName: false,
|
74
74
|
}
|
75
75
|
|
76
|
+
export const DisabledAndPreDefined = Template.bind({})
|
77
|
+
DisabledAndPreDefined.args = {
|
78
|
+
placeholder: 'Enter Value',
|
79
|
+
disabled: true,
|
80
|
+
isPreDefined: true,
|
81
|
+
value: '',
|
82
|
+
inputWidth: '200px',
|
83
|
+
isError: false,
|
84
|
+
numberPrecision: 0,
|
85
|
+
noBorder: false,
|
86
|
+
textAlign: 'left',
|
87
|
+
showLinearUnitName: false,
|
88
|
+
}
|
89
|
+
|
76
90
|
export const LinearUnit = Template.bind({})
|
77
91
|
LinearUnit.args = {
|
78
92
|
placeholder: 'Enter Value',
|
@@ -43,23 +43,20 @@
|
|
43
43
|
:color-mode="colorMode"
|
44
44
|
:data-id="inputDataId"
|
45
45
|
:data-qa-id="dataQaId"
|
46
|
-
:disabled="disabled"
|
47
46
|
:font-color="colorMode === 'transparent' ? 'white' : fontColor"
|
48
47
|
:font-size="fontSize"
|
49
48
|
:has-label-slot="hasLabelSlot"
|
50
49
|
:has-slot="hasSlot"
|
51
50
|
:has-unit="unitName && !!unitName.length"
|
52
51
|
:input-height="inputHeight"
|
53
|
-
:is-border-error-only="isBorderErrorOnly"
|
54
52
|
:is-disabled="disabled"
|
55
53
|
:is-error="isError"
|
56
|
-
:is-info-border="isInfoBorder"
|
57
54
|
:is-interactive="isInteractive"
|
55
|
+
:is-pre-defined="isPreDefined"
|
58
56
|
:min-width="minWidth"
|
59
57
|
:no-border="noBorder"
|
60
58
|
:placeholder="displayedPlaceholder"
|
61
59
|
:read-only="isReadOnly"
|
62
|
-
:readonly="isReadOnly"
|
63
60
|
:show-arrow-controls="showArrowControls"
|
64
61
|
:show-linear-unit-name="showLinearUnitName"
|
65
62
|
:slot-size="slotSize"
|
@@ -83,7 +80,7 @@
|
|
83
80
|
>{{ unitName }}</UnitContainer
|
84
81
|
>
|
85
82
|
<IconWrapper
|
86
|
-
v-if="isError && !showLinearUnitName
|
83
|
+
v-if="isError && !showLinearUnitName"
|
87
84
|
:margin-right="showSelect ? selectWidth : 0"
|
88
85
|
size="16px"
|
89
86
|
>
|
@@ -137,9 +134,7 @@
|
|
137
134
|
</ArrowButton>
|
138
135
|
</ArrowControls>
|
139
136
|
</InputWrapper>
|
140
|
-
<ErrorMessage v-if="isError && errorMessage">{{
|
141
|
-
errorMessage
|
142
|
-
}}</ErrorMessage>
|
137
|
+
<ErrorMessage v-if="isError && errorMessage">{{ errorMessage }}</ErrorMessage>
|
143
138
|
</Container>
|
144
139
|
</template>
|
145
140
|
|
@@ -202,6 +197,7 @@
|
|
202
197
|
slotSize: String,
|
203
198
|
inputHeight: String,
|
204
199
|
isInteractive: Boolean,
|
200
|
+
isPreDefined: Boolean,
|
205
201
|
alignItems: String,
|
206
202
|
labelFontColor: String,
|
207
203
|
labelFontWeight: String,
|
@@ -210,8 +206,6 @@
|
|
210
206
|
colorMode: String,
|
211
207
|
showArrowControls: Boolean,
|
212
208
|
readOnly: Boolean,
|
213
|
-
isBorderErrorOnly: Boolean,
|
214
|
-
isInfoBorder: Boolean,
|
215
209
|
}
|
216
210
|
|
217
211
|
const Container = styled('div', inputProps)`
|
@@ -224,9 +218,7 @@
|
|
224
218
|
|
225
219
|
const InputContainer = styled('input', inputProps)`
|
226
220
|
border: ${(props) =>
|
227
|
-
props.
|
228
|
-
? '1px solid ' + props.theme.semanticColors.blue[500]
|
229
|
-
: props.isError
|
221
|
+
props.isError
|
230
222
|
? '1px solid ' + props.theme.colors.red
|
231
223
|
: props.noBorder
|
232
224
|
? 'none'
|
@@ -245,17 +237,16 @@
|
|
245
237
|
showLinearUnitName,
|
246
238
|
colorMode,
|
247
239
|
showArrowControls,
|
248
|
-
isBorderErrorOnly,
|
249
240
|
}) =>
|
250
241
|
showArrowControls
|
251
242
|
? '40px'
|
252
243
|
: colorMode === 'transparent'
|
253
244
|
? '0'
|
254
245
|
: slotSize
|
255
|
-
? isError && !showLinearUnitName
|
246
|
+
? isError && !showLinearUnitName
|
256
247
|
? 'calc(' + slotSize + ' + 24px)'
|
257
248
|
: 'calc(' + slotSize + ' + 10px)'
|
258
|
-
: isError && !showLinearUnitName
|
249
|
+
: isError && !showLinearUnitName
|
259
250
|
? '24px'
|
260
251
|
: '5px'};
|
261
252
|
border-radius: ${(props) =>
|
@@ -269,7 +260,7 @@
|
|
269
260
|
color: ${(props) =>
|
270
261
|
props.isError
|
271
262
|
? props.theme.colors.grey6
|
272
|
-
: props.isDisabled
|
263
|
+
: props.isDisabled && !props.isPreDefined
|
273
264
|
? props.colorMode === 'transparent'
|
274
265
|
? props.theme.colors.white
|
275
266
|
: props.theme.colors.grey2
|
@@ -547,6 +538,11 @@
|
|
547
538
|
required: false,
|
548
539
|
default: 0,
|
549
540
|
},
|
541
|
+
isPreDefined: {
|
542
|
+
type: Boolean,
|
543
|
+
required: false,
|
544
|
+
default: false,
|
545
|
+
},
|
550
546
|
minDecimals: {
|
551
547
|
type: Number,
|
552
548
|
required: false,
|
@@ -667,12 +663,18 @@
|
|
667
663
|
required: false,
|
668
664
|
default: '',
|
669
665
|
},
|
666
|
+
labelDataTestId: {
|
667
|
+
type: String,
|
668
|
+
required: false,
|
669
|
+
default: '',
|
670
|
+
},
|
670
671
|
inputDataId: {
|
671
672
|
type: String,
|
672
673
|
required: false,
|
673
674
|
default: '',
|
674
675
|
},
|
675
676
|
dataQaId: {
|
677
|
+
type: String,
|
676
678
|
required: false,
|
677
679
|
default: '',
|
678
680
|
},
|
@@ -708,14 +710,6 @@
|
|
708
710
|
type: Boolean,
|
709
711
|
default: false,
|
710
712
|
},
|
711
|
-
isBorderErrorOnly: {
|
712
|
-
type: Boolean,
|
713
|
-
default: false,
|
714
|
-
},
|
715
|
-
isInfoBorder: {
|
716
|
-
type: Boolean,
|
717
|
-
default: false,
|
718
|
-
},
|
719
713
|
},
|
720
714
|
data() {
|
721
715
|
return {
|
@@ -5,7 +5,8 @@
|
|
5
5
|
:has-info-text="!!infoText"
|
6
6
|
:margin-bottom="marginBottom"
|
7
7
|
>
|
8
|
-
<span data-test-id="page_subtitle_text">
|
8
|
+
<span v-if="containsHtml" data-test-id="page_subtitle_text" v-html="text"></span>
|
9
|
+
<span v-else data-test-id="page_subtitle_text">
|
9
10
|
{{ text }}
|
10
11
|
</span>
|
11
12
|
<InfoText
|
@@ -58,6 +59,11 @@
|
|
58
59
|
required: true,
|
59
60
|
type: String,
|
60
61
|
},
|
62
|
+
containsHtml: {
|
63
|
+
required: false,
|
64
|
+
type: Boolean,
|
65
|
+
default: false,
|
66
|
+
},
|
61
67
|
color: {
|
62
68
|
required: false,
|
63
69
|
type: String,
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<template>
|
2
2
|
<TitleWrap data-test-id="page_wrapper" :has-info-text="!!infoText">
|
3
3
|
<TitleText
|
4
|
-
:color="color"
|
5
4
|
data-test-id="page_title_text"
|
5
|
+
:color="color"
|
6
6
|
:font-size="fontSize"
|
7
7
|
:uppercase="uppercase"
|
8
8
|
>
|
@@ -10,8 +10,8 @@
|
|
10
10
|
</TitleText>
|
11
11
|
<InfoText
|
12
12
|
v-if="!!infoText"
|
13
|
-
:align-arrow="infoAlign"
|
14
13
|
data-test-id="page_title_tooltip"
|
14
|
+
:align-arrow="infoAlign"
|
15
15
|
:text="infoText"
|
16
16
|
/>
|
17
17
|
</TitleWrap>
|
@@ -44,8 +44,9 @@
|
|
44
44
|
const titleAttrs = { color: String, fontSize: String, uppercase: Boolean }
|
45
45
|
const TitleText = styled('span', titleAttrs)`
|
46
46
|
color: ${(props) => (props.color ? props.color : props.theme.colors.black)};
|
47
|
-
font-weight:
|
47
|
+
font-weight: bold;
|
48
48
|
font-size: ${(props) => (props.fontSize ? props.fontSize : '20px')};
|
49
|
+
text-transform: ${(props) => (props.uppercase ? 'uppercase' : 'none')};
|
49
50
|
`
|
50
51
|
|
51
52
|
export default {
|
package/src/TestChart.vue
DELETED
@@ -1,229 +0,0 @@
|
|
1
|
-
<template>
|
2
|
-
<div
|
3
|
-
style="
|
4
|
-
margin-top: 100px;
|
5
|
-
margin-left: 80px;
|
6
|
-
padding-bottom: 100px;
|
7
|
-
display: flex;
|
8
|
-
flex-direction: column;
|
9
|
-
"
|
10
|
-
>
|
11
|
-
<!-- Simple bar chart -->
|
12
|
-
<BarChart
|
13
|
-
:bar-width="60"
|
14
|
-
chart-controls-position="bottom"
|
15
|
-
:data="monthlyData"
|
16
|
-
height="400px"
|
17
|
-
:is-bottom-fields-shown="true"
|
18
|
-
:is-scrollable="false"
|
19
|
-
:is-selection-enabled="true"
|
20
|
-
:selection-size="3"
|
21
|
-
:value-formatter="valueFormatter"
|
22
|
-
width="700px"
|
23
|
-
@selection-change="handleSelectionChange"
|
24
|
-
/>
|
25
|
-
<br />
|
26
|
-
<br />
|
27
|
-
|
28
|
-
<!-- Stacked bar chart -->
|
29
|
-
<BarChart
|
30
|
-
:bar-width="60"
|
31
|
-
:data="monthLabels"
|
32
|
-
height="400px"
|
33
|
-
:is-bottom-fields-shown="true"
|
34
|
-
:is-legend-shown="true"
|
35
|
-
:legends-item-per-row="4"
|
36
|
-
:selected-split-button="selectedTimeFrame"
|
37
|
-
:series="tariffZones"
|
38
|
-
:show-percentage-on-tooltip="true"
|
39
|
-
:split-button-options="options"
|
40
|
-
:value-formatter="valueFormatter"
|
41
|
-
width="700px"
|
42
|
-
y-axis-title="Energy (kWh)"
|
43
|
-
@input-blur="handleInputBlur"
|
44
|
-
@select-split-button="handleSelectSplitButton"
|
45
|
-
/>
|
46
|
-
|
47
|
-
<!-- Stacked bar chart -->
|
48
|
-
<BarChart
|
49
|
-
:bar-width="60"
|
50
|
-
:data="monthLabels"
|
51
|
-
field-mode="percentage"
|
52
|
-
height="400px"
|
53
|
-
:is-bottom-fields-shown="true"
|
54
|
-
:is-legend-shown="false"
|
55
|
-
:legends-item-per-row="4"
|
56
|
-
:series="tariffZones"
|
57
|
-
:value-formatter="valueFormatter"
|
58
|
-
width="700px"
|
59
|
-
@input-blur="handleInputBlur"
|
60
|
-
@select-split-button="handleSelectSplitButton"
|
61
|
-
>
|
62
|
-
<!-- <template #tooltip="{ item, segment }">
|
63
|
-
<div style="display: flex; flex-direction: column">
|
64
|
-
{{ $c.log(item, segment) }}
|
65
|
-
<div>{{ item.label }}</div>
|
66
|
-
<div>{{ item.segments[0].value }} kWh</div>
|
67
|
-
</div>
|
68
|
-
</template> -->
|
69
|
-
</BarChart>
|
70
|
-
</div>
|
71
|
-
</template>
|
72
|
-
|
73
|
-
<script setup>
|
74
|
-
import { ref } from 'vue'
|
75
|
-
import BarChart from '@/components/barchart/index.vue'
|
76
|
-
|
77
|
-
const options = [
|
78
|
-
{ label: 'Day', value: 'day' },
|
79
|
-
{ label: 'Month', value: 'month' },
|
80
|
-
{ label: 'Year', value: 'year' },
|
81
|
-
]
|
82
|
-
|
83
|
-
const selectedTimeFrame = ref('day')
|
84
|
-
|
85
|
-
const handleSelectSplitButton = (value) => {
|
86
|
-
selectedTimeFrame.value = value
|
87
|
-
}
|
88
|
-
|
89
|
-
const monthlyData = [
|
90
|
-
{ label: 'Jan', value: 300 },
|
91
|
-
{ label: 'Feb', value: 600 },
|
92
|
-
{ label: 'Mar', value: 1000 },
|
93
|
-
{ label: 'Apr', value: 1200 },
|
94
|
-
{ label: 'May', value: 1400 },
|
95
|
-
{ label: 'Jun', value: 1810 },
|
96
|
-
{ label: 'Jul', value: 1400 },
|
97
|
-
{ label: 'Aug', value: 1200 },
|
98
|
-
{ label: 'Sep', value: 1000 },
|
99
|
-
// { label: 'Oct', value: 800 },
|
100
|
-
// { label: 'Nov', value: 600 },
|
101
|
-
// { label: 'Dec', value: 400 },
|
102
|
-
// { label: 'Jan', value: 300 },
|
103
|
-
// { label: 'Feb', value: 600 },
|
104
|
-
// { label: 'Mar', value: 1000 },
|
105
|
-
// { label: 'Apr', value: 1200 },
|
106
|
-
// { label: 'May', value: 1400 },
|
107
|
-
// { label: 'Jun', value: 1810 },
|
108
|
-
// { label: 'Jul', value: 1400 },
|
109
|
-
// { label: 'Aug', value: 1200 },
|
110
|
-
// { label: 'Sep', value: 1000 },
|
111
|
-
// { label: 'Oct', value: 800 },
|
112
|
-
// { label: 'Nov', value: 600 },
|
113
|
-
// { label: 'Dec', value: 400 },
|
114
|
-
|
115
|
-
// ... more months
|
116
|
-
]
|
117
|
-
|
118
|
-
const monthLabels = [
|
119
|
-
{ label: 'Jan' },
|
120
|
-
{ label: 'Feb' },
|
121
|
-
{ label: 'Mar' },
|
122
|
-
{ label: 'Apr' },
|
123
|
-
{ label: 'May' },
|
124
|
-
{ label: 'Jun' },
|
125
|
-
// ... more months
|
126
|
-
]
|
127
|
-
|
128
|
-
const tariffZones = ref([
|
129
|
-
{
|
130
|
-
name: 'Tariff Zone 1',
|
131
|
-
data: [
|
132
|
-
{ label: 'Jan', value: 200 },
|
133
|
-
{ label: 'Feb', value: 130 },
|
134
|
-
{ label: 'Mar', value: 220 },
|
135
|
-
{ label: 'Apr', value: 230 },
|
136
|
-
{ label: 'May', value: 200 },
|
137
|
-
{ label: 'Jun', value: 210 },
|
138
|
-
// ... more months
|
139
|
-
],
|
140
|
-
},
|
141
|
-
{
|
142
|
-
name: 'Tariff Zone 2',
|
143
|
-
data: [
|
144
|
-
{ label: 'Jan', value: 200 },
|
145
|
-
{ label: 'Feb', value: 100 },
|
146
|
-
{ label: 'Mar', value: 270 },
|
147
|
-
{ label: 'Apr', value: 180 },
|
148
|
-
{ label: 'May', value: 300 },
|
149
|
-
{ label: 'Jun', value: 250 },
|
150
|
-
// ... more months
|
151
|
-
],
|
152
|
-
},
|
153
|
-
{
|
154
|
-
name: 'Tariff Zone 3',
|
155
|
-
data: [
|
156
|
-
{ label: 'Jan', value: 200 },
|
157
|
-
{ label: 'Feb', value: 100 },
|
158
|
-
{ label: 'Mar', value: 210 },
|
159
|
-
{ label: 'Apr', value: 220 },
|
160
|
-
{ label: 'May', value: 300 },
|
161
|
-
{ label: 'Jun', value: 190 },
|
162
|
-
// ... more months
|
163
|
-
],
|
164
|
-
},
|
165
|
-
{
|
166
|
-
name: 'Tariff Zone 4',
|
167
|
-
data: [
|
168
|
-
{ label: 'Jan', value: 200 },
|
169
|
-
{ label: 'Feb', value: 100 },
|
170
|
-
{ label: 'Mar', value: 210 },
|
171
|
-
{ label: 'Apr', value: 220 },
|
172
|
-
{ label: 'May', value: 300 },
|
173
|
-
{ label: 'Jun', value: 190 },
|
174
|
-
// ... more months
|
175
|
-
],
|
176
|
-
},
|
177
|
-
{
|
178
|
-
name: 'Tariff Zone 5',
|
179
|
-
data: [
|
180
|
-
{ label: 'Jan', value: 200 },
|
181
|
-
{ label: 'Feb', value: 100 },
|
182
|
-
{ label: 'Mar', value: 210 },
|
183
|
-
{ label: 'Apr', value: 220 },
|
184
|
-
{ label: 'May', value: 300 },
|
185
|
-
{ label: 'Jun', value: 190 },
|
186
|
-
// ... more months
|
187
|
-
],
|
188
|
-
},
|
189
|
-
{
|
190
|
-
name: 'Tariff Zone 6',
|
191
|
-
data: [
|
192
|
-
{ label: 'Jan', value: 200 },
|
193
|
-
{ label: 'Feb', value: 100 },
|
194
|
-
{ label: 'Mar', value: 210 },
|
195
|
-
{ label: 'Apr', value: 220 },
|
196
|
-
{ label: 'May', value: 300 },
|
197
|
-
{ label: 'Jun', value: 190 },
|
198
|
-
// ... more months
|
199
|
-
],
|
200
|
-
},
|
201
|
-
// ... more tariff zones
|
202
|
-
])
|
203
|
-
|
204
|
-
const valueFormatter = (value) => {
|
205
|
-
return `${value} kWh`
|
206
|
-
}
|
207
|
-
|
208
|
-
const handleSelectionChange = (selectedBars) => {
|
209
|
-
console.log('selectedBars', selectedBars)
|
210
|
-
}
|
211
|
-
|
212
|
-
const handleInputBlur = (payload) => {
|
213
|
-
const newVal = [...tariffZones.value].map((zone) => {
|
214
|
-
if (zone.name === payload.seriesName) {
|
215
|
-
zone.data = zone.data.map((item) => {
|
216
|
-
if (item.label === payload.label) {
|
217
|
-
item.value = payload.value
|
218
|
-
}
|
219
|
-
return item
|
220
|
-
})
|
221
|
-
}
|
222
|
-
return zone
|
223
|
-
})
|
224
|
-
|
225
|
-
tariffZones.value = newVal
|
226
|
-
}
|
227
|
-
</script>
|
228
|
-
|
229
|
-
<style lang="scss" scoped></style>
|