@eturnity/eturnity_reusable_components 8.19.8-EPDM-14690.4 → 8.19.8-EPDM-11600.11
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/svgIcons/erase.svg +2 -3
- package/src/assets/theme.js +1 -79
- 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 +28 -56
- package/src/components/barchart/styles/bottomFields.js +4 -18
- package/src/components/barchart/styles/chart.js +21 -15
- 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/InputNumber.stories.js +5 -5
- package/src/components/inputs/inputNumber/index.vue +11 -92
- package/src/components/pageSubtitle/index.vue +7 -1
- 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 {
|
@@ -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.purple[
|
336
|
+
backgroundColor: semanticColors.purple[50],
|
337
337
|
textColor: semanticColors.purple[600],
|
338
338
|
borderColor: semanticColors.grey[600],
|
339
339
|
},
|
@@ -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()
|