Sorting attribute table

4435
7
Jump to solution
02-04-2013 10:01 AM
SamirGambhir
Occasional Contributor III
Hi,
I need to display geographies on a map which have five(5), or any number, highest values of an attribute. Similarly, I would like to display the bottom X number of geographies based on an attribute. For both these queries, I need to sort the attribute table based on the attribute of interest. I am not sure where to begin and how to accomplish this. Can someone please point me to the right source of information for this?
Thanks
Samir
0 Kudos
1 Solution

Accepted Solutions
SteveCole
Frequent Contributor
If you can get the featureSet of your layer, you could sort the featureSet since it really just is an array:

 var _sort = function(field) {     return function(a, b) {    var x, y;    x = a.attributes[field];    y = b.attributes[field];     return (x < y) ? -1 : 1;     };  };          theFeatureSet.sort(_sort('Your Field Name'));


Another way of sorting the featureSet would be:

 theFeatureSet.sort(function(a,b) {   return a.attributes.fieldName - b.attributes.fieldName;  });


Both of my examples would be for a numeric field.

View solution in original post

0 Kudos
7 Replies
SteveCole
Frequent Contributor
If you can get the featureSet of your layer, you could sort the featureSet since it really just is an array:

 var _sort = function(field) {     return function(a, b) {    var x, y;    x = a.attributes[field];    y = b.attributes[field];     return (x < y) ? -1 : 1;     };  };          theFeatureSet.sort(_sort('Your Field Name'));


Another way of sorting the featureSet would be:

 theFeatureSet.sort(function(a,b) {   return a.attributes.fieldName - b.attributes.fieldName;  });


Both of my examples would be for a numeric field.
0 Kudos
DianaBenedict
Occasional Contributor III
Have you looked at the esri.tasks.query.orderByFields method?  Here is the help documentation link

http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/#Query/groupByFieldsForStatistics

You will want to be sure to read the specific information about this method since it requires layers that support advanced queries.

You might also want to look at the StatisticDefinition class (esri.tasks.StatisticDefinition) to see if you can use the statistics type of "count" to return your unique list of values for example.

You can use either the esri.tasks.QueryTask or esri.layers.FeatureLayer.queryFeatures to pass in the esri.tasks.query object to perform your query.  The results will give you a FeatureSet that you can further manipulate as needed (as indicated above).

Not sure if this is what you need but figured it is worth a try. Good luck
0 Kudos
SamirGambhir
Occasional Contributor III
Have you looked at the esri.tasks.query.orderByFields method?  Here is the help documentation link

http://help.arcgis.com/en/webapi/javascript/arcgis/jsapi/#Query/groupByFieldsForStatistics

You will want to be sure to read the specific information about this method since it requires layers that support advanced queries.

You might also want to look at the StatisticDefinition class (esri.tasks.StatisticDefinition) to see if you can use the statistics type of "count" to return your unique list of values for example.

You can use either the esri.tasks.QueryTask or esri.layers.FeatureLayer.queryFeatures to pass in the esri.tasks.query object to perform your query.  The results will give you a FeatureSet that you can further manipulate as needed (as indicated above).

Not sure if this is what you need but figured it is worth a try. Good luck


Hi Diana and Steve,
I tried both your options but it did not seem to work.
I tried query.orderByFeilds, as Diana suggested, as the code below:
if (rate == "higher rates") { //retrieved from the user selection using a combobox
           fieldOrderString = '["' + indv + ' ASC"]'; //'indv' is the indicator selected
  } else if (rate == "lower rates") {
   fieldOrderString = '["' + indv + ' DESC"]';
  }
  query.orderByFields = fieldOrderString;
  queryTask.execute(query, function(featureSet) {
          for ( i = 0; i < numg; i++) { //'numg' is the number of features that user would like to be selected
          var features = featureSet.features;
          }
  });

and I get an error "Object ["All_CBR ASC"] has no method 'join' " where 'All_CBR' is the user selected indicator

I tried Steve's suggestion in the folowing code:
stateFeatureLayer.queryFeatures(query, function (featureSet){ //'stateFeatureLayer' is the feature layer
  featureSet.sort(function(a,b) {
   return a.attributes.All_CBR - b.attributes.All_CBR;
  });
  });

This gives me a type error.

I believe I am not using your suggestions correctly, and I apologize for that. Could you please let me know how to improve on this?
Thanks
Samir
0 Kudos
DianaBenedict
Occasional Contributor III
Samir

What type of layer are you performing your query on and what version of ArcGIS Server?  According to the documentation you have serveral requirements that must be met in order to use orderByFields query param. I have listed them below:
1) orderByFields is only supported on dynamic layers and tables where supportsAdvancedQueries is true
2) Requires ArcGIS Server service version 10.1 or greater (As of v2.6)
0 Kudos
SamirGambhir
Occasional Contributor III
Samir

