@eturnity/eturnity_reusable_components 8.19.8-EPDM-14690.4 → 8.19.8-EPDM-15590.0
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/App.vue +1 -3
- package/src/assets/theme.js +0 -78
- package/src/components/barchart/BottomFields.vue +36 -126
- 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 +15 -58
- package/src/components/barchart/styles/bottomFields.js +4 -18
- package/src/components/barchart/styles/chart.js +0 -1
- package/src/components/buttons/mainButton/index.vue +0 -2
- package/src/components/errorMessage/index.vue +1 -1
- package/src/components/icon/index.vue +2 -4
- package/src/components/infoCard/index.vue +3 -15
- package/src/components/infoCard/infoCard.spec.js +3 -3
- package/src/components/infoText/index.vue +31 -36
- package/src/components/inputs/inputNumber/index.vue +6 -92
- package/src/components/inputs/radioButton/RadioButton.stories.js +6 -0
- package/src/components/inputs/radioButton/index.vue +11 -3
- package/src/components/pageTitle/index.vue +1 -0
- package/src/DemoChart.vue +0 -424
- package/src/TestChart.vue +0 -229
- package/src/components/tag/proTag/index.vue +0 -19
package/package.json
CHANGED
package/src/App.vue
CHANGED
@@ -1,19 +1,17 @@
|
|
1
1
|
<template>
|
2
2
|
<ThemeProvider :style="{ height: '100%' }" :theme="theme">
|
3
3
|
<RouterView />
|
4
|
-
<ProTag />
|
5
4
|
</ThemeProvider>
|
6
5
|
</template>
|
7
6
|
|
8
7
|
<script>
|
9
8
|
import { ThemeProvider } from 'vue3-styled-components'
|
10
9
|
import theme from '@/assets/theme.js'
|
11
|
-
|
10
|
+
|
12
11
|
export default {
|
13
12
|
name: 'App',
|
14
13
|
components: {
|
15
14
|
ThemeProvider,
|
16
|
-
ProTag,
|
17
15
|
},
|
18
16
|
setup() {
|
19
17
|
return {
|
package/src/assets/theme.js
CHANGED
@@ -416,30 +416,6 @@ const theme = (() => {
|
|
416
416
|
},
|
417
417
|
},
|
418
418
|
},
|
419
|
-
protag: {
|
420
|
-
main: {
|
421
|
-
default: {
|
422
|
-
backgroundColor: semanticColors.yellow[300],
|
423
|
-
textColor: semanticColors.teal[800],
|
424
|
-
borderColor: 'transparent',
|
425
|
-
},
|
426
|
-
hover: {
|
427
|
-
backgroundColor: semanticColors.yellow[300],
|
428
|
-
textColor: semanticColors.teal[800],
|
429
|
-
borderColor: '',
|
430
|
-
},
|
431
|
-
active: {
|
432
|
-
backgroundColor: semanticColors.yellow[300],
|
433
|
-
textColor: semanticColors.teal[800],
|
434
|
-
borderColor: '',
|
435
|
-
},
|
436
|
-
disabled: {
|
437
|
-
backgroundColor: semanticColors.yellow[300],
|
438
|
-
textColor: semanticColors.teal[400],
|
439
|
-
borderColor: '',
|
440
|
-
},
|
441
|
-
},
|
442
|
-
},
|
443
419
|
filter: {
|
444
420
|
main: {
|
445
421
|
default: {
|
@@ -614,55 +590,6 @@ const theme = (() => {
|
|
614
590
|
},
|
615
591
|
},
|
616
592
|
},
|
617
|
-
tertiary: {
|
618
|
-
// type
|
619
|
-
main: {
|
620
|
-
// variant: this is the default variant
|
621
|
-
default: {
|
622
|
-
backgroundColor: 'transparent',
|
623
|
-
textColor: semanticColors.purple[50],
|
624
|
-
borderColor: semanticColors.teal[500],
|
625
|
-
},
|
626
|
-
hover: {
|
627
|
-
backgroundColor: semanticColors.teal[600],
|
628
|
-
textColor: semanticColors.purple[50],
|
629
|
-
borderColor: semanticColors.teal[400],
|
630
|
-
},
|
631
|
-
active: {
|
632
|
-
backgroundColor: semanticColors.teal[700],
|
633
|
-
textColor: semanticColors.purple[50],
|
634
|
-
borderColor: semanticColors.teal[300],
|
635
|
-
},
|
636
|
-
disabled: {
|
637
|
-
textColor: semanticColors.grey[600],
|
638
|
-
backgroundColor: semanticColors.grey[500],
|
639
|
-
borderColor: semanticColors.grey[800],
|
640
|
-
},
|
641
|
-
},
|
642
|
-
cancel: {
|
643
|
-
// variant
|
644
|
-
default: {
|
645
|
-
backgroundColor: semanticColors.teal[200],
|
646
|
-
textColor: semanticColors.red[400],
|
647
|
-
borderColor: semanticColors.teal[500],
|
648
|
-
},
|
649
|
-
hover: {
|
650
|
-
backgroundColor: semanticColors.red[700],
|
651
|
-
textColor: semanticColors.red[700],
|
652
|
-
borderColor: semanticColors.teal[400],
|
653
|
-
},
|
654
|
-
active: {
|
655
|
-
backgroundColor: semanticColors.red[600],
|
656
|
-
textColor: semanticColors.red[200],
|
657
|
-
borderColor: semanticColors.teal[300],
|
658
|
-
},
|
659
|
-
disabled: {
|
660
|
-
textColor: semanticColors.grey[600],
|
661
|
-
backgroundColor: semanticColors.grey[500],
|
662
|
-
borderColor: semanticColors.grey[800],
|
663
|
-
},
|
664
|
-
},
|
665
|
-
},
|
666
593
|
ghost: {
|
667
594
|
// type
|
668
595
|
main: {
|
@@ -753,11 +680,6 @@ const theme = (() => {
|
|
753
680
|
fontSize: '14px',
|
754
681
|
iconWidth: '26px',
|
755
682
|
},
|
756
|
-
tiny: {
|
757
|
-
padding: '2px 5px',
|
758
|
-
fontSize: '10px',
|
759
|
-
iconWidth: '18px',
|
760
|
-
},
|
761
683
|
},
|
762
684
|
},
|
763
685
|
}
|
@@ -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,36 +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
|
-
:is-info-border="
|
39
|
-
fieldMode === 'percentage'
|
40
|
-
? calculatePercentageTotal(item.label) !== 100
|
41
|
-
: false
|
42
|
-
"
|
36
|
+
:number-precision="0"
|
43
37
|
:min-decimals="0"
|
44
|
-
:number-precision="fieldMode === 'percentage' ? 2 : 0"
|
45
38
|
text-align="center"
|
46
39
|
:unit-name="fieldMode === 'percentage' ? '%' : ''"
|
47
40
|
:value="getDisplayValue(series.data, item.label)"
|
48
|
-
@input-blur="
|
49
|
-
handleInputBlur($event, series.name, item.label, series.data)
|
50
|
-
"
|
41
|
+
@input-blur="handleInputBlur($event, series.name, item.label)"
|
51
42
|
@input-focus="handleInputFocus(series.name, item.label)"
|
52
43
|
/>
|
53
44
|
</InputGroup>
|
@@ -56,18 +47,16 @@
|
|
56
47
|
<TotalInputRow v-if="fieldMode === 'percentage'">
|
57
48
|
<InputGroup
|
58
49
|
v-for="(item, index) in props.data"
|
59
|
-
:key="index"
|
60
50
|
:bar-width="barWidth"
|
61
51
|
:is-scrollable="isScrollable"
|
52
|
+
:key="index"
|
62
53
|
>
|
63
54
|
<InputNumber
|
64
55
|
:allow-negative="false"
|
65
|
-
:disabled="isInputsDisabled"
|
66
56
|
input-height="36px"
|
67
|
-
:is-disabled-styled-only="true"
|
68
57
|
:is-read-only="true"
|
58
|
+
:number-precision="0"
|
69
59
|
:min-decimals="0"
|
70
|
-
:number-precision="fieldMode === 'percentage' ? 2 : 0"
|
71
60
|
text-align="center"
|
72
61
|
:unit-name="fieldMode === 'percentage' ? '%' : ''"
|
73
62
|
:value="calculatePercentageTotal(item.label)"
|
@@ -78,23 +67,17 @@
|
|
78
67
|
<TotalInputRow>
|
79
68
|
<InputGroup
|
80
69
|
v-for="(item, index) in props.data"
|
81
|
-
:key="index"
|
82
70
|
:bar-width="barWidth"
|
83
71
|
:is-scrollable="isScrollable"
|
72
|
+
:key="index"
|
84
73
|
>
|
85
74
|
<InputNumber
|
86
75
|
input-height="36px"
|
87
|
-
:is-border-error-only="true"
|
88
|
-
:is-info-border="
|
89
|
-
fieldMode === 'percentage'
|
90
|
-
? calculatePercentageTotal(item.label) !== 100
|
91
|
-
: false
|
92
|
-
"
|
93
76
|
:is-read-only="true"
|
77
|
+
:number-precision="2"
|
94
78
|
:min-decimals="0"
|
95
|
-
:number-precision="0"
|
96
79
|
text-align="center"
|
97
|
-
:value="
|
80
|
+
:value="calculateTotal(item.label)"
|
98
81
|
/>
|
99
82
|
</InputGroup>
|
100
83
|
</TotalInputRow>
|
@@ -105,20 +88,17 @@
|
|
105
88
|
<InputRow>
|
106
89
|
<InputGroup
|
107
90
|
v-for="(item, index) in props.data"
|
108
|
-
:key="index"
|
109
91
|
:bar-width="barWidth"
|
110
92
|
:is-scrollable="isScrollable"
|
93
|
+
:key="index"
|
111
94
|
>
|
112
95
|
<InputNumber
|
113
|
-
:allow-negative="false"
|
114
|
-
:disabled="isInputsDisabled"
|
115
96
|
input-height="36px"
|
116
|
-
:is-disabled-styled-only="true"
|
117
97
|
:min-decimals="0"
|
118
|
-
:number-precision="
|
98
|
+
:number-precision="2"
|
119
99
|
text-align="center"
|
120
100
|
:value="item.value"
|
121
|
-
@input-blur="handleInputBlur($event, null, item.label
|
101
|
+
@input-blur="handleInputBlur($event, null, item.label)"
|
122
102
|
@input-focus="handleInputFocus(null, item.label)"
|
123
103
|
/>
|
124
104
|
</InputGroup>
|
@@ -127,22 +107,11 @@
|
|
127
107
|
</FieldsWrapper>
|
128
108
|
</FieldsContainer>
|
129
109
|
</Container>
|
130
|
-
<InfoCardContainer
|
131
|
-
v-if="hasAnySegmentNotTotatTo100Percent && fieldMode === 'percentage'"
|
132
|
-
:yAxisWidth="yAxisWidth"
|
133
|
-
>
|
134
|
-
<InfoCard align-items="center" type="info">
|
135
|
-
<InfoCardBody>
|
136
|
-
{{ percentageErrorMessage }}
|
137
|
-
</InfoCardBody>
|
138
|
-
</InfoCard>
|
139
|
-
</InfoCardContainer>
|
140
110
|
</template>
|
141
111
|
|
142
112
|
<script setup>
|
143
|
-
import { ref
|
113
|
+
import { ref } from 'vue'
|
144
114
|
import InputNumber from '../inputs/inputNumber'
|
145
|
-
import InfoCard from '../infoCard'
|
146
115
|
|
147
116
|
import {
|
148
117
|
Container,
|
@@ -154,8 +123,6 @@
|
|
154
123
|
InputRow,
|
155
124
|
TotalInputRow,
|
156
125
|
InputGroup,
|
157
|
-
InfoCardContainer,
|
158
|
-
InfoCardBody,
|
159
126
|
} from './styles/bottomFields'
|
160
127
|
|
161
128
|
const props = defineProps({
|
@@ -192,51 +159,6 @@
|
|
192
159
|
default: 'absolute',
|
193
160
|
validator: (value) => ['absolute', 'percentage'].includes(value),
|
194
161
|
},
|
195
|
-
isInputsDisabled: {
|
196
|
-
type: Boolean,
|
197
|
-
default: false,
|
198
|
-
},
|
199
|
-
percentageErrorMessage: {
|
200
|
-
type: String,
|
201
|
-
default: '',
|
202
|
-
},
|
203
|
-
})
|
204
|
-
|
205
|
-
const seriesData = ref([])
|
206
|
-
|
207
|
-
watchEffect(() => {
|
208
|
-
let isNewSetOfSeries = false
|
209
|
-
const seriesDataCopy = [...seriesData.value]
|
210
|
-
if (
|
211
|
-
!seriesDataCopy.length ||
|
212
|
-
!props.series.length ||
|
213
|
-
seriesDataCopy.length !== props.series.length ||
|
214
|
-
!seriesDataCopy.some((item) => {
|
215
|
-
return props.series.map((s) => s.name).includes(item.name)
|
216
|
-
})
|
217
|
-
) {
|
218
|
-
isNewSetOfSeries = true
|
219
|
-
}
|
220
|
-
const currentSeriesData = !isNewSetOfSeries ? seriesDataCopy : []
|
221
|
-
const newSeriesData = []
|
222
|
-
|
223
|
-
props.series.forEach((item, itemIndex) => {
|
224
|
-
const data = item.data.map((d, dIndex) => ({
|
225
|
-
label: d.label,
|
226
|
-
value: d.value,
|
227
|
-
percentage: d.percentage,
|
228
|
-
originalValue: currentSeriesData.length
|
229
|
-
? currentSeriesData[itemIndex].data[dIndex].originalValue
|
230
|
-
: d.value,
|
231
|
-
}))
|
232
|
-
|
233
|
-
newSeriesData.push({
|
234
|
-
name: item.name,
|
235
|
-
data,
|
236
|
-
})
|
237
|
-
})
|
238
|
-
|
239
|
-
seriesData.value = [...newSeriesData]
|
240
162
|
})
|
241
163
|
|
242
164
|
const emit = defineEmits([
|
@@ -253,13 +175,11 @@
|
|
253
175
|
emit('input-focus', { seriesName, label })
|
254
176
|
}
|
255
177
|
|
256
|
-
const
|
257
|
-
|
178
|
+
const calculateTotal = (label) => {
|
179
|
+
return props.series.reduce((sum, series) => {
|
258
180
|
const value = series.data.find((d) => d.label === label)?.value || 0
|
259
181
|
return sum + value
|
260
182
|
}, 0)
|
261
|
-
|
262
|
-
return Math.round(total)
|
263
183
|
}
|
264
184
|
|
265
185
|
const syncScroll = (scrollLeft) => {
|
@@ -270,38 +190,34 @@
|
|
270
190
|
container.scrollLeft = scrollLeft
|
271
191
|
}
|
272
192
|
}
|
273
|
-
|
274
|
-
const getDisplayValue = (data, label, shouldRound = true) => {
|
193
|
+
const getDisplayValue = (seriesData, label) => {
|
275
194
|
if (props.fieldMode === 'absolute') {
|
276
|
-
return
|
195
|
+
return seriesData.find((d) => d.label === label)?.value || ''
|
277
196
|
}
|
278
197
|
|
279
|
-
|
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
|
280
201
|
}
|
281
202
|
|
282
203
|
const calculatePercentageTotal = (label) => {
|
283
|
-
|
284
|
-
const
|
285
|
-
|
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
|
286
208
|
return sum + percentage
|
287
209
|
}, 0)
|
288
|
-
|
289
|
-
return Math.round(percentageTotal)
|
290
210
|
}
|
291
211
|
|
292
212
|
const handleInputBlur = (_value, seriesName, label) => {
|
293
|
-
if (props.isInputsDisabled) {
|
294
|
-
return
|
295
|
-
}
|
296
213
|
let value = Number(_value)
|
297
214
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
: { 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 }
|
305
221
|
emit('input-blur', payload)
|
306
222
|
focusedInput.value = null
|
307
223
|
|
@@ -327,12 +243,6 @@
|
|
327
243
|
}
|
328
244
|
}
|
329
245
|
|
330
|
-
const hasAnySegmentNotTotatTo100Percent = computed(() => {
|
331
|
-
return props.data.some((d) => {
|
332
|
-
return calculatePercentageTotal(d.label) !== 100
|
333
|
-
})
|
334
|
-
})
|
335
|
-
|
336
246
|
const handleFieldsScroll = (event) => {
|
337
247
|
emit('sync-scroll', event.target.scrollLeft)
|
338
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,7 +17,7 @@
|
|
17
17
|
/>
|
18
18
|
</ChartControlsWrapper>
|
19
19
|
<GraphSection :height="height" :width="width">
|
20
|
-
<YAxis :
|
20
|
+
<YAxis :width="yAxisWidth" :height="height">
|
21
21
|
<YAxisTitleWrapper v-if="yAxisTitle" :height="yAxisHeight">
|
22
22
|
{{ yAxisTitle }}
|
23
23
|
</YAxisTitleWrapper>
|
@@ -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,9 +159,7 @@
|
|
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
|
-
:percentage-error-message="percentageErrorMessage"
|
169
163
|
:series="series"
|
170
164
|
:y-axis-width="yAxisWidth"
|
171
165
|
@input-blur="handleInputBlur"
|
@@ -177,13 +171,12 @@
|
|
177
171
|
</template>
|
178
172
|
|
179
173
|
<script setup>
|
180
|
-
import { useSlots, computed
|
174
|
+
import { useSlots, computed } from 'vue'
|
181
175
|
|
182
176
|
import ChartControls from './ChartControls'
|
183
177
|
import BottomFields from './BottomFields'
|
184
178
|
import SelectionBox from './SelectionBox'
|
185
179
|
import Spinner from '../spinner'
|
186
|
-
import { numberToString } from '../../helpers/numberConverter'
|
187
180
|
|
188
181
|
import {
|
189
182
|
useTooltip,
|
@@ -253,6 +246,10 @@
|
|
253
246
|
type: String,
|
254
247
|
default: '',
|
255
248
|
},
|
249
|
+
valueFormatter: {
|
250
|
+
type: Function,
|
251
|
+
default: null,
|
252
|
+
},
|
256
253
|
isLegendShown: {
|
257
254
|
type: Boolean,
|
258
255
|
default: false,
|
@@ -299,14 +296,6 @@
|
|
299
296
|
type: Boolean,
|
300
297
|
default: false,
|
301
298
|
},
|
302
|
-
showPercentageOnTooltip: {
|
303
|
-
type: Boolean,
|
304
|
-
default: false,
|
305
|
-
},
|
306
|
-
percentageErrorMessage: {
|
307
|
-
type: String,
|
308
|
-
default: '',
|
309
|
-
},
|
310
299
|
})
|
311
300
|
|
312
301
|
const generateChartId = () =>
|
@@ -389,40 +378,8 @@
|
|
389
378
|
}
|
390
379
|
|
391
380
|
const handleValueFormatter = (value) => {
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
value: formattedValue,
|
396
|
-
numberPrecision: 0,
|
397
|
-
minDecimals: 0,
|
398
|
-
})
|
399
|
-
} else if (value < 1000000) {
|
400
|
-
formattedValue = numberToString({
|
401
|
-
value: Number(formattedValue / 1000),
|
402
|
-
numberPrecision: 2,
|
403
|
-
minDecimals: 2,
|
404
|
-
})
|
405
|
-
} else {
|
406
|
-
formattedValue = numberToString({
|
407
|
-
value: Number(formattedValue / 1000000),
|
408
|
-
numberPrecision: 2,
|
409
|
-
minDecimals: 2,
|
410
|
-
})
|
411
|
-
}
|
412
|
-
if (value < 1000) {
|
413
|
-
return `${formattedValue} kWh`
|
414
|
-
} else if (value < 1000000) {
|
415
|
-
return `${formattedValue} MWh`
|
416
|
-
} else {
|
417
|
-
return `${formattedValue} GWh`
|
418
|
-
}
|
419
|
-
}
|
420
|
-
|
421
|
-
const getYAxisLabel = (label) => {
|
422
|
-
return numberToString({
|
423
|
-
value: label,
|
424
|
-
numberPrecision: 0,
|
425
|
-
minDecimals: 0,
|
426
|
-
})
|
381
|
+
return props.valueFormatter
|
382
|
+
? props.valueFormatter(Math.round(value))
|
383
|
+
: value
|
427
384
|
}
|
428
385
|
</script>
|