diff options
| author | grothedev <grothedev@gmail.com> | 2026-05-29 21:49:20 -0400 |
|---|---|---|
| committer | grothedev <grothedev@gmail.com> | 2026-05-29 21:49:20 -0400 |
| commit | 6196004b51a6850909c154f5402ff4858eab479a (patch) | |
| tree | 126b8bb1600d0a656e0df016e25d08c390f3540e /web-timeplot/src/data/parse-replay-csv.js | |
| parent | 27dc5849c3eaf4824d79938e7077abdbe2c82e24 (diff) | |
mv web stuff to root project dirHEADprototypeframeworkmain
Diffstat (limited to 'web-timeplot/src/data/parse-replay-csv.js')
| -rw-r--r-- | web-timeplot/src/data/parse-replay-csv.js | 108 |
1 files changed, 0 insertions, 108 deletions
diff --git a/web-timeplot/src/data/parse-replay-csv.js b/web-timeplot/src/data/parse-replay-csv.js deleted file mode 100644 index b6ce97a..0000000 --- a/web-timeplot/src/data/parse-replay-csv.js +++ /dev/null @@ -1,108 +0,0 @@ -function splitRow(line) { - return line.split(/[;,\t]/).map((value) => value.trim()); -} - -function isNumeric(value) { - return value !== '' && Number.isFinite(Number(value)); -} - -function detectHeader(rows) { - if (rows.length === 0) { - return { hasHeader: false, headers: [] }; - } - - const [firstRow] = rows; - const hasHeader = firstRow.some((value) => !isNumeric(value)); - return { - hasHeader, - headers: hasHeader ? firstRow.map((value) => value.toLowerCase()) : [], - }; -} - -function detectTimeScale(headers) { - const timeHeader = headers.find((header) => header.includes('time') || header.includes('timestamp')); - if (!timeHeader) { - return 1; - } - - if (timeHeader.includes('sec') && !timeHeader.includes('msec') && !timeHeader.includes('ms')) { - return 1000; - } - - return 1; -} - -function detectColumnIndexes(headers, columnCount) { - if (headers.length === 0) { - return { - timeIndex: columnCount > 1 ? 0 : -1, - valueIndex: columnCount > 1 ? 1 : 0, - }; - } - - const timeIndex = headers.findIndex((header) => header.includes('time') || header.includes('timestamp')); - const valueIndex = headers.findIndex((header) => header.includes('value') || header.includes('signal') || header.includes('y')); - - return { - timeIndex, - valueIndex: valueIndex >= 0 ? valueIndex : (headers.length > 1 ? 1 : 0), - }; -} - -export function parseReplayCsv(text, { sampleRateHz = 60 } = {}) { - const rows = text - .split(/\r?\n/) - .map((line) => line.trim()) - .filter((line) => line && !line.startsWith('#')) - .map(splitRow) - .filter((row) => row.some((value) => value !== '')); - - if (rows.length === 0) { - throw new Error('CSV file is empty'); - } - - const { hasHeader, headers } = detectHeader(rows); - const dataRows = hasHeader ? rows.slice(1) : rows; - const columnCount = rows[0].length; - const { timeIndex, valueIndex } = detectColumnIndexes(headers, columnCount); - const timeScale = detectTimeScale(headers); - const intervalMs = 1000 / Math.max(1, sampleRateHz); - - const points = dataRows - .map((row, index) => { - const rawValue = row[valueIndex]; - if (!isNumeric(rawValue)) { - return null; - } - - const parsedValue = Number(rawValue); - const parsedTime = timeIndex >= 0 && isNumeric(row[timeIndex]) - ? Number(row[timeIndex]) * timeScale - : index * intervalMs; - - return { - timeMs: parsedTime, - value: parsedValue, - }; - }) - .filter(Boolean) - .sort((left, right) => left.timeMs - right.timeMs); - - if (points.length === 0) { - throw new Error('CSV file did not contain any numeric data points'); - } - - const firstTime = points[0].timeMs; - const normalizedPoints = points.map((point) => ({ - timeMs: point.timeMs - firstTime, - value: point.value, - })); - - return { - points: normalizedPoints, - metadata: { - pointCount: normalizedPoints.length, - durationMs: normalizedPoints.at(-1)?.timeMs ?? 0, - }, - }; -} |
