93 lines
2.4 KiB
Vue
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>
|