Skip to content

Commit 8f05a50

Browse files
committed
VueUi -Quadrant -Onion -Waffle -Xy -Radar improvements
1 parent 5a20ea9 commit 8f05a50

12 files changed

+212
-52
lines changed

package-lock.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-data-ui",
33
"private": false,
4-
"version": "1.9.16",
4+
"version": "1.9.17",
55
"type": "module",
66
"description": "A user-empowering data visualization Vue components library",
77
"keywords": [

src/App.vue

+8-5
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@ const dataset2 = ref([
6161
useArea: true,
6262
useProgression: true,
6363
dataLabels: false,
64+
shape: "hexagon"
6465
},
6566
{
6667
name: "Series 3",
6768
series: [ 64, 60, 52, 42, 30, 16, 0, -18, -38, -46, -50, -46, -38, -18, 0, 16, 30, 42, 52, 60, 64],
6869
type: "plot",
69-
color: "rgb(255,100,0)"
70+
color: "rgb(255,100,0)",
71+
shape: "star"
7072
},
7173
{
7274
name: "Series 4",
@@ -75,7 +77,8 @@ const dataset2 = ref([
7577
smooth: true,
7678
useArea: false,
7779
dataLabels: false,
78-
color: "rgb(200,200,50)"
80+
color: "rgb(200,200,50)",
81+
shape: "pentagon"
7982
},
8083
{
8184
name: "Target",
@@ -3656,7 +3659,7 @@ function copyConfig(c) {
36563659
<RadarTest
36573660
ref="radartest"
36583661
:dataset="radarDataset"
3659-
:config="{useCssAnimation: false, style: { chart: { title: { text: 'Title', subtitle: { text: 'Subtitle'}}}}}"
3662+
:config="{...radarConfig, useCssAnimation: false, style: { chart: { title: { text: 'Title', subtitle: { text: 'Subtitle'}}}}}"
36603663
@selectLegend="selectRadarLegend"
36613664
/>
36623665
</template>
@@ -3865,15 +3868,15 @@ function copyConfig(c) {
38653868
<WaffleTest
38663869
ref="waffletest"
38673870
:dataset="donutDataset"
3868-
:config="{style:{chart:{title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
3871+
:config="{useBlurOnHover: true, style:{chart:{title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
38693872
@selectLegend="selectLegendWaffle"
38703873
/>
38713874
</template>
38723875
<template #prod>
38733876
<VueUiWaffle
38743877
ref="waffletest"
38753878
:dataset="donutDataset"
3876-
:config="{style:{chart:{title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
3879+
:config="{useBlurOnHover: true, style:{chart:{title:{text:'Title',subtitle:{text:'Subtitle'}}}}}"
38773880
@selectLegend="selectLegendWaffle"
38783881
/>
38793882
</template>

src/atoms/Tooltip.vue

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const position = computed(() => {
5050
>
5151
<slot/>
5252
<div v-html="content"/>
53+
<slot name="content-after"/>
5354
</div>
5455
</template>
5556

src/components/vue-ui-onion.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,14 @@ defineExpose({
376376

377377
<!-- LABELS -->
378378
<g v-if="onionConfig.style.chart.layout.labels.show">
379-
<g v-for="onion in mutableDataset">
379+
<g v-for="(onion, i) in mutableDataset">
380380
<text
381381
v-if="!segregated.includes(onion.id)"
382382
:x="svg.width / 2 - onionSkin.gutter * 0.8 + onionConfig.style.chart.layout.labels.offsetX"
383383
:y="onion.labelY"
384384
text-anchor="end"
385385
:font-size="onionConfig.style.chart.layout.labels.fontSize"
386-
:fill="onionConfig.style.chart.layout.labels.color"
386+
:fill="onionConfig.useBlurOnHover && ![null, undefined].includes(selectedSerie) && selectedSerie === i ? onion.color: onionConfig.style.chart.layout.labels.color"
387387
:font-weight="onionConfig.style.chart.layout.labels.bold ? 'bold' : 'normal'"
388388
>
389389
{{ onion.name }} {{ onionConfig.style.chart.layout.labels.percentage.show ? ` : ${onion.percentage.toFixed(onionConfig.style.chart.layout.labels.roundingPercentage)}%` : '' }} {{ !onionConfig.style.chart.layout.labels.percentage.show && onionConfig.style.chart.layout.labels.value.show ? ` : ${onion.value ? `${onion.prefix || ""}${onion.value.toFixed(onionConfig.style.chart.layout.labels.roundingValue)}${onion.suffix || ""}` : '' }` : `${onionConfig.style.chart.layout.labels.value.show ? onion.value ? `(${onion.prefix || ""}${onion.value.toFixed(onionConfig.style.chart.layout.labels.roundingValue)}${onion.suffix || ""})` : '' : ''}` }}

src/components/vue-ui-quadrant.vue

+28-10
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,17 @@ const table = computed(() => {
305305
306306
const body = tableData.map(td => {
307307
return [td.category, td.name, td.x, td.y, td.sideName || td.quadrantSide]
308-
});
308+
});
309309
310-
return { head, body };
310+
const itsShapes = tableData.map(td => {
311+
return {
312+
shape: td.shape,
313+
color: td.color
314+
}
315+
});
316+
console.log({itsShapes});
317+
;
318+
return { head, body, itsShapes };
311319
});
312320
313321
const legend = computed(() => {
@@ -797,12 +805,12 @@ defineExpose({
797805
>
798806
<div class="vue-ui-quadrant-legend" :style="`font-weight:${quadrantConfig.style.chart.legend.bold ? 'bold' : ''};color:${quadrantConfig.style.chart.legend.color};font-size:${quadrantConfig.style.chart.legend.fontSize}px;padding-bottom:12px;font-weight:${quadrantConfig.style.chart.legend.bold ? 'bold' : ''};height: 100%;width:100%;display: flex;align-items:center;flex-wrap: wrap;justify-content:center;column-gap: 18px;`" >
799807
<div v-for="(legendItem, i) in legend" :data-cy="`quadrant-foreignObject-legend-item-${i}`" class="vue-ui-quadrant-legend-item" @click="segregate(legendItem.id)" :style="`opacity:${segregated.includes(legendItem.id) ? 0.5 : 1};display: flex;align-items:center;justify-content: center;gap: 6px;cursor: pointer;height: 24px;`">
800-
<svg height="12" width="12" viewBox="0 0 20 20">
808+
<svg height="14" width="14" viewBox="0 0 20 20">
801809
<Shape
802810
:plot="{ x: 10, y: 10}"
803811
:shape="legendItem.shape"
804812
:color="legendItem.color"
805-
:radius="9"
813+
:radius="8"
806814
:stroke="quadrantConfig.style.chart.layout.plots.outline ? quadrantConfig.style.chart.layout.plots.outlineColor : 'none'"
807815
:strokeWidth="quadrantConfig.style.chart.layout.plots.outlineWidth"
808816
/>
@@ -817,12 +825,12 @@ defineExpose({
817825
<!-- LEGEND AS DIV -->
818826
<div v-if="quadrantConfig.style.chart.legend.show && (!mutableConfig.inside || isPrinting)" class="vue-ui-quadrant-legend" :style="`font-weight:${quadrantConfig.style.chart.legend.bold ? 'bold' : ''};background:${quadrantConfig.style.chart.legend.backgroundColor};color:${quadrantConfig.style.chart.legend.color};font-size:${quadrantConfig.style.chart.legend.fontSize}px;padding-bottom:12px;font-weight:${quadrantConfig.style.chart.legend.bold ? 'bold' : ''}`" >
819827
<div v-for="(legendItem, i) in legend" :data-cy="`quadrant-div-legend-item-${i}`" class="vue-ui-quadrant-legend-item" @click="segregate(legendItem.id)" :style="`opacity:${segregated.includes(legendItem.id) ? 0.5 : 1}`">
820-
<svg height="12" width="12" viewBox="0 0 20 20">
828+
<svg height="14" width="14" viewBox="0 0 20 20">
821829
<Shape
822830
:plot="{ x: 10, y: 10}"
823831
:shape="legendItem.shape"
824832
:color="legendItem.color"
825-
:radius="9"
833+
:radius="8"
826834
:stroke="quadrantConfig.style.chart.layout.plots.outline ? quadrantConfig.style.chart.layout.plots.outlineColor : 'none'"
827835
:strokeWidth="quadrantConfig.style.chart.layout.plots.outlineWidth"
828836
/>
@@ -839,12 +847,12 @@ defineExpose({
839847
:parent="quadrantChart"
840848
:content="tooltipContent"
841849
>
842-
<svg height="12" width="12" viewBox="0 0 20 20">
850+
<svg height="14" width="14" viewBox="0 0 20 20">
843851
<Shape
844852
:plot="{ x: 10, y: 10 }"
845853
:shape="hoveredPlot.shape"
846854
:color="hoveredPlot.color"
847-
:radius="9"
855+
:radius="8"
848856
:stroke="quadrantConfig.style.chart.layout.plots.outline ? quadrantConfig.style.chart.layout.plots.outlineColor : 'none'"
849857
:stroke-width="quadrantConfig.style.chart.layout.plots.outlineWidth"
850858
/>
@@ -872,8 +880,18 @@ defineExpose({
872880
</tr>
873881
</thead>
874882
<tbody>
875-
<tr v-for="tr in table.body">
876-
<td v-for="td in tr" :style="`background:${quadrantConfig.table.td.backgroundColor};color:${quadrantConfig.table.td.color};outline:${quadrantConfig.table.td.outline}`">
883+
<tr v-for="(tr, i) in table.body">
884+
<td v-for="(td, j) in tr" :style="`background:${quadrantConfig.table.td.backgroundColor};color:${quadrantConfig.table.td.color};outline:${quadrantConfig.table.td.outline}`">
885+
<svg v-if="j === 0" height="14" width="14" viewBox="0 0 20 20">
886+
<Shape
887+
:plot="{ x: 10, y: 10 }"
888+
:color="table.itsShapes[i].color"
889+
:shape="table.itsShapes[i].shape"
890+
:radius="8"
891+
:stroke="quadrantConfig.style.chart.layout.plots.outline ? quadrantConfig.style.chart.layout.plots.outlineColor : 'none'"
892+
:strokeWidth="quadrantConfig.style.chart.layout.plots.outlineWidth"
893+
/>
894+
</svg>
877895
{{ isNaN(td) ? td : td.toFixed(quadrantConfig.table.td.roundingValue) }}
878896
</td>
879897
</tr>

src/components/vue-ui-radar.vue

+36-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useNestedProp } from "../useNestedProp";
88
import Title from "../atoms/Title.vue";
99
import UserOptions from "../atoms/UserOptions.vue";
1010
import Tooltip from "../atoms/Tooltip.vue";
11+
import SparkBar from "./vue-ui-sparkbar.vue";
1112
1213
const props = defineProps({
1314
config: {
@@ -50,6 +51,24 @@ const mutableConfig = ref({
5051
showTable: radarConfig.value.table.show
5152
});
5253
54+
const sparkBarConfig = computed(() => {
55+
return {
56+
style: {
57+
backgroundColor: radarConfig.value.style.chart.tooltip.backgroundColor,
58+
labels: {
59+
fontSize: radarConfig.value.style.chart.tooltip.fontSize,
60+
name: {
61+
color: radarConfig.value.style.chart.tooltip.color
62+
},
63+
},
64+
gutter: {
65+
backgroundColor: '#CCCCCC',
66+
opacity: 30
67+
}
68+
}
69+
}
70+
})
71+
5372
const svg = computed(() => {
5473
const height = mutableConfig.value.inside ? 412 : 312;
5574
return {
@@ -216,15 +235,24 @@ const table = computed(() => {
216235
});
217236
218237
const selectedIndex = ref(null);
238+
const sparkBarData = ref([]);
219239
220240
function useTooltip(apex, i) {
241+
sparkBarData.value = [];
221242
selectedIndex.value = i;
222243
isTooltip.value = true;
223244
let html = "";
224245
html += `<div style="width:100%;text-align:center;border-bottom:1px solid #ccc;padding-bottom:6px;margin-bottom:3px;">${apex.name}</div>`;
225246
for(let k = 0; k < apex.values.length; k += 1) {
226247
if(!segregated.value.includes(k)) {
227-
html += `<div style="display:flex;flex-wrap:wrap;align-items:center;gap:6px"><svg viewBox="0 0 12 12" height="14" width="14"><circle cx="6" cy="6" r="6" stroke="none" fill="${datasetCopy.value[k].color}" /></svg><span>${datasetCopy.value[k].name}</span> : ${radarConfig.value.style.chart.tooltip.showValue ? `<span>${apex.values[k].toFixed(radarConfig.value.style.chart.tooltip.roundingValue)}</span>` : ''} ${!radarConfig.value.style.chart.tooltip.showValue && radarConfig.value.style.chart.tooltip.showPercentage ? `<span>${(apex.values[k] / apex.target * 100).toFixed(radarConfig.value.style.chart.tooltip.roundingPercentage)}%</span>` : radarConfig.value.style.chart.tooltip.showPercentage ? `<span>(${(apex.values[k] / apex.target * 100).toFixed(radarConfig.value.style.chart.tooltip.roundingPercentage)}%)</span>` : ''}</div>`
248+
sparkBarData.value.push({
249+
name: datasetCopy.value[k].name,
250+
value: apex.values[k] / apex.target * 100,
251+
color: datasetCopy.value[k].color,
252+
suffix: '%)',
253+
prefix: `${apex.values[k].toFixed(radarConfig.value.style.chart.tooltip.roundingValue)} (`,
254+
rounding: radarConfig.value.style.chart.tooltip.roundingPercentage
255+
})
228256
}
229257
}
230258
tooltipContent.value = html;
@@ -501,7 +529,13 @@ defineExpose({
501529
:color="radarConfig.style.chart.tooltip.color"
502530
:parent="radarChart"
503531
:content="tooltipContent"
504-
/>
532+
>
533+
<template #content-after>
534+
<div style="max-width: 200px;margin:0 auto">
535+
<SparkBar :dataset="sparkBarData" :config="sparkBarConfig"/>
536+
</div>
537+
</template>
538+
</Tooltip>
505539

506540
<!-- DATA TABLE -->
507541
<div class="vue-ui-radar-table" :style="`width:100%;margin-top:${mutableConfig.inside ? '48px' : ''}`" v-if="mutableConfig.showTable">

src/components/vue-ui-sparkbar.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup>
22
import { ref, computed } from "vue";
3-
import { treeShake, shiftHue, opacity, convertConfigColors, palette, convertColorToHex } from "../lib";
3+
import { shiftHue, opacity, palette, convertColorToHex } from "../lib";
44
import mainConfig from "../default_configs.json";
55
import { useNestedProp } from "../useNestedProp";
66
@@ -90,7 +90,7 @@ function ratioTo(val) {
9090
<stop offset="100%" :stop-color="bar.color"/>
9191
</linearGradient>
9292
</defs>
93-
<rect :height="svg.height" :width="svg.width" :x="0" :y="0" :fill="sparkbarConfig.style.gutter.backgroundColor" :rx="svg.height / 2" />
93+
<rect :height="svg.height" :width="svg.width" :x="0" :y="0" :fill="`${sparkbarConfig.style.gutter.backgroundColor}${opacity[sparkbarConfig.style.gutter.opacity]}`" :rx="svg.height / 2" />
9494
<rect :height="svg.height" :width="svg.width * ratioTo(bar.value)" :x="0" :y="0" :fill="sparkbarConfig.style.bar.gradient.underlayerColor" :rx="svg.height / 2" />
9595
<rect :height="svg.height" :width="svg.width * ratioTo(bar.value)" :x="0" :y="0" :fill="sparkbarConfig.style.bar.gradient.show ? `url(#sparkbar_gradient_${i}_${uid})` : bar.color" :rx="svg.height / 2" />
9696
</svg>

src/components/vue-ui-waffle.vue

+22-3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ const rectDimension = computed(() => {
6868
return ((drawingArea.value.width - (waffleConfig.value.style.chart.layout.grid.size * waffleConfig.value.style.chart.layout.grid.spaceBetween )) / waffleConfig.value.style.chart.layout.grid.size);
6969
});
7070
71+
const absoluteRectDimension = computed(() => {
72+
return ((drawingArea.value.width ) / waffleConfig.value.style.chart.layout.grid.size);
73+
})
74+
7175
function calculateProportions(numbers) {
7276
const totalSum = numbers.reduce((a, b) => a + b, 0);
7377
const proportions = numbers.map(num => Math.round((num / totalSum) * 100) / 100);
@@ -430,9 +434,7 @@ defineExpose({
430434
/>
431435
<rect
432436
v-for="(position, i) in positions"
433-
:data-cy="`waffle-rect-${i}`"
434-
@mouseover="useTooltip(i)"
435-
@mouseleave="isTooltip = false; selectedSerie = null"
437+
:class="{'vue-ui-waffle-blur': waffleConfig.useBlurOnHover && ![null, undefined].includes(selectedSerie) && rects[i].serieIndex !== selectedSerie}"
436438
:rx="waffleConfig.style.chart.layout.rect.rounded ? waffleConfig.style.chart.layout.rect.rounding : 0"
437439
:x="position.x"
438440
:y="position.y"
@@ -442,6 +444,18 @@ defineExpose({
442444
:stroke="waffleConfig.style.chart.layout.rect.stroke"
443445
:stroke-width="waffleConfig.style.chart.layout.rect.strokeWidth"
444446
/>
447+
<rect
448+
v-for="(position, i) in positions"
449+
:data-cy="`waffle-rect-${i}`"
450+
@mouseover="useTooltip(i)"
451+
@mouseleave="isTooltip = false; selectedSerie = null"
452+
:x="position.x"
453+
:y="position.y"
454+
:height="absoluteRectDimension"
455+
:width="absoluteRectDimension"
456+
fill="transparent"
457+
stroke="none"
458+
/>
445459

446460
<!-- LEGEND AS G -->
447461
<foreignObject
@@ -588,4 +602,9 @@ defineExpose({
588602
font-weight: 400;
589603
user-select: none;
590604
}
605+
606+
.vue-ui-waffle-blur {
607+
filter: blur(3px) opacity(50%) grayscale(100%);
608+
transition: all 0.15s ease-in-out;
609+
}
591610
</style>

0 commit comments

Comments
 (0)