88 dataLabel ,
99 error ,
1010 getMissingDatasetAttributes ,
11+ isFunction ,
1112 objectIsEmpty ,
1213 palette ,
1314 setOpacity ,
@@ -20,6 +21,7 @@ import { useNestedProp } from "../useNestedProp";
2021import Skeleton from " ./vue-ui-skeleton.vue" ;
2122import { useConfig } from " ../useConfig" ;
2223import PackageVersion from " ../atoms/PackageVersion.vue" ;
24+ import Tooltip from " ../atoms/Tooltip.vue" ;
2325
2426const { vue_ui_sparkstackbar: DEFAULT_CONFIG } = useConfig ()
2527
@@ -42,7 +44,10 @@ const isDataset = computed(() => {
4244 return !! props .dataset && props .dataset .length ;
4345});
4446
47+ const sparkstackbarChart = ref (null );
4548const uid = ref (createUid ());
49+ const isTooltip = ref (false );
50+ const tooltipContent = ref (' ' );
4651
4752const FINAL_CONFIG = computed ({
4853 get : () => {
@@ -225,10 +230,62 @@ function selectDatapoint(datapoint, index) {
225230 emits (' selectDatapoint' , { datapoint, index })
226231}
227232
233+ const dataTooltipSlot = ref (null );
234+ const useCustomFormat = ref (false );
235+
236+ function useTooltip ({ datapoint, seriesIndex }) {
237+ dataTooltipSlot .value = { datapoint, seriesIndex, config: FINAL_CONFIG .value , series: absoluteDataset .value };
238+ isTooltip .value = true ;
239+ const customFormat = FINAL_CONFIG .value .style .tooltip .customFormat ;
240+
241+ if (isFunction (customFormat)) {
242+ try {
243+ const customFormatString = customFormat ({
244+ seriesIndex,
245+ datapoint,
246+ series: absoluteDataset .value ,
247+ config: FINAL_CONFIG .value
248+ });
249+ if (typeof customFormatString === ' string' ) {
250+ tooltipContent .value = customFormatString
251+ useCustomFormat .value = true ;
252+ }
253+ } catch (err) {
254+ console .warn (' Custom format cannot be applied.' );
255+ useCustomFormat .value = false ;
256+ }
257+ }
258+
259+ if (! useCustomFormat .value ) {
260+ let html = ' ' ;
261+ html += ` <div data-cy="donut-tooltip-name" style="width:100%;text-align:center;border-bottom:1px solid ${ FINAL_CONFIG .value .style .tooltip .borderColor } ;padding-bottom:6px;margin-bottom:3px;">${ datapoint .name } </div>` ;
262+ html += ` <div style="display:flex;flex-direction:row;gap:6px;align-items:center;"><svg viewBox="0 0 12 12" height="14" width="14"><circle data-cy="donut-tooltip-marker" cx="6" cy="6" r="6" stroke="none" fill="${ datapoint .color } "/></svg>` ;
263+
264+ html += ` <b>${ datapoint .proportionLabel } </b>` ;
265+
266+ html += ` <span>(${ applyDataLabel (
267+ FINAL_CONFIG .value .style .legend .value .formatter ,
268+ datapoint .value ,
269+ dataLabel ({
270+ p: FINAL_CONFIG .value .style .legend .value .prefix ,
271+ v: datapoint .value ,
272+ s: FINAL_CONFIG .value .style .legend .value .suffix ,
273+ r: FINAL_CONFIG .value .style .legend .value .rounding
274+ }),
275+ {
276+ datapoint,
277+ seriesIndex,
278+ }
279+ )} )</span>` ;
280+
281+ tooltipContent .value = ` <div>${ html} </div>` ;
282+ }
283+ }
284+
228285 </script >
229286
230287<template >
231- <div :style =" `width:100%; background:${FINAL_CONFIG.style.backgroundColor}`" >
288+ <div ref = " sparkstackbarChart " :style =" `width:100%; background:${FINAL_CONFIG.style.backgroundColor}`" >
232289 <!-- TITLE -->
233290 <div data-cy =" sparkstackbar-title-wrapper" v-if =" FINAL_CONFIG.style.title.text" :style =" `width:calc(100% - 12px);background:transparent;margin:0 auto;margin:${FINAL_CONFIG.style.title.margin};padding: 0 6px;text-align:${FINAL_CONFIG.style.title.textAlign}`" >
234291 <div data-cy =" sparkstackbar-title" :style =" `font-size:${FINAL_CONFIG.style.title.fontSize}px;color:${FINAL_CONFIG.style.title.color};font-weight:${FINAL_CONFIG.style.title.bold ? 'bold' : 'normal'}`" >
@@ -272,7 +329,6 @@ function selectDatapoint(datapoint, index) {
272329 />
273330 <rect
274331 v-for =" (rect, i) in drawableDataset" :key =" `stack_${i}`"
275- @click =" () => selectDatapoint(rect, i)"
276332 :x =" rect.start"
277333 :y =" 0"
278334 :width =" rect.width"
@@ -282,6 +338,20 @@ function selectDatapoint(datapoint, index) {
282338 stroke-linecap =" round"
283339 :class =" {'animated': !isLoading}"
284340 />
341+ <!-- TOOLTIP TRAPS -->
342+ <rect
343+ v-for =" (rect, i) in drawableDataset" :key =" `stack_${i}`"
344+ @click =" () => selectDatapoint(rect, i)"
345+ :x =" rect.start"
346+ :y =" 0"
347+ :width =" rect.width"
348+ :height =" svg.height"
349+ fill =" transparent"
350+ stroke =" none"
351+ :class =" {'animated': !isLoading}"
352+ @mouseenter =" () => useTooltip({ datapoint: rect, seriesIndex: i })"
353+ @mouseleave =" isTooltip = false"
354+ />
285355 </g >
286356 <rect v-else
287357 :x =" 2"
@@ -358,6 +428,30 @@ function selectDatapoint(datapoint, index) {
358428 </div >
359429 </div >
360430
431+ <Tooltip
432+ :show =" isTooltip && FINAL_CONFIG.style.tooltip.show"
433+ :parent =" sparkstackbarChart"
434+ :backgroundColor =" FINAL_CONFIG.style.backgroundColor"
435+ :color =" FINAL_CONFIG.style.color"
436+ :fontSize =" FINAL_CONFIG.style.tooltip.fontSize"
437+ :borderRadius =" FINAL_CONFIG.style.tooltip.borderRadius"
438+ :borderColor =" FINAL_CONFIG.style.tooltip.borderColor"
439+ :borderWidth =" FINAL_CONFIG.style.tooltip.borderWidth"
440+ :backgroundOpacity =" FINAL_CONFIG.style.tooltip.backgroundOpacity"
441+ :position =" FINAL_CONFIG.style.tooltip.position"
442+ :content =" tooltipContent"
443+ :isCustom =" useCustomFormat"
444+ :offsetY =" -124 + FINAL_CONFIG.style.tooltip.offsetY"
445+ :blockShiftY =" true"
446+ >
447+ <template #tooltip-before >
448+ <slot name =" tooltip-before" v-bind =" {...dataTooltipSlot}" ></slot >
449+ </template >
450+ <template #tooltip-after >
451+ <slot name =" tooltip-after" v-bind =" {...dataTooltipSlot}" ></slot >
452+ </template >
453+ </Tooltip >
454+
361455 <div v-if =" $slots.source" ref =" source" dir =" auto" >
362456 <slot name =" source" />
363457 </div >
0 commit comments