Initial commit
This commit is contained in:
100
components/viz/DeepCareAnalyzer.vue
Normal file
100
components/viz/DeepCareAnalyzer.vue
Normal file
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<div class="progress" style="height: 10px">
|
||||
it works.
|
||||
<LineChart :chart-data="chartData" :options="chartOptions" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Line } from 'vue-chartjs'
|
||||
import { Chart as ChartJS, Title, Tooltip, Legend, LineElement, CategoryScale, TimeScale, LinearScale } from 'chart.js'
|
||||
import Papa from 'papaparse'
|
||||
// Chart.js Komponenten registrieren
|
||||
ChartJS.register(Title, Tooltip, Legend, LineElement, CategoryScale, TimeScale, LinearScale)
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LineChart: Line // vue-chartjs Line-Komponente einbinden
|
||||
},
|
||||
setup () {
|
||||
// Reaktive Variablen für Daten und Chart-Optionen
|
||||
const chartData = ref(null)
|
||||
const chartOptions = ref({
|
||||
responsive: true,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time', // Zeit als X-Achse
|
||||
time: {
|
||||
unit: 'min', // Zeitintervall auf der X-Achse (z.B. Minuten)
|
||||
tooltipFormat: 'll mm:ss:ms' // Format für den Tooltip
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Timestamp'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Noise Level'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// CSV-Daten laden und in das Chart-Format umwandeln
|
||||
const loadCSVData = async () => {
|
||||
// Beispiel CSV String (ersetzte es mit deinem tatsächlichen CSV)
|
||||
const csvString = `
|
||||
timestamp,sensors_ambientData_noise
|
||||
2024-10-09 08:00:00.169,35.19362197015299
|
||||
2024-10-09 08:00:00.369,34.89283749374632
|
||||
2024-10-09 08:00:00.569,34.54829716372913
|
||||
` // Hier deine CSV-Daten laden oder einen Upload implementieren
|
||||
|
||||
// CSV parsen mit PapaParse
|
||||
// eslint-disable-next-line import/no-named-as-default-member
|
||||
await Papa.parse(csvString, {
|
||||
header: true,
|
||||
dynamicTyping: true,
|
||||
complete: (result) => {
|
||||
// Extrahiere die Timestamps und Sensorwerte
|
||||
const labels = result.data.map(row => row.timestamp)
|
||||
const values = result.data.map(row => row.sensors_ambientData_noise)
|
||||
|
||||
// Erstelle die Chart-Datenstruktur
|
||||
chartData.value = {
|
||||
labels,
|
||||
datasets: [{
|
||||
label: 'Noise Level',
|
||||
data: values,
|
||||
borderColor: 'rgba(75, 192, 192, 1)',
|
||||
backgroundColor: 'rgba(75, 192, 192, 0.2)',
|
||||
fill: false // Fülle den Bereich unter der Linie nicht
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// CSV-Daten laden, sobald die Komponente gemountet ist
|
||||
onMounted(() => {
|
||||
loadCSVData()
|
||||
})
|
||||
|
||||
return {
|
||||
chartData,
|
||||
chartOptions
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Optional: Styles für das Chart */
|
||||
canvas {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
71
components/viz/LineChart.vue
Normal file
71
components/viz/LineChart.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div v-if="isLoaded">
|
||||
<div class="chart-container">
|
||||
<Line :data="chartData" :options="chartOptions" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
Loading chart data...
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, onMounted } from 'vue'
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend
|
||||
} from 'chart.js'
|
||||
import { Line } from 'vue-chartjs'
|
||||
import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
import { data, options, loadChartData } from './dataExtractor'
|
||||
|
||||
// Register Chart.js components
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
zoomPlugin
|
||||
)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LineChart',
|
||||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Line
|
||||
},
|
||||
setup () {
|
||||
const chartData = ref(data)
|
||||
const chartOptions = ref(options)
|
||||
const isLoaded = ref(false)
|
||||
|
||||
// Load CSV data when the component is mounted
|
||||
onMounted(async () => {
|
||||
await loadChartData('/data_10_16_2024.csv')
|
||||
isLoaded.value = true
|
||||
})
|
||||
|
||||
return {
|
||||
chartData,
|
||||
chartOptions,
|
||||
isLoaded
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.chart-container {
|
||||
position: relative;
|
||||
height: 90vh;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
79
components/viz/TimeDifference.vue
Normal file
79
components/viz/TimeDifference.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div v-if="isLoaded">
|
||||
<div class="chart-container">
|
||||
<Line :data="chartData" :options="chartOptions" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
Loading chart data...
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, onMounted } from 'vue'
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend
|
||||
} from 'chart.js'
|
||||
import { Line } from 'vue-chartjs'
|
||||
import zoomPlugin from 'chartjs-plugin-zoom'
|
||||
import { data, options, loadChartData } from './dataExtractor'
|
||||
|
||||
// Register Chart.js components
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
zoomPlugin
|
||||
)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TimeDifference',
|
||||
components: {
|
||||
// eslint-disable-next-line vue/no-reserved-component-names
|
||||
Line
|
||||
},
|
||||
setup () {
|
||||
const chartData = ref(data)
|
||||
const chartOptions = ref(options)
|
||||
const isLoaded = ref(false)
|
||||
|
||||
function filterTimeDiffValues () {
|
||||
let timeDiffData = chartData.value.datasets[2].data as number[]
|
||||
// useNuxtApp().$logger.log('Length of timeDiffData before cleanup: ' + timeDiffData.keys.length)
|
||||
timeDiffData = timeDiffData.filter(val => val >= 1)
|
||||
// useNuxtApp().$logger.log('Length of timeDiffData after cleanup: ' + timeDiffData.keys.length)
|
||||
return timeDiffData
|
||||
}
|
||||
// Load CSV data when the component is mounted
|
||||
onMounted(async () => {
|
||||
await loadChartData('/data_10_16_2024.csv')
|
||||
chartData.value.datasets[2].data = filterTimeDiffValues()
|
||||
isLoaded.value = true
|
||||
})
|
||||
|
||||
return {
|
||||
chartData,
|
||||
chartOptions,
|
||||
isLoaded
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<style scoped>
|
||||
.chart-container {
|
||||
position: relative;
|
||||
height: 90vh;
|
||||
width: 90vw;
|
||||
}
|
||||
</style>
|
60
components/viz/chartConfig.ts
Normal file
60
components/viz/chartConfig.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
// Export data from CSV,
|
||||
|
||||
const data = {
|
||||
labels: [
|
||||
'16.10.24 09:50.123',
|
||||
'16.10.24 09:50.143',
|
||||
'16.10.24 09:50.166',
|
||||
'16.10.24 09:50.213',
|
||||
'16.10.24 09:50.199'
|
||||
],
|
||||
datasets: [
|
||||
{
|
||||
label: 'Lautstärke (sensors_ambientData_noise)',
|
||||
backgroundColor: '#42a5f5',
|
||||
borderColor: '#1e88e5',
|
||||
data: [
|
||||
34.8861247388139, 34.8861247388139, 34.8861247388139, 38.0076076494897,
|
||||
38.0076076494897
|
||||
],
|
||||
fill: false
|
||||
},
|
||||
{
|
||||
label: 'Störfaktor (Mindboost Value)',
|
||||
backgroundColor: '#ffca28',
|
||||
borderColor: '#ff9800',
|
||||
data: [17.553421, 17.553421, 18.455361, 18.455361, 18.455361],
|
||||
fill: false
|
||||
},
|
||||
{
|
||||
label: 'time_diff',
|
||||
backgroundColor: '#fdctf',
|
||||
borderColor: '#ff9800',
|
||||
data: [143, 166, 213, 199, 214],
|
||||
fill: false
|
||||
}
|
||||
]
|
||||
}
|
||||
const options = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Timestamp'
|
||||
}
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Werte'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
// createMicrophoneSource,
|
||||
data,
|
||||
options
|
||||
}
|
16
components/viz/data/deepCareExtractor.ts
Normal file
16
components/viz/data/deepCareExtractor.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { extractAudioData } from './extractAudioData'
|
||||
|
||||
const labels: string[] = []
|
||||
const noise: number[] = []
|
||||
|
||||
// Funktion zum Laden der Daten und Initialisieren der Chart-Daten
|
||||
export const loadChartData = async (csvFilePath: string): Promise<void> => {
|
||||
const audioData = await extractAudioData(csvFilePath)
|
||||
|
||||
audioData.forEach((row:any) => {
|
||||
labels.push(row.timestamp)
|
||||
noise.push(row.sensors_ambientData_noise)
|
||||
})
|
||||
}
|
||||
|
||||
await loadChartData('/audioData.csv')
|
36
components/viz/data/extractAudioData.ts
Normal file
36
components/viz/data/extractAudioData.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import Papa from 'papaparse'
|
||||
|
||||
// Typdefinitionen für die Daten
|
||||
interface AudioData {
|
||||
timestamp: string
|
||||
sensors_ambientData_noise: number
|
||||
}
|
||||
|
||||
// Funktion zum Laden und Extrahieren der CSV-Daten
|
||||
export const extractAudioData = async (csvFilePath: string): Promise<AudioData[]> => {
|
||||
const response = await fetch(csvFilePath)
|
||||
const csvData = await response.text()
|
||||
|
||||
const audioData: AudioData[] = []
|
||||
|
||||
// eslint-disable-next-line import/no-named-as-default-member
|
||||
Papa.parse(csvData, {
|
||||
header: true,
|
||||
skipEmptyLines: true,
|
||||
complete: (result) => {
|
||||
result.data.forEach((row: any) => {
|
||||
// Extrahiere und parse die Daten
|
||||
const timestamp = row.timestamp
|
||||
const noise = parseFloat(row.sensors_ambientData_noise)
|
||||
|
||||
if (timestamp && !isNaN(noise)) {
|
||||
audioData.push({ timestamp, sensors_ambientData_noise: noise })
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(audioData), 0) // Simuliere async Verarbeitung
|
||||
})
|
||||
}
|
211
components/viz/dataExtractor.ts
Normal file
211
components/viz/dataExtractor.ts
Normal file
@@ -0,0 +1,211 @@
|
||||
import type { ChartData, ChartOptions } from 'chart.js'
|
||||
import Papa from 'papaparse'
|
||||
|
||||
// Initialize empty arrays for the chart data
|
||||
const labels: string[] = []
|
||||
const noise: number[] = []
|
||||
const disturb: number[] = []
|
||||
let timediff: number[] = []
|
||||
|
||||
// Funktion zum Formatieren des Sensorwerts
|
||||
function formatNoiseValue (rawValue: string):number {
|
||||
const firstFourDigits = rawValue.slice(0, 4) // Nimm die ersten 4 Zeichen
|
||||
const formattedValue = parseFloat(firstFourDigits.slice(0, 2) + '.' + firstFourDigits.slice(2)) // Füge Dezimalpunkt nach zwei Zeichen ein
|
||||
return formattedValue
|
||||
}
|
||||
|
||||
// to estimate the data quality a factor in % is calculated to figure out,
|
||||
// how much the data points differ from their 200ms timing
|
||||
export function filterTimeDiffValues (timeDiff:number[]) {
|
||||
// Filter the array to remove all differences below 1
|
||||
const filteredTimediff = timeDiff.filter(diff => diff >= 1)
|
||||
// Optionally, process the filtered data further
|
||||
return filteredTimediff
|
||||
}
|
||||
|
||||
// function smoothNoise (data: number[], windowSize: number): number[] {
|
||||
// const smoothed: number[] = []
|
||||
|
||||
// for (let i = 0; i < data.length; i++) {
|
||||
// const start = Math.max(0, i - Math.floor(windowSize / 2))
|
||||
// const end = Math.min(data.length, i + Math.floor(windowSize / 2) + 1)
|
||||
// const average =
|
||||
// data.slice(start, end).reduce((sum, value) => sum + value, 0) /
|
||||
// (end - start)
|
||||
// smoothed.push(average)
|
||||
// }
|
||||
|
||||
// return smoothed
|
||||
// };
|
||||
|
||||
// Fetch and parse the CSV file
|
||||
export const loadChartData = async (csvFilePath: string): Promise<void> => {
|
||||
const response = await fetch(csvFilePath)
|
||||
const csvData = await response.text()
|
||||
|
||||
// eslint-disable-next-line import/no-named-as-default-member
|
||||
Papa.parse(csvData, {
|
||||
header: true,
|
||||
skipEmptyLines: true,
|
||||
complete: (result) => {
|
||||
result.data.forEach((row: any) => {
|
||||
labels.push(row.timestamp)
|
||||
noise.push(formatNoiseValue(row.sensors_ambientData_noise.replace(/\./g, '')
|
||||
))
|
||||
disturb.push(parseFloat(row.disturbance_analysisData))
|
||||
timediff.push(parseFloat(row.time_diff || '0')) // Default to 0 if empty
|
||||
})
|
||||
const cleanTimeDiff: number[] = []
|
||||
timediff.forEach((diff) => {
|
||||
if (diff >= 1) { cleanTimeDiff.push(diff) }
|
||||
})
|
||||
timediff = cleanTimeDiff
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// function smoothNoise (data: number[], windowSize: number): number[] {
|
||||
// const smoothed: number[] = []
|
||||
|
||||
// for (let i = 0; i < data.length; i++) {
|
||||
// const start = Math.max(0, i - Math.floor(windowSize / 2))
|
||||
// const end = Math.min(data.length, i + Math.floor(windowSize / 2) + 1)
|
||||
// const average =
|
||||
// data.slice(start, end).reduce((sum, value) => sum + value, 0) /
|
||||
// (end - start)
|
||||
// smoothed.push(average)
|
||||
// }
|
||||
|
||||
// return smoothed
|
||||
// };
|
||||
|
||||
// Fetch and parse the CSV file
|
||||
export const loadCleanChartData = async (csvFilePath: string): Promise<void> => {
|
||||
const response = await fetch(csvFilePath)
|
||||
const csvData = await response.text()
|
||||
|
||||
// eslint-disable-next-line import/no-named-as-default-member
|
||||
Papa.parse(csvData, {
|
||||
header: true,
|
||||
skipEmptyLines: true,
|
||||
complete: (result) => {
|
||||
result.data.forEach((row: any) => {
|
||||
labels.push(row.timestamp)
|
||||
noise.push(formatNoiseValue(row.sensors_ambientData_noise.replace(/\./g, '')
|
||||
))
|
||||
disturb.push(parseFloat(row.disturbance_analysisData))
|
||||
timediff.push(parseFloat(row.time_diff || '0')) // Default to 0 if empty
|
||||
})
|
||||
const cleanTimeDiff: number[] = []
|
||||
timediff.forEach((diff) => {
|
||||
if (diff >= 1) { cleanTimeDiff.push(diff) }
|
||||
})
|
||||
timediff = cleanTimeDiff
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Export chart data and options (initially empty; will be filled after loading the CSV)
|
||||
export const data: ChartData<'line'> = {
|
||||
labels,
|
||||
datasets: [
|
||||
{
|
||||
label: 'Lautstärke (Noise)',
|
||||
data: noise,
|
||||
borderColor: '#42a5f5',
|
||||
backgroundColor: '#42a5f5',
|
||||
fill: true,
|
||||
tension: 0.8,
|
||||
yAxisID: 'y-noise'
|
||||
},
|
||||
{
|
||||
label: 'Störfaktor (Disturbance)',
|
||||
data: disturb,
|
||||
borderColor: '#ff9800',
|
||||
backgroundColor: '#ff9800',
|
||||
fill: false,
|
||||
tension: 0.2,
|
||||
yAxisID: 'y-disturbance'
|
||||
},
|
||||
{
|
||||
label: 'time_diff',
|
||||
backgroundColor: '#fdctf',
|
||||
borderColor: '#C9C9C9',
|
||||
data: timediff,
|
||||
fill: false,
|
||||
tension: 1,
|
||||
yAxisID: 'y-timediff'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
export const options: ChartOptions<'line'> = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
},
|
||||
zoom: {
|
||||
zoom: {
|
||||
wheel: {
|
||||
enabled: true // Enable zooming with the mouse wheel
|
||||
},
|
||||
pinch: {
|
||||
enabled: true // Enable zooming with touch gestures
|
||||
},
|
||||
mode: 'Tropics' // Allow zooming in both directions
|
||||
},
|
||||
pan: {
|
||||
enabled: true, // Enable panning
|
||||
mode: 'xy' // Allow panning in both directions
|
||||
}
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lautstärke und Störfaktor'
|
||||
}
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Timestamp'
|
||||
}
|
||||
},
|
||||
'y-noise': {
|
||||
type: 'linear',
|
||||
position: 'left', // Noise scale on the left
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Lautstärke (Geräuschkulisse)'
|
||||
},
|
||||
grid: {
|
||||
drawOnChartArea: true // Show grid lines for the noise Y-axis
|
||||
}
|
||||
},
|
||||
'y-disturbance': {
|
||||
type: 'linear',
|
||||
position: 'right', // Disturbance scale on the right
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Störfaktor (Disturbance)'
|
||||
},
|
||||
grid: {
|
||||
drawOnChartArea: false // Disable grid lines for the disturbance Y-axis
|
||||
}
|
||||
},
|
||||
'y-timediff': {
|
||||
type: 'linear',
|
||||
position: 'right', // Disturbance scale on the right
|
||||
title: {
|
||||
display: true,
|
||||
text: 'Zeitunterschied'
|
||||
},
|
||||
grid: {
|
||||
drawOnChartArea: false // Disable grid lines for the disturbance Y-axis
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user