dissertation/where_fi/visualise/frontend/src/components/Figure.vue
2025-02-22 15:13:08 +00:00

93 lines
2.4 KiB
Vue

<script setup lang="ts">
import * as Plotly from 'plotly.js-dist-min'
import { Figure, FigureData } from '../grpc/figure'
import { FigureServiceClient } from '../grpc/figure.client'
import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport'
import { host } from '../connect'
import { onMounted, ref } from 'vue'
import { onBeforeUnmount } from 'vue'
import { computed } from 'vue'
const { figure, paused = false } = defineProps<{ figure: Figure; paused?: boolean }>()
const cancel = ref<boolean>(false)
const data = ref<FigureData | null>(null)
const plotData = computed(() => {
if (data.value) {
switch (data.value.figure.oneofKind) {
case 'line':
return data.value.figure.line.lines.map((line) => ({
x: line.x.length == 0 ? undefined : line.x,
y: line.y,
type: 'scatter' as const,
name: line.label,
color: line.color ? line.color : undefined,
}))
case 'heatmap':
return []
/* data.value.figure.heatmap.lines.map((line) => {
return {
x: line.x,
y: line.y,
type: 'scatter',
name: line.label,
color: line.color,
}
})*/
}
}
return []
})
const layout = {
title: { text: figure.title },
xaxis: { title: { text: figure.xLabel } },
yaxis: { title: { text: figure.yLabel } },
}
function updateGraph() {
console.log('Updating graph with', plotData.value)
Plotly.newPlot(figure.uuid, plotData.value, layout, { responsive: true })
}
onMounted(async () => {
console.log('Mounted')
updateGraph()
const transport = new GrpcWebFetchTransport({ baseUrl: host })
const figureService = new FigureServiceClient(transport)
const stream = figureService.getFigureUpdate({ uuid: figure.uuid })
for await (const response of stream.responses) {
if (cancel.value) {
console.log('Stopping stream...')
break
}
console.log(`Got new value for ${figure.uuid}:`, response)
if (!paused) {
data.value = response
updateGraph()
}
}
})
onBeforeUnmount(() => {
console.log('Component is about to unmount, stopping stream...')
cancel.value = true
})
</script>
<template>
<v-row class="w-100">
<v-col cols="12">
<v-card class="w-100">
<v-card-title>{{ figure.title }}</v-card-title>
<v-card-text>
<div :id="figure.uuid" class="w-100" />
</v-card-text>
</v-card>
</v-col>
</v-row>
</template>