Displaying /tasks/StatisticDefinition() results

911
5
Jump to solution
04-06-2019 06:13 PM
TateM
by
New Contributor III

Hello everyone,

I'm trying to get into web developing using the ArcGIS JavaScript api, but I'm still very new to web developing.  I wanted to ask for your advice or pointers on how to do this.   I am basically trying to display the results from the query onto a div section on the page.   I cannot get it to work, am I even going in the right direction?  Below are the code that I have so far.   Thanks in Advance. 

End Goal: is to display the sum of each category(females, males, owners, renters) for entire 51 states when the page first loads, below the map div.  Then click on each individual state, and have the values/number change dynamically for those categories, to display only values/number associated with that particular clicked state. 

<!DOCTYPE html>
<html>
 <head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
  <meta http-equiv="X-UA-Compatitble" content="IE=Edge"/>
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
  <title>TEST STATISTIC</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.28/esri/css/esri.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.28/dijit/themes/claro/claro.css">
  <style>
   html, body, #mapDiv{border:0; margin:0; padding:0; height:90%; width:100%;}  
  </style>
  <script type = "text/javascript" src ="https://js.arcgis.com/3.28/"></script>
  <script type="text/javascript" >
  
   require
   (
    [
     "esri/map",
     "esri/layers/ArcGISDynamicMapServiceLayer",
     "esri/SpatialReference",
     "esri/tasks/query",
     "esri/tasks/QueryTask",
     "esri/tasks/StatisticDefinition"
    ],
    function(Map, ArcGISDynamicMapServiceLayer, SpatialReference, Query, Qt,statD)
    {
     var censusLayers = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");
     var map = new Map("mapDiv", {
      basemap: "topo",
      center: [-94.84, 39.69], 
      zoom: 5
     });
     censusLayers.setVisibleLayers([3]);
     function totalFemales()
     {
      var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
      var query = new Query();
      query.returnGeometry = false;
      query.outFields = ["FEMALES"];
      var stats = new statD();
      stats.statisticType = "sum";
      stats.onStatisticField = "FEMALES";
      stats.outStatisticName = "sum_female_pop";
      query.where = "1=1";
      query.outStatistics = [stats];
      queryTask.execute(query,showFemalesSum );
      
     };
     function showFemalesSum(results)
     {
      if ( ! results.hasOwnProperty("features") ||results.features.length === 0 )
      {
        return;
      }
      var totalSum = results.features[0].attributes.sum_female_pop;
      console.log("testing", totalSum, results.features);
      document.getElementById('totalFemales').innerHTML = "Total Females: "+totalSum;
     }
     function totalMales()
     {
      var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
      var query = new Query();
      query.returnGeometry = false;
      query.outFields = ["MALES"];
      var stats = new statD();
      stats.statisticType = "sum";
      stats.onStatisticField = "MALES";
      stats.outStatisticName = "sum_male_pop";
      query.where = "1=1";
      query.outStatistics = [stats];
      queryTask.execute(query,showMalesSum );
      
     };
     function showMalesSum(results)
     {
      if ( ! results.hasOwnProperty("features") ||results.features.length === 0 )
      {
        return;
      }
      var totalSum = results.features[0].attributes.sum_male_pop;
      console.log("testing", totalSum, results.features);
      document.getElementById('totalMales').innerHTML = "Total Males: "+totalSum;
     }
     
     map.addLayer(censusLayers);
     map.on("load",showFemalesSum,showMalesSum);
    }
   );
  
  </script>
 </head>
 <body>
  <div id ="mapDiv"></div>
  <div id = "genderPopData" style ="font-weight: bold">
   Total Gender Population
   <div id = "totalFemales" style ="font-weight: normal;  padding:3px">
    Number of Females:
   </div>
   <div id = "totalMales" style ="font-weight: normal;  padding:3px">
    Number of Males:
   </div>
  </div>
  </br>
  <div id = "housingData" style ="font-weight: bold">
   Owner Versus Renter
   <div id = "totalOwners" style ="font-weight: normal;  padding:3px">
    Number of Homeowners:
   </div>
   <div id = "totalRenter" style ="font-weight: normal;  padding:3px">
    Number of Renters:
   </div>
  </div>
 </body>
