본문 바로가기
Coding/JavaScript

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

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

 

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

chart.js를 사용하여 실시간으로 차트가 움직이는 ecg signal을 구현해보았습니다.

완벽하진 않지만 나름 괜찮은것 같네요 !!

 

예제코드
<!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="ecgChart" style="width: 800px;"></canvas>
    <script>
        const ctx = document.getElementById('ecgChart').getContext('2d');
        let time = 0; // 데이터 포인트 생성에 사용될 시간 변수
        
        const ecgChart = new Chart(ctx, {
            type: 'line',
            data: {
                datasets: [{
                    label: 'ECG Signal',
                    borderColor: 'rgb(0, 255, 0)', // 선 색상을 초록색으로 설정
                    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 updateChart() {
            let value;
            const min = 60;
            const max = 80;
            if (time % 20 === 0) { // 50단위 시간마다 높은 피크 생성
                value = Math.floor(Math.random() * (max - min + 1)) + min; // 높은 피크 값에 랜덤성 추가
            } else {
                // 뾰족한 파형 생성을 위해 Math.abs(Math.sin()) 함수 사용
                value = Math.abs(Math.sin(time * 0.2)) * 5 + Math.random() * 2; // 사인파에 랜덤 요소 추가
            }

            // 차트 데이터 업데이트
            ecgChart.data.datasets[0].data.push({
                x: time,
                y: value
            });

            // 데이터 포인트가 너무 많아지면 가장 오래된 데이터 제거
            if (ecgChart.data.datasets[0].data.length > 100) {
                ecgChart.data.datasets[0].data.shift();
            }

            // X축 범위 업데이트
            ecgChart.options.scales.x.min = time - 100; // 현재 시간에서 100 단위 이전으로 설정
            ecgChart.options.scales.x.max = time; // 현재 시간을 최대값으로 설정

            // 차트 업데이트
            ecgChart.update();
            time++; // 시간 변수 증가
        }

        // 100ms마다 updateChart 함수를 호출하여 차트 업데이트
        setInterval(updateChart, 50);
    </script>
</body>
</html>

결과

 

728x90
반응형

댓글