2020 年 10 月 1 日,星期四
作者:Sandy Galloway

Highcharts 整合

最近,我們收到一些關於以圖形格式顯示 DataTable 資訊的意見回饋。使用我們的 API 和圖表函式庫可以做到這一點。有很多可用的函式庫,但在這篇部落格文章中,我們將使用廣受歡迎的 Highcharts,展示如何將其整合到您的 DataTables 專案中。

以下是我們將建立的整合範例。請注意,當我們篩選表格時,圖表會重新繪製以反映篩選後的資料

姓名職位辦公室薪資
Tiger Nixon系統架構師愛丁堡$320,800
Garrett Winters會計師東京$170,750
Ashton Cox初級技術作者舊金山$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡$433,060
Airi Satou會計師東京$162,700
Brielle Williamson整合專員紐約$372,000
Herrod Chandler銷售助理舊金山$137,500
Rhona Davidson整合專員東京$327,900
Colleen HurstJavascript 開發人員舊金山$205,500
Sonya Frost軟體工程師愛丁堡$103,600
Jena Gaines辦公室經理倫敦$90,560
Quinn Flynn支援主管愛丁堡$342,000
Charde Marshall區域總監舊金山$470,600
Haley Kennedy資深行銷設計師倫敦$313,500
Tatyana Fitzpatrick區域總監倫敦$385,750
Michael Silva行銷設計師倫敦$198,500
Paul Byrd財務長 (CFO)紐約$725,000
Gloria Little系統管理員紐約$237,500
Bradley Greer軟體工程師倫敦$132,000
Dai Rios人事主管愛丁堡$217,500
Jenette Caldwell開發主管紐約$345,000
Yuri Berry行銷長 (CMO)紐約$675,000
Caesar Vance售前支援紐約$106,450
Doris Wilder銷售助理雪梨$85,600
Angelica Ramos執行長 (CEO)倫敦$1,200,000
Gavin Joyce開發人員愛丁堡$92,575
Jennifer Chang區域總監新加坡$357,650
Brenden Wagner軟體工程師舊金山$206,850
Fiona Green營運長 (COO)舊金山$850,000
Shou Itou區域行銷東京$163,000
Michelle House整合專員雪梨$95,400
Suki Burks開發人員倫敦$114,500
Prescott Bartlett技術作者倫敦$145,000
Gavin Cortez團隊負責人舊金山$235,500
Martena Mccray售後支援愛丁堡$324,050
Unity Butler行銷設計師舊金山$85,675
Howard Hatfield辦公室經理舊金山$164,500
Hope Fuentes秘書舊金山$109,850
Vivian Harrell財務主管舊金山$452,500
Timothy Mooney辦公室經理倫敦$136,200
Jackson Bradshaw總監紐約$645,750
Olivia Liang支援工程師新加坡$234,500
Bruno Nash軟體工程師倫敦$163,500
Sakura Yamamoto支援工程師東京$139,575
Thor Walton開發人員紐約$98,540
Finn Camacho支援工程師舊金山$87,500
Serge Baldwin資料協調員新加坡$138,575
Zenaida Frank軟體工程師紐約$125,250
Zorita Serrano軟體工程師舊金山$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡$75,650
Cara Stevens銷售助理紐約$145,600
Hermione Butler區域總監倫敦$356,250
Lael Greer系統管理員倫敦$103,500
Jonas Alexander開發人員舊金山$86,500
Shad Decker區域總監愛丁堡$183,000
Michael BruceJavascript 開發人員新加坡$183,000
Donna Snider客戶支援紐約$112,000

在這篇文章中,我將逐步介紹如何將 DataTables 與 Highcharts 連結起來。我將涵蓋

  • 靜態圖表
  • 非同步圖表
  • 使用資料處理的圖表

靜態圖表

Highcharts 提供了廣泛的不同圖形和圖表支援。在這篇文章中,我將使用圓餅圖和直條圖。

下面顯示了一個非常基本的圓餅圖初始化

var myChart = Highcharts.chart('container', {
    chart: {
        type: 'pie',
    },
    title: {
        text: 'Staff Count Per Office',
    },
    series: [
        {
            data: countMap,
        },
    ],
});

設定相當容易理解。我們將 chart.type 設定為 pie,用於圓餅圖,並將 title.text 設定為 各辦公室員工計數series 陣列設定為包含一個物件,其中包含該系列所需的資料。

現在剩下的就是從 DataTable 收集資料。為此,我們只需迭代所需欄的值,透過 column().data() 方法檢索,並在迭代時遞增值。然後將產生的分組資料轉換為 Highcharts 使用的物件陣列。

