文章分類/

Highcharts|Highcharts React Wrapper Dashboard

558 瀏覽人次

highcharts logo



在本教學中,我將向你展示如何用Highcharts和React包裝器創建一個簡單的、交互式的儀錶板。這篇文章適用於各個層次的開發者。對於任何有經驗的開發者來說,它都可以快速閱讀,並為那些剛接觸React或Highcharts的人提供幫助。

備註


我使用Create React App和Visual Studio Code
IDE來構建這個項目;你可以從這個Github鏈接或Codesandbox上下載這個項目。如果需要,可以參考之前的文章,了解如何從頭創建一個項目。


下面的儀錶盤直觀地顯示了2001年至2015年美國的淨能源生產情況。該儀表板允許瀏覽者比較以下類別的主要能源生產情況:化石燃料、水電能源、生物質能和可再生能源。我從美國能源信息署(又稱EIA)收集了這些數據。

在創建儀表板時,我遵循了這些最佳做法。

  1. 將背景與圖表分開(即用顏色來標記每個圖表部件的邊界)。
  2. 保持圖例與圖表接近

  3. 避免擁擠的圖表(即把重要的信息分成多個圖表,而不是把太多的數據塞進一個圖表中
  4. 提供探索數據的工具(如縮放和過濾)
  5. 考慮響應式設計


要了解更多關於如何創建一個有效的儀錶盤,請查看以下文章:在將圖表放入儀錶盤之前需要考慮的6件事;在那裡你會發現關於上述每一點的更多細節和演示。

要檢查實時互動儀表板,請點擊Codesandbox項目鏈接,或點擊下面的圖片。


讓我們來看看創建儀表板的過程吧!

架構


讓我們從回顧全局架構開始。架構規劃有助於顯示組件之間的連接;它還能使數據流可視化。我強烈建議在跳轉到編碼之前花一些時間規劃你的架構;你將節省大量的時間和頭髮的拉扯。


這個儀錶盤的主要想法相對簡單。用戶通過用戶界面選擇日期範圍,這個動作觸發了從這個日期範圍提取數據的過程,按能源來源總結數據,然後將結果歸類為化石燃料、水電能源、生物質能或可再生能源。最後一步是將數據顯示為四個互動的多納特圖,每個類別一個。順便說一下,甜甜圈圖或餅圖是顯示比較和構成的最佳方式;它們結構緊湊,易於理解;這就是為什麼它們經常被用於儀錶盤。


我的下一個合乎邏輯的行動是將這個想法分解成小的組件,以使我更容易編碼和維護每個組件。經過幾次草圖設計和優化,我最終得到了七個組件。

  1. 數據組件:保存從EIA網站收集的數據。
  2. 數據處理。為了在用戶選擇後將數據加起來。
  3. 圖表模板。設置Highcharts庫所要求的交互式圖表的配置。
  4. 範圍選擇組件。處理用戶使用的日期選擇器。
  5. 圖表模塊。在用戶選擇的每個範圍後渲染圖表。
  6. 儀表板組件。在一個容器中收集和呈現所有的聊天記錄。
  7. 應用程序組件。收集所有的組件並運行儀表板。


然後,我把我的項目分為七個組件,四個ReactJS組件(紫色)和三個模塊(綠色)。我的標準很簡單,如果有任何東西需要渲染,該組件就成為ReactJS組件,否則,它只是一個標準的javascript模塊,沒有渲染,只有一堆對像或函數用於數據處理。



我不得不將Highcharts React
Wrapper(藍色)添加到架構中,以實現可視化,並知道我必須將該庫添加到我的項目中。由於圖表的渲染將在Chart組件中進行,我將Highcharts
React Wrapper導入到該組件中。

Coding…有趣的部分來了


設置好架構後,我用Create React
App創建了一個新的項目;然後我添加了組件文件夾,在那裡我為每個組件製作了一個文件。為了將ReactJS組件與其他模塊分開,我將每個ReactJS組件文件的第一個字母以大寫字母開始;這是一個很好的做法,可以快速識別哪個文件做什麼,因為它使導入直觀,並減少文件之間的任何歧義。

請看下面的項目文件結構。


讓我們深入探討每個組成部分。

Data


數據模塊有一個對像數據,我把每個能源的數據存儲在一個專門的對像中,然後我使用導出默認數據導出對像數據。

const data = {  coal: {    2001: 1903955, ...  },  pliquids: {    2001: 114646, ...  },  pcoke: {    2001: 10235, ...  },  ngas: {    2001: 639129, ...  },  ogas: {    2001: 9040, ...  },  nuclear: {    2001: 768825, ...  },  chydroelectric: {    2001: 216962, ...  },  wind: {    2001: 6737, ...,    2015: 93876  },  solar: {    2001: 543, ...  },  geothermal: {    2001: 13740, ...  },  biomass: {    2001: 49749,  ...  },  wood: {    2001: 35199, ...  },  otherbio: {    2001: 14549, ...  } };  export default data; 

DATA PROCESSING


該模塊從數據模塊導入數據,然後將數據與yearFrom和yearTo作為參數傳遞給箭頭函數dataProcessing。

import data from './data'; let dataProcessing = (yearFrom, yearTo) => { ... 

該函數計算出每個能源在日期範圍內產生的能量數量。

if (yearFrom < yearTo) {    let coal = 0,      pliquids = 0,      pcoke = 0,      ngas = 0,      ogas = 0,      nuclear = 0,      chydroelectric = 0,      wind = 0,      solar = 0,      geothermal = 0,      biomass = 0,      wood = 0,      otherbio = 0;    for (let i = yearFrom; i < yearTo; i++) {      coal += data.coal[i];      pliquids += data.pliquids[i];      pcoke += data.pcoke[i];      ngas += data.ngas[i];      ogas += data.ogas[i];      nuclear += data.nuclear[i];      chydroelectric += data.chydroelectric[i];      wind += data.wind[i];      solar += data.solar[i];      geothermal += data.geothermal[i];      biomass += data.biomass[i];      wood += data.wood[i];      otherbio += data.otherbio[i];    } 

根據能源的性質,計算出的數據被保存在四個對像中。

 fossilFuelData = [      { name: 'coal', y: coal },      { name: 'Petroleum Liquids', y: pliquids },      { name: 'Petroleum Coke', y: pcoke },      { name: 'Natural gas', y: ngas },      { name: 'Other Gases', y: ogas }    ];     hydroElectricData = [      { name: 'Nuclear', y: nuclear },      { name: 'Conventional Hydroelectric', y: chydroelectric }    ];     biomassData = [      { name: 'Biomass', y: biomass },      { name: 'Wood', y: wood },      { name: 'Otherbio', y: otherbio }    ];     renewableEnergyData = [      { name: 'Wind', y: wind },      { name: 'Solar', y: solar },      { name: 'Geothermal', y: geothermal }    ]; 


該函數還處理了一個信息,以表示給用戶選擇範圍,並確保yearFrom總是小於或等於yearTo。


Template


儀錶盤有四個交互式甜甜圈圖表,所以我沒有單獨創建每個圖表,而是按照Highcharts庫的結構設置了一個模板模塊,然後在App模塊中使用它來創建圖表。

const template = {  userConfig: {    tooltip: {      pointFormat: "{point.y} thousand megawatthours"    },    plotOptions: {      pie: {        showInLegend: true,        innerSize: "60%",        dataLabels: {          enabled: false,          distance: -14,          color: "white",          style: {            fontweight: "bold",            fontsize: 50          }        }      }    }  },  yearFrom: "2001",  yearTo: "2015",  msg: "Select the range" };  export default template; 


正如你所看到的,該模板有主要的標準Highchart圖表配置,如工具提示和plotOptions。

SELECTION

這個文件是一個ReactJS組件;它渲染了選擇元素,允許用戶選擇日期範圍。



對於這個組件,我使用Bootstrap來設計元素的樣式,你可以自由地想出你自己的樣式,但同樣為了可維護性,我決定使用一個標準的樣式庫。

Charts

Chart.js文件是另一個ReactJS組件;它在每次有更新時都會渲染圖表。


這個組件的關鍵元素是componentDidUpdate(prevProps,
prevState)方法;我用它來檢查是否有任何更新,然後獲取新圖表的參數,再將這些參數傳遞給Chart狀態組件。

componentDidUpdate(prevProps, prevState) {     if (this.props.data !== prevProps.data) {       this.setState({         chartData: {           ...this.state.chartData,           subtitle: {             text:               (                 this.props.data.reduce((accumulator, obj) => accumulator + obj.y,0) / 1000).toFixed(2) + " TWh"           },           series: [             {               data: this.props.data             }           ]         }       });     }   } 

DASHBOARD

在這個組件中,我使用以下代碼動態地渲染所有的圖表。

{this.props.charts && this.props.charts.map(chart => {            return (              <div className="col-xs-12 col-sm-6 mb-2" key={i}>                <Chart                  data={chart.serie}                  userConfig={this.props.userConfig}                  titleName={chart.title}                />              </div>            );          })}

APP

最後,我把所有的ReactJS組件聚集在這個主組件App.js中,以渲染整個儀表板。

在這個組件中,有一個箭頭功能 handleChangeYear。

handleChangeYear = e => {               this.setState({                   [e.target.name]: e.target.value               }); }; 

該函數處理選擇元素的事件,並將新的時間範圍保存在組件App.js的狀態中;這個過程會觸發方法componentDidUpdate(prevProps,
prevState)。

 componentDidUpdate(prevProps, prevState) {    if (prevState.yearFrom !== this.state.yearFrom) {      this.handleChangeSelect();    }    if (prevState.yearTo !== this.state.yearTo) {      this.handleChangeSelect();    }  } 

該組件componentDidUpdate(prevProps,
prevState)調用handleChangeSelect()來處理數據(在數據處理模塊),然後更新圖表。

整個過程的最後一步是在儀表板上顯示新的圖表。

在App.js文件中,我還使用了Bootstrap來設計儀錶盤上顯示的不同元素的樣式。

項目完成後,我意識到最具挑戰性和最耗時的部分是弄清架構;之後,編碼部分就很簡單了。我在handleChangeYear方面也遇到了一些挑戰;我不得不使用括號符號來確定我正在處理正確的按鈕。

快速跳轉目錄

✦ 群昱 AccessSoft 你的全面軟體解決方案 ✦

身為全球眾多知名軟體在台灣合作夥伴,歡迎諮詢你需要的軟體服務!

Picture of 軟體專家
軟體專家

群昱作為全球知名軟體推薦合作夥伴,致力於提供更多軟體解決方案給你!

更多軟體新知

立即詢價

請留下完整資訊,以便我們提供精確的服務內容給你。

詢價資訊