{"id":17415,"date":"2019-02-02T22:03:52","date_gmt":"2019-02-02T21:03:52","guid":{"rendered":"http:\/\/www.highcharts.com\/blog\/?p=17415"},"modified":"2026-01-12T10:04:49","modified_gmt":"2026-01-12T10:04:49","slug":"highcharts-react-wrapper-dashboard","status":"publish","type":"post","link":"https:\/\/www.highcharts.com\/blog\/integration\/highcharts-react-wrapper-dashboard\/","title":{"rendered":"Highcharts React Wrapper Dashboard"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p>In my <a href=\"https:\/\/www.highcharts.com\/blog\/post\/highcharts-wrapper-for-react-101\/\">previous post<\/a>, I showed you how to get started with the <a href=\"https:\/\/github.com\/highcharts\/highcharts-react\">official Highcharts React wrapper<\/a>.<\/p>\n<p>In this tutorial, I will show you how to create a simple, interactive dashboard with Highcharts and the React wrapper. This article is suitable for developers at all levels. It will be a quick read for any experienced developer and provide help for those who are new to either React or Highcharts.<\/p>\n<p><i><b>Remark<\/b><br \/>\nI use <a href=\"https:\/\/github.com\/facebook\/create-react-app\">Create React App<\/a> and the <a href=\"https:\/\/code.visualstudio.com\/\">Visual Studio Code IDE<\/a> to build this project; you can download the project from this <a href=\"https:\/\/github.com\/mekhatria\/HighchartsReactDashboard\">Github link<\/a> or from the <a href=\"https:\/\/codesandbox.io\/s\/3yqw8y52v6?view=preview\">Codesandbox<\/a>. If needed, refer to the previous post for how to create a project from scratch.<\/i><\/p>\n<p>&nbsp;<\/p>\n<p>The dashboard below visualizes the net energy generation in the United States from 2001 to 2015. The dashboard allows the viewer to compare the main energy sources produced in the following categories fossil fuel, hydroelectric energy, biomass, and renewable energy. I collected the data from the <a href=\"https:\/\/www.eia.gov\/electricity\/data\/browser\/#\/topic\/0?agg=2,0,1&amp;fuel=vtvo&amp;geo=g&amp;sec=g&amp;linechart=ELEC.GEN.ALL-US-99.M~ELEC.GEN.COW-US-99.M~ELEC.GEN.NG-US-99.M~ELEC.GEN.NUC-US-99.M~ELEC.GEN.HYC-US-99.M~ELEC.GEN.WND-US-99.M&amp;columnchart=ELEC.GEN.ALL-US-99.M~ELEC.GEN.COW-US-99.M~ELEC.GEN.NG-US-99.M~ELEC.GEN.NUC-US-99.M~ELEC.GEN.HYC-US-99.M~ELEC.GEN.WND-US-99.M&amp;map=ELEC.GEN.ALL-US-99.M&amp;freq=M&amp;start=200101&amp;end=201505&amp;chartindexed=2&amp;ctype=linechart&amp;ltype=pin&amp;rtype=s&amp;pin=&amp;rse=0&amp;maptype=0\">U.S. Energy Information Administration<\/a> also known as <strong>EIA<\/strong>.<\/p>\n<p>In creating the dashboard, I followed these best practices:<\/p>\n<ol>\n<li>Separate background from the charts (i.e. use color to mark the boundaries of each chart widget)<\/li>\n<li>Keep the legend close to the charts<\/li>\n<li>Avoid crowded charts (i.e. break out important information into multiple charts, rather than cramming too much data into one chart)<\/li>\n<li>Provide tools to explore data (e.g. zooming and filtering)<\/li>\n<li>Think responsive design<\/li>\n<\/ol>\n<p>To learn more about how to create an effective dashboard check the following article <a href=\"https:\/\/technologyadvice.com\/blog\/information-technology\/consider-charts-dashboard\/\">6 Things to Consider Before Putting Charts Into a Dashboard<\/a>; where you will find more details and demos about each point described above.<\/p>\n<p>To check the live interactive dashboard click on the <a href=\"https:\/\/codesandbox.io\/s\/3yqw8y52v6?view=preview\">Codesandbox project link<\/a>, or click on the picture below:<\/p>\n<p><!--iframe style=\"width: 100%; height: 1300px; border: 0; border-radius: 4px; overflow: hidden;\" src=\"https:\/\/codesandbox.io\/embed\/3yqw8y52v6?view=preview\" sandbox=\"allow-modals allow-forms allow-popups allow-scripts allow-same-origin\"><\/iframe--><\/p>\n<p><a href=\"https:\/\/codesandbox.io\/embed\/3yqw8y52v6?view=preview\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-17490\" src=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard.jpg\" alt=\"\" width=\"1160\" height=\"1010\" srcset=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard.jpg 1160w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-70x60.jpg 70w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-505x440.jpg 505w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-768x669.jpg 768w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-678x590.jpg 678w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-322x280.jpg 322w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/06235222\/Highcharts-React-Wrapper-Dashboard-1034x900.jpg 1034w\" sizes=\"auto, (max-width: 1160px) 100vw, 1160px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<p>Let\u2019s go through the process to create the dashboard!<\/p>\n<p>&nbsp;<\/p>\n<h4 style=\"text-align: center;\"><b>The architecture<\/b><\/h4>\n<p>Let\u2019s start by reviewing global architecture. Architecture planning helps show what the connections between components will be; it also visualizes the data flow. I strongly recommend to take some time planning your architecture before jumping to code; you will save a lot of time and hair pulling.<\/p>\n<p>The main idea of this dashboard is relatively simple: A user selects date range via the UI, this action triggers the process to pull data from this date range, summarizes data by energy source, then categorizes the result into either a fossil fuel, Hydroelectric energy, Biomass or Renewable energy. The final step is to display the data into four interactive Donut charts, one for each category. By the way, Donut or Pie charts are great to show comparison and composition at a glance; there are compact and easy to understand; which is why they are so often used for dashboards.<\/p>\n<p>My next logical action was to break down the idea into small components, to make it easier for me to code and to maintain each component. After a few sketches and optimizations, I ended up with seven components:<\/p>\n<ol>\n<li><b>Data component<\/b>: to save the data collected from the EIA website.<\/li>\n<li><b>Data processing<\/b>: To add up the data after the user selection.<\/li>\n<li><b>Chart template<\/b>: To set up the interactive charts\u2019 configurations required by the Highcharts library.<\/li>\n<li><b>Range selection component<\/b>: To handle the date selectors used by the user.<\/li>\n<li><b>Chart module<\/b>: To render the charts after each range selected by the user.<\/li>\n<li><b>Dashboard component<\/b>: To gather and render all the chats on one container.<\/li>\n<li><b>The App component<\/b>: To gather all the components and run the dashboard.<\/li>\n<\/ol>\n<p>Then, I divided my project into seven components four ReactJS components (<span style=\"color: #9e3ff4;\"><strong>purple<\/strong><\/span>) and three modules (<span style=\"color: #40a978;\">green<\/span>). My criterium was simple; if there is anything to render, the component becomes ReactJS component, otherwise, it is just a standard javascript module where there is no rendering, just a bunch of objects or functions for data processing.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17421\" src=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture.jpg\" alt=\"\" width=\"100%\" srcset=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture.jpg 1160w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture-560x291.jpg 560w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture-768x399.jpg 768w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture-760x394.jpg 760w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01160947\/architecture-360x187.jpg 360w\" sizes=\"(max-width: 1160px) 100vw, 1160px\" \/><\/p>\n<p>I had to add the Highcharts React Wrapper (<span style=\"color: #76abd7;\"><strong>blue<\/strong><\/span>) to the architecture to visualize and to know where I have to add the library to my project. And since the chart rendering is going to be in the Chart component, I imported the Highcharts React Wrapper to that component.<\/p>\n<h4 style=\"text-align: center;\"><b>Coding \u2026 the fun part<\/b><\/h4>\n<p>After I set up the architecture, I created a new project using Create React App; then I added the folder components where I made a file for each component. To separate the ReactJS components from the other modules, I started the first letter of each ReactJS component file with an uppercase; it is a good practice to quickly recognize which file does what since it makes the import intuitive, and reduce any ambiguity among files.<\/p>\n<p>Check below the project file structure:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17426\" src=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure.jpg\" alt=\"\" width=\"100%\" srcset=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure.jpg 1160w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure-560x280.jpg 560w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure-768x384.jpg 768w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure-760x380.jpg 760w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/01164256\/structure-360x180.jpg 360w\" sizes=\"(max-width: 1160px) 100vw, 1160px\" \/><\/p>\n<p>Let\u2019s explore each component in depth:<\/p>\n<h4><b>Data<\/b><\/h4>\n<p>The data module has an object <code>data<\/code>, where I store the data about each energy source in one dedicated object, then I export the object <code>data<\/code> using the <code>export default data<\/code>:<\/p>\n<pre>const data = {\r\n coal: {\r\n   2001: 1903955,\r\n...\r\n },\r\n pliquids: {\r\n   2001: 114646,\r\n...\r\n },\r\n pcoke: {\r\n   2001: 10235,\r\n...\r\n },\r\n ngas: {\r\n   2001: 639129,\r\n...\r\n },\r\n ogas: {\r\n   2001: 9040,\r\n...\r\n },\r\n nuclear: {\r\n   2001: 768825,\r\n...\r\n },\r\n chydroelectric: {\r\n   2001: 216962,\r\n...\r\n },\r\n wind: {\r\n   2001: 6737,\r\n...,\r\n   2015: 93876\r\n },\r\n solar: {\r\n   2001: 543,\r\n...\r\n },\r\n geothermal: {\r\n   2001: 13740,\r\n...\r\n },\r\n biomass: {\r\n   2001: 49749,\r\n ...\r\n },\r\n wood: {\r\n   2001: 35199,\r\n...\r\n },\r\n otherbio: {\r\n   2001: 14549,\r\n...\r\n }\r\n};\r\n\r\nexport default data;\r\n<\/pre>\n<p>&nbsp;<\/p>\n<h4><b>Data processing<\/b><\/h4>\n<p>This module imports the data from the data module then passes the data with the <code>yearFrom<\/code> and the <code>yearTo<\/code> as parameters to an arrow function <code>dataProcessing<\/code>.<\/p>\n<pre>import data from '.\/data';\r\nlet dataProcessing = (yearFrom, yearTo) =&gt; {\r\n...<\/pre>\n<p>The function calculates the amounts of energy produced during the date range for each energy source.<\/p>\n<pre> if (yearFrom &lt; yearTo) {\r\n   let coal = 0,\r\n     pliquids = 0,\r\n     pcoke = 0,\r\n     ngas = 0,\r\n     ogas = 0,\r\n     nuclear = 0,\r\n     chydroelectric = 0,\r\n     wind = 0,\r\n     solar = 0,\r\n     geothermal = 0,\r\n     biomass = 0,\r\n     wood = 0,\r\n     otherbio = 0;\r\n   for (let i = yearFrom; i &lt; yearTo; i++) {\r\n     coal += data.coal[i];\r\n     pliquids += data.pliquids[i];\r\n     pcoke += data.pcoke[i];\r\n     ngas += data.ngas[i];\r\n     ogas += data.ogas[i];\r\n     nuclear += data.nuclear[i];\r\n     chydroelectric += data.chydroelectric[i];\r\n     wind += data.wind[i];\r\n     solar += data.solar[i];\r\n     geothermal += data.geothermal[i];\r\n     biomass += data.biomass[i];\r\n     wood += data.wood[i];\r\n     otherbio += data.otherbio[i];\r\n   }\r\n<\/pre>\n<p>The data calculated is saved in the four objects depending on the nature of the energy source:<\/p>\n<pre> fossilFuelData = [\r\n     { name: 'coal', y: coal },\r\n     { name: 'Petroleum Liquids', y: pliquids },\r\n     { name: 'Petroleum Coke', y: pcoke },\r\n     { name: 'Natural gas', y: ngas },\r\n     { name: 'Other Gases', y: ogas }\r\n   ];\r\n\r\n   hydroElectricData = [\r\n     { name: 'Nuclear', y: nuclear },\r\n     { name: 'Conventional Hydroelectric', y: chydroelectric }\r\n   ];\r\n\r\n   biomassData = [\r\n     { name: 'Biomass', y: biomass },\r\n     { name: 'Wood', y: wood },\r\n     { name: 'Otherbio', y: otherbio }\r\n   ];\r\n\r\n   renewableEnergyData = [\r\n     { name: 'Wind', y: wind },\r\n     { name: 'Solar', y: solar },\r\n     { name: 'Geothermal', y: geothermal }\r\n   ];<\/pre>\n<p>The function also handles a message to indicated to the user to select the range, and to be sure that the <code>yearFrom<\/code> is always smaller or equal to the <code>yearTo<\/code>.<\/p>\n<h4><b>Template<\/b><\/h4>\n<p>The dashboard has four interactive donut charts, so instead of creating each chart separately, I set up one template module following the Highcharts library structure, then use it in the App module to create the charts.<\/p>\n<pre>const template = {\r\n userConfig: {\r\n   tooltip: {\r\n     pointFormat: \"<b>{point.y} thousand megawatthours<\/b>\"\r\n   },\r\n   plotOptions: {\r\n     pie: {\r\n       showInLegend: true,\r\n       innerSize: \"60%\",\r\n       dataLabels: {\r\n         enabled: false,\r\n         distance: -14,\r\n         color: \"white\",\r\n         style: {\r\n           fontweight: \"bold\",\r\n           fontsize: 50\r\n         }\r\n       }\r\n     }\r\n   }\r\n },\r\n yearFrom: \"2001\",\r\n yearTo: \"2015\",\r\n msg: \"Select the range\"\r\n};\r\n\r\nexport default template;\r\n<\/pre>\n<p>As you can see, the template has the main standard Highchart chart\u2019s configuration such as the <code>tooltip<\/code> and the <code>plotOptions<\/code>.<\/p>\n<h4><b>Selection<\/b><\/h4>\n<p>This file is a ReactJS component; it renders the select elements that allow the user to choose the date range.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-17461\" src=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector.jpg\" alt=\"\" width=\"50%\" srcset=\"https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector.jpg 999w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector-560x273.jpg 560w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector-768x374.jpg 768w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector-760x370.jpg 760w, https:\/\/wp-assets.highcharts.com\/www-highcharts-com\/blog\/wp-content\/uploads\/2019\/02\/02212742\/selector-360x175.jpg 360w\" sizes=\"(max-width: 999px) 100vw, 999px\" \/><\/p>\n<p>For this component, I use Bootstrap to style the elements, you are free to come up with your own style, but again for the sake of the maintainability, I decided to go with a standard styling library.<\/p>\n<h4><b>Chart<\/b><\/h4>\n<p>The <code>Chart.js<\/code> file is another ReactJS component; it renders the charts each time there is an update.<\/p>\n<p>The key element in this component is the <code>componentDidUpdate(prevProps, prevState)<\/code> method; I use it to check if there is any update before fetching the new charts\u2019 parameters, then passing those parameters to the Chart state component.<\/p>\n<pre>componentDidUpdate(prevProps, prevState) {\r\n    if (this.props.data !== prevProps.data) {\r\n      this.setState({\r\n        chartData: {\r\n          ...this.state.chartData,\r\n          subtitle: {\r\n            text:\r\n              (\r\n                this.props.data.reduce((accumulator, obj) =&gt; accumulator + obj.y,0) \/ 1000).toFixed(2) + \" TWh\"\r\n          },\r\n          series: [\r\n            {\r\n              data: this.props.data\r\n            }\r\n          ]\r\n        }\r\n      });\r\n    }\r\n  }<\/pre>\n<h4><b>Dashboard<\/b><\/h4>\n<p>In this component, I render all the charts dynamically using the following code:<\/p>\n<pre>{this.props.charts &amp;&amp; this.props.charts.map(chart =&gt; {\r\n           return (\r\n             &lt;div className=\"col-xs-12 col-sm-6 mb-2\" key={i}&gt;\r\n               &lt;Chart\r\n                 data={chart.serie}\r\n                 userConfig={this.props.userConfig}\r\n                 titleName={chart.title}\r\n               \/&gt;\r\n             &lt;\/div&gt;\r\n           );\r\n         })}<\/pre>\n<h4><b>App<\/b><\/h4>\n<p>Finally, I gather all the ReactJS components in this main component <code>App.js<\/code> to render the whole dashboard.<\/p>\n<p>In this component, there is an arrow functions <code>handleChangeYear<\/code>:<\/p>\n<pre>handleChangeYear = e =&gt; {\r\n              this.setState({\r\n                  [e.target.name]: e.target.value\r\n              });\r\n};<\/pre>\n<p>The function handles events on the select elements and saves the new time range in the state of the component <code>App.js<\/code>; this process triggers the method <code>componentDidUpdate(prevProps, prevState)<\/code><\/p>\n<pre> componentDidUpdate(prevProps, prevState) {\r\n   if (prevState.yearFrom !== this.state.yearFrom) {\r\n     this.handleChangeSelect();\r\n   }\r\n   if (prevState.yearTo !== this.state.yearTo) {\r\n     this.handleChangeSelect();\r\n   }\r\n }<\/pre>\n<p>The component <code>componentDidUpdate(prevProps, prevState)<\/code> calls the <code>handleChangeSelect()<\/code> to process the data (in the data process module), then update the charts.<br \/>\nThe last step in this entire process is to display the new charts on the dashboard.<\/p>\n<p>In the <code>App.js<\/code> file, I also use Bootstrap to style the different elements that are displayed on the dashboard.<\/p>\n<p>Once the project was done, I realized that the most challenging and the most time-consuming part was to figure out the architecture; after that, the code part was straightforward. I also had some challenges with the <code>handleChangeYear<\/code>; I had to use the bracket notation to be sure that I am handling the right button.<\/p>\n<p>Well, that is it. I hope my experience will be helpful for you, and feel free to share your own experience with the wrapper, or leave a comment\/question below, I will be happy to answer you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to create an interactive dashboard using Highcharts React Wrapper and bootstrap.<\/p>\n","protected":false},"author":32,"featured_media":17475,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"meta_title":"","meta_description":"","hc_selected_options":[],"footnotes":""},"categories":[1105],"tags":[1010,1031,824],"coauthors":[699],"class_list":["post-17415","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-integration","tag-highcharts-dashboards","tag-javascript","tag-react"],"_links":{"self":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/17415","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/comments?post=17415"}],"version-history":[{"count":1,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/17415\/revisions"}],"predecessor-version":[{"id":24778,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/posts\/17415\/revisions\/24778"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media\/17475"}],"wp:attachment":[{"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/media?parent=17415"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/categories?post=17415"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/tags?post=17415"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.highcharts.com\/blog\/wp-json\/wp\/v2\/coauthors?post=17415"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}