var table = $('#example').DataTable();
var counts = {};

// Count the number of entries for each office
table
    .column(2, { search: 'applied' })
    .data()
    .each(function (val) {
        if (counts[val]) {
            counts[val] += 1;
        } else {
            counts[val] = 1;
        }
    });

// And map it to the format highcharts uses
var countMap = $.map(counts, function (val, key) {
    return {
        name: key,
        y: val,
    };
});

下面顯示了此程式碼產生的表格和圖表範例。還有 可用的即時版本,讓您可以修改和實驗。

姓名職位辦公室薪資
Tiger Nixon系統架構師愛丁堡$320,800
Garrett Winters會計師東京$170,750
Ashton Cox初級技術作者舊金山$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡$433,060
Airi Satou會計師東京$162,700
Brielle Williamson整合專員紐約$372,000
Herrod Chandler銷售助理舊金山$137,500
Rhona Davidson整合專員東京$327,900
Colleen HurstJavascript 開發人員舊金山$205,500
Sonya Frost軟體工程師愛丁堡$103,600
Jena Gaines辦公室經理倫敦$90,560
Quinn Flynn支援主管愛丁堡$342,000
Charde Marshall區域總監舊金山$470,600
Haley Kennedy資深行銷設計師倫敦$313,500
Tatyana Fitzpatrick區域總監倫敦$385,750
Michael Silva行銷設計師倫敦$198,500
Paul Byrd財務長 (CFO)紐約$725,000
Gloria Little系統管理員紐約$237,500
Bradley Greer軟體工程師倫敦$132,000
Dai Rios人事主管愛丁堡$217,500
Jenette Caldwell開發主管紐約$345,000
Yuri Berry行銷長 (CMO)紐約$675,000
Caesar Vance售前支援紐約$106,450
Doris Wilder銷售助理雪梨$85,600
Angelica Ramos執行長 (CEO)倫敦$1,200,000
Gavin Joyce開發人員愛丁堡$92,575
Jennifer Chang區域總監新加坡$357,650
Brenden Wagner軟體工程師舊金山$206,850
Fiona Green營運長 (COO)舊金山$850,000
Shou Itou區域行銷東京$163,000
Michelle House整合專員雪梨$95,400
Suki Burks開發人員倫敦$114,500
Prescott Bartlett技術作者倫敦$145,000
Gavin Cortez團隊負責人舊金山$235,500
Martena Mccray售後支援愛丁堡$324,050
Unity Butler行銷設計師舊金山$85,675
Howard Hatfield辦公室經理舊金山$164,500
Hope Fuentes秘書舊金山$109,850
Vivian Harrell財務主管舊金山$452,500
Timothy Mooney辦公室經理倫敦$136,200
Jackson Bradshaw總監紐約$645,750
Olivia Liang支援工程師新加坡$234,500
Bruno Nash軟體工程師倫敦$163,500
Sakura Yamamoto支援工程師東京$139,575
Thor Walton開發人員紐約$98,540
Finn Camacho支援工程師舊金山$87,500
Serge Baldwin資料協調員新加坡$138,575
Zenaida Frank軟體工程師紐約$125,250
Zorita Serrano軟體工程師舊金山$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡$75,650
Cara Stevens銷售助理紐約$145,600
Hermione Butler區域總監倫敦$356,250
Lael Greer系統管理員倫敦$103,500
Jonas Alexander開發人員舊金山$86,500
Shad Decker區域總監愛丁堡$183,000
Michael BruceJavascript 開發人員新加坡$183,000
Donna Snider客戶支援紐約$112,000

現在這非常酷,但如果圖表可以反映套用的任何篩選,不是會更好嗎?繼續閱讀...

非同步圖表

為了實現這一點,我們將不得不對上面的程式碼進行一些更改。我們將把辦公室計數從 $(document).ready(...) 監聽器中取出,並將其放入自己的函式中,並用對我們新函式的呼叫來取代它。該函式應該看起來像這樣

function chartData(table) {
    var counts = {};

    // Count the number of entries for each office
    table
        .column(2, { search: 'applied' })
        .data()
        .each(function (val) {
            if (counts[val]) {
                counts[val] += 1;
            } else {
                counts[val] = 1;
            }
        });

    // And map it to the format highcharts uses
    return $.map(counts, function (val, key) {
        return {
            name: key,
            y: val,
        };
    });
}

使用這種方法意味著當進行篩選時,職位會從圖表中消失,從而帶來更簡潔的圖表體驗。

現在剩下要做的就是添加一個監聽器,以便在發生篩選時告知圖表使用新資料更新 - 為此,我們使用 draw

