본문 바로가기
Coding/JavaScript

[JavaScript] chart.js 를 사용하여 PPG Signal(심박수) 처럼 그래프 만드는 방법 !!

by 포스트it 2024. 2. 25.
728x90
반응형

 

[JavaScript] chart.js 를 사용하여 PPG Signal(심박수) 처럼 그래프 만드는 방법 !!

지난 ECG Signal에 이어서 이번에는 PPG(심박수)를 chart.js 를 활용하여 그려보았습니다 ㅎ

 

예제코드
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Real-time ECG Simulation with Peaks</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
    <canvas id="ppgChart" style="width: 800px;"></canvas>
    <script>
        const ctx = document.getElementById('ppgChart').getContext('2d');
        let time = 0; // 데이터 포인트 생성에 사용될 시간 변수
        
        const ppgChart = new Chart(ctx, {
            type: 'line',
            data: {
                datasets: [{
                    label: 'PPG Signal',
                    borderColor: '#FF00FF', // 선 색상을 초록색으로 설정
                    borderWidth: 2,
                    lineTension: 0,
                    fill: false, // 배경 채우기를 사용하지 않음
                    pointRadius: 0, // 데이터 포인트 제거
                    data: []
                }]
            },
            options: {
                responsive: false,
                animation: false,
                scales: {
                    x: { // X축 설정
                        type: 'linear',
                        display: true,
                    },
                    y: { // Y축 설정
                        display: true,
                    }
                },
                plugins: {
                    legend: {
                        labels: {
                            color: 'rgb(255, 255, 255)' // 범례 텍스트 색상을 흰색으로 설정
                        }
                    },
                    tooltip: {
                        enabled: false // 툴팁 비활성화
                    }
                }
            },
            plugins: [{
                beforeDraw: function(chart) {
                    const ctx = chart.canvas.getContext('2d');
                    ctx.fillStyle = 'rgb(0, 0, 0)'; // 캔버스 배경색을 검정색으로 설정
                    ctx.fillRect(0, 0, chart.width, chart.height);
                }
            }]
        });

        function updateppgChart() {
    let baseLine = 20; // 기본선 값 설정

    // Gaussian 피크 함수 정의
    function gaussian(x, amplitude, position, width) {
        return amplitude * Math.exp(-((x - position) ** 2) / (2 * width ** 2));
    }

    // 메인 피크와 작은 피크 간격 설정
    let peakInterval = 60; // 메인 피크 간격
    let smallPeakDelay = 15; // 메인 피크로부터 작은 피크까지의 지연 시간

    // 메인 피크 설정
    let mainPeakPosition = Math.round(time / peakInterval) * peakInterval;
    let mainPeakHeight = 25; // 메인 피크 높이
    let peakWidth = peakInterval / 10; // 메인 피크 폭
    let mainPeakValue = gaussian(time, mainPeakHeight, mainPeakPosition, peakWidth);

    // 작은 피크 설정
    let smallPeakPosition = mainPeakPosition + smallPeakDelay; // 작은 피크 위치
    let smallPeakHeight = mainPeakHeight / 3; // 작은 피크는 메인 피크의 1/3 높이
    let smallPeakValue = gaussian(time, smallPeakHeight, smallPeakPosition, peakWidth / 2); // 작은 피크 폭은 메인 피크의 절반

    // 최종 값 계산
    let value = mainPeakValue + smallPeakValue + baseLine;

    // 잡음 추가 (선택적)
    let randomNoise = Math.random() * 0.2;
    value += randomNoise;

    ppgChart.data.datasets[0].data.push({x: time, y: value});
    if (ppgChart.data.datasets[0].data.length > 250) {
        ppgChart.data.datasets[0].data.shift();
    }

    ppgChart.options.scales.x.min = time - 250;
    ppgChart.options.scales.x.max = time;

    ppgChart.update();
    time++;
}

setInterval(updateppgChart, 40);

    </script>
</body>
</html>

결과

728x90
반응형

댓글