2023-12-03 18:02:07 +00:00
|
|
|
<script setup lang="ts">
|
|
|
|
// @ts-nocheck
|
|
|
|
// reason for no check is, that we have some mixing of typescript and chart js which seems to be not to be fixed that easy
|
2023-12-10 15:49:42 +00:00
|
|
|
import { ref, computed, onMounted, nextTick } from "vue";
|
2023-12-10 08:01:20 +00:00
|
|
|
import { initWaterfall, setColormap } from "../../js/waterfallHandler.js";
|
2023-12-03 18:02:07 +00:00
|
|
|
import { setActivePinia } from "pinia";
|
2023-12-09 06:18:16 +00:00
|
|
|
import pinia from "../../store/index";
|
2023-12-03 18:02:07 +00:00
|
|
|
setActivePinia(pinia);
|
|
|
|
|
2023-12-09 06:18:16 +00:00
|
|
|
import { settingsStore as settings } from "../../store/settingsStore.js";
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-09 06:18:16 +00:00
|
|
|
import { useStateStore } from "../../store/stateStore.js";
|
2023-12-03 18:02:07 +00:00
|
|
|
const state = useStateStore(pinia);
|
|
|
|
|
|
|
|
import {
|
|
|
|
Chart as ChartJS,
|
|
|
|
CategoryScale,
|
|
|
|
LinearScale,
|
|
|
|
PointElement,
|
|
|
|
LineElement,
|
|
|
|
Title,
|
|
|
|
Tooltip,
|
|
|
|
Legend,
|
|
|
|
} from "chart.js";
|
|
|
|
import { Line, Scatter } from "vue-chartjs";
|
|
|
|
|
2023-12-10 08:00:39 +00:00
|
|
|
const localSpectrumView = ref("waterfall");
|
|
|
|
function selectStatsControl(item) {
|
|
|
|
switch (item) {
|
|
|
|
case "wf":
|
|
|
|
localSpectrumView.value = "waterfall";
|
2023-12-03 18:02:07 +00:00
|
|
|
break;
|
2023-12-10 08:00:39 +00:00
|
|
|
case "scatter":
|
|
|
|
localSpectrumView.value = "scatter";
|
2023-12-03 18:02:07 +00:00
|
|
|
break;
|
2023-12-10 08:00:39 +00:00
|
|
|
case "chart":
|
|
|
|
localSpectrumView.value = "chart";
|
2023-12-03 18:02:07 +00:00
|
|
|
break;
|
|
|
|
default:
|
2023-12-10 08:00:39 +00:00
|
|
|
localSpectrumView.value = "waterfall";
|
2023-12-03 18:02:07 +00:00
|
|
|
}
|
|
|
|
//saveSettingsToFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
ChartJS.register(
|
|
|
|
CategoryScale,
|
|
|
|
LinearScale,
|
|
|
|
PointElement,
|
|
|
|
LineElement,
|
|
|
|
Title,
|
|
|
|
Tooltip,
|
|
|
|
Legend,
|
|
|
|
);
|
|
|
|
|
|
|
|
// https://www.chartjs.org/docs/latest/samples/line/segments.html
|
|
|
|
const skipped = (speedCtx, value) =>
|
|
|
|
speedCtx.p0.skip || speedCtx.p1.skip ? value : undefined;
|
|
|
|
const down = (speedCtx, value) =>
|
|
|
|
speedCtx.p0.parsed.y > speedCtx.p1.parsed.y ? value : undefined;
|
|
|
|
|
|
|
|
var transmissionSpeedChartOptions = {
|
|
|
|
//type: "line",
|
|
|
|
responsive: true,
|
|
|
|
animations: true,
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
cubicInterpolationMode: "monotone",
|
|
|
|
tension: 0.4,
|
|
|
|
scales: {
|
|
|
|
SNR: {
|
|
|
|
type: "linear",
|
|
|
|
ticks: { beginAtZero: false, color: "rgb(255, 99, 132)" },
|
|
|
|
position: "right",
|
|
|
|
},
|
|
|
|
SPEED: {
|
|
|
|
type: "linear",
|
|
|
|
ticks: { beginAtZero: false, color: "rgb(120, 100, 120)" },
|
|
|
|
position: "left",
|
|
|
|
grid: {
|
|
|
|
drawOnChartArea: false, // only want the grid lines for one axis to show up
|
|
|
|
},
|
|
|
|
},
|
|
|
|
x: { ticks: { beginAtZero: true } },
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
const transmissionSpeedChartData = computed(() => ({
|
|
|
|
labels: state.arq_speed_list_timestamp,
|
|
|
|
datasets: [
|
|
|
|
{
|
|
|
|
type: "line",
|
|
|
|
label: "SNR[dB]",
|
|
|
|
data: state.arq_speed_list_snr,
|
|
|
|
borderColor: "rgb(75, 192, 192, 1.0)",
|
|
|
|
pointRadius: 1,
|
|
|
|
segment: {
|
|
|
|
borderColor: (speedCtx) =>
|
|
|
|
skipped(speedCtx, "rgb(0,0,0,0.4)") ||
|
|
|
|
down(speedCtx, "rgb(192,75,75)"),
|
|
|
|
borderDash: (speedCtx) => skipped(speedCtx, [3, 3]),
|
|
|
|
},
|
|
|
|
spanGaps: true,
|
|
|
|
backgroundColor: "rgba(75, 192, 192, 0.2)",
|
|
|
|
order: 1,
|
|
|
|
yAxisID: "SNR",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: "bar",
|
|
|
|
label: "Speed[bpm]",
|
|
|
|
data: state.arq_speed_list_bpm,
|
|
|
|
borderColor: "rgb(120, 100, 120, 1.0)",
|
|
|
|
backgroundColor: "rgba(120, 100, 120, 0.2)",
|
|
|
|
order: 0,
|
|
|
|
yAxisID: "SPEED",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}));
|
|
|
|
|
|
|
|
const scatterChartOptions = {
|
|
|
|
responsive: true,
|
|
|
|
maintainAspectRatio: false,
|
|
|
|
scales: {
|
|
|
|
x: {
|
|
|
|
type: "linear",
|
|
|
|
position: "bottom",
|
|
|
|
grid: {
|
|
|
|
display: true,
|
|
|
|
lineWidth: 1, // Set the line width for x-axis grid lines
|
|
|
|
},
|
|
|
|
ticks: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
y: {
|
|
|
|
type: "linear",
|
|
|
|
position: "left",
|
|
|
|
grid: {
|
|
|
|
display: true,
|
|
|
|
lineWidth: 1, // Set the line width for y-axis grid lines
|
|
|
|
},
|
|
|
|
ticks: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
plugins: {
|
|
|
|
legend: {
|
|
|
|
display: false,
|
|
|
|
},
|
|
|
|
tooltip: {
|
|
|
|
enabled: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
// dummy data
|
|
|
|
//state.scatter = [{"x":"166","y":"46"},{"x":"-193","y":"-139"},{"x":"-165","y":"-291"},{"x":"311","y":"-367"},{"x":"389","y":"199"},{"x":"78","y":"372"},{"x":"242","y":"-431"},{"x":"-271","y":"-248"},{"x":"28","y":"-130"},{"x":"-20","y":"187"},{"x":"74","y":"362"},{"x":"-316","y":"-229"},{"x":"-180","y":"261"},{"x":"321","y":"360"},{"x":"438","y":"-288"},{"x":"378","y":"-94"},{"x":"462","y":"-163"},{"x":"-265","y":"248"},{"x":"210","y":"314"},{"x":"230","y":"-320"},{"x":"261","y":"-244"},{"x":"-283","y":"-373"}]
|
|
|
|
|
|
|
|
const scatterChartData = computed(() => ({
|
|
|
|
datasets: [
|
|
|
|
{
|
|
|
|
type: "scatter",
|
|
|
|
fill: true,
|
|
|
|
data: state.scatter,
|
|
|
|
label: "Scatter",
|
|
|
|
tension: 0.1,
|
|
|
|
borderColor: "rgb(0, 255, 0)",
|
|
|
|
},
|
|
|
|
],
|
|
|
|
}));
|
2023-12-04 03:43:48 +00:00
|
|
|
var localSpectrum;
|
2023-12-10 15:49:42 +00:00
|
|
|
//Define and generate a unique ID for canvas
|
|
|
|
const localSpectrumID = ref("");
|
2023-12-10 15:50:07 +00:00
|
|
|
localSpectrumID.value =
|
|
|
|
"gridwfid-" + (Math.random() + 1).toString(36).substring(7);
|
2023-12-04 03:43:48 +00:00
|
|
|
onMounted(() => {
|
2023-12-04 03:49:02 +00:00
|
|
|
// This code will be executed after the component is mounted to the DOM
|
|
|
|
// You can access DOM elements or perform other initialization here
|
|
|
|
//const myElement = this.$refs.waterfall; // Access the DOM element with ref
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
// init waterfall
|
2023-12-10 15:49:42 +00:00
|
|
|
localSpectrum = initWaterfall(localSpectrumID.value);
|
2023-12-04 03:43:48 +00:00
|
|
|
});
|
2023-12-03 18:02:07 +00:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
2023-12-04 03:49:02 +00:00
|
|
|
<div class="card h-100">
|
2023-12-10 08:00:39 +00:00
|
|
|
<div class="card-header p-1">
|
2023-12-04 03:49:02 +00:00
|
|
|
<div class="btn-group" role="group">
|
|
|
|
<div
|
|
|
|
class="list-group bg-body-tertiary list-group-horizontal"
|
|
|
|
id="list-tab"
|
|
|
|
role="tablist"
|
|
|
|
>
|
|
|
|
<a
|
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-waterfall"
|
|
|
|
v-bind:class="{
|
2023-12-10 08:00:39 +00:00
|
|
|
active: localSpectrumView == 'waterfall',
|
2023-12-04 03:49:02 +00:00
|
|
|
}"
|
2023-12-10 08:00:39 +00:00
|
|
|
@click="selectStatsControl('wf')"
|
2023-12-04 03:49:02 +00:00
|
|
|
><strong><i class="bi bi-water"></i></strong
|
|
|
|
></a>
|
|
|
|
<a
|
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-scatter"
|
|
|
|
v-bind:class="{
|
2023-12-10 08:00:39 +00:00
|
|
|
active: localSpectrumView == 'scatter',
|
2023-12-04 03:49:02 +00:00
|
|
|
}"
|
2023-12-10 08:00:39 +00:00
|
|
|
@click="selectStatsControl('scatter')"
|
2023-12-04 03:49:02 +00:00
|
|
|
><strong><i class="bi bi-border-outer"></i></strong
|
|
|
|
></a>
|
|
|
|
<a
|
|
|
|
class="py-0 list-group-item list-group-item-dark list-group-item-action"
|
|
|
|
data-bs-toggle="list"
|
|
|
|
role="tab"
|
|
|
|
aria-controls="list-chart"
|
2023-12-10 08:00:39 +00:00
|
|
|
v-bind:class="{ active: localSpectrumView == 'chart' }"
|
|
|
|
@click="selectStatsControl('chart')"
|
2023-12-04 03:49:02 +00:00
|
|
|
><strong><i class="bi bi-graph-up-arrow"></i></strong
|
|
|
|
></a>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="btn-group" role="group" aria-label="Busy indicators">
|
|
|
|
<button
|
|
|
|
class="btn btn-sm ms-1 p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-warning': state.channel_busy_slot[0] === true,
|
|
|
|
'btn-outline-secondary': state.channel_busy_slot[0] === false,
|
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S1
|
|
|
|
</button>
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-warning': state.channel_busy_slot[1] === true,
|
|
|
|
'btn-outline-secondary': state.channel_busy_slot[1] === false,
|
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S2
|
|
|
|
</button>
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-warning': state.channel_busy_slot[2] === true,
|
|
|
|
'btn-outline-secondary': state.channel_busy_slot[2] === false,
|
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S3
|
|
|
|
</button>
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-warning': state.channel_busy_slot[3] === true,
|
|
|
|
'btn-outline-secondary': state.channel_busy_slot[3] === false,
|
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S4
|
|
|
|
</button>
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-warning': state.channel_busy_slot[4] === true,
|
|
|
|
'btn-outline-secondary': state.channel_busy_slot[4] === false,
|
|
|
|
}"
|
|
|
|
title="Channel busy state: <strong class='text-success'>not busy</strong> / <strong class='text-danger'>busy </strong>"
|
|
|
|
>
|
|
|
|
S5
|
|
|
|
</button>
|
2023-12-03 18:02:07 +00:00
|
|
|
|
2023-12-04 03:49:02 +00:00
|
|
|
<button
|
|
|
|
class="btn btn-sm p-1 disabled"
|
|
|
|
type="button"
|
|
|
|
data-bs-placement="top"
|
|
|
|
data-bs-toggle="tooltip"
|
|
|
|
data-bs-trigger="hover"
|
|
|
|
data-bs-html="true"
|
|
|
|
title="Recieving data: illuminates <strong class='text-success'>green</strong> if receiving codec2 data"
|
|
|
|
v-bind:class="{
|
|
|
|
'btn-success': state.is_codec2_traffic === true,
|
|
|
|
'btn-outline-secondary': state.is_codec2_traffic === false,
|
|
|
|
}"
|
|
|
|
>
|
|
|
|
data
|
|
|
|
</button>
|
|
|
|
</div>
|
2023-12-03 18:02:07 +00:00
|
|
|
</div>
|
2023-12-10 08:00:39 +00:00
|
|
|
<div class="card-body w-100 h-100 overflow-auto p-2">
|
2023-12-04 03:43:48 +00:00
|
|
|
<div class="tab-content h-100 w-100" id="nav-stats-tabContent">
|
2023-12-03 18:02:07 +00:00
|
|
|
<div
|
2023-12-04 03:43:48 +00:00
|
|
|
class="tab-pane fade h-100 w-100"
|
2023-12-03 18:02:07 +00:00
|
|
|
v-bind:class="{
|
2023-12-10 08:00:39 +00:00
|
|
|
'show active': localSpectrumView == 'waterfall',
|
2023-12-03 18:02:07 +00:00
|
|
|
}"
|
|
|
|
role="stats_tabpanel"
|
|
|
|
aria-labelledby="list-waterfall-list"
|
|
|
|
>
|
2024-01-13 15:58:15 +00:00
|
|
|
<canvas v-bind:id="localSpectrumID" class="force-gpu"></canvas>
|
2023-12-03 18:02:07 +00:00
|
|
|
</div>
|
|
|
|
<div
|
2023-12-10 08:00:39 +00:00
|
|
|
class="tab-pane fade h-100 w-100"
|
2023-12-03 18:02:07 +00:00
|
|
|
v-bind:class="{
|
2023-12-10 08:00:39 +00:00
|
|
|
'show active': localSpectrumView == 'scatter',
|
2023-12-03 18:02:07 +00:00
|
|
|
}"
|
|
|
|
role="tabpanel"
|
|
|
|
aria-labelledby="list-scatter-list"
|
|
|
|
>
|
|
|
|
<Scatter :data="scatterChartData" :options="scatterChartOptions" />
|
|
|
|
</div>
|
|
|
|
<div
|
2023-12-10 08:00:39 +00:00
|
|
|
class="tab-pane fade h-100 w-100"
|
|
|
|
v-bind:class="{ 'show active': localSpectrumView == 'chart' }"
|
2023-12-03 18:02:07 +00:00
|
|
|
role="tabpanel"
|
|
|
|
aria-labelledby="list-chart-list"
|
|
|
|
>
|
|
|
|
<Line
|
|
|
|
:data="transmissionSpeedChartData"
|
|
|
|
:options="transmissionSpeedChartOptions"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<!--278px-->
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|