Using Third Party Graphing Libraries With The 4.x JavaScript API

5754
3
06-13-2018 03:50 PM
Labels (2)
MunachisoOgbuchiekwe
New Contributor III
5 3 5,754

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.

<script>
        const options = {
            // tell Dojo where to load other packages
            dojoConfig: {
                async: true,
            packages: [
                {
                    location: 'https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js',
                    name: 'Chart'
                }
            ]
            }
        };
</script>
<script src="https://js.arcgis.com/4.7/"></script>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

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...

require([
    "esri/Map",
    "esri/views/MapView",
    "esri/PopupTemplate",
    "esri/layers/FeatureLayer",
    "esri/widgets/Popup",
    "esri/tasks/support/Query",
    "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.js",
    "dojo/domReady!"
  ],
  function (Map, MapView, PopupTemplate, FeatureLayer, Popup, Query, Chart)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

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.

   var query = new Query();

    query.returnGeometry = true;
    query.outFields = ["STATE_NAME", "WHITE", "BLACK", "ASIAN", "HAWN_PI", "OTHER", "HISPANIC"];
    query.where = "1=1";
    query.num = 50;

    // On view click, query the feature layer and pass the results to setContentInfo function.
    view.on("click", (e) => {
      query.geometry = e.mapPoint;
      featureLayer.queryFeatures(query).then((results) =>{
        if(results.features[0].attributes.STATE_NAME === "California"){
          view.popup.visible = true;
          view.popup.open({
              title: "Doughnut Graph Example",
              content: setContentInfo(results.features[0].attributes)
          });
        }
      });
    });‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

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.

var canvas = document.createElement('canvas');
canvas.id = "myChart";‍‍‍‍

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.

var data = {
      datasets:[{
        data: [results.ASIAN, results.BLACK, results.HAWN_PI, results.HISPANIC, 
                 results.OTHER, results.WHITE],
        backgroundColor: ["#4286f4", "#41f4be", "#8b41f4", "#e241f4", "#f44185", "#f4cd41"]
      }],
      labels: [
        'Asian',
        'Black',
        'Hawaiian',
        'Hispanic',
        'Other',
        'White'
      ]
    };‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

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.

var myPieChart = new Chart(canvas,{
      type: 'doughnut',
      data: data
  });
return canvas;‍‍‍‍‍‍‍‍‍‍

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.

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.

3 Comments
davidround
New Contributor II

Super cool! A perfect example of why pie charts are terrible obviously but cool nonetheless. I'm going to have a go.

MatthewHamilton-Smith
New Contributor II

I am using typescript to develop applications using the ArcGIS Javascript API. When you import chart.js as above (importing using a script tag or dojoConfig), the type definitions are not available when coding. Alternatively, when you import the types using ...

 

import Chart from 'chart.js';

 

 after running ...

 

npm i --save-dev @types/chart.js
npm i --save chart.js

 

a 404 error occurs at runtime, stating that "<websiteUrl>/chart.js is not found". The site is smart enough to not look for "esri/..." modules in the root of the url. How can I make it just as smart with respect to the "chart.js" module? Simply adding ...

 

{
    name: "chart.js",
    location: 
}

 

 to window.dojoConfig.packages does not change anything - I still get a 404 error at runtime. 😞

If you have insight, please help!

* Update *

So it looks like dojoConfig does not like package names containing ".". Modifying the name of the type definition file (found in node_modules/@types) from "chart.js" to "chartjs" did the trick, along with this addition window.dojoConfig.packages:

{
    name: "chartjs",
    location: "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/",
    main: "Chart"
}

 

RobertMEIER
Occasional Contributor

I have successfully integrated Chart.js into may application, but have not been able to get the zooming/panning to wok on my line chart. I've tried many options, etc. I even tried disabling the wheel zoom for map navigation. I'm not getting any errors, it just doesn't work.

has anyone gotten this to work?