improves performance

This commit is contained in:
2024-12-25 12:32:36 -05:00
parent cd3e15d9e9
commit 147d1abaf8
6 changed files with 193 additions and 104 deletions

View File

@@ -282,7 +282,7 @@ const lines = computed(() => {
} }
.middle_text { .middle_text {
alignment-baseline: middle; dominant-baseline: middle;
font-family: variables.$text-font; font-family: variables.$text-font;
} }

View File

@@ -2,6 +2,7 @@
import { computed, provide, ref } from 'vue'; import { computed, provide, ref } from 'vue';
import { useNow } from '@/composables/ticker'; import { useNow } from '@/composables/ticker';
import { GRAPH_DATA, type GraphData } from '@/graph/graph'; import { GRAPH_DATA, type GraphData } from '@/graph/graph';
import TimeText from '@/components/TimeText.vue';
const props = defineProps<{ const props = defineProps<{
width: number; width: number;
@@ -82,7 +83,7 @@ provide<GraphData>(GRAPH_DATA, {
const duration = computed(() => { const duration = computed(() => {
const diff_x = max_x.value - min_x.value; const diff_x = max_x.value - min_x.value;
return time_lines.find((duration) => diff_x / duration >= 3)!; return time_lines.find((duration) => diff_x / duration >= 2)!;
}); });
const lines = computed(() => { const lines = computed(() => {
@@ -97,54 +98,6 @@ const lines = computed(() => {
} }
return result; return result;
}); });
function getDateString(date: Date) {
const year = props.utc ? date.getUTCFullYear() : date.getFullYear();
const month = (
(props.utc ? date.getMonth() : date.getMonth()) + 1
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const day = (props.utc ? date.getUTCDate() : date.getDate()).toLocaleString(
'en-US',
{
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
},
);
const hour = (
props.utc ? date.getUTCHours() : date.getHours()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const minute = (
props.utc ? date.getUTCMinutes() : date.getMinutes()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const second = (
props.utc ? date.getUTCSeconds() : date.getSeconds()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const milliseconds = (
props.utc ? date.getUTCMilliseconds() : date.getMilliseconds()
).toLocaleString('en-US', {
minimumIntegerDigits: 3,
useGrouping: false,
maximumFractionDigits: 0,
});
return `${year}/${month}/${day} ${hour}:${minute}:${second}${duration.value < 1000 ? `.${milliseconds}` : ''}${props.utc ? 'Z' : ''}`;
}
</script> </script>
<template> <template>
@@ -180,13 +133,15 @@ function getDateString(date: Date) {
<polyline <polyline
:points="`${x_map(tick)},${border_top_bottom} ${x_map(tick)},${height - border_top_bottom}`" :points="`${x_map(tick)},${border_top_bottom} ${x_map(tick)},${height - border_top_bottom}`"
></polyline> ></polyline>
<text <TimeText
class="bottom_edge" class="bottom_edge"
:x="x_map(tick)" :x="x_map(tick)"
:y="height - border_top_bottom + text_offset" :y="height - border_top_bottom + text_offset"
:timestamp="tick"
:utc="props.utc"
:show_millis="duration < 1000"
> >
{{ getDateString(new Date(tick)) }} </TimeText>
</text>
</template> </template>
</g> </g>
<slot></slot> <slot></slot>
@@ -198,7 +153,7 @@ function getDateString(date: Date) {
.bottom_edge { .bottom_edge {
text-anchor: middle; text-anchor: middle;
alignment-baseline: text-before-edge; dominant-baseline: hanging;
font-family: variables.$text-font; font-family: variables.$text-font;
} }

View File

@@ -9,7 +9,6 @@ import {
shallowRef, shallowRef,
type ShallowRef, type ShallowRef,
toValue, toValue,
useTemplateRef,
watch, watch,
} from 'vue'; } from 'vue';
import { import {
@@ -19,6 +18,7 @@ import {
} from '@/composables/websocket'; } from '@/composables/websocket';
import { GRAPH_DATA, type GraphData } from '@/graph/graph'; import { GRAPH_DATA, type GraphData } from '@/graph/graph';
import { AXIS_DATA, type AxisData } from '@/graph/axis'; import { AXIS_DATA, type AxisData } from '@/graph/axis';
import ValueLabel from '@/components/ValueLabel.vue';
const props = defineProps<{ const props = defineProps<{
data: string; data: string;
@@ -28,7 +28,6 @@ const props = defineProps<{
const smoothing_distance = 0.15 * 1000; const smoothing_distance = 0.15 * 1000;
const text_offset = computed(() => 10); const text_offset = computed(() => 10);
const background_offset = computed(() => 5);
const { data } = useTelemetry(() => props.data); const { data } = useTelemetry(() => props.data);
const websocket = inject<ShallowRef<WebsocketHandle>>(WEBSOCKET_SYMBOL)!; const websocket = inject<ShallowRef<WebsocketHandle>>(WEBSOCKET_SYMBOL)!;
@@ -127,6 +126,7 @@ watch(
}, },
); );
// This function is somewhat slow
const points = computed(() => { const points = computed(() => {
let points = ''; let points = '';
if (memo.value.length == 0 || data.value == null) { if (memo.value.length == 0 || data.value == null) {
@@ -156,7 +156,6 @@ const points = computed(() => {
return points; return points;
}); });
const labelRef = useTemplateRef<SVGTextElement>('label-ref');
const current_value = computed(() => { const current_value = computed(() => {
const val = value.value; const val = value.value;
if (val) { if (val) {
@@ -173,27 +172,13 @@ const current_value = computed(() => {
clip-path="url(#content)" clip-path="url(#content)"
:points="points" :points="points"
></polyline> ></polyline>
<template v-if="current_value"> <ValueLabel
<rect v-if="current_value"
v-if="labelRef"
:x="
graph_data.x_map(toValue(graph_data.max_x)) +
text_offset -
background_offset
"
:y="axis_data.y_map(current_value) - 9 - background_offset"
:width="labelRef.getBBox().width + background_offset * 2"
:height="16 + background_offset * 2"
></rect>
<text
ref="label-ref"
:x="graph_data.x_map(toValue(graph_data.max_x)) + text_offset" :x="graph_data.x_map(toValue(graph_data.max_x)) + text_offset"
:y="axis_data.y_map(current_value)" :y="axis_data.y_map(current_value)"
:value="current_value"
> >
{{ max.toFixed(2) }} </ValueLabel>
{{ min.toFixed(2) }}
</text>
</template>
</g> </g>
</template> </template>
@@ -204,18 +189,4 @@ polyline {
stroke-width: 1px; stroke-width: 1px;
stroke: var(--indexed-color); stroke: var(--indexed-color);
} }
rect {
fill: variables.$background-color;
stroke-width: 1px;
stroke: var(--indexed-color);
}
text {
alignment-baseline: middle;
font-family: variables.$text-font;
text-anchor: start;
stroke: var(--indexed-color);
fill: var(--indexed-color);
}
</style> </style>

View File

@@ -0,0 +1,78 @@
<script setup lang="ts">
import { computed } from 'vue';
const props = defineProps<{
x: number;
y: number;
timestamp: number;
utc?: boolean
show_millis?: boolean
}>();
// This function is slow
function getDateString(date: Date) {
const year = props.utc ? date.getUTCFullYear() : date.getFullYear();
const month = (
(props.utc ? date.getMonth() : date.getMonth()) + 1
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const day = (props.utc ? date.getUTCDate() : date.getDate()).toLocaleString(
'en-US',
{
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
},
);
const hour = (
props.utc ? date.getUTCHours() : date.getHours()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const minute = (
props.utc ? date.getUTCMinutes() : date.getMinutes()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const second = (
props.utc ? date.getUTCSeconds() : date.getSeconds()
).toLocaleString('en-US', {
minimumIntegerDigits: 2,
useGrouping: false,
maximumFractionDigits: 0,
});
const milliseconds = (
props.utc ? date.getUTCMilliseconds() : date.getMilliseconds()
).toLocaleString('en-US', {
minimumIntegerDigits: 3,
useGrouping: false,
maximumFractionDigits: 0,
});
return `${year}/${month}/${day} ${hour}:${minute}:${second}${props.show_millis ? `.${milliseconds}` : ''}${props.utc ? 'Z' : ''}`;
}
const timetext = computed(() => {
return getDateString(new Date(props.timestamp));
});
</script>
<template>
<text
:x="props.x"
:y="props.y"
>
{{ timetext }}
</text>
</template>
<style scoped lang="scss">
</style>

View File

@@ -0,0 +1,62 @@
<script setup lang="ts">
import { computed, ref, useTemplateRef, watch, watchPostEffect } from 'vue';
import { useNow } from '@/composables/ticker';
const props = defineProps<{
x: number;
y: number;
value: number;
}>();
const background_offset = computed(() => 5);
const y_offset = computed(() => 9);
const labelRef = useTemplateRef<SVGTextElement>('label-ref');
const value_text = computed(() => {
return props.value.toFixed(2);
});
const label_width = ref(0);
watch([value_text, labelRef], ([_, label]) => {
label_width.value = label?.getBBox().width || 0;
}, {
flush: 'post',
});
</script>
<template>
<rect
:x="x - background_offset"
:y="y - y_offset - background_offset"
:width="label_width + background_offset * 2"
:height="16 + background_offset * 2"
></rect>
<text
ref="label-ref"
:x="x"
:y="y"
>
{{ value_text }}
</text>
</template>
<style scoped lang="scss">
@use '@/assets/variables';
rect {
fill: variables.$background-color;
stroke-width: 1px;
stroke: var(--indexed-color);
}
text {
font-family: variables.$text-font;
text-anchor: start;
stroke: var(--indexed-color);
fill: var(--indexed-color);
dominant-baseline: middle;
}
</style>

View File

@@ -12,24 +12,47 @@ provide(WEBSOCKET_SYMBOL, websocket);
<template> <template>
<main> <main>
<Graph <Graph
:width="1500" :width="800"
:height="800" :height="400"
:border_top_bottom="24" :border_top_bottom="24"
:border_left_right="128" :border_left_right="128"
> >
<Axis> <Axis>
<Line data="simple_producer/sin"></Line> <Line data="simple_producer/sin"></Line>
<Line data="simple_producer/cos4"></Line>
</Axis>
</Graph>
<Graph
:width="800"
:height="400"
:border_top_bottom="24"
:border_left_right="128"
>
<Axis>
<Line data="simple_producer/sin2"></Line>
<Line data="simple_producer/cos"></Line> <Line data="simple_producer/cos"></Line>
<!-- <Line data="simple_producer/sin2"></Line>--> </Axis>
<!-- <Line data="simple_producer/cos2"></Line>--> </Graph>
<!-- <Line data="simple_producer/sin3"></Line>--> <Graph
<!-- <Line data="simple_producer/cos3"></Line>--> :width="800"
<!-- <Line data="simple_producer/sin4"></Line>--> :height="400"
<!-- <Line data="simple_producer/cos4"></Line>--> :border_top_bottom="24"
<!-- <Line data="simple_producer/sin5"></Line>--> :border_left_right="128"
<!-- <Line data="simple_producer/cos5"></Line>--> >
<!-- <Line data="simple_producer/sin6"></Line>--> <Axis>
<!-- <Line data="simple_producer/cos6"></Line>--> <Line data="simple_producer/sin3"></Line>
<Line data="simple_producer/cos2"></Line>
</Axis>
</Graph>
<Graph
:width="800"
:height="400"
:border_top_bottom="24"
:border_left_right="128"
>
<Axis>
<Line data="simple_producer/sin4"></Line>
<Line data="simple_producer/cos3"></Line>
</Axis> </Axis>
</Graph> </Graph>
</main> </main>