table.on('draw', function () {
    // Set the data for the first series to be the map returned from the chartData function
    myChart.series[0].setData(chartData(table));
});

下面提供了此程式碼的範例,並且與之前一樣,提供了顯示完整執行程式碼的即時版本

姓名職位辦公室薪資
Tiger Nixon系統架構師愛丁堡$320,800
Garrett Winters會計師東京$170,750
Ashton Cox初級技術作者舊金山$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡$433,060
Airi Satou會計師東京$162,700
Brielle Williamson整合專員紐約$372,000
Herrod Chandler銷售助理舊金山$137,500
Rhona Davidson整合專員東京$327,900
Colleen HurstJavascript 開發人員舊金山$205,500
Sonya Frost軟體工程師愛丁堡$103,600
Jena Gaines辦公室經理倫敦$90,560
Quinn Flynn支援主管愛丁堡$342,000
Charde Marshall區域總監舊金山$470,600
Haley Kennedy資深行銷設計師倫敦$313,500
Tatyana Fitzpatrick區域總監倫敦$385,750
Michael Silva行銷設計師倫敦$198,500
Paul Byrd財務長 (CFO)紐約$725,000
Gloria Little系統管理員紐約$237,500
Bradley Greer軟體工程師倫敦$132,000
Dai Rios人事主管愛丁堡$217,500
Jenette Caldwell開發主管紐約$345,000
Yuri Berry行銷長 (CMO)紐約$675,000
Caesar Vance售前支援紐約$106,450
Doris Wilder銷售助理雪梨$85,600
Angelica Ramos執行長 (CEO)倫敦$1,200,000
Gavin Joyce開發人員愛丁堡$92,575
Jennifer Chang區域總監新加坡$357,650
Brenden Wagner軟體工程師舊金山$206,850
Fiona Green營運長 (COO)舊金山$850,000
Shou Itou區域行銷東京$163,000
Michelle House整合專員雪梨$95,400
Suki Burks開發人員倫敦$114,500
Prescott Bartlett技術作者倫敦$145,000
Gavin Cortez團隊負責人舊金山$235,500
Martena Mccray售後支援愛丁堡$324,050
Unity Butler行銷設計師舊金山$85,675
Howard Hatfield辦公室經理舊金山$164,500
Hope Fuentes秘書舊金山$109,850
Vivian Harrell財務主管舊金山$452,500
Timothy Mooney辦公室經理倫敦$136,200
Jackson Bradshaw總監紐約$645,750
Olivia Liang支援工程師新加坡$234,500
Bruno Nash軟體工程師倫敦$163,500
Sakura Yamamoto支援工程師東京$139,575
Thor Walton開發人員紐約$98,540
Finn Camacho支援工程師舊金山$87,500
Serge Baldwin資料協調員新加坡$138,575
Zenaida Frank軟體工程師紐約$125,250
Zorita Serrano軟體工程師舊金山$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡$75,650
Cara Stevens銷售助理紐約$145,600
Hermione Butler區域總監倫敦$356,250
Lael Greer系統管理員倫敦$103,500
Jonas Alexander開發人員舊金山$86,500
Shad Decker區域總監愛丁堡$183,000
Michael BruceJavascript 開發人員新加坡$183,000
Donna Snider客戶支援紐約$112,000

這不僅適用於 DataTables 的全域篩選輸入,也適用於 SearchPanes 等擴充功能,您可以在以下範例中看到。這裡稍有不同的是,我們正在繪製職位欄。同樣,我連結了一個 即時版本

