|
POST
|
The grid click event is still tied to the field-id. When I tried to switch it to field-selection, it didn't work. It seems like that's all I needed to change.
... View more
09-04-2014
01:02 PM
|
0
|
0
|
3140
|
|
POST
|
It seems to work if I make a new array by using splice and push that to my 'array of arrays' instead.
... View more
09-04-2014
12:50 PM
|
0
|
0
|
1046
|
|
POST
|
I have a queryFeatures on a featureLayer that is based on mutiple objectIds. I need to iterate through each feature and store attributes in an array. I need to keep each feature's array in another array (or maybe an object?) so I can have it as input to my chart.
gQuery = new Query();
gQuery.objectIds = idList; //defined earlier
seriesList.length = 0; //declared earlier as seriesList = [];
featureLayer.queryFeatures(gQuery, function(results) {
arrayUtils.forEach(results.features, function (result){
var list = createRateList(result);
console.log("list is " + list);
seriesList.push({data: list});
});
});
function createRateList(results){
var atts = results.attributes;
var county = atts.County;
rateList.length = 0;
reverseRateFields.length = 0;
//gets the rate values for selected county for all years, list of field defined earlier
arrayUtils.forEach(reverseRateFields, function (field){
rateList.push(atts[field]);
});
return rateList;
}
At the point I have do a console.log on list, it contains the values I expect. I add it to my seriesList and it still looked OK. Going to the next feature, I the console.log display what I expect from the list, but what I push to seriesList affects what's already in there. Examining the contents of seriesList shows the initial item [0] with content I just added from the 2nd time through. This continues through how ever many features I had from queryFeatures until I have a seriesList full of the exact same list of values, which are from the final feature. I don't know if I have a looping problem, or don't understand the nature of array variables.
... View more
09-04-2014
09:46 AM
|
0
|
1
|
1527
|
|
POST
|
I figured it out! If you increase the length of the x Axis slightly, it won't cut the point off. I did this in my example by adding 0.5 var xAxisMax = years.length + 0.5; //extends the X axis so it doesn't crop off the point
... View more
09-03-2014
02:15 PM
|
1
|
1
|
2608
|
|
POST
|
I was able to get a selector added to my grid my changing the data to a store, so that's sorted out. That was exactly the problem there, but I won't mark it correct, since that's only one aspect of my overall question. Now I'm trying to figure out how to manage the individual list of attributes for each of the selected rows in the grid. I'm getting lost in how to manage my array variable. I'd still like to have the user generate a single chart automatically with a row click, but for now I have a Make Chart button, which uses the grid.selection to get the objectIds of the rows and pass those to a featureLayer.queryFeatures. I realized I could start with what is essentially an empty chart to start and add a series to the chart for each row. All a series is is an array of values, there's nothing fancy about it. function createMultiChart(){ var rowid,gQuery; var idList = []; var countyList = []; maxList.length = 0; for (var rowid in grid.selection) { var row = grid.row(rowid); idList.push(parseFloat(rowid));//a list of objectIds countyList.push(row.data.County);// a list of selected counties } console.log("county list = " + countyList); lineChart = new Chart2D("chartDiv"); gQuery = new Query(); gQuery.objectIds = idList; featureLayer.queryFeatures(gQuery, function(results) { arrayUtils.forEach(results.features, function (result){ createRateList(result); }); }); var maxRate = findMax(maxList); finishLineChart(maxRate); } function createRateList(results){ var atts = results.attributes; var county = atts.County; var rateList = []; //prefer to see chart in ascending order, changing the order the yearly rate fields for (var i = rateFields.length - 1; i >= 0; i--) { reverseRateFields.push(rateFields); } //gets the rate values for selected county for all years arrayUtils.forEach(reverseRateFields, function (field){ rateList.push(atts[field]); }); maxList.push(findMax(rateList)); lineChart.addSeries(county, rateList, { stroke: { color: "red", width: 2 } }); rateList.length = 0; } I can see that each time I execute the createRateList, that I am creating a list of rates for that county, which becomes a new series in the chart. The problem is that the first series has just the rates I expect, the 2nd series has all those rates AGAIN, plus the additional ones from the 2nd county (etc etc). Obviously I'm not using my rateList variable properly, but I can seem to get it sorted out. I've tried setting the length to 0, but maybe this is in the wrong spot? I also need to determine the maximum value of all the rates from the selected counties. This will be used to determine the Y axis on the chart. That will be used later in my finishLineChart function that will add the axes, title etc.
... View more
09-03-2014
12:06 PM
|
0
|
0
|
3140
|
|
POST
|
I have other code that has the store as part of the grid definition somewhere. I don't remember anymore the difference between the way I have it and the one where I declare a memory store instead. Probably something to do with the id property or something. I'll have to go through other places I used grids. I end up using them quite a bit. In the meantime, I changed the default selectionMode to single and added dojo/keys to my code and have a listener for the gridDiv for whether the user has the Ctrl key held down or not. If it is, the selectionMode is set to extended. It seems to work OK, although I don't have much code changed to manage the multiple selections. At least I didn't break what I already had. It doesn't seem like I should have had to do this, but it wasn't much code, so I guess I'll go with it for now.
... View more
09-02-2014
01:51 PM
|
0
|
0
|
3140
|
|
POST
|
Ken, since I have a function already for building my columns (the fields will vary), I'd need to figure out how to add that selector into my buildColumns function. Or is there somehow I can add it into my Grid declaration. At the moment I just have a column that says Object Object. //creates a column definition for the grid based on the attributes returned from the query function buildColumns() { var columns = []; //qryOutFields is an array of fieldNames defined earlier var sel = { "selection": selector({ label: "Select" }) }; columns.push(sel); arrayUtils.forEach(qryOutFields, function(field){ var objects = {}; objects.label = field; objects.field = field; if (field === 'OBJECTID') {//assumed name for internal ID from map service objects.hidden = true; } columns.push(objects); }); return columns; }
... View more
09-02-2014
12:10 PM
|
0
|
1
|
3140
|
|
POST
|
I actually used to have a 'generate a chart' button. The way my project is laid out, the map is in the center and the left pane has the grid with the div for the chart below it. Whether the user selects a county from the dGrid or from the map, it generates a chart. That comes across so seamlessly, the 'make a chart' button felt like I was making them do an extra step, so I took it out. That gives me an idea, though. Maybe I could have a check box or something for Chart multiple counties'. I was planning on limiting the number of counties they could select and I have to fit that somewhere as a dialog anyway. I could start out with selection set to single and switch it if the box was checked. That could also control a chart button, whether or not it was available depending on the mode. I tried adding a selector, because I thought having checkboxes next to the counties made it more clear which they were selecting. But a selector column wasn't displaying just be adding it to the grid declaration. I wondered if maybe it was being particular about the idProperty. I didn't explicitly set it anywhere.
... View more
09-02-2014
11:33 AM
|
0
|
2
|
3140
|
|
POST
|
I'm having a hard time managing my selected rows in my dGrid. I read that the default selection mode is already set to extended. I have an event on dgrid-select that fire my chart function and that works. I'd to be able to select mutiple rows from the grid to generate a chart with the information from multiple rows, but I'm having a hard time managing the selection. As soon as I select one row, my chart gets generated. I am creating my grid based on a featureLayer,queryFeatures. Here's the result handler.
function gridHandler(results) {
var rateTest, countTest;
var returnObj = {};
domConstruct.empty(dom.byId('gridDiv'));
var gridColumns = buildColumns();
var data = arrayUtils.map(results.featureSet.features, function(feature){
return feature.attributes;
});
grid = new (declare([Grid, Selection]))({
id:'grid',
columns: gridColumns
}, "gridDiv");
grid.renderArray(data);
grid.sort('County');
grid.on("dgrid-select", function(event){
var rows = event.rows;
var row = event.rows[0];
var gridQuery = new Query();
gridQuery.objectIds = [row.data.OBJECTID];
featureLayer.selectFeatures(gridQuery, FeatureLayer.SELECTION_NEW, function(results) {
if ( results.length > 0 ) {
// createLineChart(results);
createLineChart(results[0]);
var feature = results[0];
feature.setInfoTemplate(infoTemplate);
var resultGeometry = results[0].geometry;
map.infoWindow.setFeatures(results);
// map.infoWindow.show(resultGeometry.getExtent().getCenter()); //assume geometry is a polygon
} else {
console.log("error in grid.on click function");
}
});
});
dom.byId("gridText").innerHTML = title+ " - " + currentYear;
}
//creates a column definition for the grid based on the attributes returned from the query
function buildColumns() {
var columns = [];
//qryOutFields is an array of fieldNames defined earlier
arrayUtils.forEach(qryOutFields, function(field){
var objects = {};
objects.label = field;
objects.field = field;
if (field === 'OBJECTID') {//assumed name for internal ID from map service
objects.hidden = true;
}
columns.push(objects);
});
return columns;
}
... View more
09-02-2014
10:33 AM
|
0
|
9
|
7897
|
|
POST
|
Never mind. I have learned since I created this custom legend how to control the legend widget, so I switched it out. the IdentifyTask was operator error.
... View more
08-27-2014
02:08 PM
|
0
|
0
|
1038
|
|
POST
|
This is the first time I've needed to deal with the token when using IdentityManager. I have an existing application that worked fine with open services that is failing in two places now that I've secured the services: my custom created legend and my identifyTask. I've check through the threads, but I don't understand what I've found on how to determine what token was generated from the IdentifyManager. Even after I find the token, I'm not where where it goes in my code. First place it needs a token - legend I wanted a bit more control over my legend so I'm making a call to the legend, but parsing it as JSON and recreating the look of it. The odd thing here is that the text string comes through OK, but not the image representing the symbol. In this url is the path of a ArcGISDynamicServiceLayer
// create legend based on symbology in service
function createLegendJSON(url){
mapUrl = url;
var divLegend = dom.byId("legendDiv");
legendURL = url + "/legend";
var requestHandle = esriRequest({
"url": legendURL,
"content": {
"f": "json"
},
"callbackParamName": "callback"
});
requestHandle.then(requestSucceeded, requestFailed);
}
function requestFailed(error){
console.log("request failed" + error);
}
function requestSucceeded(response, io){
var lyr, visLayers;
var htmlString = "<table class='legend'>";
var divLegend = dom.byId("legendDiv");
if (ncdmLayer.visible){
mapURL = ncdmLayer.url;
visLayers = ncdmLayer.visibleLayers;
dom.byId('legendTitle').innerHTML = currentYear + " " + title + " Rates";
}else{
visLayers = [0];
mapURL = p1950Layer.url;
dom.byId('legendTitle').innerHTML = "Percent Pre-1950 Housing";
}
if (response != null && response.layers.length > 0) {
// for (var iCnt = 0; iCnt < response.layers.length; iCnt++) {//interface only allows one layer, so took out the loop
lyr = response.layers[visLayers];
if (lyr.legend.length > 1) {
// htmlString += "<tr><td colspan='2' style='font-weight:bold;'>" + currentYear + " " + title + " Rates </td></tr>";
for (var jCnt = 0; jCnt < lyr.legend.length; jCnt++) {
var src = mapURL + "/" + lyr.layerId + "/images/" + lyr.legend[jCnt].url;
var strlbl = lyr.legend[jCnt].label.replace("<Null>", "Null");
htmlString += "<tr><td align='left'><img src=\"" + src + "\" alt ='' /></td><td>" + strlbl + "</td></tr>";
}
}
else {
htmlString += "<tr><td colspan='2' style='font-weight:bold;'>" + lyr.layerName + "</td></tr>";
var src = mapURL + "/" + lyr.layerId + "/images/" + lyr.legend[0].url;
htmlString += "<tr><td colspan='2' ><img src=\"" + src + "\" alt ='' /></td></tr>";
}
// }
htmlString += "</table>";
if (ncdmLayer.visible){
htmlString += "<div class='legend'><i>" + rateNote + "</i></div>"
}
}
divLegend.innerHTML = htmlString;
}
The 2nd place it looks to be failing is in my identifyTask. I have this set up as a deferred call so it has time to drill down through whatever layers I have turned on. The variable ncdmLayer.url is the URL for the ArcGISDynamicMapService (the same as for my legend). Some of my idParams are set earlier in the code, in case you think something is missing.
function clickIdentify(event){
idParams.geometry = event.mapPoint;
idParams.mapExtent = map.extent;
idParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE;
if (ncdmLayer.visible) {
idTask = new IdentifyTask(ncdmLayer.url);
var visLayers = ncdmLayer.visibleLayers;
idParams.layerIds = ncdmLayer.visibleLayers;
} else {
idParams.layerIds = [0];
idTask = new IdentifyTask(p1950Layer.url);//supplemental layer, generally not turned on.
}
var deferred = idTask.execute(idParams).addCallback(function(response){
return arrayUtils.map(response, function(result){
var feature = result.feature;
layerSel = getLayer(result.layerName);
infoTemplate.setContent(generateInfoContent);
feature.setInfoTemplate(infoTemplate);
feature.geometry.spatialReference = spatialReference;
return feature;
});
});
map.infoWindow.setFeatures([deferred]);
map.infoWindow.show(event.mapPoint);
}
... View more
08-27-2014
01:18 PM
|
0
|
1
|
2968
|
|
POST
|
That was it. I was trying to find it within the legend reference. It didn't occur to me to look at the renderer.
... View more
08-27-2014
06:14 AM
|
1
|
0
|
912
|
|
POST
|
Your way worked and is more right then my workaround method, so I changed which one is marked as Correct Answer.
... View more
08-27-2014
06:12 AM
|
0
|
0
|
1526
|
|
POST
|
In my legend I have some 'no data' values from my classification and they appear in my legend as 'others'. Is there a way I can change this to say something else?
... View more
08-26-2014
02:27 PM
|
0
|
2
|
1526
|
|
POST
|
That's not just changing the title, it's getting rid of the entire legend and recreating it every time. I'd like to avoid this. What I did was add another div right above the legend, calling it legendTitle. Then I styled the legend so that its default title wouldn't display at all.
.esriLegendServiceLabel {
display:none;
}
Then I set the content of my new legendTitle to be the field name like I wanted.
... View more
08-26-2014
12:28 PM
|
0
|
0
|
1526
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 06-02-2017 02:38 PM | |
| 2 | 03-18-2022 10:14 AM | |
| 2 | 02-18-2016 06:28 AM | |
| 1 | 03-18-2024 07:29 AM | |
| 4 | 08-02-2023 06:08 AM |
| Online Status |
Offline
|
| Date Last Visited |
02-25-2025
01:56 PM
|