You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ChartJS从MySQL定时更新数据:性能优化与动画禁用求助

解决Chart.js实时更新的负载与动画问题

Hey there! Let's fix those two issues you're facing with your temperature chart—high browser load and unwanted animations on data updates. Here's how to tackle each one:

1. 优化浏览器负载过高的问题

Your current code creates a new Chart instance every 5 seconds and fetches all historical data each time—this is the main reason for the high load. Let's fix this with two key changes:

a. 复用Chart实例,不要每次都新建

Instead of creating a new Chart() every time your update runs, initialize the chart once, then only update its data when new values come in. This avoids redundant DOM and JavaScript work.

b. 只请求新增的数据,而非全量数据

Modify your PHP endpoint to accept the last fetched ID, so it only returns new sensor readings since the last update. This cuts down on data transfer and processing time significantly.

修改后的代码:

data.php(支持增量请求)
<?php
header('Content-Type: application/json');
$conn = mysqli_connect("localhost","user","password","db");

// Get the last ID from the request (default to 0 if not provided)
$lastId = isset($_POST['last_id']) ? (int)$_POST['last_id'] : 0;

// Only fetch rows with ID greater than the last one we received
$sqlQuery = "SELECT id,temp1,temp2 FROM table.results WHERE id > $lastId ORDER BY id";
$result = mysqli_query($conn,$sqlQuery);

$data = array();
foreach ($result as $row) {
    $data[] = $row;
}

mysqli_close($conn);
echo json_encode($data, JSON_NUMERIC_CHECK);
?>
index.php(复用Chart实例+增量更新)
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/Chart.min.js"></script>
</head>
<body>
<div id="chart-container">
    <canvas id="graphCanvas"></canvas>
</div>
<script>
// Store the chart instance and last fetched ID globally
let barGraph = null;
let lastFetchedId = 0;

$(document).ready(function () {
    // Initialize the chart with full data first
    initializeChart();
    // Start the update interval after initialization
    setInterval(updateChartData, 5000);
});

function initializeChart() {
    $.post("data.php", function (initialData) {
        if (initialData.length === 0) return;

        // Extract initial data
        const id = initialData.map(row => row.id);
        const temp1 = initialData.map(row => row.temp1);
        const temp2 = initialData.map(row => row.temp2);

        // Update last fetched ID to the latest in initial data
        lastFetchedId = initialData[initialData.length - 1].id;

        const chartdata = {
            labels: id,
            datasets: [
                {
                    label: 'Temp1',
                    borderColor: '#46d5f1',
                    hoverBorderColor: '#666666',
                    data: temp1
                },
                {
                    label: 'Temp2',
                    borderColor: '#f14646', // Changed to red for better visual distinction
                    hoverBorderColor: '#666666',
                    data: temp2
                }
            ]
        };

        const graphTarget = $("#graphCanvas");
        barGraph = new Chart(graphTarget, {
            type: 'line',
            data: chartdata,
            options: {
                animation: false // Disable animations from the start
            }
        });
    });
}

function updateChartData() {
    if (!barGraph) return; // Wait until chart is fully initialized

    // Send the last fetched ID to get only new data
    $.post("data.php", { last_id: lastFetchedId }, function (newData) {
        if (newData.length === 0) return; // No new data, skip update

        // Add new data points to the chart
        newData.forEach(row => {
            barGraph.data.labels.push(row.id);
            barGraph.data.datasets[0].data.push(row.temp1);
            barGraph.data.datasets[1].data.push(row.temp2);
            lastFetchedId = row.id; // Update the last ID to the newest entry
        });

        // Optional: Limit displayed points to keep the chart clean (adjust maxPoints as needed)
        const maxPoints = 50;
        if (barGraph.data.labels.length > maxPoints) {
            barGraph.data.labels.shift();
            barGraph.data.datasets[0].data.shift();
            barGraph.data.datasets[1].data.shift();
        }

        // Update the chart without any animation
        barGraph.update({
            duration: 0,
            lazy: true
        });
    });
}
</script>

2. 禁用数据重载时的动画

We've already covered this in the modified code, but let's break it down clearly:

  • Disable animations permanently: Add animation: false to the chart's options during initialization (as shown in initializeChart()). This turns off all animations by default.
  • Update without animation: When calling barGraph.update(), pass { duration: 0 } to ensure no animation runs for that specific data refresh.

Either method will eliminate the unwanted animation during updates.

Quick note on CanvasJS

Your current Chart.js setup is totally sufficient once optimized—CanvasJS doesn't offer any meaningful advantage for this use case. The core issues were in how you were updating the chart, not the library itself.

内容的提问来源于stack exchange,提问作者Torben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:41:38