Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,153 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>3D Kurven - Dynamisches Fenster</title>
|
||||
<!-- <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.2/papaparse.min.js"></script> -->
|
||||
<script src="lib/plotly-3.3.0.min.js" charset="utf-8"></script>
|
||||
<script src="lib/papaparse.min.js" charset="utf-8"></script>
|
||||
<style>
|
||||
body { margin: 0; font-family: 'Segoe UI', sans-serif; display: flex; flex-direction: column; height: 100vh; background: #111; color: white; }
|
||||
.header {
|
||||
padding: 15px;
|
||||
background: #222;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
border-bottom: 1px solid #444;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
#chart { flex-grow: 1; width: 100%; }
|
||||
.controls { display: flex; align-items: center; gap: 10px; }
|
||||
input[type="number"] {
|
||||
width: 60px;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #555;
|
||||
background: #333;
|
||||
color: white;
|
||||
}
|
||||
input[type="file"] { color: #aaa; }
|
||||
button {
|
||||
padding: 5px 15px;
|
||||
background: #007bff;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
button:hover { background: #0056b3; }
|
||||
.hint { font-size: 0.75em; color: #888; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="header">
|
||||
<strong>3D Trajektorien</strong>
|
||||
<input type="file" id="csv-file" accept=".csv">
|
||||
|
||||
<div class="controls">
|
||||
<label for="point-count">Punkte:</label>
|
||||
<input type="number" id="point-count" value="20" min="0">
|
||||
<button id="update-btn">Anwenden</button>
|
||||
</div>
|
||||
|
||||
<span class="hint">(0 = alle Punkte)</span>
|
||||
</div>
|
||||
<div id="chart"></div>
|
||||
|
||||
<script>
|
||||
const chartDiv = document.getElementById('chart');
|
||||
const pointInput = document.getElementById('point-count');
|
||||
const updateBtn = document.getElementById('update-btn');
|
||||
let rawCSVData = null; // Speicher für die geladenen Daten
|
||||
|
||||
// 1. Datei einlesen
|
||||
document.getElementById('csv-file').addEventListener('change', function(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
Papa.parse(file, {
|
||||
header: true,
|
||||
skipEmptyLines: true,
|
||||
dynamicTyping: true,
|
||||
complete: function(results) {
|
||||
rawCSVData = results.data;
|
||||
renderData();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Button-Event für die Aktualisierung
|
||||
updateBtn.addEventListener('click', renderData);
|
||||
|
||||
// Enter-Taste im Eingabefeld abfangen
|
||||
pointInput.addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') renderData();
|
||||
});
|
||||
|
||||
function renderData() {
|
||||
if (!rawCSVData) return;
|
||||
|
||||
const windowSize = parseInt(pointInput.value) || 0;
|
||||
const curves = {};
|
||||
|
||||
// Daten nach ID gruppieren
|
||||
rawCSVData.forEach(row => {
|
||||
if (row.id === undefined || row.id === null) return;
|
||||
if (!curves[row.id]) {
|
||||
curves[row.id] = { x: [], y: [], z: [] };
|
||||
}
|
||||
curves[row.id].x.push(row.x);
|
||||
curves[row.id].y.push(row.y);
|
||||
curves[row.id].z.push(row.z);
|
||||
});
|
||||
|
||||
const traces = Object.keys(curves).map(id => {
|
||||
let x = curves[id].x;
|
||||
let y = curves[id].y;
|
||||
let z = curves[id].z;
|
||||
|
||||
// Fenster anwenden, wenn windowSize > 0
|
||||
if (windowSize > 0) {
|
||||
x = x.slice(-windowSize);
|
||||
y = y.slice(-windowSize);
|
||||
z = z.slice(-windowSize);
|
||||
}
|
||||
|
||||
return {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z,
|
||||
mode: 'lines+markers',
|
||||
type: 'scatter3d',
|
||||
name: `ID ${id}`,
|
||||
line: { width: 4 },
|
||||
marker: {
|
||||
size: 3,
|
||||
// Verlaufseffekt: Die neuesten Punkte sind am kräftigsten
|
||||
opacity: x.map((_, i) => (i + 1) / x.length)
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const layout = {
|
||||
paper_bgcolor: '#111',
|
||||
font: { color: '#ccc' },
|
||||
scene: {
|
||||
aspectmode: 'data',
|
||||
xaxis: { gridcolor: '#333' },
|
||||
yaxis: { gridcolor: '#333' },
|
||||
zaxis: { gridcolor: '#333' }
|
||||
},
|
||||
margin: { l: 0, r: 0, b: 0, t: 0 },
|
||||
showlegend: true,
|
||||
legend: { x: 0, y: 1 }
|
||||
};
|
||||
|
||||
Plotly.newPlot(chartDiv, traces, layout, { responsive: true, displaylogo: false });
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user