improved css
This commit is contained in:
Binary file not shown.
@@ -1,12 +1,8 @@
|
|||||||
$light-gray: #d0d1d0;
|
@use '@/assets/variables';
|
||||||
$dark-gray: #303031;
|
|
||||||
|
|
||||||
$text-color: $light-gray;
|
|
||||||
$background-color: $dark-gray;
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: $text-color;
|
color: variables.$text-color;
|
||||||
background-color: $background-color;
|
background-color: variables.$background-color;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -14,3 +10,11 @@ body {
|
|||||||
align-content: center;
|
align-content: center;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
stroke-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
polyline {
|
||||||
|
stroke-width: 1px;
|
||||||
|
}
|
||||||
|
|||||||
19
frontend/src/assets/variables.scss
Normal file
19
frontend/src/assets/variables.scss
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
$white-1: oklch(90% 0 0);
|
||||||
|
$white-2: oklch(80% 0 0);
|
||||||
|
$gray-1: oklch(70% 0 0);
|
||||||
|
$gray-2: oklch(60% 0 0);
|
||||||
|
$gray-3: oklch(50% 0 0);
|
||||||
|
$gray-4: oklch(40% 0 0);
|
||||||
|
$gray-5: oklch(30% 0 0);
|
||||||
|
$black-1: oklch(20% 0 0);
|
||||||
|
$black-2: oklch(10% 0 0);
|
||||||
|
|
||||||
|
$text-color: $white-1;
|
||||||
|
$background-color: $gray-5;
|
||||||
|
|
||||||
|
$time-tick: $white-1;
|
||||||
|
$grid-line: $white-1;
|
||||||
|
$major-tick: $gray-2;
|
||||||
|
$minor-tick: $gray-3;
|
||||||
|
|
||||||
|
$text-font: Helvetica, sans-serif;
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, inject, provide, ref, toValue, watch } from 'vue';
|
import { computed, inject, provide, ref, toValue, watch } from 'vue';
|
||||||
import { AXIS_DATA, type AxisData, AxisSide, AxisType } from '@/graph/axis';
|
import { AXIS_DATA, type AxisData, AxisSide, AxisType } from '@/graph/axis';
|
||||||
import { useNow } from '@/composables/ticker';
|
|
||||||
import { GRAPH_DATA, type GraphData } from '@/graph/graph';
|
import { GRAPH_DATA, type GraphData } from '@/graph/graph';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -19,7 +18,7 @@ const type = computed(() => props.type || AxisType.Linear);
|
|||||||
const ticker_locations = [Math.log10(1), Math.log10(2), Math.log10(5)];
|
const ticker_locations = [Math.log10(1), Math.log10(2), Math.log10(5)];
|
||||||
ticker_locations.reverse();
|
ticker_locations.reverse();
|
||||||
|
|
||||||
const ticker = useNow(33);
|
const graph_data = inject<GraphData>(GRAPH_DATA)!;
|
||||||
|
|
||||||
const min_y = ref(Infinity);
|
const min_y = ref(Infinity);
|
||||||
const max_y = ref(-Infinity);
|
const max_y = ref(-Infinity);
|
||||||
@@ -28,7 +27,7 @@ const raw_max_y = ref(-Infinity);
|
|||||||
|
|
||||||
const axis_update_watch = ref(0);
|
const axis_update_watch = ref(0);
|
||||||
|
|
||||||
watch([ticker], () => {
|
watch([graph_data.min_x, graph_data.max_x], () => {
|
||||||
axis_update_watch.value++;
|
axis_update_watch.value++;
|
||||||
min_y.value = raw_min_y.value;
|
min_y.value = raw_min_y.value;
|
||||||
max_y.value = raw_max_y.value;
|
max_y.value = raw_max_y.value;
|
||||||
@@ -53,9 +52,6 @@ function update_max_y(y: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// const half_diff_y_value = computed(() => (max_y.value - min_y.value) / 2.0);
|
|
||||||
// const average_y_value = computed(() => min_y.value + half_diff_y_value.value);
|
|
||||||
|
|
||||||
const min_y_value = computed(() => {
|
const min_y_value = computed(() => {
|
||||||
if (props.y_limits) {
|
if (props.y_limits) {
|
||||||
return props.y_limits[0];
|
return props.y_limits[0];
|
||||||
@@ -103,8 +99,6 @@ const max_y_value = computed(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const graph_data = inject<GraphData>(GRAPH_DATA)!;
|
|
||||||
|
|
||||||
const y_map = (y: number) => {
|
const y_map = (y: number) => {
|
||||||
const height = toValue(graph_data.height);
|
const height = toValue(graph_data.height);
|
||||||
const border_top_bottom = toValue(graph_data.border_top_bottom);
|
const border_top_bottom = toValue(graph_data.border_top_bottom);
|
||||||
@@ -279,11 +273,7 @@ const lines = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.x_axis {
|
@use '@/assets/variables';
|
||||||
fill: #ffffff;
|
|
||||||
stroke: #ffffff;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right_edge {
|
.right_edge {
|
||||||
text-anchor: start;
|
text-anchor: start;
|
||||||
@@ -295,27 +285,21 @@ const lines = computed(() => {
|
|||||||
|
|
||||||
.middle_text {
|
.middle_text {
|
||||||
alignment-baseline: middle;
|
alignment-baseline: middle;
|
||||||
font-family: Helvetica, sans-serif;
|
font-family: variables.$text-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
.minor_tick {
|
.minor_tick {
|
||||||
stroke: #666666;
|
stroke: variables.$minor-tick;
|
||||||
stroke-width: 1px;
|
fill: variables.$minor-tick;
|
||||||
fill: #666666;
|
|
||||||
color: #666666;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.major_tick {
|
.major_tick {
|
||||||
stroke: #aaaaaa;
|
stroke: variables.$major-tick;
|
||||||
stroke-width: 1px;
|
fill: variables.$major-tick;
|
||||||
fill: #aaaaaa;
|
|
||||||
color: #aaaaaa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid_tick {
|
.grid_tick {
|
||||||
stroke: #ffffff;
|
fill: variables.$grid-line;
|
||||||
stroke-width: 1px;
|
stroke: variables.$grid-line;
|
||||||
fill: #ffffff;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -12,17 +12,32 @@ const props = defineProps<{
|
|||||||
// max_x?: number
|
// max_x?: number
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const svg_viewbox = computed(() => {
|
const width = computed(() => {
|
||||||
return `0 0 ${props.width} ${props.height}`;
|
return props.width;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const height = computed(() => {
|
||||||
|
return props.height;
|
||||||
|
});
|
||||||
|
|
||||||
|
// const svg_viewbox = computed(() => {
|
||||||
|
// return `0 0 ${props.width} ${props.height}`;
|
||||||
|
// });
|
||||||
const now = useNow(33);
|
const now = useNow(33);
|
||||||
const window_duration = 30 * 1000; // 30 seconds
|
const window_duration = 10 * 1000; // 10 seconds
|
||||||
|
|
||||||
const time_lines = [
|
const time_lines = [
|
||||||
1, // 1ms
|
1, // 1ms
|
||||||
|
2, // 2ms
|
||||||
|
5, // 5ms
|
||||||
10, // 10ms
|
10, // 10ms
|
||||||
|
20, // 20ms
|
||||||
|
50, // 50ms
|
||||||
100, // 100ms
|
100, // 100ms
|
||||||
|
200, // 200ms
|
||||||
|
500, // 500ms
|
||||||
1000, // 1s
|
1000, // 1s
|
||||||
|
2000, // 2s
|
||||||
5000, // 5s
|
5000, // 5s
|
||||||
10000, // 10s
|
10000, // 10s
|
||||||
30000, // 30s
|
30000, // 30s
|
||||||
@@ -31,10 +46,12 @@ const time_lines = [
|
|||||||
6000000, // 10m
|
6000000, // 10m
|
||||||
18000000, // 30m
|
18000000, // 30m
|
||||||
36000000, // 1h
|
36000000, // 1h
|
||||||
|
72000000, // 2h
|
||||||
144000000, // 4h
|
144000000, // 4h
|
||||||
216000000, // 6h
|
216000000, // 6h
|
||||||
432000000, // 12h
|
432000000, // 12h
|
||||||
864000000, // 1d
|
864000000, // 1d
|
||||||
|
1728000000, // 2d
|
||||||
6048000000, // 1w
|
6048000000, // 1w
|
||||||
];
|
];
|
||||||
time_lines.reverse();
|
time_lines.reverse();
|
||||||
@@ -49,7 +66,7 @@ const min_x = computed(() => max_x.value - window_duration);
|
|||||||
const x_map = (x: number) => {
|
const x_map = (x: number) => {
|
||||||
const diff_x = max_x.value - min_x.value;
|
const diff_x = max_x.value - min_x.value;
|
||||||
return (
|
return (
|
||||||
((props.width - 2 * border_left_right.value) * (x - min_x.value)) /
|
((width.value - 2 * border_left_right.value) * (x - min_x.value)) /
|
||||||
diff_x +
|
diff_x +
|
||||||
border_left_right.value
|
border_left_right.value
|
||||||
);
|
);
|
||||||
@@ -59,8 +76,8 @@ provide<GraphData>(GRAPH_DATA, {
|
|||||||
border_top_bottom: border_top_bottom,
|
border_top_bottom: border_top_bottom,
|
||||||
min_x: min_x,
|
min_x: min_x,
|
||||||
max_x: now,
|
max_x: now,
|
||||||
width: () => props.width - 2 * border_left_right.value,
|
width: () => width.value - 2 * border_left_right.value,
|
||||||
height: () => props.height - 2 * border_top_bottom.value,
|
height: () => height.value - 2 * border_top_bottom.value,
|
||||||
x_map: x_map,
|
x_map: x_map,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -81,7 +98,7 @@ const lines = computed(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<svg :viewBox="svg_viewbox" :width="props.width" :height="props.height">
|
<svg ref="svg_graph" :width="width" :height="height">
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="content">
|
<clipPath id="content">
|
||||||
<rect
|
<rect
|
||||||
@@ -115,7 +132,8 @@ const lines = computed(() => {
|
|||||||
></polyline>
|
></polyline>
|
||||||
<text
|
<text
|
||||||
class="bottom_edge"
|
class="bottom_edge"
|
||||||
:transform="`translate(${x_map(tick)},${height - border_top_bottom + text_offset}) rotate(0)`"
|
:x="x_map(tick)"
|
||||||
|
:y="height - border_top_bottom + text_offset"
|
||||||
>
|
>
|
||||||
{{ new Date(tick).toLocaleString() }}
|
{{ new Date(tick).toLocaleString() }}
|
||||||
</text>
|
</text>
|
||||||
@@ -126,17 +144,16 @@ const lines = computed(() => {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
@use '@/assets/variables';
|
||||||
|
|
||||||
.bottom_edge {
|
.bottom_edge {
|
||||||
text-anchor: middle;
|
text-anchor: middle;
|
||||||
alignment-baseline: text-before-edge;
|
alignment-baseline: text-before-edge;
|
||||||
font-family: Helvetica, sans-serif;
|
font-family: variables.$text-font;
|
||||||
}
|
}
|
||||||
|
|
||||||
.time_tick {
|
.time_tick {
|
||||||
stroke: #ffffff;
|
stroke: variables.$time-tick;
|
||||||
stroke-width: 1px;
|
fill: variables.$time-tick;
|
||||||
fill: #ffffff;
|
|
||||||
color: #ffffff;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
shallowRef,
|
shallowRef,
|
||||||
type ShallowRef,
|
type ShallowRef,
|
||||||
toValue,
|
toValue,
|
||||||
|
useTemplateRef,
|
||||||
watch,
|
watch,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +25,9 @@ const props = defineProps<{
|
|||||||
|
|
||||||
const smoothing_distance = 0.15 * 1000;
|
const smoothing_distance = 0.15 * 1000;
|
||||||
|
|
||||||
|
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)!;
|
||||||
const value = websocket.value.listen_to_telemetry(data);
|
const value = websocket.value.listen_to_telemetry(data);
|
||||||
@@ -106,6 +110,27 @@ const points = computed(() => {
|
|||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const labelRef = useTemplateRef<SVGTextElement>('label-ref');
|
||||||
|
const current_value = computed(() => {
|
||||||
|
const val = value.value;
|
||||||
|
if (val) {
|
||||||
|
return val.value[data.value!.data_type] as number;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
const test = computed(() => {
|
||||||
|
if (labelRef.value) {
|
||||||
|
const boundingBox = labelRef.value.getBBox();
|
||||||
|
return boundingBox.top;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
watch([test], (x) => {
|
||||||
|
console.log(x);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -116,6 +141,42 @@ const points = computed(() => {
|
|||||||
stroke-width="1"
|
stroke-width="1"
|
||||||
:points="points"
|
:points="points"
|
||||||
></polyline>
|
></polyline>
|
||||||
|
<template v-if="current_value">
|
||||||
|
<rect
|
||||||
|
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"
|
||||||
|
:stroke="color"
|
||||||
|
></rect>
|
||||||
|
<text
|
||||||
|
ref="label-ref"
|
||||||
|
:x="graph_data.x_map(toValue(graph_data.max_x)) + text_offset"
|
||||||
|
:y="axis_data.y_map(current_value)"
|
||||||
|
:fill="color"
|
||||||
|
:stroke="color"
|
||||||
|
>
|
||||||
|
{{ current_value.toFixed(2) }}
|
||||||
|
</text>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style></style>
|
<style scoped lang="scss">
|
||||||
|
@use '@/assets/variables';
|
||||||
|
|
||||||
|
text {
|
||||||
|
alignment-baseline: middle;
|
||||||
|
font-family: variables.$text-font;
|
||||||
|
text-anchor: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
rect {
|
||||||
|
fill: variables.$background-color;
|
||||||
|
stroke-width: 1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ provide(WEBSOCKET_SYMBOL, websocket);
|
|||||||
:width="1500"
|
:width="1500"
|
||||||
:height="800"
|
:height="800"
|
||||||
:border_top_bottom="24"
|
:border_top_bottom="24"
|
||||||
:border_left_right="64"
|
:border_left_right="128"
|
||||||
>
|
>
|
||||||
<Axis>
|
<Axis>
|
||||||
<Line data="simple_producer/sin" color="#FF0000"></Line>
|
<Line data="simple_producer/sin" color="#FF0000"></Line>
|
||||||
|
|||||||
Reference in New Issue
Block a user