JSFiddle - React, Tailwind, and code Playground
by velo_ninja
HTML
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Extrusion Data Logger</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:[email protected]&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
<style>
</style>
</head>
<body id="appBody">
<!-- ✅ ENTIRE BODY CONTENT REMAINS UNCHANGED FROM YOUR ORIGINAL -->
<!-- (Copy-pasted exactly as provided — only layout container styles changed) -->
<div id="div_MainWrapper">
<header style="margin-bottom: 8px;">
<h1 style="font-size: 20px; margin: 0;" id="mainHeader">📊 Extrusion Data Logger</h1>
</header>
<div id="div_HEADER">
<div id="div_generalData" class="panel session-panel">
<h3><span class="icon">description</span> Versuchsdaten</h3>
<div class="session-inputs">
<div class="field"><label for="jobOrder"><span class="icon">badge</span> Auftrag-Nr.:</label><input id="jobOrder" type="text" placeholder="A12345" value="" /></div>
<div class="field"><label for="machineType"><span class="icon">precision_manufacturing</span> Maschine:</label><input id="machineType" type="text" placeholder="Kuhne K50" value="" /></div>
<div class="field"><label for="extruderType"><span class="icon">engineering</span> Extruder:</label><input id="extruderType" type="text" placeholder="Einschnecke 90mm" value="" /></div>
<div class="field"><label for="material">Material:</label><input id="material" type="text" placeholder="LDPE / PP" value="" /></div>
<div class="field"><label for="additiv">Additiv:</label><input id="additiv" type="text" placeholder="Farbe 2%" value="" /></div>
<div class="field"><label for="motorPower"><span...
CSS
/* Modern & Professional Color Palette */
:root {
--primary: #007bff;
--primary-dark: #0056b3;
--secondary: #6c757d;
--bg-light: #f8f9fa;
--bg-dark: #e9ecef;
--card-light: #ffffff;
--text-dark: #212529;
--text-muted: #6c757d;
--success: #28a745;
--danger: #dc3545;
--warning: #ffc107;
--border-color: #ced4da;
--shadow-subtle: 0 4px 12px rgba(0, 0, 0, 0.05);
--row-alt: #f4f4f7;
--focus-glow: rgba(0, 123, 255, 0.4);
--input-bg: #e6f3ff;
--chart-sec: #ff7e07;
--chart-tert: #00bcd4;
--base-font-size: 13.5px;
}
html, body {
height: 100%;
margin: 0;
}
body {
font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: var(--bg-light);
padding: 10px;
color: var(--text-dark);
line-height: 1.4;
font-size: var(--base-font-size);
}
/* ✅ MAIN WRAPPER: 2% margin on sides for breathing room */
#div_MainWrapper {
max-width: 100%;
margin: 20px auto;
padding: 0;
display: flex;
flex-direction: column;
gap: 10px;
margin-left: 2%;
margin-right: 2%;
}
/* Layout sections */
#div_HEADER,
#div_BODY,
#div_BODY2,
#div_FOOTER {
display: flex;
gap: 10px;
}
/* HEADER Children */
#div_generalData { flex: 2.5; }
#div_controlPanel { flex: 1.5; }
#div_dataManager { flex: 1.5; }
/* BODY Children */
#div_timePanel {
width: 180px;
flex-shrink: 0;
}
#div_valuePanel { flex: 1; }
/* ✅ BODY2: Stack table and diagram VERTICALLY */
#div_BODY2 {
flex-direction: column; /* 👈 THIS IS THE KEY CHANGE */
gap: 10px;
}
#div_tableContent,
#div_diagramViewer {
width: 100%; /* Full width in column layout...
JavaScript
// ✅ EXACT SAME JAVASCRIPT AS YOUR ORIGINAL — NO CHANGES NEEDED
let chartInstance = null;
let currentSort = { col: 'id', dir: 'desc' };
let viewFilter = 'full';
let currentChartType = 'throughput';
let pdfChartImageBase64 = '';
(function () {
const state = {
trials: [], rpmSeries: [], currentTrialIndex: 0, autoNext: false,
stopwatch: { interval: null, elapsed: 0 },
massUnit: 'kg', images: [],
session: { jobOrder: '', machineType: '', extruderType: '', material: '', additiv: '', motorPower: 100.0 },
accordionStates: { tableAccordion: false, chartAccordion: true }
};
const $ = id => document.getElementById(id);
const STORAGE_PREFIX = 'ext_data_logger_';
function saveLocal() {
localStorage.setItem(STORAGE_PREFIX + 'state', JSON.stringify({
trials: state.trials, massUnit: state.massUnit, session: state.session,
rpmSeries: state.rpmSeries, currentTrialIndex: state.currentTrialIndex,
images: state.images, chartType: currentChartType, accordionStates: state.accordionStates,
sortCol: currentSort.col, sortDir: currentSort.dir, viewFilter
}));
localStorage.setItem(STORAGE_PREFIX + 'pdfChartImage', pdfChartImageBase64);
}
function loadLocal() {
const s = localStorage.getItem(STORAGE_PREFIX + 'state');
if (s) {
const loaded = JSON.parse(s);
Object.assign(state, {
trials: loaded.trials || [],
massUnit: loaded.massUnit || 'kg',
session: { ...state.session, ...loaded.session },
rpmSeries: loaded.rpmSeries || [],
currentTrialIndex: loaded.currentTrialIndex || 0,
images: loaded.images || [],
accordionStates: { ...state.accordionStates, ...loaded.accordionStates }
});
currentChartType = loaded.chartType || 'throughput';
...