Introduction
This is a quick blog post to show how easy it is to integrate beautiful graphs into your JavaScript application using the 4.x API. If you are new to the ArcGIS API for JavaScript, we provide an easy way to get started making web mapping applications. Head over to the ArcGIS API for JavaScript site to get started. For this sample we will be using a third party library called Chart.js. Chart.js is a simple yet flexible JavaScript charting library which makes it easy to make simple graphs for your data.
Load in the Chart.js library into your JavaScript application
In order to use Chart.js in our application we need to load it in as a module. This is because Dojo uses Asynchronous Module Definition (AMD) format to load in modules as supposed to loading in a file using a script tag. To achieve this we can use dojoConfig to load in our custom JS package as a module.
<SPAN class="language-javascript script token"><SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN>script</SPAN><SPAN class="punctuation token">></SPAN></SPAN>
<SPAN class="keyword token">const</SPAN> options <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="comment token">// tell Dojo where to load other packages</SPAN>
dojoConfig<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">async</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">true</SPAN><SPAN class="punctuation token">,</SPAN>
packages<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN>
<SPAN class="punctuation token">{</SPAN>
location<SPAN class="punctuation token">:</SPAN> <SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2FChart.js%2F2.7.2%2FChart.js" target="_blank">https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js</A><SPAN>'</SPAN></SPAN><SPAN class="punctuation token">,</SPAN>
name<SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'Chart'</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN>script</SPAN><SPAN class="punctuation token">></SPAN></SPAN></SPAN>
<SPAN class="language-javascript script token"><SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"><</SPAN>script</SPAN> <SPAN class="attr-name token">src</SPAN><SPAN class="attr-value token"><SPAN class="punctuation token">=</SPAN><SPAN class="punctuation token">"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fjs.arcgis.com%2F4.7%2F" target="_blank">https://js.arcgis.com/4.7/</A><SPAN class="punctuation token">"</SPAN></SPAN><SPAN class="punctuation token">></SPAN></SPAN><SPAN class="token tag"><SPAN class="token tag"><SPAN class="punctuation token"></</SPAN>script</SPAN><SPAN class="punctuation token">></SPAN></SPAN></SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>As you can see from the sample code above, we are going to tell dojo to load in a module from a Content Delivery Network (CDN). In this case we are using the CDN that Chart.js provides for us. You can also install the files through a package manager like npm or Bower. You can learn the different ways of installing Chart.js through their Installation documentation. To avoid any potential errors, ensure the dojoConfig is declared before the ArcGIS for JavaScript API.
Integrating Chart.js in your JavaScript application
Once you have completed the above steps, we can now use Chart.js in our JavaScript file...
<SPAN class="token function">require</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">[</SPAN>
<SPAN class="string token">"esri/Map"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"esri/views/MapView"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"esri/PopupTemplate"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"esri/layers/FeatureLayer"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"esri/widgets/Popup"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"esri/tasks/support/Query"</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token"><SPAN>"</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2FChart.js%2F2.7.2%2FChart.js" target="_blank">https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js</A><SPAN>"</SPAN></SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">"dojo/domReady!"</SPAN>
<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="keyword token">function</SPAN> <SPAN class="punctuation token">(</SPAN>Map<SPAN class="punctuation token">,</SPAN> MapView<SPAN class="punctuation token">,</SPAN> PopupTemplate<SPAN class="punctuation token">,</SPAN> FeatureLayer<SPAN class="punctuation token">,</SPAN> Popup<SPAN class="punctuation token">,</SPAN> Query<SPAN class="punctuation token">,</SPAN> Chart<SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
In the require array we put in the CDN link to the library. We then name the module Chart so that we can create a new instance of it later on in our code.
Querying data from a Feature Layer
In this example I am using a Feature Layer of California from ArcGIS online . Each time I click on a county, I want a pop up to show information about the demographics of the area. For this we can use a Query, which will allow us to get information from our Feature Layer and spatially query the layer to only show data where we clicked. Once the promise has resolved, we will call the view's PopUp and send the data to setContentInfo. This is a function that will create the chart for us. The setContentInfo function will be explained more in detail on the next section. Here is the code snippet that shows this.
<SPAN class="keyword token">var</SPAN> query <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Query</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
query<SPAN class="punctuation token">.</SPAN>returnGeometry <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">true</SPAN><SPAN class="punctuation token">;</SPAN>
query<SPAN class="punctuation token">.</SPAN>outFields <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="string token">"STATE_NAME"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"WHITE"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"BLACK"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"ASIAN"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"HAWN_PI"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"OTHER"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"HISPANIC"</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN>
query<SPAN class="punctuation token">.</SPAN>where <SPAN class="operator token">=</SPAN> <SPAN class="string token">"1=1"</SPAN><SPAN class="punctuation token">;</SPAN>
query<SPAN class="punctuation token">.</SPAN>num <SPAN class="operator token">=</SPAN> <SPAN class="number token">50</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// On view click, query the feature layer and pass the results to setContentInfo function.</SPAN>
view<SPAN class="punctuation token">.</SPAN><SPAN class="token function">on</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"click"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN>e<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">=</SPAN><SPAN class="operator token">></SPAN> <SPAN class="punctuation token">{</SPAN>
query<SPAN class="punctuation token">.</SPAN>geometry <SPAN class="operator token">=</SPAN> e<SPAN class="punctuation token">.</SPAN>mapPoint<SPAN class="punctuation token">;</SPAN>
featureLayer<SPAN class="punctuation token">.</SPAN><SPAN class="token function">queryFeatures</SPAN><SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN><SPAN class="token function">then</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">)</SPAN> <SPAN class="operator token">=</SPAN><SPAN class="operator token">></SPAN><SPAN class="punctuation token">{</SPAN>
<SPAN class="keyword token">if</SPAN><SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">.</SPAN>features<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>attributes<SPAN class="punctuation token">.</SPAN>STATE_NAME <SPAN class="operator token">===</SPAN> <SPAN class="string token">"California"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">{</SPAN>
view<SPAN class="punctuation token">.</SPAN>popup<SPAN class="punctuation token">.</SPAN>visible <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">true</SPAN><SPAN class="punctuation token">;</SPAN>
view<SPAN class="punctuation token">.</SPAN>popup<SPAN class="punctuation token">.</SPAN><SPAN class="token function">open</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN>
title<SPAN class="punctuation token">:</SPAN> <SPAN class="string token">"Doughnut Graph Example"</SPAN><SPAN class="punctuation token">,</SPAN>
content<SPAN class="punctuation token">:</SPAN> <SPAN class="token function">setContentInfo</SPAN><SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">.</SPAN>features<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">.</SPAN>attributes<SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>Create a graph using Chart.js
We now get to include the Chart module that we instantiated awhile ago. In the previous code we set the content parameter to a function called setContentInfo and passed in the data. In the next code snippet, we are going to create this function and use it to initialize our charts inside the pop up. To start off we are going to create a new canvas element and give it the id of myChart.
<SPAN class="keyword token">var</SPAN> canvas <SPAN class="operator token">=</SPAN> document<SPAN class="punctuation token">.</SPAN><SPAN class="token function">createElement</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">'canvas'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
canvas<SPAN class="punctuation token">.</SPAN>id <SPAN class="operator token">=</SPAN> <SPAN class="string token">"myChart"</SPAN><SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN></SPAN>
Then we are going to set up the Data Structure object with our own data. In this particular case we are using a doughnut graph which would have a different Data Structure than a line graph. For more information about the different types of charts you can use, please see the following documentation on the Chart.js website. For a doughnut graph the object would look like the following code snippet below.
<SPAN class="keyword token">var</SPAN> data <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">{</SPAN>
datasets<SPAN class="punctuation token">:</SPAN><SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">{</SPAN>
data<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN>results<SPAN class="punctuation token">.</SPAN>ASIAN<SPAN class="punctuation token">,</SPAN> results<SPAN class="punctuation token">.</SPAN>BLACK<SPAN class="punctuation token">,</SPAN> results<SPAN class="punctuation token">.</SPAN>HAWN_PI<SPAN class="punctuation token">,</SPAN> results<SPAN class="punctuation token">.</SPAN>HISPANIC<SPAN class="punctuation token">,</SPAN>
results<SPAN class="punctuation token">.</SPAN>OTHER<SPAN class="punctuation token">,</SPAN> results<SPAN class="punctuation token">.</SPAN>WHITE<SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
backgroundColor<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="string token">"#4286f4"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"#41f4be"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"#8b41f4"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"#e241f4"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"#f44185"</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"#f4cd41"</SPAN><SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN>
labels<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN>
<SPAN class="string token">'Asian'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'Black'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'Hawaiian'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'Hispanic'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'Other'</SPAN><SPAN class="punctuation token">,</SPAN>
<SPAN class="string token">'White'</SPAN>
<SPAN class="punctuation token">]</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>You can see that in the data array, we are setting the results that we got from our feature layer. Each result will represent one piece of the doughnut graph, the backgroundColor is also set for each result value. Additionally, the labels attribute is set for each item in the data array.
Finally, our last step is to create a new Chart object with the data and type properties. Then we return the Chart object.
<SPAN class="keyword token">var</SPAN> myPieChart <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Chart</SPAN><SPAN class="punctuation token">(</SPAN>canvas<SPAN class="punctuation token">,</SPAN><SPAN class="punctuation token">{</SPAN>
type<SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'doughnut'</SPAN><SPAN class="punctuation token">,</SPAN>
data<SPAN class="punctuation token">:</SPAN> data
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="keyword token">return</SPAN> canvas<SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>Once the object is return we should get a chart inside our pop up showing demographic information each time we click on a county. You can also create this sample using TypeScript. Here is a link to the sample, if you are wondering how it would look in TypeScript.
Tip: Here is a quick video showing how the sample works.
https://www.screencast.com/users/mogbuchiekwe/folders/Snagit/media/ea3ff749-15b3-4de3-89ce-6e1e1526aeab/embed
Conclusion
The ArcGIS API for JavaScript makes it super simple to integrate beautiful graphs from third party libraries like Chart.js. There are many more libraries that you can integrate into your JavaScript application like this that allows you to make powerful maps with additional functionality. Feel free to head over to the GitHub Gist page for the full sample.