</html>
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Tate,

   You had a couple of issue in your code:

  1. It is outStatisticFieldName not outStatisticName.
  2. You were calling the queryTask result function on map load instead of the totalFeamels and totalMales functions that launch the queries.
  3. You map load handler would have only called the first function on successful map load and the second function on map load failure.
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta http-equiv="X-UA-Compatitble" content="IE=Edge" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>TEST STATISTIC</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.28/esri/css/esri.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.28/dijit/themes/claro/claro.css">
  <style>
    html, body, #mapDiv{border:0; margin:0; padding:0; height:90%; width:100%;}
  </style>
  <script type="text/javascript" src="https://js.arcgis.com/3.28/"></script>
  <script type="text/javascript">
    require
      (
        [
          "esri/map",
          "esri/layers/ArcGISDynamicMapServiceLayer",
          "esri/SpatialReference",
          "esri/tasks/query",
          "esri/tasks/QueryTask",
          "esri/tasks/StatisticDefinition"
        ],
        function(Map, ArcGISDynamicMapServiceLayer, SpatialReference, Query, Qt, statD) {
          var censusLayers = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");
          var map = new Map("mapDiv", {
            basemap: "topo",
            center: [-94.84, 39.69],
            zoom: 5
          });
          censusLayers.setVisibleLayers([3]);

          function totalFemales() {
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["FEMALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "FEMALES";
            stats.outStatisticFieldName = "sum_female_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, showFemalesSum, showFail);
          };

          function showFail(error){
            console.error(error);
          }

          function showFemalesSum(results) {
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_female_pop;
            console.log("testing", totalSum, results.features);
            document.getElementById('totalFemales').innerHTML = "Total Females: " + totalSum;
          }

          function totalMales() {
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["MALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "MALES";
            stats.outStatisticFieldName = "sum_male_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, showMalesSum, showFail);
          };

          function showMalesSum(results) {
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_male_pop;
            console.log("testing", totalSum, results.features);
            document.getElementById('totalMales').innerHTML = "Total Males: " + totalSum;
          }

          map.addLayer(censusLayers);
          map.on("load", function(){
            totalFemales();
            totalMales();
          });
        }
      );
  </script>
</head>

<body>
  <div id="mapDiv"></div>
  <div id="genderPopData" style="font-weight: bold">
    Total Gender Population
    <div id="totalFemales" style="font-weight: normal;  padding:3px">
      Number of Females:
    </div>
    <div id="totalMales" style="font-weight: normal;  padding:3px">
      Number of Males:
    </div>
  </div>
  </br>
  <div id="housingData" style="font-weight: bold">
    Owner Versus Renter
    <div id="totalOwners" style="font-weight: normal;  padding:3px">
      Number of Homeowners:
    </div>
    <div id="totalRenter" style="font-weight: normal;  padding:3px">
      Number of Renters:
    </div>
  </div>
</body>

</html>

View solution in original post

0 Kudos
5 Replies
RobertScheitlin__GISP
MVP Emeritus

Tate,

   You had a couple of issue in your code:

  1. It is outStatisticFieldName not outStatisticName.
  2. You were calling the queryTask result function on map load instead of the totalFeamels and totalMales functions that launch the queries.
  3. You map load handler would have only called the first function on successful map load and the second function on map load failure.
<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta http-equiv="X-UA-Compatitble" content="IE=Edge" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>TEST STATISTIC</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.28/esri/css/esri.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.28/dijit/themes/claro/claro.css">
  <style>
    html, body, #mapDiv{border:0; margin:0; padding:0; height:90%; width:100%;}
  </style>
  <script type="text/javascript" src="https://js.arcgis.com/3.28/"></script>
  <script type="text/javascript">
    require
      (
        [
          "esri/map",
          "esri/layers/ArcGISDynamicMapServiceLayer",
          "esri/SpatialReference",
          "esri/tasks/query",
          "esri/tasks/QueryTask",
          "esri/tasks/StatisticDefinition"
        ],
        function(Map, ArcGISDynamicMapServiceLayer, SpatialReference, Query, Qt, statD) {
          var censusLayers = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");
          var map = new Map("mapDiv", {
            basemap: "topo",
            center: [-94.84, 39.69],
            zoom: 5
          });
          censusLayers.setVisibleLayers([3]);

          function totalFemales() {
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["FEMALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "FEMALES";
            stats.outStatisticFieldName = "sum_female_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, showFemalesSum, showFail);
          };

          function showFail(error){
            console.error(error);
          }

          function showFemalesSum(results) {
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_female_pop;
            console.log("testing", totalSum, results.features);
            document.getElementById('totalFemales').innerHTML = "Total Females: " + totalSum;
          }

          function totalMales() {
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["MALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "MALES";
            stats.outStatisticFieldName = "sum_male_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, showMalesSum, showFail);
          };

          function showMalesSum(results) {
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_male_pop;
            console.log("testing", totalSum, results.features);
            document.getElementById('totalMales').innerHTML = "Total Males: " + totalSum;
          }

          map.addLayer(censusLayers);
          map.on("load", function(){
            totalFemales();
            totalMales();
          });
        }
      );
  </script>
</head>

<body>
  <div id="mapDiv"></div>
  <div id="genderPopData" style="font-weight: bold">
    Total Gender Population
    <div id="totalFemales" style="font-weight: normal;  padding:3px">
      Number of Females:
    </div>
    <div id="totalMales" style="font-weight: normal;  padding:3px">
      Number of Males:
    </div>
  </div>
  </br>
  <div id="housingData" style="font-weight: bold">
    Owner Versus Renter
    <div id="totalOwners" style="font-weight: normal;  padding:3px">
      Number of Homeowners:
    </div>
    <div id="totalRenter" style="font-weight: normal;  padding:3px">
      Number of Renters:
    </div>
  </div>
</body>

</html>
0 Kudos
TateM
by
New Contributor III

Thanks Robert! This works great.

I did come up with an alternative way using Query and QueryTask modules. 

Another thing I wanted to do is trying to get the percentage of Females and Males, by dividing the sum of the two. 

I created a global variable,  and inside of the showFemalesSum() I assigned the totalSum to that global variable and return it.  Outside of that function I tried print the global variable out onto the console.log(), but nothing comes out, just say undefined. 

Just wanting to see what's the best way to get the 2 returning values so that I can do some division, nothing works so far.

          var usFemalesNum; //global variable

                     function totalFemales() {
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["FEMALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "FEMALES";
            stats.outStatisticFieldName = "sum_female_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, showFemalesSum, showFail);
          };

          function showFail(error){
            console.error(error);
          }

          function showFemalesSum(results) {
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_female_pop;
            console.log("testing", totalSum, results.features);
            document.getElementById('totalFemales').innerHTML = "Total Females: " + totalSum;

                        usFemalesNum = totalSum;

                        return usFemalesNum;
          }

       Console.log("US Females Number: "+ usFemalesNum); //undefined.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tate,

   The reason is timing. The query task is an async process and you are trying to log the value of usFemalesNum before the async result is done and the var is set. You can put the log in the showFemalesSum function and it will work fine.

Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.

0 Kudos
TateM
by
New Contributor III

Thanks, I marked answered. 

right the console.log(totalSum) works fine inside of the showFemalesSum() and as well as showMalesSum(), with respect to their own totalSum counter variable.  How would I get the answer if I want to divide totalSum in showFemalesSum() with totalSum in showMalesSum() or vice versa?  Would I have to create another function inside one of those function(i.e. showFemalesSum()), if so how would I get the totalSum result for showMalesSum() to inside of the showFemalesSum()?   Thanks,

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Tate,

  See if this helps. What I have done is turned all the functions into deferred's and then used dojo promise all to wait for all the deferred's to resolve before trying to do anything with the results:

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  <meta http-equiv="X-UA-Compatitble" content="IE=Edge" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>TEST STATISTIC</title>
  <link rel="stylesheet" href="https://js.arcgis.com/3.28/esri/css/esri.css">
  <link rel="stylesheet" href="http://js.arcgis.com/3.28/dijit/themes/claro/claro.css">
  <style>
    html, body, #mapDiv{border:0; margin:0; padding:0; height:90%; width:100%;}
  </style>
  <script type="text/javascript" src="https://js.arcgis.com/3.28/"></script>
  <script type="text/javascript">
    var usFemalesNum, usMaleNum; //global variable
    require([
          "esri/map",
          "esri/layers/ArcGISDynamicMapServiceLayer",
          "esri/SpatialReference",
          "esri/tasks/query",
          "esri/tasks/QueryTask",
          "esri/tasks/StatisticDefinition",
          "dojo/Deferred",
          "dojo/promise/all"
        ],
        function(Map, ArcGISDynamicMapServiceLayer, SpatialReference, Query, Qt, statD, Deferred, all) {
          var censusLayers = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer");
          var map = new Map("mapDiv", {
            basemap: "topo",
            center: [-94.84, 39.69],
            zoom: 5
          });
          censusLayers.setVisibleLayers([3]);

          function totalFemales() {
            var retDef = new Deferred();
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["FEMALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "FEMALES";
            stats.outStatisticFieldName = "sum_female_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, function(result){
              showFemalesSum(result).then(function(value){
                retDef.resolve(value);
              });
            }, showFail);
            return retDef;
          };

          function showFail(error){
            console.error(error);
            return null;
          }

          function showFemalesSum(results) {
            var retDef = new Deferred();
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_female_pop;
            document.getElementById('totalFemales').innerHTML = "Total Females: " + totalSum;
            retDef.resolve(totalSum);
            return retDef;
          }

          function totalMales() {
            var retDef = new Deferred();
            var queryTask = new Qt("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3");
            var query = new Query();
            query.returnGeometry = false;
            query.outFields = ["MALES"];
            var stats = new statD();
            stats.statisticType = "sum";
            stats.onStatisticField = "MALES";
            stats.outStatisticFieldName = "sum_male_pop";
            query.where = "1=1";
            query.outStatistics = [stats];
            queryTask.execute(query, function(result){
              showMalesSum(result).then(function(value){
                retDef.resolve(value);
              });
            }, showFail);
            return retDef;
          };

          function showMalesSum(results) {
            var retDef = new Deferred();
            if (!results.hasOwnProperty("features") || results.features.length === 0) {
              return;
            }
            var totalSum = results.features[0].attributes.sum_male_pop;
            document.getElementById('totalMales').innerHTML = "Total Males: " + totalSum;
            retDef.resolve(totalSum);
            return retDef;
          }

          map.addLayer(censusLayers);
          map.on("load", function(){
            //This will wait for both function to return before executing.
            all([totalFemales(), totalMales()]).then(function(results){
              usFemalesNum = results[0];
              usMalesNum = results[1];
//Now that you have both male and female results do something with that info
              console.info(usFemalesNum, usMalesNum);
            });
          });
        }
      );
  </script>
</head>

<body>
  <div id="mapDiv"></div>
  <div id="genderPopData" style="font-weight: bold">
    Total Gender Population
    <div id="totalFemales" style="font-weight: normal;  padding:3px">
      Number of Females:
    </div>
    <div id="totalMales" style="font-weight: normal;  padding:3px">
      Number of Males:
    </div>
  </div>
  </br>
  <div id="housingData" style="font-weight: bold">
    Owner Versus Renter
    <div id="totalOwners" style="font-weight: normal;  padding:3px">
      Number of Homeowners:
    </div>
    <div id="totalRenter" style="font-weight: normal;  padding:3px">
      Number of Renters:
    </div>
  </div>
</body>

</html>
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos