<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VS Data Visualization</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&amp;display=swap" rel="stylesheet">
    <style>
        :root {
            --bg-light: #f4f7f6;
            --bg-dark: #121212;
            --text-light: #333;
            --text-dark: #e0e0e0;
            --primary-color: #3498db;
            --accent-color: #2ecc71;
            --card-bg-light: white;
            --card-bg-dark: #1e1e1e;
            --shadow-light: rgba(0, 0, 0, 0.1);
            --shadow-dark: rgba(255, 255, 255, 0.1);
        }

        body {
            font-family: 'Inter', Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            background-color: var(--bg-light);
            margin: 0;
            transition: background-color 0.3s, color 0.3s;
        }

        body.dark-mode {
            background-color: var(--bg-dark);
            color: var(--text-dark);
        }

        .container {
            background: var(--card-bg-light);
            color: var(--text-light);
            padding: 10mm;
            border-radius: 16px;
            box-shadow: 0 10px 25px var(--shadow-light);
            width: 100%;
            max-width: 100%;
            transition: background 0.3s;
            justify-content: center;
        }

        .container.dark-mode {
            background: var(--card-bg-dark);
            color: var(--text-dark);
        }

        h1 {
            color: var(--primary-color);
            text-align: center;
            margin-bottom: 20px;
        }

        #fileInput {
            display: block;
            margin: 20px auto;
            padding: 15px;
            border: 2px dashed var(--primary-color);
            border-radius: 10px;
            background: #f5f5f5;
            text-align: center;
            cursor: pointer;
            color: black;
            transition: background-color 0.3s;
        }

        #fileInput:hover {
            background-color: rgba(52, 152, 219, 0.1);
        }

        .toggle-wrapper {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-top: 20px;
            gap: 10px;
        }

        .toggle {
            position: relative;
            display: inline-block;
            width: 60px;
            height: 34px;
        }

        .toggle input {
            opacity: 0;
            width: 0;
            height: 0;
        }

        .slider {
            position: absolute;
            cursor: pointer;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: #ccc;
            transition: .4s;
            border-radius: 34px;

        }

        .slider:before {
            position: absolute;
            content: "☀️"; 
            height: 26px;
            width: 26px;
            left: 4px;
            bottom: 4px;
            background-color: white;
            transition: .8s;
            border-radius: 50%;
            display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-size: 16px;
        }

        .toggle input:checked + .slider {
            background-color: var(--primary-color);
        }

        .toggle input:checked + .slider:before {
            transform: translateX(26px);
            content: "🌙"; /* Emoji for dark mode */
display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-size: 16px;
       }
       
       .chart-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}
        .chart-container canvas {
            width: 100%;
            max-width: 100%;
            justify-content: center;
            background-color: #f8f9fa;
            border: 1px solid #ddd;
            border-radius: 12px;
            padding: 10px;
            box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px;
                        margin: 10px auto;
            justify-content: center;
            height: auto !important;
        }

        .print-button {
            display: block;
            margin: 20px auto;
            padding: 10px 20px;
            background-color: var(--primary-color);
            border: none;
            color: white;
            text-align: center;
            text-decoration: none;
            font-size: 16px;
            cursor: pointer;
            border-radius: 8px;
            transition: transform 0.2s;
        }

        .print-button:hover {
            transform: scale(1.05);
        }

        .legend {
            margin-top: 20px;
            text-align: center;
            background-color: rgba(52, 152, 219, 0.1);
            padding: 15px;
            border-radius: 10px;
        }

        /* New Date Filter Styles */
        .date-filter {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 15px;
            margin-bottom: 20px;
            background-color: rgba(52, 152, 219, 0.05);
            padding: 15px;
            border-radius: 12px;
        }

        .date-filter input, .date-filter button {
            padding: 10px;
            border-radius: 8px;
            border: 1px solid var(--primary-color);
            transition: all 0.3s ease;
            font-family: 'Inter', sans-serif;
        }

        .date-filter button {
            background-color: var(--primary-color);
            color: white;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 5px;
        }

        .date-filter button:hover {
            opacity: 0.8;
            transform: scale(1.05);
        }

        .emoji-toggle {
            display: flex;
            align-items: center;
            gap: 10px;
            transition: all 0.3s ease;
        }

        .emoji-toggle span {
            font-size: 1.2em;
            transition: transform 0.3s ease;
        }

        .emoji-toggle input:checked + .slider + span {
            transform: rotate(180deg);
        }
    </style>
