Skip to content

Commit 89606fd

Browse files
committed
Improvement - VueUiGauge - Add segment name labels
1 parent 62eeeed commit 89606fd

File tree

1 file changed

+84
-2
lines changed

1 file changed

+84
-2
lines changed

src/components/vue-ui-gauge.vue

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
translateSize,
1717
offsetFromCenterPoint,
1818
XMLNS,
19+
calcMarkerOffsetX,
1920
} from "../lib.js";
2021
import { throttle } from "../canvas-lib";
2122
import themes from "../themes.json";
@@ -123,8 +124,8 @@ const mutableDataset = computed(() => {
123124
const arr = [];
124125
125126
(props.dataset.series || []).forEach(serie => {
126-
arr.push(serie.from || 0);
127-
arr.push(serie.to || 0);
127+
arr.push(serie.from || 0.0000001);
128+
arr.push(serie.to || 0.0000001);
128129
});
129130
const max = Math.max(...arr);
130131
return {
@@ -155,6 +156,7 @@ const svg = ref({
155156
pointerSize: FINAL_CONFIG.value.style.chart.layout.pointer.size,
156157
pointerStrokeWidth: FINAL_CONFIG.value.style.chart.layout.pointer.strokeWidth,
157158
markerOffset: FINAL_CONFIG.value.style.chart.layout.markers.offsetY + 3,
159+
segmentFontSize: FINAL_CONFIG.value.style.chart.layout.segmentNames.fontSize
158160
});
159161
160162
const max = ref(0);
@@ -283,6 +285,13 @@ function prepareChart() {
283285
threshold: 2,
284286
fallback: 2
285287
})
288+
svg.value.segmentFontSize = translateSize({
289+
relator: Math.min(width, height),
290+
adjuster: baseSize.value,
291+
source: FINAL_CONFIG.value.style.chart.layout.segmentNames.fontSize,
292+
threshold: 8,
293+
fallback: 8
294+
})
286295
});
287296
288297
resizeObserver.value = new ResizeObserver(handleResize);
@@ -352,6 +361,43 @@ const arcs = computed(() => {
352361
return donut;
353362
})
354363
364+
const labelArcs = computed(() => {
365+
const donut = makeDonut(
366+
{series: mutableDataset.value.series},
367+
svg.value.width / 2,
368+
arcSizeSource.value.base,
369+
arcSizeSource.value.arcs * FINAL_CONFIG.value.style.chart.layout.segmentNames.offsetRatio,
370+
arcSizeSource.value.arcs * FINAL_CONFIG.value.style.chart.layout.segmentNames.offsetRatio,
371+
1,
372+
1,
373+
1,
374+
180,
375+
109.9495,
376+
40 * svg.value.trackSize
377+
);
378+
return donut;
379+
});
380+
381+
const pathRadius = computed(() => arcSizeSource.value.arcs * FINAL_CONFIG.value.style.chart.layout.segmentNames.offsetRatio);
382+
383+
function calculateCumulativeHalfCircleOffsets(percentages) {
384+
const totalPercentage = percentages.reduce((sum, val) => sum + val, 0);
385+
if (totalPercentage > 100) {
386+
throw new Error("Total % must not exceed 100");
387+
}
388+
const halfCircleLength = 50;
389+
let cumulative = 0;
390+
return percentages.map(percentage => {
391+
cumulative += percentage;
392+
const offset = (cumulative / 100) * halfCircleLength;
393+
return `${offset - percentage / 4}%`;
394+
});
395+
}
396+
397+
const curveLabelOffsets = computed(() => {
398+
return calculateCumulativeHalfCircleOffsets(arcs.value.map(arc => arc.proportion * 100))
399+
})
400+
355401
const gradientArcs = computed(() => {
356402
const donut = makeDonut(
357403
{series: mutableDataset.value.series},
@@ -499,6 +545,42 @@ defineExpose({
499545
stroke-linecap="round"
500546
/>
501547

548+
<template v-if="FINAL_CONFIG.style.chart.layout.segmentNames.show && FINAL_CONFIG.style.chart.layout.segmentNames.curved">
549+
<!-- CIRCLE PATH AS BASE FOR CURVED LABELS -->
550+
<path
551+
:id="`curve_${uid}`"
552+
:d="`M ${pointer.x1},${pointer.y1} m -${pathRadius},0 a ${pathRadius},${pathRadius} 0 1,1 ${2 * pathRadius},0 a ${pathRadius},${pathRadius} 0 1,1 -${2 * pathRadius},0`" fill="transparent"
553+
/>
554+
555+
<!-- CURVED LABELS -->
556+
<text
557+
v-for="(arc, i) in arcs"
558+
:fill="FINAL_CONFIG.style.chart.layout.segmentNames.useSerieColor ? arc.color : FINAL_CONFIG.style.chart.layout.segmentNames.color"
559+
:font-size="svg.segmentFontSize"
560+
:font-weight="FINAL_CONFIG.style.chart.layout.segmentNames.bold ? 'bold' : 'normal'"
561+
text-anchor="middle"
562+
>
563+
<textPath :href="`#curve_${uid}`" :startOffset="curveLabelOffsets[i]">
564+
{{ arc.name || '' }}
565+
</textPath>
566+
</text>
567+
</template>
568+
569+
<template v-if="FINAL_CONFIG.style.chart.layout.segmentNames.show && !FINAL_CONFIG.style.chart.layout.segmentNames.curved">
570+
<text
571+
v-for="(arc, i) in labelArcs"
572+
:x="arc.center.endX"
573+
:y="arc.center.endY"
574+
:text-anchor="calcMarkerOffsetX(arc, false, 12).anchor"
575+
:fill="FINAL_CONFIG.style.chart.layout.segmentNames.useSerieColor ? arc.color : FINAL_CONFIG.style.chart.layout.segmentNames.color"
576+
:font-size="svg.segmentFontSize"
577+
:font-weight="FINAL_CONFIG.style.chart.layout.segmentNames.bold ? 'bold' : 'normal'"
578+
>
579+
{{ arc.name || '' }}
580+
</text>
581+
</template>
582+
583+
502584
<!-- ARC STEPS GRADIENTS-->
503585
<template v-if="FINAL_CONFIG.style.chart.layout.track.useGradient">
504586
<path

0 commit comments

Comments
 (0)