Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+7
View File
@@ -0,0 +1,7 @@
/* @license
Papa Parse
v5.3.2
https://github.com/mholt/PapaParse
License: MIT
*/
!function(e,t){"function"==typeof define&&define.amd?define([],t):"object"==typeof module&&"undefined"!=typeof exports?module.exports=t():e.Papa=t()}(this,function s(){"use strict";var f="undefined"!=typeof self?self:"undefined"!=typeof window?window:void 0!==f?f:{};var n=!f.document&&!!f.postMessage,o=n&&/blob:/i.test((f.location||{}).protocol),a={},h=0,b={parse:function(e,t){var i=(t=t||{}).dynamicTyping||!1;M(i)&&(t.dynamicTypingFunction=i,i={});if(t.dynamicTyping=i,t.transform=!!M(t.transform)&&t.transform,t.worker&&b.WORKERS_SUPPORTED){var r=function(){if(!b.WORKERS_SUPPORTED)return!1;var e=(i=f.URL||f.webkitURL||null,r=s.toString(),b.BLOB_URL||(b.BLOB_URL=i.createObjectURL(new Blob(["(",r,")();"],{type:"text/javascript"})))),t=new f.Worker(e);var i,r;return t.onmessage=_,t.id=h++,a[t.id]=t}();return r.userStep=t.step,r.userChunk=t.chunk,r.userComplete=t.complete,r.userError=t.error,t.step=M(t.step),t.chunk=M(t.chunk),t.complete=M(t.complete),t.error=M(t.error),delete t.worker,void r.postMessage({input:e,config:t,workerId:r.id})}var n=null;b.NODE_STREAM_INPUT,"string"==typeof e?n=t.download?new l(t):new p(t):!0===e.readable&&M(e.read)&&M(e.on)?n=new g(t):(f.File&&e instanceof File||e instanceof Object)&&(n=new c(t));return n.stream(e)},unparse:function(e,t){var n=!1,_=!0,m=",",y="\r\n",s='"',a=s+s,i=!1,r=null,o=!1;!function(){if("object"!=typeof t)return;"string"!=typeof t.delimiter||b.BAD_DELIMITERS.filter(function(e){return-1!==t.delimiter.indexOf(e)}).length||(m=t.delimiter);("boolean"==typeof t.quotes||"function"==typeof t.quotes||Array.isArray(t.quotes))&&(n=t.quotes);"boolean"!=typeof t.skipEmptyLines&&"string"!=typeof t.skipEmptyLines||(i=t.skipEmptyLines);"string"==typeof t.newline&&(y=t.newline);"string"==typeof t.quoteChar&&(s=t.quoteChar);"boolean"==typeof t.header&&(_=t.header);if(Array.isArray(t.columns)){if(0===t.columns.length)throw new Error("Option columns is empty");r=t.columns}void 0!==t.escapeChar&&(a=t.escapeChar+s);("boolean"==typeof t.escapeFormulae||t.escapeFormulae instanceof RegExp)&&(o=t.escapeFormulae instanceof RegExp?t.escapeFormulae:/^[=+\-@\t\r].*$/)}();var h=new RegExp(j(s),"g");"string"==typeof e&&(e=JSON.parse(e));if(Array.isArray(e)){if(!e.length||Array.isArray(e[0]))return u(null,e,i);if("object"==typeof e[0])return u(r||Object.keys(e[0]),e,i)}else if("object"==typeof e)return"string"==typeof e.data&&(e.data=JSON.parse(e.data)),Array.isArray(e.data)&&(e.fields||(e.fields=e.meta&&e.meta.fields||r),e.fields||(e.fields=Array.isArray(e.data[0])?e.fields:"object"==typeof e.data[0]?Object.keys(e.data[0]):[]),Array.isArray(e.data[0])||"object"==typeof e.data[0]||(e.data=[e.data])),u(e.fields||[],e.data||[],i);throw new Error("Unable to serialize unrecognized input");function u(e,t,i){var r="";"string"==typeof e&&(e=JSON.parse(e)),"string"==typeof t&&(t=JSON.parse(t));var n=Array.isArray(e)&&0<e.length,s=!Array.isArray(t[0]);if(n&&_){for(var a=0;a<e.length;a++)0<a&&(r+=m),r+=v(e[a],a);0<t.length&&(r+=y)}for(var o=0;o<t.length;o++){var h=n?e.length:t[o].length,u=!1,f=n?0===Object.keys(t[o]).length:0===t[o].length;if(i&&!n&&(u="greedy"===i?""===t[o].join("").trim():1===t[o].length&&0===t[o][0].length),"greedy"===i&&n){for(var d=[],l=0;l<h;l++){var c=s?e[l]:l;d.push(t[o][c])}u=""===d.join("").trim()}if(!u){for(var p=0;p<h;p++){0<p&&!f&&(r+=m);var g=n&&s?e[p]:p;r+=v(t[o][g],p)}o<t.length-1&&(!i||0<h&&!f)&&(r+=y)}}return r}function v(e,t){if(null==e)return"";if(e.constructor===Date)return JSON.stringify(e).slice(1,25);var i=!1;o&&"string"==typeof e&&o.test(e)&&(e="'"+e,i=!0);var r=e.toString().replace(h,a);return(i=i||!0===n||"function"==typeof n&&n(e,t)||Array.isArray(n)&&n[t]||function(e,t){for(var i=0;i<t.length;i++)if(-1<e.indexOf(t[i]))return!0;return!1}(r,b.BAD_DELIMITERS)||-1<r.indexOf(m)||" "===r.charAt(0)||" "===r.charAt(r.length-1))?s+r+s:r}}};if(b.RECORD_SEP=String.fromCharCode(30),b.UNIT_SEP=String.fromCharCode(31),b.BYTE_ORDER_MARK="\ufeff",b.BAD_DELIMITERS=["\r","\n",'"',b.BYTE_ORDER_MARK],b.WORKERS_SUPPORTED=!n&&!!f.Worker,b.NODE_STREAM_INPUT=1,b.LocalChunkSize=10485760,b.RemoteChunkSize=5242880,b.DefaultDelimiter=",",b.Parser=E,b.ParserHandle=i,b.NetworkStreamer=l,b.FileStreamer=c,b.StringStreamer=p,b.ReadableStreamStreamer=g,f.jQuery){var d=f.jQuery;d.fn.parse=function(o){var i=o.config||{},h=[];return this.each(function(e){if(!("INPUT"===d(this).prop("tagName").toUpperCase()&&"file"===d(this).attr("type").toLowerCase()&&f.FileReader)||!this.files||0===this.files.length)return!0;for(var t=0;t<this.files.length;t++)h.push({file:this.files[t],inputElem:this,instanceConfig:d.extend({},i)})}),e(),this;function e(){if(0!==h.length){var e,t,i,r,n=h[0];if(M(o.before)){var s=o.before(n.file,n.inputElem);if("object"==typeof s){if("abort"===s.action)return e="AbortError",t=n.file,i=n.inputElem,r=s.reason,void(M(o.error)&&o.error({name:e},t,i,r));if("skip"===s.action)return void u();"object"==typeof s.config&&(n.instanceConfig=d.extend(n.instanceConfig,s.config))}else if(Line truncated
File diff suppressed because it is too large. Load diff
@@ -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>