Skip to content

Commit

Permalink
refactor: remove custom tooltip
Browse files Browse the repository at this point in the history
  • Loading branch information
pirhoo committed Jun 25, 2024
1 parent 638a64f commit aa691d3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 121 deletions.
101 changes: 23 additions & 78 deletions lib/datavisualisations/ColumnChart.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { ComponentPublicInstance, computed, defineComponent, PropType, ref, watch } from 'vue'
import { ComponentPublicInstance, computed, defineComponent, getCurrentInstance, PropType, ref, watch } from 'vue'
import { identity, iteratee, sortBy } from 'lodash'
import * as d3 from 'd3'
import { chartProps, getChartProps, useChart } from '@/composables/chart'
Expand Down Expand Up @@ -306,6 +306,9 @@ export default defineComponent({
.ticks(props.yAxisTicks)
})
const activeBar = computed((): ColumnBar => bars.value[shownTooltip.value] ?? null)
const activeBarId = computed((): string => columnUniqueId(shownTooltip.value))
function formatXDatum(d: any) {
return d3Formatter(d, props.xAxisTickFormat)
}
Expand Down Expand Up @@ -351,11 +354,10 @@ export default defineComponent({
.attr('x2', padded.value.width)
}
function barTooltipStyle(bar: { x: number; y: number; width: number }) {
const { x, y } = el?.value?.getBoundingClientRect() ?? new DOMRect()
const top = `${y + bar.y + margin.value.top}px`
const left = `${x + bar.x + bar.width / 2 + margin.value.left}px`
return { top, left }
function columnUniqueId(i: number) {
// @ts-ignore
const { uid } = getCurrentInstance()
return `column-${uid}-${i}`
}
function highlighted(datum: any): boolean {
Expand All @@ -369,6 +371,9 @@ export default defineComponent({
return {
el,
activeBar,
activeBarId,
columnUniqueId,
dataHasHighlights,
width,
height,
Expand All @@ -379,7 +384,6 @@ export default defineComponent({
bars,
select,
highlighted,
barTooltipStyle,
formatYDatum,
formatXDatum
}
Expand Down Expand Up @@ -437,34 +441,24 @@ export default defineComponent({
:height="bar.height"
:width="bar.width"
:y="bar.y"
:id="columnUniqueId(index)"
class="column-chart__columns__item__bar"
/>
</g>
</g>
</svg>
<teleport to="body">
<div v-if="!noTooltips" class="column-chart__tooltips">
<div v-for="(bar, index) in bars" :key="index">
<div :style="barTooltipStyle(bar)" class="column-chart__tooltips__item">
<transition name="fade">
<div
v-if="shownTooltip === index"
class="column-chart__tooltips__item__wrapper"
>
<slot name="tooltip" v-bind="bar">
<h6 class="column-chart__tooltips__item__wrapper__heading mb-0">
{{ formatXDatum(bar.datum[timeseriesKey]) }}
</h6>
<div class="column-chart__tooltips__item__wrapper__value">
{{ formatYDatum(bar.datum[seriesName]) }}
</div>
</slot>
</div>
</transition>
<template v-if="!noTooltips && activeBar">
<b-tooltip :target="activeBarId" teleport-to="body" manual :model-value="true" class="column-chart__tooltip">
<slot name="tooltip" v-bind="activeBar">
<h6 class="column-chart__tooltip__heading mb-0">
{{ formatXDatum(activeBar.datum[timeseriesKey]) }}
</h6>
<div class="column-chart__tooltip__value">
{{ formatYDatum(activeBar.datum[seriesName]) }}
</div>
</div>
</div>
</teleport>
</slot>
</b-tooltip>
</template>
</div>
</template>

Expand Down Expand Up @@ -519,54 +513,5 @@ export default defineComponent({
display: none;
}
}
&__tooltips {
pointer-events: none;
position: absolute;
top: 0;
left: 0;
&__item {
$tooltip-bg: $body-emphasis-color;
display: inline-flex;
text-align: center;
flex-direction: row;
align-items: flex-end;
justify-content: flex-start;
position: absolute;
transform: translate(-50%, -100%);
margin-top: -0.5 * $tooltip-arrow-width;
&__wrapper {
max-width: $tooltip-max-width;
background: rgba($tooltip-bg, $tooltip-opacity);
border-radius: $tooltip-border-radius;
color: $tooltip-color;
margin: 0;
padding: $tooltip-padding-y $tooltip-padding-x;
&.fade-enter-active,
&.fade-leave-active {
transition: $transition-fade;
}
&.fade-enter-from,
&.fade-leave-to {
opacity: 0;
}
&:after {
content: '';
border: ($tooltip-arrow-width * 0.5) solid transparent;
border-top-color: rgba($tooltip-bg, $tooltip-opacity);
transform: translateX(-50%);
position: absolute;
left: 50%;
top: 100%;
}
}
}
}
}
</style>
43 changes: 0 additions & 43 deletions tests/unit/datavisualisations/ColumnChart.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,49 +335,6 @@ describe('ColumnChart.vue', () => {
expect(height).toBe(wrapper.vm.padded.height / 2)
})

it('should have 3 tooltips, none visible', () => {
const tooltips = wrapper.findAll('.column-chart__tooltips__item')
console.log(wrapper.html())
expect(tooltips).toHaveLength(3)
const visibleTooltips = wrapper.findAll('.column-chart__tooltips__item__wrapper')
expect(visibleTooltips).toHaveLength(0)
})

it('should have one tooltip visible after the mouse overs a column', async () => {
await wrapper.findAll('.column-chart__columns__item').at(0).trigger('mouseover') // TODO fix me
await wrapper.vm.$nextTick()
const visibleTooltips = wrapper.findAll('.column-chart__tooltips__item__wrapper')
expect(visibleTooltips).toHaveLength(1)
})

it('should hide the tooltip after the mouse leaves a column', async () => {
const firstColumn = wrapper.findAll('.column-chart__columns__item').at(0)

await firstColumn.trigger('mouseover')
await wrapper.vm.$nextTick()
expect(wrapper.findAll('.column-chart__tooltips__item__wrapper')).toHaveLength(1)

await firstColumn.trigger('mouseleave')
await wrapper.vm.$nextTick()
expect(wrapper.findAll('.column-chart__tooltips__item__wrapper')).toHaveLength(0)
})

it('should position the first tooltip next to the first bar', () => {
const { element: firstTooltip } = wrapper.findAll('.column-chart__tooltips__item').at(0)
const x = wrapper.vm.bars[0].x + wrapper.vm.bars[0].width / 2 + wrapper.vm.margin.left
const y = wrapper.vm.bars[0].y + wrapper.vm.margin.top
expect(firstTooltip.style.left).toBe(`${x}px`)
expect(firstTooltip.style.top).toBe(`${y}px`)
})

it('should position the third tooltip before to the third bar', () => {
const { element: thirdTooltip } = wrapper.findAll('.column-chart__tooltips__item').at(2)
const x = wrapper.vm.bars[2].x + wrapper.vm.bars[2].width / 2 + wrapper.vm.margin.left
const y = wrapper.vm.bars[2].y + wrapper.vm.margin.top
expect(thirdTooltip.style.left).toBe(`${x}px`)
expect(thirdTooltip.style.top).toBe(`${y}px`)
})

it('should emit a "select" event when clicking on an item', async () => {
await wrapper.findAll('.column-chart__columns__item__bar').at(0).trigger('click')

Expand Down

0 comments on commit aa691d3

Please sign in to comment.