Skip to content

Commit 30ef8f3

Browse files
committed
VueUiHeatmap redesigned legend in bottom position
1 parent 9842ee0 commit 30ef8f3

File tree

5 files changed

+58
-49
lines changed

5 files changed

+58
-49
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

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

src/App.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2507,6 +2507,10 @@ const heatmapConfig = ref({
25072507
console.log({seriesIndex, datapoint, series, config});
25082508
return "TEST"
25092509
}
2510+
},
2511+
legend: {
2512+
show: true,
2513+
position: 'bottom'
25102514
}
25112515
}
25122516
})
@@ -3215,7 +3219,7 @@ function selectHistoDatapoint({ datapoint, index }) {
32153219
</template>
32163220
</Box>
32173221

3218-
<Box open @copy="copyConfig(PROD_CONFIG.vue_ui_scatter)">
3222+
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_scatter)">
32193223
<template #title>
32203224
<BaseIcon name="chartScatter" />
32213225
VueUiScatter
@@ -3822,7 +3826,7 @@ function selectHistoDatapoint({ datapoint, index }) {
38223826
</template>
38233827
</Box>
38243828

3825-
<Box @copy="copyConfig(PROD_CONFIG.vue_ui_heatmap)">
3829+
<Box open @copy="copyConfig(PROD_CONFIG.vue_ui_heatmap)">
38263830
<template #title>
38273831
<BaseIcon name="chartHeatmap"/>
38283832
VueUiHeatmap

src/components/vue-ui-heatmap.vue

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ const maxX = computed(() => {
8181
const svg = computed(() => {
8282
const height = heatmapConfig.value.style.layout.padding.top + heatmapConfig.value.style.layout.padding.bottom + (props.dataset.length * heatmapConfig.value.style.layout.cells.height) + (mutableConfig.value.inside ? 92 : 0);
8383
const width= heatmapConfig.value.style.layout.padding.left + heatmapConfig.value.style.layout.padding.right + ((maxX.value < props.dataset.length ? props.dataset.length : maxX.value) * heatmapConfig.value.style.layout.cells.height);
84+
const heightWithLegend = height + (heatmapConfig.value.style.legend.show ? (heatmapConfig.value.style.legend.position === 'right' ? 0 : ((heatmapConfig.value.style.layout.cells.height * 2))) : 0)
8485
8586
return {
8687
height,
88+
heightWithLegend,
8789
width
8890
}
8991
});
@@ -205,6 +207,10 @@ const sideLegendIndicatorY = computed(() => {
205207
return drawingArea.value.top + (sideLegendHeight.value * (1 - hoveredValue.value / maxValue.value))
206208
})
207209
210+
const bottomLegendIndicatorX = computed(() => {
211+
return drawingArea.value.left + ((svg.value.width - drawingArea.value.left - heatmapConfig.value.style.layout.padding.right) * (hoveredValue.value / maxValue.value))
212+
})
213+
208214
const __to__ = ref(null);
209215
210216
function showSpinnerPdf() {
@@ -337,7 +343,7 @@ defineExpose({
337343
/>
338344

339345
<!-- CHART -->
340-
<svg :class="{ 'vue-data-ui-fullscreen--on': isFullscreen, 'vue-data-ui-fulscreen--off': !isFullscreen }" :viewBox="`0 0 ${svg.width} ${svg.height}`" :style="`max-width:100%;overflow:visible;background:${heatmapConfig.style.backgroundColor};color:${heatmapConfig.style.color}`" >
346+
<svg :class="{ 'vue-data-ui-fullscreen--on': isFullscreen, 'vue-data-ui-fulscreen--off': !isFullscreen }" :viewBox="`0 0 ${svg.width} ${svg.heightWithLegend}`" :style="`max-width:100%;overflow:visible;background:${heatmapConfig.style.backgroundColor};color:${heatmapConfig.style.color}`" >
341347
<!-- TITLE AS G -->
342348
<g v-if="heatmapConfig.style.title.text && mutableConfig.inside && !isPrinting">
343349
<text
@@ -437,6 +443,7 @@ defineExpose({
437443
</text>
438444
</g>
439445

446+
<!-- LEGEND RIGHT -->
440447
<g v-if="heatmapConfig.style.legend.show && legendPosition === 'right'">
441448
<defs>
442449
<linearGradient id="colorScaleVertical" x2="0%" y2="100%" >
@@ -474,53 +481,44 @@ defineExpose({
474481
<path v-if="hoveredValue !== null" :fill="heatmapConfig.style.color" stroke="none" :d="`M ${drawingArea.right + 36},${sideLegendIndicatorY} ${drawingArea.right + 26},${sideLegendIndicatorY - 8} ${drawingArea.right + 26},${sideLegendIndicatorY + 8}z`" />
475482
</g>
476483

477-
<!-- LEGEND AS G -->
478-
<foreignObject
479-
v-if="heatmapConfig.style.legend.show && mutableConfig.inside && !isPrinting"
480-
:x="0"
481-
:y="svg.height / 2 + 150"
482-
width="100%"
483-
height="100"
484-
style="overflow:visible"
485-
>
486-
<div class="vue-ui-heatmap-legend" :style="`color:${heatmapConfig.style.legend.color};font-size:${heatmapConfig.style.legend.fontSize*2}px;padding-bottom:12px;font-weight:${heatmapConfig.style.legend.bold ? 'bold' : ''};display:flex; flex-direction:row;gap:3px;align-items:center;justify-content:center;font-weight:${heatmapConfig.style.legend.bold ? 'bold':'normal'}`" >
487-
<span data-cy="heatmap-legend-foreignObject-min" style="text-align:right">{{ Number(minValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}</span>
488-
<svg viewBox="0 0 120 12" style="width: 25%">
489-
<rect v-for="(_,i) in 12"
490-
:x="i * 12"
491-
:y="0"
492-
:height="12"
493-
:width="12"
494-
:fill="heatmapConfig.style.layout.cells.colors.underlayer"
495-
/>
496-
<rect v-for="(_,i) in 12"
497-
:x="i * 12"
498-
:y="0"
499-
:height="12"
500-
:width="12"
501-
:fill="i < 5 ? `${heatmapConfig.style.layout.cells.colors.cold}${opacity[Math.round((1-(i / 5)) * 100)]}` : `${heatmapConfig.style.layout.cells.colors.hot}${opacity[Math.round((((i-5) / 5)) * 100)]}`"
502-
/>
503-
</svg>
504-
<span data-cy="heatmap-legend-foreignObject-max" style="text-align:left">{{ Number(maxValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}</span>
505-
</div>
506-
</foreignObject>
507-
<slot name="svg" :svg="svg"/>
508-
</svg>
509-
510-
<!-- LEGEND AS DIV -->
511-
<div v-if="heatmapConfig.style.legend.show && heatmapConfig.style.legend.position === 'bottom' && (!mutableConfig.inside || isPrinting)" class="vue-ui-heatmap-legend" :style="`background:${heatmapConfig.style.legend.backgroundColor};color:${heatmapConfig.style.legend.color};font-size:${heatmapConfig.style.legend.fontSize}px;padding-bottom:12px;font-weight:${heatmapConfig.style.legend.bold ? 'bold' : ''};display:flex; flex-direction:row;gap:3px;align-items:center;justify-content:center;font-weight:${heatmapConfig.style.legend.bold ? 'bold':'normal'}`" >
512-
<span data-cy="heatmap-legend-min" style="text-align:right">{{ Number(minValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}</span>
513-
<svg viewBox="0 0 132 12" style="width: 300px">
484+
<!-- LEGEND BOTTOM -->
485+
<g v-if="heatmapConfig.style.legend.show && legendPosition === 'bottom'">
514486
<defs>
515-
<linearGradient id="colorScale" x1="0%" y1="0%" x2="100%" y2="0%" >
487+
<linearGradient id="colorScaleHorizontal" x1="0%" x2="100%" y1="0%" y2="0%">
516488
<stop offset="0%" :stop-color="heatmapConfig.style.layout.cells.colors.cold"/>
517489
<stop offset="100%" :stop-color="heatmapConfig.style.layout.cells.colors.hot"/>
518490
</linearGradient>
519491
</defs>
520-
<rect x="0" y="0" height="12" width="132" fill="url(#colorScale)"/>
521-
</svg>
522-
<span data-cy="heatmap-legend-max" style="text-align:left">{{ Number(maxValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}</span>
523-
</div>
492+
<rect
493+
:x="drawingArea.left"
494+
:y="drawingArea.bottom + heatmapConfig.style.layout.cells.height"
495+
:width="svg.width - drawingArea.left - heatmapConfig.style.layout.padding.right"
496+
:height="heatmapConfig.style.layout.cells.height"
497+
:rx="heatmapConfig.style.layout.cells.height / 2"
498+
fill="url(#colorScaleHorizontal)"
499+
/>
500+
<text
501+
:x="drawingArea.left"
502+
:y="drawingArea.bottom + heatmapConfig.style.layout.cells.height * 2 + heatmapConfig.style.legend.fontSize * 2"
503+
text-anchor="start"
504+
:font-size="heatmapConfig.style.legend.fontSize * 2"
505+
>
506+
{{ Number(minValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}
507+
</text>
508+
<text
509+
:x="drawingArea.right"
510+
:y="drawingArea.bottom + heatmapConfig.style.layout.cells.height * 2 + heatmapConfig.style.legend.fontSize * 2"
511+
text-anchor="end"
512+
:font-size="heatmapConfig.style.legend.fontSize * 2"
513+
>
514+
{{ Number(maxValue.toFixed(heatmapConfig.style.legend.roundingValue)).toLocaleString() }}
515+
</text>
516+
<line v-if="hoveredValue !== null" :stroke="heatmapConfig.style.backgroundColor" stroke-width="2" :x1="bottomLegendIndicatorX" :x2="bottomLegendIndicatorX" :y1="drawingArea.bottom + heatmapConfig.style.layout.cells.height" :y2="drawingArea.bottom + heatmapConfig.style.layout.cells.height * 2" />
517+
<path v-if="hoveredValue !== null" :fill="heatmapConfig.style.color" stroke="none" :d="`M ${bottomLegendIndicatorX},${drawingArea.bottom + heatmapConfig.style.layout.cells.height} ${bottomLegendIndicatorX - 12},${drawingArea.bottom + heatmapConfig.style.layout.cells.height - 20} ${bottomLegendIndicatorX + 12},${drawingArea.bottom + heatmapConfig.style.layout.cells.height - 20}z`" />
518+
</g>
519+
520+
<slot name="svg" :svg="svg"/>
521+
</svg>
524522

525523
<!-- TOOLTIP -->
526524
<Tooltip

src/lib.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,13 @@ export function dataLabel({ p = '', v, s = '', r = 0, space = false }) {
929929
return `${p ?? ''}${space ? ' ' : ''}${[undefined, null].includes(v) ? '-' : Number(Number(v).toFixed(r).toLocaleString())}${space ? ' ' : ''}${s ?? ''}`
930930
}
931931

932+
/**
933+
* @typedef Abbreviation
934+
* @type {object}
935+
* @property {(number|string)} source - The string to abbreviate
936+
* @property {number=} length - The size of the abbreviation
937+
* @type {Abbreviation}
938+
*/
932939
export function abbreviate({ source, length = 3 }) {
933940
if (!source && source !== 0) {
934941
return ''

0 commit comments

Comments
 (0)