Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
| Prossima revisione | Revisione precedente | ||
| dashboard:monitoraggio_terapia_antibiotica_-_dot [2025/09/27 06:51] – creata neoadmin | dashboard:monitoraggio_terapia_antibiotica_-_dot [2025/09/27 22:51] (versione attuale) – neoadmin | ||
|---|---|---|---|
| Linea 1: | Linea 1: | ||
| - | < | + | [[https://docuneo.org/app_est/control_chart_final%20(2).html]] |
| - | < | + | |
| - | <meta charset=" | + | |
| - | <meta name=" | + | |
| - | < | + | |
| - | <script src=" | + | |
| - | < | + | |
| - | body { | + | |
| - | font-family: | + | |
| - | margin: 0; | + | |
| - | padding: 20px; | + | |
| - | background: #f5f5f5; | + | |
| - | } | + | |
| - | .container { | + | |
| - | max-width: 1200px; | + | |
| - | margin: 0 auto; | + | |
| - | background: white; | + | |
| - | border-radius: | + | |
| - | padding: 20px; | + | |
| - | box-shadow: 0 4px 6px rgba(0, | + | |
| - | } | + | |
| - | .header { | + | |
| - | text-align: center; | + | |
| - | padding: 20px; | + | |
| - | background: #2c3e50; | + | |
| - | color: white; | + | |
| - | border-radius: | + | |
| - | margin-bottom: | + | |
| - | } | + | |
| - | .header.dot { background: #9b59b6; } | + | |
| - | .header.manual { background: #2c3e50; } | + | |
| - | + | ||
| - | .sample-buttons { | + | |
| - | display: grid; | + | |
| - | grid-template-columns: | + | |
| - | gap: 10px; | + | |
| - | margin: 20px 0; | + | |
| - | } | + | |
| - | .sample-btn { | + | |
| - | padding: 15px; | + | |
| - | border: none; | + | |
| - | border-radius: | + | |
| - | color: white; | + | |
| - | cursor: pointer; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | .btn-dot { background: #9b59b6; } | + | |
| - | + | ||
| - | /* GRAFICO IN EVIDENZA */ | + | |
| - | .chart-container { | + | |
| - | margin: 20px 0; | + | |
| - | padding: 20px; | + | |
| - | background: #fff; | + | |
| - | border-radius: | + | |
| - | border: 3px solid #007bff; | + | |
| - | box-shadow: 0 8px 16px rgba(0, | + | |
| - | } | + | |
| - | .chart-wrapper { | + | |
| - | position: relative; | + | |
| - | height: 500px; | + | |
| - | margin: 20px 0; | + | |
| - | } | + | |
| - | + | ||
| - | .stats { | + | |
| - | display: grid; | + | |
| - | grid-template-columns: | + | |
| - | gap: 15px; | + | |
| - | margin: 20px 0; | + | |
| - | } | + | |
| - | .stat { | + | |
| - | text-align: center; | + | |
| - | padding: 15px; | + | |
| - | background: #f8f9fa; | + | |
| - | border-radius: | + | |
| - | } | + | |
| - | .stat-value { | + | |
| - | font-size: 1.5rem; | + | |
| - | font-weight: | + | |
| - | color: #2c3e50; | + | |
| - | } | + | |
| - | .stat-label { | + | |
| - | font-size: 0.9rem; | + | |
| - | color: #666; | + | |
| - | margin-top: 5px; | + | |
| - | } | + | |
| - | + | ||
| - | /* SEZIONI COLLASSABILI */ | + | |
| - | .collapsible-section { | + | |
| - | margin: 15px 0; | + | |
| - | border: 1px solid #ddd; | + | |
| - | border-radius: | + | |
| - | overflow: hidden; | + | |
| - | } | + | |
| - | .collapsible-header { | + | |
| - | background: #f8f9fa; | + | |
| - | padding: 15px 20px; | + | |
| - | cursor: pointer; | + | |
| - | display: flex; | + | |
| - | justify-content: | + | |
| - | align-items: | + | |
| - | font-weight: | + | |
| - | color: #2c3e50; | + | |
| - | transition: background 0.3s; | + | |
| - | } | + | |
| - | .collapsible-header: | + | |
| - | background: #e9ecef; | + | |
| - | } | + | |
| - | .collapsible-header .toggle-icon { | + | |
| - | font-size: 18px; | + | |
| - | transition: transform 0.3s; | + | |
| - | } | + | |
| - | .collapsible-header.collapsed .toggle-icon { | + | |
| - | transform: rotate(-90deg); | + | |
| - | } | + | |
| - | .collapsible-content { | + | |
| - | padding: 20px; | + | |
| - | background: white; | + | |
| - | max-height: 2000px; | + | |
| - | transition: max-height 0.3s ease-out, padding 0.3s; | + | |
| - | overflow: hidden; | + | |
| - | } | + | |
| - | .collapsible-content.collapsed { | + | |
| - | max-height: 0; | + | |
| - | padding: 0 20px; | + | |
| - | } | + | |
| - | + | ||
| - | .alert { | + | |
| - | padding: 15px; | + | |
| - | border-radius: | + | |
| - | margin: 15px 0; | + | |
| - | border-left: | + | |
| - | } | + | |
| - | .alert-success { background: #d4edda; border-color: | + | |
| - | .alert-info { background: #d1ecf1; border-color: | + | |
| - | .alert-danger { background: #f8d7da; border-color: | + | |
| - | + | ||
| - | .data-management { | + | |
| - | background: #f8f9fa; | + | |
| - | padding: 10px 15px; | + | |
| - | border-radius: | + | |
| - | margin-bottom: | + | |
| - | display: flex; | + | |
| - | align-items: | + | |
| - | gap: 10px; | + | |
| - | flex-wrap: wrap; | + | |
| - | } | + | |
| - | .data-management-label { | + | |
| - | font-size: 12px; | + | |
| - | color: #666; | + | |
| - | font-weight: | + | |
| - | margin-right: | + | |
| - | } | + | |
| - | + | ||
| - | .save-buttons { | + | |
| - | display: flex; | + | |
| - | gap: 8px; | + | |
| - | margin: 15px 0; | + | |
| - | flex-wrap: wrap; | + | |
| - | } | + | |
| - | .save-btn { | + | |
| - | padding: 6px 12px; | + | |
| - | border: none; | + | |
| - | border-radius: | + | |
| - | cursor: pointer; | + | |
| - | font-weight: | + | |
| - | font-size: 12px; | + | |
| - | } | + | |
| - | .save-data-btn { background: #28a745; color: white; } | + | |
| - | .save-chart-btn { background: #17a2b8; color: white; } | + | |
| - | .load-data-btn { background: #ffc107; color: #333; } | + | |
| - | + | ||
| - | .manual-input { | + | |
| - | background: #f8f9fa; | + | |
| - | padding: 20px; | + | |
| - | border-radius: | + | |
| - | margin: 20px 0; | + | |
| - | } | + | |
| - | .input-row { | + | |
| - | display: grid; | + | |
| - | grid-template-columns: | + | |
| - | gap: 10px; | + | |
| - | margin-bottom: | + | |
| - | align-items: | + | |
| - | } | + | |
| - | .input-row input { | + | |
| - | padding: 8px; | + | |
| - | border: 1px solid #ddd; | + | |
| - | border-radius: | + | |
| - | font-size: 14px; | + | |
| - | } | + | |
| - | .add-row-btn, | + | |
| - | padding: 8px 12px; | + | |
| - | border: none; | + | |
| - | border-radius: | + | |
| - | cursor: pointer; | + | |
| - | font-size: 16px; | + | |
| - | } | + | |
| - | .add-row-btn { | + | |
| - | background: #28a745; | + | |
| - | color: white; | + | |
| - | margin-top: 10px; | + | |
| - | } | + | |
| - | .remove-row-btn { | + | |
| - | background: #dc3545; | + | |
| - | color: white; | + | |
| - | } | + | |
| - | .process-btn { | + | |
| - | background: #007bff; | + | |
| - | color: white; | + | |
| - | padding: 12px 24px; | + | |
| - | border: none; | + | |
| - | border-radius: | + | |
| - | cursor: pointer; | + | |
| - | font-size: 16px; | + | |
| - | margin-top: 15px; | + | |
| - | } | + | |
| - | + | ||
| - | .data-table { | + | |
| - | width: 100%; | + | |
| - | border-collapse: | + | |
| - | margin: 20px 0; | + | |
| - | } | + | |
| - | .data-table th, .data-table td { | + | |
| - | border: 1px solid #ddd; | + | |
| - | padding: 8px; | + | |
| - | text-align: left; | + | |
| - | } | + | |
| - | .data-table th { | + | |
| - | background: #f2f2f2; | + | |
| - | font-weight: | + | |
| - | } | + | |
| - | .violation { background: #ffe6e6; } | + | |
| - | + | ||
| - | .hidden { display: none; } | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <h1 id=" | + | |
| - | <p id=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <button class=" | + | |
| - | 💊 DOT - Days of Therapy | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div id=" | + | |
| - | + | ||
| - | <!-- ============ GRAFICO IN ALTO - SEMPRE VISIBILE ============ --> | + | |
| - | <div class=" | + | |
| - | <h2 id=" | + | |
| - | <div class=" | + | |
| - | <canvas id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- Statistiche --> | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <span class=" | + | |
| - | <button class=" | + | |
| - | <button class=" | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- ============ SEZIONE COLLASSABILE: | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | <span class=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | <span class=" | + | |
| - | <button class=" | + | |
| - | <button class=" | + | |
| - | <button class=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div style=" | + | |
| - | <label style=" | + | |
| - | <input type=" | + | |
| - | </ | + | |
| - | + | ||
| - | <div style=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <div id=" | + | |
| - | <div class=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <button class=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <button class=" | + | |
| - | <button class=" | + | |
| - | + | ||
| - | <input type=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | <!-- ============ SEZIONE COLLASSABILE: | + | |
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | <span class=" | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | <table class=" | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | <tbody id=" | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | let currentChart = null; | + | |
| - | let currentData = []; | + | |
| - | + | ||
| - | const examples = { | + | |
| - | dot: { | + | |
| - | theme: ' | + | |
| - | name: 'DOT - Days of Therapy', | + | |
| - | icon: ' | + | |
| - | units: ' | + | |
| - | data: [ | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | {periodo: ' | + | |
| - | ] | + | |
| - | } | + | |
| - | }; | + | |
| - | + | ||
| - | function loadSample(type) { | + | |
| - | const example = examples[type]; | + | |
| - | processData(example.data, | + | |
| - | } | + | |
| - | + | ||
| - | function toggleSection(sectionId) { | + | |
| - | const content = document.getElementById(sectionId + ' | + | |
| - | const header = content.previousElementSibling; | + | |
| - | content.classList.toggle(' | + | |
| - | header.classList.toggle(' | + | |
| - | } | + | |
| - | + | ||
| - | function processData(data, | + | |
| - | if (!config) { | + | |
| - | config = { | + | |
| - | theme: ' | + | |
| - | name: 'Dati Manuali', | + | |
| - | icon: ' | + | |
| - | units: '%' | + | |
| - | }; | + | |
| - | } | + | |
| - | + | ||
| - | currentData = data; | + | |
| - | + | ||
| - | const values = data.map(d => d.valore); | + | |
| - | const mean = values.reduce((a, | + | |
| - | const std = Math.sqrt(values.reduce((sum, | + | |
| - | const ucl = mean + 3 * std; | + | |
| - | const lcl = Math.max(0, mean - 3 * std); | + | |
| - | + | ||
| - | const violations = []; | + | |
| - | values.forEach((val, | + | |
| - | if (val > ucl || val < lcl) violations.push(i); | + | |
| - | }); | + | |
| - | + | ||
| - | updateHeader(config); | + | |
| - | updateStats(mean, | + | |
| - | createChart(data, | + | |
| - | updateTable(data, | + | |
| - | showAlert(violations.length, | + | |
| - | } | + | |
| - | + | ||
| - | function updateHeader(config) { | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| - | + | ||
| - | function updateStats(mean, | + | |
| - | const formatValue = (val) => { | + | |
| - | if (val < 1 && val > 0) return (val * 100).toFixed(1) + ' | + | |
| - | return val.toFixed(1); | + | |
| - | }; | + | |
| - | + | ||
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| - | + | ||
| - | function createChart(data, | + | |
| - | if (currentChart) { | + | |
| - | currentChart.destroy(); | + | |
| - | currentChart = null; | + | |
| - | } | + | |
| - | + | ||
| - | document.getElementById(' | + | |
| - | + | ||
| - | const values = data.map(d => d.valore); | + | |
| - | const labels = data.map((d, | + | |
| - | const colors = values.map((val, | + | |
| - | const sizes = values.map((val, | + | |
| - | + | ||
| - | const formatValue = (val) => { | + | |
| - | if (val < 1 && val > 0) return (val * 100).toFixed(1) + ' | + | |
| - | return val.toFixed(1); | + | |
| - | }; | + | |
| - | + | ||
| - | const ctx = document.getElementById(' | + | |
| - | currentChart = new Chart(ctx, { | + | |
| - | type: ' | + | |
| - | data: { | + | |
| - | labels: labels, | + | |
| - | datasets: [{ | + | |
| - | label: `${config.name} (${config.units})`, | + | |
| - | data: values, | + | |
| - | borderColor: | + | |
| - | backgroundColor: | + | |
| - | pointRadius: | + | |
| - | pointBackgroundColor: | + | |
| - | fill: false, | + | |
| - | tension: 0.1 | + | |
| - | }, { | + | |
| - | label: `UCL (${formatValue(ucl)})`, | + | |
| - | data: Array(values.length).fill(ucl), | + | |
| - | borderColor: | + | |
| - | borderDash: [5, 5], | + | |
| - | pointRadius: | + | |
| - | fill: false | + | |
| - | }, { | + | |
| - | label: `Media (${formatValue(mean)})`, | + | |
| - | data: Array(values.length).fill(mean), | + | |
| - | borderColor: | + | |
| - | pointRadius: | + | |
| - | fill: false | + | |
| - | }, { | + | |
| - | label: `LCL (${formatValue(lcl)})`, | + | |
| - | data: Array(values.length).fill(lcl), | + | |
| - | borderColor: | + | |
| - | borderDash: [5, 5], | + | |
| - | pointRadius: | + | |
| - | fill: false | + | |
| - | }] | + | |
| - | }, | + | |
| - | options: { | + | |
| - | responsive: true, | + | |
| - | maintainAspectRatio: | + | |
| - | plugins: { | + | |
| - | title: { | + | |
| - | display: true, | + | |
| - | text: `${config.icon} Control Chart - ${config.name}`, | + | |
| - | font: { size: 16, weight: ' | + | |
| - | } | + | |
| - | }, | + | |
| - | scales: { | + | |
| - | y: { | + | |
| - | title: { | + | |
| - | display: true, | + | |
| - | text: `${config.name} (${config.units})` | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | } | + | |
| - | }); | + | |
| - | } | + | |
| - | + | ||
| - | function updateTable(data, | + | |
| - | const tbody = document.getElementById(' | + | |
| - | tbody.innerHTML = ''; | + | |
| - | + | ||
| - | data.forEach((row, | + | |
| - | const tr = document.createElement(' | + | |
| - | if (violations.includes(i)) tr.className = ' | + | |
| - | tr.innerHTML = ` | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | `; | + | |
| - | tbody.appendChild(tr); | + | |
| - | }); | + | |
| - | } | + | |
| - | + | ||
| - | function showAlert(violationsCount, | + | |
| - | const status = document.getElementById(' | + | |
| - | status.classList.remove(' | + | |
| - | + | ||
| - | if (violationsCount === 0) { | + | |
| - | status.innerHTML = `<div class=" | + | |
| - | } else { | + | |
| - | status.innerHTML = `<div class=" | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | function addRow() { | + | |
| - | const container = document.getElementById(' | + | |
| - | const newRow = document.createElement(' | + | |
| - | newRow.className = ' | + | |
| - | newRow.innerHTML = ` | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <button class=" | + | |
| - | `; | + | |
| - | container.appendChild(newRow); | + | |
| - | saveToLocalStorage(); | + | |
| - | } | + | |
| - | + | ||
| - | function removeRow(button) { | + | |
| - | const container = document.getElementById(' | + | |
| - | if (container.children.length > 1) { | + | |
| - | button.parentElement.remove(); | + | |
| - | saveToLocalStorage(); | + | |
| - | } else { | + | |
| - | alert(' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | function processManualData() { | + | |
| - | const title = document.getElementById(' | + | |
| - | const rows = document.getElementById(' | + | |
| - | const data = []; | + | |
| - | + | ||
| - | for (let row of rows) { | + | |
| - | const periodo = row.querySelector(' | + | |
| - | const valore = parseFloat(row.querySelector(' | + | |
| - | const note = row.querySelector(' | + | |
| - | + | ||
| - | if (periodo && !isNaN(valore)) { | + | |
| - | data.push({ periodo, valore, note }); | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | if (data.length === 0) { | + | |
| - | alert(' | + | |
| - | return; | + | |
| - | } | + | |
| - | + | ||
| - | const config = { | + | |
| - | theme: ' | + | |
| - | name: title, | + | |
| - | icon: ' | + | |
| - | units: ' | + | |
| - | }; | + | |
| - | + | ||
| - | processData(data, | + | |
| - | + | ||
| - | // Aggiorna il pulsante esempio con il titolo inserito | + | |
| - | if (title && title !== 'Dati Manuali' | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | function saveToLocalStorage() { | + | |
| - | const title = document.getElementById(' | + | |
| - | const rows = document.getElementById(' | + | |
| - | const data = []; | + | |
| - | + | ||
| - | for (let row of rows) { | + | |
| - | const periodo = row.querySelector(' | + | |
| - | const valore = row.querySelector(' | + | |
| - | const note = row.querySelector(' | + | |
| - | data.push({ periodo, valore, note }); | + | |
| - | } | + | |
| - | + | ||
| - | localStorage.setItem(' | + | |
| - | title: title, | + | |
| - | lastSaved: new Date().toISOString(), | + | |
| - | rows: data | + | |
| - | })); | + | |
| - | } | + | |
| - | + | ||
| - | function loadFromLocalStorage() { | + | |
| - | const saved = localStorage.getItem(' | + | |
| - | if (!saved) return false; | + | |
| - | + | ||
| - | try { | + | |
| - | const savedData = JSON.parse(saved); | + | |
| - | document.getElementById(' | + | |
| - | + | ||
| - | const container = document.getElementById(' | + | |
| - | container.innerHTML = ''; | + | |
| - | + | ||
| - | savedData.rows.forEach((row) => { | + | |
| - | const newRow = document.createElement(' | + | |
| - | newRow.className = ' | + | |
| - | newRow.innerHTML = ` | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <button class=" | + | |
| - | `; | + | |
| - | container.appendChild(newRow); | + | |
| - | }); | + | |
| - | + | ||
| - | addAutoSaveListeners(); | + | |
| - | return true; | + | |
| - | } catch (error) { | + | |
| - | return false; | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | function addAutoSaveListeners() { | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | } | + | |
| - | + | ||
| - | function saveManualData() { | + | |
| - | const title = document.getElementById(' | + | |
| - | const rows = document.getElementById(' | + | |
| - | const data = []; | + | |
| - | + | ||
| - | for (let row of rows) { | + | |
| - | data.push({ | + | |
| - | periodo: row.querySelector(' | + | |
| - | valore: row.querySelector(' | + | |
| - | note: row.querySelector(' | + | |
| - | }); | + | |
| - | } | + | |
| - | + | ||
| - | const blob = new Blob([JSON.stringify({title, | + | |
| - | const url = URL.createObjectURL(blob); | + | |
| - | const link = document.createElement(' | + | |
| - | link.href = url; | + | |
| - | link.download = `control_chart_${title.replace(/ | + | |
| - | link.click(); | + | |
| - | URL.revokeObjectURL(url); | + | |
| - | } | + | |
| - | + | ||
| - | function loadManualData() { | + | |
| - | const input = document.getElementById(' | + | |
| - | input.onchange = function() { | + | |
| - | const file = input.files[0]; | + | |
| - | if (!file) return; | + | |
| - | + | ||
| - | const reader = new FileReader(); | + | |
| - | reader.onload = function(e) { | + | |
| - | try { | + | |
| - | const savedData = JSON.parse(e.target.result); | + | |
| - | document.getElementById(' | + | |
| - | + | ||
| - | const container = document.getElementById(' | + | |
| - | container.innerHTML = ''; | + | |
| - | + | ||
| - | savedData.rows.forEach((row) => { | + | |
| - | const newRow = document.createElement(' | + | |
| - | newRow.className = ' | + | |
| - | newRow.innerHTML = ` | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <button class=" | + | |
| - | `; | + | |
| - | container.appendChild(newRow); | + | |
| - | }); | + | |
| - | + | ||
| - | saveToLocalStorage(); | + | |
| - | alert(' | + | |
| - | } catch (error) { | + | |
| - | alert(' | + | |
| - | } | + | |
| - | }; | + | |
| - | reader.readAsText(file); | + | |
| - | input.value = ''; | + | |
| - | }; | + | |
| - | input.click(); | + | |
| - | } | + | |
| - | + | ||
| - | function clearLocalStorage() { | + | |
| - | if (confirm(' | + | |
| - | localStorage.removeItem(' | + | |
| - | document.getElementById(' | + | |
| - | document.getElementById(' | + | |
| - | <div class=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <input type=" | + | |
| - | <button class=" | + | |
| - | </ | + | |
| - | `; | + | |
| - | addAutoSaveListeners(); | + | |
| - | alert(' | + | |
| - | } | + | |
| - | } | + | |
| - | + | ||
| - | function saveChartImage() { | + | |
| - | if (!currentChart) return; | + | |
| - | const url = document.getElementById(' | + | |
| - | const link = document.createElement(' | + | |
| - | link.href = url; | + | |
| - | link.download = `control_chart_${new Date().toISOString().split(' | + | |
| - | link.click(); | + | |
| - | } | + | |
| - | + | ||
| - | function saveChartPDF() { | + | |
| - | if (!currentChart || currentData.length === 0) return; | + | |
| - | + | ||
| - | const canvas = document.getElementById(' | + | |
| - | const imageData = canvas.toDataURL(' | + | |
| - | + | ||
| - | const reportHTML = ` | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | <meta charset=" | + | |
| - | < | + | |
| - | < | + | |
| - | body { font-family: | + | |
| - | h1 { color: #2c3e50; } | + | |
| - | .stats { display: flex; gap: 20px; margin: 20px 0; } | + | |
| - | .stat { background: #f8f9fa; padding: 15px; border-radius: | + | |
| - | img { max-width: 100%; height: auto; margin: 20px 0; } | + | |
| - | table { width: 100%; border-collapse: | + | |
| - | th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } | + | |
| - | th { background: #f2f2f2; } | + | |
| - | .violation { background: #ffe6e6; } | + | |
| - | </ | + | |
| - | </ | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | < | + | |
| - | + | ||
| - | <div class=" | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | </ | + | |
| - | + | ||
| - | < | + | |
| - | <img src=" | + | |
| - | + | ||
| - | < | + | |
| - | ${document.getElementById(' | + | |
| - | + | ||
| - | <p style=" | + | |
| - | Report generato da Control Chart System - ${new Date().toLocaleString(' | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |
| - | `; | + | |
| - | + | ||
| - | const blob = new Blob([reportHTML], { type: ' | + | |
| - | const url = URL.createObjectURL(blob); | + | |
| - | const link = document.createElement(' | + | |
| - | link.href = url; | + | |
| - | link.download = `control_chart_report_${new Date().toISOString().split(' | + | |
| - | link.click(); | + | |
| - | URL.revokeObjectURL(url); | + | |
| - | } | + | |
| - | + | ||
| - | window.addEventListener(' | + | |
| - | const loaded = loadFromLocalStorage(); | + | |
| - | if (loaded) { | + | |
| - | document.getElementById(' | + | |
| - | <div class=" | + | |
| - | < | + | |
| - | </ | + | |
| - | `; | + | |
| - | document.getElementById(' | + | |
| - | + | ||
| - | setTimeout(() => { | + | |
| - | processManualData(); | + | |
| - | }, 300); | + | |
| - | } else { | + | |
| - | addAutoSaveListeners(); | + | |
| - | } | + | |
| - | }); | + | |
| - | </ | + | |
| - | </ | + | |
| - | </ | + | |