adds telemetry list

This commit is contained in:
2025-02-14 20:22:31 -08:00
parent 44523f3cdb
commit a864c0b41c
19 changed files with 553 additions and 58 deletions

View File

@@ -0,0 +1,13 @@
<script setup lang="ts"></script>
<template>
<div></div>
</template>
<style scoped lang="scss">
@use '@/assets/variables';
div {
align-self: stretch;
border: 1px solid variables.$major-tick;
}
</style>

View File

@@ -0,0 +1,31 @@
<script setup lang="ts">
import {
type PanelHeirarchyChildren,
PanelHeirarchyType,
} from '@/panels/panel';
defineProps<{
heirarchy: PanelHeirarchyChildren;
}>();
</script>
<template>
<ul>
<li v-for="child in heirarchy" :key="child.name">
<RouterLink
v-if="child.type == PanelHeirarchyType.LEAF"
:to="child.to"
>
{{ child.name }}
</RouterLink>
<template v-if="child.type == PanelHeirarchyType.FOLDER">
{{ child.name }}
<PanelHeirarchy :heirarchy="child.children"> </PanelHeirarchy>
</template>
</li>
</ul>
</template>
<style scoped lang="scss">
@use '@/assets/variables';
</style>

View File

@@ -35,6 +35,7 @@ const width = ref(0);
const height = ref(0);
const controls_height = 32;
const min_time_label_separation = 250;
const resize_observer = new ResizeObserver((elements) => {
for (const element of elements) {
@@ -80,6 +81,7 @@ const time_lines = [
10000, // 10s
30000, // 30s
60000, // 1m
150000, // 2.5m
300000, // 5m
6000000, // 10m
18000000, // 30m
@@ -92,7 +94,7 @@ const time_lines = [
1728000000, // 2d
6048000000, // 1w
];
time_lines.reverse();
// time_lines.reverse();
const text_offset = computed(() => 5);
const legend_width = 160;
@@ -192,15 +194,20 @@ const legend_y_stride = computed(() => 16);
const legend_width_output = computed(() => legend_width - 8);
const line_duration = computed(() => {
const width_px = width.value;
const diff_x = max_x.value - min_x.value;
return time_lines.find((duration) => diff_x / duration >= 2)!;
return time_lines.find((duration) => {
const line_count = diff_x / duration;
const width_per_line = width_px / line_count;
return width_per_line >= min_time_label_separation;
})!;
});
const lines = computed(() => {
const result = [];
for (
let i = Math.ceil(max_x.value / line_duration.value);
i >= Math.ceil(min_x.value / line_duration.value) - 5;
i >= Math.floor(min_x.value / line_duration.value);
i--
) {
const x = i * line_duration.value;
@@ -356,6 +363,7 @@ provide<GraphData>(GRAPH_DATA, {
:timestamp="tick"
:utc="props.utc"
:show_millis="line_duration < 1000"
:key="tick"
></TimeText>
</template>
</g>
@@ -425,8 +433,4 @@ div.controls-header {
gap: 0 1em;
margin: 0 1em 0 1em;
}
div.controls-header > div.grow {
flex-grow: 1;
}
</style>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
import type { TelemetryDefinition } from '@/composables/telemetry';
import Line from '@/components/TelemetryLine.vue';
import SvgGraph from '@/components/SvgGraph.vue';
import Axis from '@/components/GraphAxis.vue';
import { computed } from 'vue';
const props = defineProps<{
telemetry_definition: TelemetryDefinition | null;
secondary: TelemetryDefinition | null;
}>();
const lines = computed(() => {
const result = [];
if (props.secondary) {
result.push(props.secondary);
}
if (props.telemetry_definition) {
result.push(props.telemetry_definition);
}
return result;
});
</script>
<template>
<div class="row">
<span>
{{ telemetry_definition?.name || 'No Telemetry Selected' }}
</span>
</div>
<div :class="`row ${telemetry_definition == null ? 'hidden' : ''}`">
<span>
{{ telemetry_definition?.uuid || '0' }}
</span>
</div>
<div :class="`row ${telemetry_definition == null ? 'hidden' : ''}`">
<span>
{{ telemetry_definition?.data_type || '0' }}
</span>
</div>
<div class="row graph grow no-min-height no-basis">
<SvgGraph right_axis>
<Axis>
<Line
v-for="line in lines"
:data="line.name"
:key="line.uuid"
></Line>
</Axis>
</SvgGraph>
</div>
</template>
<style scoped lang="scss">
.graph {
min-height: 50px;
}
.hidden {
visibility: hidden;
}
</style>

View File

@@ -525,21 +525,8 @@ rect.legend:has(~ .legend:hover) {
cursor: help;
}
div.column {
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: flex-start;
align-content: flex-start;
gap: 0.25em;
}
div.column,
div.row {
display: flex;
flex-flow: row nowrap;
justify-content: flex-start;
align-items: center;
align-content: center;
gap: 0.25em;
}

View File

@@ -0,0 +1,104 @@
<script setup lang="ts">
import {
type TelemetryDefinition,
useAllTelemetry,
} from '@/composables/telemetry';
import { computed, ref, watch } from 'vue';
const props = defineProps<{
search?: string;
}>();
const emit = defineEmits<{
(
e: 'select',
tlm_entry: [TelemetryDefinition | null, TelemetryDefinition | null],
): void;
}>();
const search_value = computed(() => (props.search || '').toLowerCase());
const { data: telemetry_data } = useAllTelemetry();
const sorted_tlm_data = computed(() => {
const tlm_data = telemetry_data.value;
if (tlm_data != null) {
return tlm_data
.filter((entry) =>
entry.name.toLowerCase().includes(search_value.value),
)
.sort((a, b) => a.name.localeCompare(b.name));
}
return [];
});
const mousedover = ref<TelemetryDefinition | null>(null);
const selected = ref<TelemetryDefinition | null>(null);
function onMouseover(tlm_entry: TelemetryDefinition) {
mousedover.value = tlm_entry;
}
function onMouseleave() {
mousedover.value = null;
}
function onClick(tlm_entry: TelemetryDefinition) {
selected.value = tlm_entry;
}
watch([mousedover, selected], ([mousedover_val, selected_val]) => {
if (mousedover_val) {
emit('select', [
mousedover_val,
mousedover_val.uuid != selected_val?.uuid ? selected_val : null,
]);
} else if (selected_val) {
emit('select', [selected_val, null]);
} else {
emit('select', [null, null]);
}
});
</script>
<template>
<template v-if="sorted_tlm_data.length > 0">
<div
v-for="tlm_entry in sorted_tlm_data"
:class="`row data ${selected?.uuid == tlm_entry.uuid ? 'selected' : ''}`"
:key="tlm_entry.uuid"
@mouseover="() => onMouseover(tlm_entry)"
@mouseleave="() => onMouseleave()"
@click="() => onClick(tlm_entry)"
>
<span>
{{ tlm_entry.name }}
</span>
</div>
</template>
<template v-else>
<div class="row">
<span> No Matches Found </span>
</div>
</template>
</template>
<style scoped lang="scss">
@use '@/assets/variables';
div {
padding: 0.3em;
border: 0;
border-bottom: variables.$gray-3 solid 1px;
border-top: 0;
}
.data.selected:has(~ .data:hover),
.data:hover ~ .data.selected {
background-color: variables.$light-background-color;
}
.data.selected,
.data:hover {
background-color: variables.$light2-background-color;
}
</style>

View File

@@ -0,0 +1,47 @@
<script setup lang="ts">
import { onMounted, useTemplateRef } from 'vue';
const props = defineProps<{
autofocus?: boolean;
placeholder?: string;
}>();
const model = defineModel();
const emit = defineEmits<{
(e: 'enter'): void;
}>();
const inputRef = useTemplateRef<HTMLInputElement>('input-ref');
onMounted(() => {
if (props.autofocus) {
inputRef.value?.focus();
}
});
</script>
<template>
<input
ref="input-ref"
class="grow"
v-model="model"
:placeholder="placeholder"
v-on:keyup.enter="emit('enter')"
/>
</template>
<style scoped lang="scss">
@use '@/assets/variables';
input {
appearance: none;
color: inherit;
background-color: inherit;
border: 0 solid variables.$gray-3;
border-bottom: 1px solid variables.$gray-3;
padding: 0.5ex;
font-size: inherit;
outline: none;
min-width: 5em;
}
</style>