<script defer="" data-domain="graphvitals.tiiny.site" src="https://analytics.tiiny.site/js/plausible.js"></script><script type="text/javascript" src="https://tiiny.host/ad-script.js"></script><script defer="" data-domain="graphvitals.tiiny.site" src="https://analytics.tiiny.site/js/plausible.js"></script><script type="text/javascript" src="https://tiiny.host/ad-script.js"></script></head>
<body style="margin-bottom: 55px !important;" class="dark-mode">
    <div class="container dark-mode">
        <h1>Vital Signs Data Visualization</h1>
        
        <input type="file" id="fileInput" accept=".csv">

        <div class="date-filter">
            <input type="date" id="startDate">
            <input type="date" id="endDate">
            <button id="filterButton">Filter 📊</button>
            <button id="resetButton">Reset 🔄</button>
        </div>

        <div class="toggle-wrapper emoji-toggle">
            <label class="toggle">
                <input type="checkbox" id="darkModeToggle">
                <span class="slider"></span>
            </label>
        </div>
<br>
        <div id="charts" class="chart-container">
                <canvas id="bloodPressureChart" style="display: block; box-sizing: border-box; height: 636px; width: 1273px;" width="1273" height="636"></canvas>
                <canvas id="heartRateChart" style="display: block; box-sizing: border-box; height: 636px; width: 1273px;" width="1273" height="636"></canvas>
                <canvas id="sugarLevelChart" style="display: block; box-sizing: border-box; height: 636px; width: 1273px;" width="1273" height="636"></canvas>
            </div>
                <div class="legend">
                    <span><strong>Blood Pressure</strong> | 
                        Min: 101/56 | 
                        Max: 139/95 | 
                        Average: 122.85/75.60<br>
                    </span>
                    <span><strong>Heart Rate</strong> | 
                        Min: 50 | 
                        Max: 99 | 
                        Average: 79.99<br>
                    </span>
                    <span><strong>Sugar Level</strong> | 
                        Min: 4 | 
                        Max: 17 | 
                        Average: 7.91<br>
                    </span>
                </div>
            
                
            
                
            
        <button class="print-button" onclick="window.print()">Print</button>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
    
    <script>
        let globalChartData = null;
        let charts = [];

        // Cookie and Storage Management
        function setCookie(name, value, days) {
            const expires = new Date(Date.now() + days * 864e5).toUTCString();
            document.cookie = `${name}=${encodeURIComponent(value)};expires=${expires};path=/`;
        }

        function getCookie(name) {
            const value = `; ${document.cookie}`;
            const parts = value.split(`; ${name}=`);
            return parts.length === 2 ? decodeURIComponent(parts.pop().split(';').shift()) : null;
        }

        // File Input and Data Processing
        document.getElementById('fileInput').addEventListener('change', function(e) {
            const file = e.target.files[0];
            if (file) {
                const reader = new FileReader();
                reader.onload = function(e) {
                    const csvText = e.target.result;
                    localStorage.setItem('savedCSVData', csvText);
                    setCookie('csvUploaded', 'true', 7);
                    processCSVData(csvText);
                };
                reader.readAsText(file);
            }
        });

        function processCSVData(csvText) {
            const data = parseCSV(csvText);
            if (data && data.length > 0) {
                globalChartData = data;
                createCharts(data);
            } else {
                alert("Invalid CSV data. Please check the file format.");
            }
        }

        // Date Filtering
        document.getElementById('filterButton').addEventListener('click', () => {
            const startDate = new Date(document.getElementById('startDate').value);
            const endDate = new Date(document.getElementById('endDate').value);
            
            if (startDate && endDate && globalChartData) {
                const filteredData = globalChartData.filter(item => 
                    item.date >= startDate && item.date <= endDate
                );
                createCharts(filteredData);
            }
        });

        // Reset Button
        document.getElementById('resetButton').addEventListener('click', () => {
            localStorage.removeItem('savedCSVData');
            document.getElementById('fileInput').value = '';
            document.getElementById('startDate').value = '';
            document.getElementById('endDate').value = '';
            
            // Clear existing charts
            const chartContainer = document.getElementById('charts');
            chartContainer.innerHTML = `
                <canvas id="bloodPressureChart"></canvas>
                <canvas id="heartRateChart"></canvas>
                <canvas id="sugarLevelChart"></canvas>
            `;
            globalChartData = null;
        });

        // Dark Mode Toggle with Emoji
        const darkModeToggle = document.getElementById('darkModeToggle');
        darkModeToggle.addEventListener('change', function() {
            document.body.classList.toggle('dark-mode');
            document.querySelector('.container').classList.toggle('dark-mode');
        });

        // Restore previous data on page load
        window.addEventListener('load', () => {
            const savedCSV = localStorage.getItem('savedCSVData');
            if (savedCSV) {
                processCSVData(savedCSV);
            }
        });

        function parseCSV(csv) {
            const lines = csv.split('\n');
            if (lines.length <= 1) return null;
            const result = [];
            const headers = lines[0].split(',').map(header => header.trim().toLowerCase());
            
            for (let i = 1; i < lines.length; i++) {
                if (!lines[i].trim()) continue;
                const values = lines[i].split(',').map(value => value.trim());
                if (values.length !== headers.length) continue;
                
                const obj = {};
                for (let j = 0; j < headers.length; j++) {
                    const header = headers[j];
                    let value = values[j];
                    
                    if (header === 'date') {
                        obj[header] = new Date(value);
                    } else if (header === 'time') {
                        const timeParts = value.match(/(\d+):(\d+):(\d+) (AM|PM)/i);
                        if (timeParts) {
                            let hours = parseInt(timeParts[1]);
                            const minutes = parseInt(timeParts[2]);
                            const seconds = parseInt(timeParts[3]);
                            const ampm = timeParts[4].toUpperCase();

                            if (ampm === 'PM' && hours !== 12) hours += 12;
                            if (ampm === 'AM' && hours === 12) hours = 0;

                            const dateObj = obj.date || new Date();
                            dateObj.setHours(hours, minutes, seconds);
                            obj.date = dateObj;
                        }
                    } else if (header === 'systolic' || header === 'diastolic' || header === 'heart rate') {
                        obj[header.replace(' ', '')] = parseInt(value) || null;
                    } else if (header === 'sugar') {
                        obj['sugarValue'] = parseFloat(value) || null;
                    }
                }
                result.push(obj);
            }
            return result;
        }

        function computeStatistics(arr) {
            const filtered = arr.filter(value => value !== null);
            if (filtered.length === 0) return { average: null, min: null, max: null };
            const sum = filtered.reduce((a, b) => a + b, 0);
            const avg = sum / filtered.length;
            const min = Math.min(...filtered);
            const max = Math.max(...filtered);
            return { average: avg, min, max };
        }
        function createCharts(data) {
            // Clear existing charts
            charts.forEach(chart => chart.destroy());
            charts = [];

            const ctxBP = document.getElementById('bloodPressureChart').getContext('2d');
            const ctxHR = document.getElementById('heartRateChart').getContext('2d');
            const ctxSL = document.getElementById('sugarLevelChart').getContext('2d');

            const labels = data.map(item => item.date);
            const systolicStats = computeStatistics(data.map(item => item.systolic));
            const diastolicStats = computeStatistics(data.map(item => item.diastolic));
            const heartRateStats = computeStatistics(data.map(item => item.heartrate));
            const sugarStats = computeStatistics(data.map(item => item.sugarValue));

            // Blood Pressure Chart
            const bloodPressureChart = new Chart(ctxBP, {
    type: 'scatter',
    data: {
        datasets: [
            {
                label: 'Systolic',
                data: data.map(item => ({ x: item.date, y: item.systolic })),
                backgroundColor: 'red',
                pointRadius: 5,
                pointHoverRadius: 8,
                yAxisID: 'yScatter' // Use a separate y-axis for scatter points
            },
            {
                label: 'Diastolic',
                data: data.map(item => ({ x: item.date, y: item.diastolic })),
                backgroundColor: 'blue',
                pointRadius: 5,
                pointHoverRadius: 8,
                yAxisID: 'yScatter' // Use a separate y-axis for scatter points
            },
            {
                type: 'bar',
                label: '', // No label for this dataset
                data: data.map(item => ({
                    x: item.date,
                    y: item.diastolic // Base of the bar
                })),
                backgroundColor: 'rgba(0, 0, 0, 0)', // Fully transparent
                hoverBackgroundColor: 'rgba(0, 0, 0, 0)',
                barThickness: 10,
                yAxisID: 'yBar',
                tooltip: { enabled: false } // Disable tooltips for this dataset
            },
            {
                type: 'bar',
                label: 'Blood Pressure Range',
                data: data.map(item => ({
                    x: item.date,
                    y: item.systolic - item.diastolic // Height of the bar
                })),
                backgroundColor: 'rgba(0, 128, 255, 0.08)', // Light blue for range
                borderColor: 'rgba(0, 128, 255, 1)',
                barThickness: 10,
                borderRadius: { 
                    topLeft: 5, 
                    topRight: 5, 
                    bottomLeft: 5, 
                    bottomRight: 5 // Rounded corners at the bottom
                },
                yAxisID: 'yBar'
            },
            {
                type: 'line',
                label: 'Avg Systolic',
                data: data.map(item => ({ x: item.date, y: systolicStats.average })),
                borderColor: 'red',
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0,
                yAxisID: 'yScatter' // Use the scatter y-axis for averages
            },
            {
                type: 'line',
                label: 'Avg Diastolic',
                data: data.map(item => ({ x: item.date, y: diastolicStats.average })),
                borderColor: 'blue',
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0,
                yAxisID: 'yScatter' // Use the scatter y-axis for averages
            },
            
            {
                type: 'line',
                label: 'High limit Sys.',
                data: data.map(item => ({ x: item.date, y: 140 })),
                borderColor: 'maroon',
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0,
                yAxisID: 'yScatter' // Use the scatter y-axis for averages
            },
            {
                type: 'line',
                label: 'High Limit Dia.',
                data: data.map(item => ({ x: item.date, y: 90 })),
                borderColor: 'purple',
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0,
                yAxisID: 'yScatter' // Use the scatter y-axis for averages
            }
        ]
    },
    options: {
        interaction: {
            mode: 'nearest',
            intersect: true,
            axis: 'x',
            // Ignore the transparent dataset
            filter: function(tooltipItem) {
                return tooltipItem.datasetIndex !== 2; // Assuming dataset index 2 is the transparent bar
            }
        },
        scales: {
            x: {
                type: 'time',
                time: {
                    unit: 'day'
                },
                ticks: {
                    source: 'data'
                }
            },
            yScatter: {
                type: 'linear',
                position: 'left',
                beginAtZero: false,
                stacked: false // No stacking for scatter points
            },
            yBar: {
                type: 'linear',
                position: 'right',
                beginAtZero: false,
                stacked: true // Enable stacking for bars
            }
        },
        plugins: {
            tooltip: {
                enabled: true // Enable tooltips globally but filter out the transparent bar
            },
            legend: {
                position: 'bottom'
            }
        }
    }
});
            charts.push(bloodPressureChart);

            // Heart Rate Chart
            const heartRateChart = new Chart(ctxHR, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: [{
                        label: 'Heart Rate',
                        data: data.map(item => item.heartrate),
                        borderColor: 'rgb(75, 192, 192)',
                        fill: false
                    },
                    {
                        label: 'Average',
                        data: Array(labels.length).fill(heartRateStats.average),
                        borderColor: 'rgba(255, 205, 86, 1)',
                        borderDash: [5, 5],
                        fill: false
                    }]
                },
                options: {
                    scales: {
                         x: {
                            type: 'time',
                            time: {
                                unit: 'day'
                            },
                            ticks: {
                                source: 'data'
                            }
                        },
                        y: {
                            beginAtZero: false
                        }
                    },
                     plugins: {
                        legend: {
                            position: 'bottom'
                        }
                    }
                }
            });

            charts.push(heartRateChart);

            // Sugar Level Chart
            const sugarLevelChart = new Chart(ctxSL, {
                type: 'line',
                data: {
                    labels: labels,
                    datasets: [{
                        label: 'Sugar Level',
                        data: data.map(item => item.sugarValue),
                        borderColor: 'rgb(255, 99, 132)',
                        spanGaps: true,
                        fill: false
                    },
                    {
                        label: 'Average',
                        data: Array(labels.length).fill(sugarStats.average),
                        borderColor: 'rgba(255, 205, 86, 1)',
                        borderDash: [5, 5],
                        fill: false
                    }]
                },
                options: {
                    scales: {
                        x: {
                            type: 'time',
                            time: {
                                unit: 'day'
                            },
                            ticks: {
                                source: 'data'
                            }
                        },
                        y: {
                            beginAtZero: true
                        }
                    },
                    plugins: {
                        legend: {
                            position: 'bottom'
                        }
                    }
                }
            });

            charts.push(sugarLevelChart);

            // Legend with Statistics
            const legendHTML = `
                <div class="legend">
                    <span><strong>Blood Pressure</strong> | 
                        Min: ${systolicStats.min}/${diastolicStats.min} | 
                        Max: ${systolicStats.max}/${diastolicStats.max} | 
                        Average: ${systolicStats.average ? systolicStats.average.toFixed(2) : "N/A"}/${diastolicStats.average ? diastolicStats.average.toFixed(2) : "N/A"}<br>
                    </span>
                    <span><strong>Heart Rate</strong> | 
                        Min: ${heartRateStats.min} | 
                        Max: ${heartRateStats.max} | 
                        Average: ${heartRateStats.average ? heartRateStats.average.toFixed(2) : "N/A"}<br>
                    </span>
                    <span><strong>Sugar Level</strong> | 
                        Min: ${sugarStats.min} | 
                        Max: ${sugarStats.max} | 
                        Average: ${sugarStats.average ? sugarStats.average.toFixed(2) : "N/A"}<br>
                    </span>
                </div>
            `;

            // Remove existing legend and add new one
            const existingLegend = document.querySelector('.legend');
            if (existingLegend) {
                existingLegend.remove();
            }
            document.querySelector('#charts').insertAdjacentHTML('afterend', legendHTML);
        }
    </script>



</body></html>