Added timeline with points shown on hover.
This commit is contained in:
parent
b7c6ae1f55
commit
a833d43586
7 changed files with 320 additions and 15 deletions
frontend/src/components
146
frontend/src/components/Timeline.vue
Normal file
146
frontend/src/components/Timeline.vue
Normal file
|
@ -0,0 +1,146 @@
|
|||
<template>
|
||||
<div class="timeline-container">
|
||||
<h1 v-if="loading">Loading...</h1>
|
||||
<h1 v-else-if="!points.length">No data to display</h1>
|
||||
<div class="timeline" v-else>
|
||||
<Line :data="graphData" :options="graphOptions" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {
|
||||
CategoryScale,
|
||||
Chart as ChartJS,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
TimeScale,
|
||||
Title,
|
||||
Tooltip,
|
||||
} from 'chart.js';
|
||||
|
||||
import { Line } from 'vue-chartjs';
|
||||
import 'chartjs-adapter-date-fns';
|
||||
|
||||
import GPSPoint from '../models/GPSPoint';
|
||||
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
TimeScale,
|
||||
Title,
|
||||
Tooltip,
|
||||
);
|
||||
|
||||
export default {
|
||||
emits: ['point-hover'],
|
||||
components: {
|
||||
Line,
|
||||
},
|
||||
|
||||
props: {
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
points: {
|
||||
type: Array as () => GPSPoint[],
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
graphData() {
|
||||
return {
|
||||
labels: this.points.map((point: GPSPoint) => point.timestamp),
|
||||
datasets: [
|
||||
{
|
||||
label: 'Altitude (m)',
|
||||
backgroundColor: '#7979f8',
|
||||
borderColor: '#5959a8',
|
||||
fill: false,
|
||||
data: this.points.map((point: GPSPoint) => point.altitude),
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
graphOptions() {
|
||||
return {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
elements: {
|
||||
point: {
|
||||
borderWidth: 1,
|
||||
hoverRadius: 4,
|
||||
hoverBorderWidth: 2,
|
||||
},
|
||||
line: {
|
||||
tension: 0.5,
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
}
|
||||
},
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
onHover: (_: MouseEvent, activeElements: any) => {
|
||||
if (activeElements.length) {
|
||||
const index = activeElements[0].index;
|
||||
const point = this.points[index];
|
||||
this.$emit('point-hover', point);
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
grid: {
|
||||
drawOnChartArea: true,
|
||||
drawTicks: true,
|
||||
},
|
||||
time: {
|
||||
tooltipFormat: 'MMM dd, HH:mm',
|
||||
unit: 'minute',
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Date'
|
||||
},
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Altitude (m)'
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.timeline-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.timeline {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
canvas {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue