What is the best way to "highlight" a feature on a featurelayer, or a graphic on a graphicslayer, much in the same way a feature is highlighted when user clicks on it to show the InfoWindow (but without showing the InfoWindow). This is different from the selection of a feature which is controlled by setting the selection symbol. Also do not want to actually select the feature if possible.
(Usually the highlight feature surrounds the feature with a box with a cross overlaid on it.)
Thanks.
Solved! Go to Solution.
Edward,
I think this sample is what you are looking for (be aware the use of the "target" SMS style is undocumented and subject to change):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>Drop Down Test</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html,
body,
#mainWindow {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
#header {
height: 3%;
overflow: auto;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map",
"dojo/on",
"esri/tasks/query",
"esri/graphic",
"esri/layers/FeatureLayer",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/CartographicLineSymbol",
"esri/Color",
"dojo/store/Memory",
"dojo/_base/array",
"dojo/_base/lang",
"esri/request",
"dojo/json",
"dojo/parser",
"dijit/registry",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/form/Button",
"dijit/form/ComboBox",
"dojo/domReady!"
], function(
Map, on, Query, Graphic, FeatureLayer, SimpleMarkerSymbol, CartographicLineSymbol, Color, Memory, array, lang, esriRequest, json, parser, registry
) {
parser.parse();
map = new Map("map", {
basemap: "topo",
center: [-120.1883, 37.0868],
zoom: 6
});
var vendors = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/ALL_City_Vendors/FeatureServer/0", {
outFields: ["*"]
});
//point target symbol
var cls = new CartographicLineSymbol(CartographicLineSymbol.STYLE_SOLID, new Color([0,255,255,1]), 2, CartographicLineSymbol.CAP_ROUND, CartographicLineSymbol.JOIN_ROUND);
var sms = new SimpleMarkerSymbol("target", 16, cls, new Color([0,0,0,0]));
sms._spikeSize = 7;
sms._targetHeight = 17;
sms._targetWidth = 17;
sms.setAngle(0);
map.addLayers([vendors]);
map.on("layers-add-result", lang.hitch(this, function(){
var url = "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/ALL_City_Vendors/FeatureServer/0/ge...";
var classificationDef = {"type":"uniqueValueDef","uniqueValueFields":["Vendor_Name"]};
var str = json.stringify(classificationDef);
esriRequest({
url:url,
content:{
classificationDef:str,
f:'json'
},
handleAs:'json',
callbackParamName:'callback',
timeout:15000
}).then(lang.hitch(this,function(response){
var uniqueValueInfos = response && response.uniqueValueInfos;
if(uniqueValueInfos){
var store2 = new Memory({data:[]});
registry.byId("uniqueValuesSelect").set('store',store2);
var data = array.map(uniqueValueInfos,lang.hitch(this,function(info,index){
var value = info.value;
//value = parseFloat(value);
var dataItem = {
id:index,
name:value
};
return dataItem;
}));
store2 = new Memory({data:data});
registry.byId("uniqueValuesSelect").set('store',store2);
}
}),lang.hitch(this,function(error){
console.error(error);
}));
}));
registry.byId("clearBtn").on("click", function(){
map.graphics.clear();
});
registry.byId("uniqueValuesSelect").on("change", function(){
var query = new Query();
query.where = "Vendor_Name='" + registry.byId("uniqueValuesSelect").get('value') + "'";
console.info(query.where);
query.returnGeometry = true;
vendors.queryFeatures(query, function (featureSet) {
var Geom = featureSet.features[0].geometry;
var gra = new Graphic(Geom, sms);
map.graphics.add(gra);
map.centerAndZoom(Geom, 16);
});
});
});
</script>
</head>
<body class="claro">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:false" style="padding:0px;margin:0px;">
<div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="overflow:hidden;border:none;border-bottom: 3px solid #CC9900;font-family: Windows;font-size:14pt; color: #FFFFFF;background: #000000; "> Select a Vendor name and it will be selected and zoomed to it on the map:
<select id="uniqueValuesSelect" data-dojo-type="dijit/form/ComboBox"></select>
<button id="clearBtn" data-dojo-type="dijit/form/Button">Clear Selection</button>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'left'" style="width:100%;height:95%;border:none;padding:0px;margin:0px;"></div>
</div>
</body>
</html>
Edward,
I think this sample is what you are looking for (be aware the use of the "target" SMS style is undocumented and subject to change):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>Drop Down Test</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html,
body,
#mainWindow {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
#header {
height: 3%;
overflow: auto;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map",
"dojo/on",
"esri/tasks/query",
"esri/graphic",
"esri/layers/FeatureLayer",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/CartographicLineSymbol",
"esri/Color",
"dojo/store/Memory",
"dojo/_base/array",
"dojo/_base/lang",
"esri/request",
"dojo/json",
"dojo/parser",
"dijit/registry",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/form/Button",
"dijit/form/ComboBox",
"dojo/domReady!"
], function(
Map, on, Query, Graphic, FeatureLayer, SimpleMarkerSymbol, CartographicLineSymbol, Color, Memory, array, lang, esriRequest, json, parser, registry
) {
parser.parse();
map = new Map("map", {
basemap: "topo",
center: [-120.1883, 37.0868],
zoom: 6
});
var vendors = new FeatureLayer("http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/ALL_City_Vendors/FeatureServer/0", {
outFields: ["*"]
});
//point target symbol
var cls = new CartographicLineSymbol(CartographicLineSymbol.STYLE_SOLID, new Color([0,255,255,1]), 2, CartographicLineSymbol.CAP_ROUND, CartographicLineSymbol.JOIN_ROUND);
var sms = new SimpleMarkerSymbol("target", 16, cls, new Color([0,0,0,0]));
sms._spikeSize = 7;
sms._targetHeight = 17;
sms._targetWidth = 17;
sms.setAngle(0);
map.addLayers([vendors]);
map.on("layers-add-result", lang.hitch(this, function(){
var url = "http://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/ALL_City_Vendors/FeatureServer/0/ge...";
var classificationDef = {"type":"uniqueValueDef","uniqueValueFields":["Vendor_Name"]};
var str = json.stringify(classificationDef);
esriRequest({
url:url,
content:{
classificationDef:str,
f:'json'
},
handleAs:'json',
callbackParamName:'callback',
timeout:15000
}).then(lang.hitch(this,function(response){
var uniqueValueInfos = response && response.uniqueValueInfos;
if(uniqueValueInfos){
var store2 = new Memory({data:[]});
registry.byId("uniqueValuesSelect").set('store',store2);
var data = array.map(uniqueValueInfos,lang.hitch(this,function(info,index){
var value = info.value;
//value = parseFloat(value);
var dataItem = {
id:index,
name:value
};
return dataItem;
}));
store2 = new Memory({data:data});
registry.byId("uniqueValuesSelect").set('store',store2);
}
}),lang.hitch(this,function(error){
console.error(error);
}));
}));
registry.byId("clearBtn").on("click", function(){
map.graphics.clear();
});
registry.byId("uniqueValuesSelect").on("change", function(){
var query = new Query();
query.where = "Vendor_Name='" + registry.byId("uniqueValuesSelect").get('value') + "'";
console.info(query.where);
query.returnGeometry = true;
vendors.queryFeatures(query, function (featureSet) {
var Geom = featureSet.features[0].geometry;
var gra = new Graphic(Geom, sms);
map.graphics.add(gra);
map.centerAndZoom(Geom, 16);
});
});
});
</script>
</head>
<body class="claro">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:false" style="padding:0px;margin:0px;">
<div id="header" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'" style="overflow:hidden;border:none;border-bottom: 3px solid #CC9900;font-family: Windows;font-size:14pt; color: #FFFFFF;background: #000000; "> Select a Vendor name and it will be selected and zoomed to it on the map:
<select id="uniqueValuesSelect" data-dojo-type="dijit/form/ComboBox"></select>
<button id="clearBtn" data-dojo-type="dijit/form/Button">Clear Selection</button>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'left'" style="width:100%;height:95%;border:none;padding:0px;margin:0px;"></div>
</div>
</body>
</html>
Thank you. Will look at it.
Is there a best way to do the same for polylines and polygon shapes?
Figured out for polygons. I guess for polylines, just use SimpleLineSymbol..?
Edward,
Correct just use a SimpleLineSymbol.
Don't forget to mark this thread as answered, by clicking the "Correct Answer" button on the reply that answered your question.
Is there a way to prevent the mouse-over and mouse-out events for the map.graphics layer or for a separate graphics layer? The issue is as follows. I am highlighting (not selecting) a feature as user mouse over it. It works, however the addition of the highlight symbol (above) to the featurelayer is causing additional unwanted mouse-over/out events to be fired because of the overlaying of the highlight graphic over the featurelayer. This is causing multiple mouse-over/out events to be fired causing the highlight symbol to flicker.
Events:
featurelayer: mouse-over (highlight graphic is added over the feature)
featurelayer: mouse-out (highlight graphic is removed)
highlight graphic: mouse-over
highlight graphic: mouse-out
featurelayer: mouse-over (highlight graphic is added over the feature)
featurelayer: mouse-out (highlight graphic is removed)
highlight graphic: mouse-over
highlight graphic: mouse-out
featurelayer: mouse-over (highlight graphic is added over the feature)
featurelayer: mouse-out (highlight graphic is removed)
etc... as mouse moves over the feature.
This is happening even though there is no mouseover/out event handlers defined for the highlight graphics/layer.
One way to prevent this may be to prevent the mouseover/out events for the highlight graphics layer so only one set of events is fired:
featurelayer: mouse-over (highlight graphic is added over the feature)
featurelayer: mouse-out (highlight graphic is removed)
Perhaps the highlight graphic can be added to a separate graphicslayer and put this at bottom of the layer ordering under the featurelayer?
I figured out!
Thanks for your replies.