姓名職位辦公室薪資
Tiger Nixon系統架構師愛丁堡$320,800
Garrett Winters會計師東京$170,750
Ashton Cox初級技術作者舊金山$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡$433,060
Airi Satou會計師東京$162,700
Brielle Williamson整合專員紐約$372,000
Herrod Chandler銷售助理舊金山$137,500
Rhona Davidson整合專員東京$327,900
Colleen HurstJavascript 開發人員舊金山$205,500
Sonya Frost軟體工程師愛丁堡$103,600
Jena Gaines辦公室經理倫敦$90,560
Quinn Flynn支援主管愛丁堡$342,000
Charde Marshall區域總監舊金山$470,600
Haley Kennedy資深行銷設計師倫敦$313,500
Tatyana Fitzpatrick區域總監倫敦$385,750
Michael Silva行銷設計師倫敦$198,500
Paul Byrd財務長 (CFO)紐約$725,000
Gloria Little系統管理員紐約$237,500
Bradley Greer軟體工程師倫敦$132,000
Dai Rios人事主管愛丁堡$217,500
Jenette Caldwell開發主管紐約$345,000
Yuri Berry行銷長 (CMO)紐約$675,000
Caesar Vance售前支援紐約$106,450
Doris Wilder銷售助理雪梨$85,600
Angelica Ramos執行長 (CEO)倫敦$1,200,000
Gavin Joyce開發人員愛丁堡$92,575
Jennifer Chang區域總監新加坡$357,650
Brenden Wagner軟體工程師舊金山$206,850
Fiona Green營運長 (COO)舊金山$850,000
Shou Itou區域行銷東京$163,000
Michelle House整合專員雪梨$95,400
Suki Burks開發人員倫敦$114,500
Prescott Bartlett技術作者倫敦$145,000
Gavin Cortez團隊負責人舊金山$235,500
Martena Mccray售後支援愛丁堡$324,050
Unity Butler行銷設計師舊金山$85,675
Howard Hatfield辦公室經理舊金山$164,500
Hope Fuentes秘書舊金山$109,850
Vivian Harrell財務主管舊金山$452,500
Timothy Mooney辦公室經理倫敦$136,200
Jackson Bradshaw總監紐約$645,750
Olivia Liang支援工程師新加坡$234,500
Bruno Nash軟體工程師倫敦$163,500
Sakura Yamamoto支援工程師東京$139,575
Thor Walton開發人員紐約$98,540
Finn Camacho支援工程師舊金山$87,500
Serge Baldwin資料協調員新加坡$138,575
Zenaida Frank軟體工程師紐約$125,250
Zorita Serrano軟體工程師舊金山$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡$75,650
Cara Stevens銷售助理紐約$145,600
Hermione Butler區域總監倫敦$356,250
Lael Greer系統管理員倫敦$103,500
Jonas Alexander開發人員舊金山$86,500
Shad Decker區域總監愛丁堡$183,000
Michael BruceJavascript 開發人員新加坡$183,000
Donna Snider客戶支援紐約$112,000

使用資料處理的圖表

當然,也可以對來自 DataTable 的資料進行更多處理。以下範例正在建立一個直條圖,顯示範例表格中員工的平均薪資(按辦公室劃分)。當然,這裡有一個 即時版本連結。

姓名職位辦公室薪資
Tiger Nixon系統架構師愛丁堡$320,800
Garrett Winters會計師東京$170,750
Ashton Cox初級技術作者舊金山$86,000
Cedric Kelly資深 Javascript 開發人員愛丁堡$433,060
Airi Satou會計師東京$162,700
Brielle Williamson整合專員紐約$372,000
Herrod Chandler銷售助理舊金山$137,500
Rhona Davidson整合專員東京$327,900
Colleen HurstJavascript 開發人員舊金山$205,500
Sonya Frost軟體工程師愛丁堡$103,600
Jena Gaines辦公室經理倫敦$90,560
Quinn Flynn支援主管愛丁堡$342,000
Charde Marshall區域總監舊金山$470,600
Haley Kennedy資深行銷設計師倫敦$313,500
Tatyana Fitzpatrick區域總監倫敦$385,750
Michael Silva行銷設計師倫敦$198,500
Paul Byrd財務長 (CFO)紐約$725,000
Gloria Little系統管理員紐約$237,500
Bradley Greer軟體工程師倫敦$132,000
Dai Rios人事主管愛丁堡$217,500
Jenette Caldwell開發主管紐約$345,000
Yuri Berry行銷長 (CMO)紐約$675,000
Caesar Vance售前支援紐約$106,450
Doris Wilder銷售助理雪梨$85,600
Angelica Ramos執行長 (CEO)倫敦$1,200,000
Gavin Joyce開發人員愛丁堡$92,575
Jennifer Chang區域總監新加坡$357,650
Brenden Wagner軟體工程師舊金山$206,850
Fiona Green營運長 (COO)舊金山$850,000
Shou Itou區域行銷東京$163,000
Michelle House整合專員雪梨$95,400
Suki Burks開發人員倫敦$114,500
Prescott Bartlett技術作者倫敦$145,000
Gavin Cortez團隊負責人舊金山$235,500
Martena Mccray售後支援愛丁堡$324,050
Unity Butler行銷設計師舊金山$85,675
Howard Hatfield辦公室經理舊金山$164,500
Hope Fuentes秘書舊金山$109,850
Vivian Harrell財務主管舊金山$452,500
Timothy Mooney辦公室經理倫敦$136,200
Jackson Bradshaw總監紐約$645,750
Olivia Liang支援工程師新加坡$234,500
Bruno Nash軟體工程師倫敦$163,500
Sakura Yamamoto支援工程師東京$139,575
Thor Walton開發人員紐約$98,540
Finn Camacho支援工程師舊金山$87,500
Serge Baldwin資料協調員新加坡$138,575
Zenaida Frank軟體工程師紐約$125,250
Zorita Serrano軟體工程師舊金山$115,000
Jennifer Acosta初級 Javascript 開發人員愛丁堡$75,650
Cara Stevens銷售助理紐約$145,600
Hermione Butler區域總監倫敦$356,250
Lael Greer系統管理員倫敦$103,500
Jonas Alexander開發人員舊金山$86,500
Shad Decker區域總監愛丁堡$183,000
Michael BruceJavascript 開發人員新加坡$183,000
Donna Snider客戶支援紐約$112,000

