Client - display a marker on map when mouse is over the chart

This commit is contained in:
Sam
2021-09-26 11:21:09 +02:00
parent 2736368626
commit 279271af42
7 changed files with 77 additions and 11 deletions

View File

@ -23,7 +23,11 @@
{{ t('workouts.DURATION') }}
</label>
</div>
<LineChart v-bind="lineChartProps" class="line-chart" />
<LineChart
v-bind="lineChartProps"
class="line-chart"
@mouseleave="emitEmptyCoordinates"
/>
<div class="no-data-cleaning">
{{ t('workouts.NO_DATA_CLEANING') }}
</div>
@ -40,7 +44,11 @@
import Card from '@/components/Common/Card.vue'
import { IAuthUserProfile } from '@/types/user'
import { IWorkoutChartData, IWorkoutState } from '@/types/workouts'
import {
IWorkoutChartData,
IWorkoutState,
TCoordinates,
} from '@/types/workouts'
import { getDatasets } from '@/utils/workouts'
export default defineComponent({
@ -59,7 +67,8 @@
required: true,
},
},
setup(props) {
emits: ['getCoordinates'],
setup(props, { emit }) {
const { t } = useI18n()
let displayDistance = ref(true)
const datasets: ComputedRef<IWorkoutChartData> = computed(() =>
@ -76,6 +85,9 @@
])
),
}))
const coordinates: ComputedRef<TCoordinates[]> = computed(
() => datasets.value.coordinates
)
const options = computed<ChartOptions<'line'>>(() => ({
responsive: true,
animation: false,
@ -151,6 +163,9 @@
: label + ' km/h'
},
title: function (tooltipItems) {
if (tooltipItems.length > 0) {
emitCoordinates(coordinates.value[tooltipItems[0].dataIndex])
}
return tooltipItems.length === 0
? ''
: displayDistance.value
@ -168,6 +183,12 @@
function formatDuration(duration: string | number): string {
return new Date(+duration * 1000).toISOString().substr(11, 8)
}
function emitCoordinates(coordinates: TCoordinates) {
emit('getCoordinates', coordinates)
}
function emitEmptyCoordinates() {
emitCoordinates({ latitude: null, longitude: null })
}
const { lineChartProps } = useLineChart({
chartData,
@ -177,6 +198,7 @@
displayDistance,
lineChartProps,
t,
emitEmptyCoordinates,
updateDisplayDistance,
}
},

View File

@ -17,6 +17,10 @@
:bounds="bounds"
/>
<LGeoJson :geojson="geoJson.jsonData" />
<LMarker
v-if="markerCoordinates.latitude"
:lat-lng="[markerCoordinates.latitude, markerCoordinates.longitude]"
/>
</LMap>
</div>
<div v-else class="no-map">{{ t('workouts.NO_MAP') }}</div>
@ -25,13 +29,13 @@
<script lang="ts">
import { gpx } from '@tmcw/togeojson'
import { LGeoJson, LMap, LTileLayer } from '@vue-leaflet/vue-leaflet'
import { LGeoJson, LMap, LMarker, LTileLayer } from '@vue-leaflet/vue-leaflet'
import { ComputedRef, PropType, computed, defineComponent, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { ROOT_STORE } from '@/store/constants'
import { GeoJSONData } from '@/types/geojson'
import { IWorkoutState } from '@/types/workouts'
import { IWorkoutState, TCoordinates } from '@/types/workouts'
import { useStore } from '@/use/useStore'
import { getApiUrl } from '@/utils'
@ -40,12 +44,17 @@
components: {
LGeoJson,
LMap,
LMarker,
LTileLayer,
},
props: {
workout: {
type: Object as PropType<IWorkoutState>,
},
markerCoordinates: {
type: Object as PropType<TCoordinates>,
required: false,
},
},
setup(props) {
const { t } = useI18n()

View File

@ -53,7 +53,7 @@
</div>
</template>
<template #content>
<WorkoutMap :workout="workout" />
<WorkoutMap :workout="workout" :markerCoordinates="markerCoordinates" />
<WorkoutData :workout="workout.workout" />
</template>
</Card>
@ -71,7 +71,7 @@
import { WORKOUTS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports'
import { IAuthUserProfile } from '@/types/user'
import { IWorkoutState } from '@/types/workouts'
import { IWorkoutState, TCoordinates } from '@/types/workouts'
import { useStore } from '@/use/useStore'
import { formatWorkoutDate, getDateWithTZ } from '@/utils/dates'
@ -87,6 +87,10 @@
type: Object as PropType<IAuthUserProfile>,
required: true,
},
markerCoordinates: {
type: Object as PropType<TCoordinates>,
required: false,
},
sports: {
type: Object as PropType<ISport[]>,
},