What type of layer are you performing your query on and what version of ArcGIS Server?  According to the documentation you have serveral requirements that must be met in order to use orderByFields query param. I have listed them below:
1) orderByFields is only supported on dynamic layers and tables where supportsAdvancedQueries is true
2) Requires ArcGIS Server service version 10.1 or greater (As of v2.6)


I apologize, I should have mentioned the version. It is 10.1. I am running orderByFields on a feature layer. I believe that itself rules out the use of this method.

Thanks
Samir
0 Kudos
DianaBenedict
Occasional Contributor III
Samir

I think what they mean "dynamic layers" as a property of the service. 

NOTE: this is a property of the ArcGIS REST Services Directory for your MapService
Supports Dynamic Layers: true

I am not too sure if this is the correct way for you to follow.  I just tried implementing what you are trying to do and had no success. However, in my case, the queries ran correctly with no errors but the featureSet was not "ordered by" the field that I indicated.  Sometimes it would actually change my result set based on OBJECTID ASC or DESC order (which I had indicted in the orderByFields param) but it NEVER sorted by the field that I indicated.  I am not sure if I was implementing it correctly  ... but my results were inconclusive.  I tried it with both a featureLayer.selectFeatures and an MapService URL via a QueryTask.execute.  No luck.  Sorry, I wish I could be more of help but I am also stuck here with no way to order my results other than what was suggested by Steve (array.sort).

Below is a "watered-down" version of the two different sets of code that I used for testing:

//TEST 1: Use existing featureLayer to perform query
var selectQuery  = new esri.tasks.Query();
selectQuery.geometry = geometry;
selectQuery.orderByFields = ["MEASURE ASC"];
pointFeatureLayer.selectFeatures(selectQuery, esri.layers.FeatureLayer.SELECTION_NEW); 


//TEST 2: Use QueryTask to query MapServer Layer
var queryTaskOperation = new esri.tasks.QueryTask("http://myserver:6080/arcgis/rest/services/FeatureServices/TestEditngService/MapServer/0");
query.outFields = ["OBJECTID", "REACHCODE", "REACHRESOLUTION", "MEASURE", "EVENTTYPE"];

var query= new esri.tasks.Query();
query.geometry = geometry;
query.orderByFields = ["MEASURE DESC"];
query.returnGeometry = true;

queryTaskOperation.execute(query, function (featureSet) {
  alert("total features = " + featureSet.features.length);
  //NOTE: I step through the code and can see what the returned featureSet.features array looks like here!
}, function (e) {
  alert("Error during query task");
});
0 Kudos
SamirGambhir
Occasional Contributor III
Samir

I think what they mean "dynamic layers" as a property of the service. 

NOTE: this is a property of the ArcGIS REST Services Directory for your MapService
Supports Dynamic Layers: true

I am not too sure if this is the correct way for you to follow.  I just tried implementing what you are trying to do and had no success. However, in my case, the queries ran correctly with no errors but the featureSet was not "ordered by" the field that I indicated.  Sometimes it would actually change my result set based on OBJECTID ASC or DESC order (which I had indicted in the orderByFields param) but it NEVER sorted by the field that I indicated.  I am not sure if I was implementing it correctly  ... but my results were inconclusive.  I tried it with both a featureLayer.selectFeatures and an MapService URL via a QueryTask.execute.  No luck.  Sorry, I wish I could be more of help but I am also stuck here with no way to order my results other than what was suggested by Steve (array.sort).

Below is a "watered-down" version of the two different sets of code that I used for testing:

//TEST 1: Use existing featureLayer to perform query
var selectQuery  = new esri.tasks.Query();
selectQuery.geometry = geometry;
selectQuery.orderByFields = ["MEASURE ASC"];
pointFeatureLayer.selectFeatures(selectQuery, esri.layers.FeatureLayer.SELECTION_NEW); 


//TEST 2: Use QueryTask to query MapServer Layer
var queryTaskOperation = new esri.tasks.QueryTask("http://myserver:6080/arcgis/rest/services/FeatureServices/TestEditngService/MapServer/0");
query.outFields = ["OBJECTID", "REACHCODE", "REACHRESOLUTION", "MEASURE", "EVENTTYPE"];

var query= new esri.tasks.Query();
query.geometry = geometry;
query.orderByFields = ["MEASURE DESC"];
query.returnGeometry = true;

queryTaskOperation.execute(query, function (featureSet) {
  alert("total features = " + featureSet.features.length);
  //NOTE: I step through the code and can see what the returned featureSet.features array looks like here!
}, function (e) {
  alert("Error during query task");
});


Hello,
Steve's code actually worked for me. I made minor modifications and the code is below:
myFeatureLayer.queryFeatures(query, function(featureSet) {
                featureSet.features.sort(function(a, b) {
   return a.attributes[myField] - b.attributes[myField]; //ascending order
  });
});


Thanks
Samir
0 Kudos