此範例的程式碼與之前的範例非常相似,只是對我們建立的額外函式進行了一些調整。

function getSalaries(table) {
    var salaryCounts = {};
    var salary = {};

    // Get the row indexes for the rows displayed under the current search
    var indexes = table.rows({ search: 'applied' }).indexes().toArray();

    // For each row, extract the office and add the salary to the array
    for (var i = 0; i < indexes.length; i++) {
        var office = table.cell(indexes[i], 2).data();
        if (salaryCounts[office] === undefined) {
            salaryCounts[office] = [
                +table
                    .cell(indexes[i], 3)
                    .data()
                    .replace(/[^0-9.]/g, ''),
            ];
        } else {
            salaryCounts[office].push(
                +table
                    .cell(indexes[i], 3)
                    .data()
                    .replace(/[^0-9.]/g, '')
            );
        }
    }

    // Extract the office names that are present in the table
    var keys = Object.keys(salaryCounts);

    // For each office work out the average salary
    for (var i = 0; i < keys.length; i++) {
        var length = salaryCounts[keys[i]].length;
        var total = salaryCounts[keys[i]].reduce((a, b) => a + b, 0);
        salary[keys[i]] = total / length;
    }

    return salary;
}

這裡我們有 2 個物件,第一個 salary 物件將保存我們需要的直條圖最終資料,而 salaryCounts 是一個臨時物件,將允許我們執行一些額外處理。

我們還必須對我們的 series 變數進行更改,資料現在是 salary 陣列的值。我們還需要宣告 x 和 y 軸。將所有這些放在一起,我們得到以下腳本,用於上面的範例。

$(document).ready(function () {
    var table = $('#example').DataTable();
    var salary = getSalaries(table);

    // Declare axis for the column graph
    var axis = {
        id: 'salary',
        min: 0,
        title: {
            text: 'Average Salary',
        },
    };

    // Declare inital series with the values from the getSalaries function
    var series = {
        name: 'Overall',
        data: Object.values(salary),
    };

    var myChart = Highcharts.chart('container', {
        chart: {
            type: 'column',
        },
        title: {
            text: 'Average Salary',
        },
        xAxis: {
            categories: Object.keys(salary),
        },
        yAxis: axis,
        series: [series],
    });

    // On draw, get updated salaries and refresh axis and series
    table.on('draw', function () {
        salary = getSalaries(table);
        myChart.axes[0].categories = Object.keys(salary);
        myChart.series[0].setData(Object.values(salary));
    });
});

function getSalaries(table) {
    var salaryCounts = {};
    var salary = {};

    // Get the row indexes for the rows displayed under the current search
    var indexes = table.rows({ search: 'applied' }).indexes().toArray();

    // For each row, extract the office and add the salary to the array
    for (var i = 0; i < indexes.length; i++) {
        var office = table.cell(indexes[i], 2).data();
        if (salaryCounts[office] === undefined) {
            salaryCounts[office] = [
                +table
                    .cell(indexes[i], 3)
                    .data()
                    .replace(/[^0-9.]/g, ''),
            ];
        } else {
            salaryCounts[office].push(
                +table
                    .cell(indexes[i], 3)
                    .data()
                    .replace(/[^0-9.]/g, '')
            );
        }
    }

    // Extract the office names that are present in the table
    var keys = Object.keys(salaryCounts);

    // For each office work out the average salary
    for (var i = 0; i < keys.length; i++) {
        var length = salaryCounts[keys[i]].length;
        var total = salaryCounts[keys[i]].reduce((a, b) => a + b, 0);
        salary[keys[i]] = total / length;
    }

    return salary;
}

正如我所提到的,Highcharts 提供了廣泛的不同圖表,透過利用 DataTables API,可以輕鬆地建立動態圖表,與 DataTable 一起執行。

希望這將有助於為您的 DataTables 實作增加另一個維度。