首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Highcharts 大數據量動態載入與滾動條事件實作

     編輯:程式設計疑難解答

核心需求

後端資料量大,無法一次性載入。需在圖表下方提供滾動條,用戶拖動時動態請求對應區間資料並繪製。

Highcharts 內建滾動與動態載入方案

1. 啟用內建滾動條

Highcharts.chart('container', {
    chart: {
        type: 'line',
        zoomType: 'x',
        panning: true,
        panKey: 'shift'
    },
    xAxis: {
        min: 0,
        max: 100, // 初始顯示前 100 點
        scrollbar: {
            enabled: true,
            liveRedraw: false // 拖動時不即時重繪,釋放滑鼠後重繪
        }
    },
    series: [{
        data: initialData // 首批資料
    }]
});

2. 監聽滾動/縮放事件動態載入

const chart = Highcharts.chart('container', options);

// 監聽 xAxis 事件
chart.xAxis[0].update({
    events: {
        afterSetExtremes: function(e) {
            // e.min, e.max 為當前可視範圍 (資料索引或時間)
            if (e.trigger !== 'navigator') { // 避免導覽器觸發重複請求
                loadDataForRange(e.min, e.max);
            }
        }
    }
});

function loadDataForRange(min, max) {
    // 轉換為業務參數 (如時間戳、ID 範圍)
    const startTime = indexToTimestamp(min);
    const endTime = indexToTimestamp(max);
    
    // 顯示載入中
    chart.showLoading('載入資料中...');
    
    fetch(`/api/data?start=${startTime}&end=${endTime}`)
        .then(res => res.json())
        .then(data => {
            // 更新系列資料 (可選:合併現有資料、或替換)
            chart.series[0].setData(data, true); // true = 重繪
            chart.hideLoading();
        })
        .catch(err => {
            console.error(err);
            chart.hideLoading();
        });
}

3. 使用 Navigator (導覽器) 替代滾動條

Highcharts 內建 navigator 更適合大數據:

navigator: {
    enabled: true,
    series: {
        data: navigatorData // 縮略圖資料 (可為降採樣資料)
    },
    xAxis: {
        min: 0,
        max: 100
    }
},
scrollbar: {
    enabled: false // 關閉滾動條,使用 navigator
}

進階:資料分頁與快取策略

資料結構設計

// 後端 API 回傳格式
{
    "data": [[timestamp, value], ...],
    "meta": {
        "totalPoints": 1000000,
        "resolution": "1m" // 資料粒度
    }
}

前端快取管理

const dataCache = new Map(); // key: "start-end", value: data[]

function loadDataForRange(min, max) {
    const key = `${min}-${max}`;
    if (dataCache.has(key)) {
        chart.series[0].setData(dataCache.get(key), true);
        return;
    }
    
    chart.showLoading();
    fetch(`/api/data?min=${min}&max=${max}`)
        .then(res => res.json())
        .then(result => {
            dataCache.set(key, result.data);
            // 限制快取大小 (LRU)
            if (dataCache.size > 20) {
                const firstKey = dataCache.keys().next().value;
                dataCache.delete(firstKey);
            }
            chart.series[0].setData(result.data, true);
            chart.hideLoading();
        });
}

替代方案:使用 Highcharts Boost Module

若資料量 < 100 萬點,可一次性載入並啟用 Boost:

<script src="https://code.highcharts.com/modules/boost.js"></script>

plotOptions: {
    series: {
        boost: {
            useGPUTranslations: true,
            threshold: 5000 // 超過 5000 點啟用 WebGL 渲染
        },
        turboThreshold: 0 // 關閉預設限制
    }
}

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved