This sample shows how a FeatureEffect can be used to highlight features in a CSVLayerView
and select the corresponding rows in a FeatureTable. A rectangle can be drawn on the view by clicking on the Select features by rectangle
button and drawing a rectangle on the map.
The following code runs when user clicks on the Select features by rectangle
button:
// click event for the select by rectangle button
selectButton.addEventListener("click", () => {
view.closePopup();
sketchViewModel.create("rectangle");
});
Once the rectangle is drawn, the SketchViewModel's create event is called as shown below. When the rectangle is created, we query for features within that geometry, and highlight those features in the FeatureTable using the FeatureTable.highlightIds property. The user can draw additional rectangles on the map, the app will call the geometryEngineAsync.union method to merge the rectangles drawn on the map and will use the merged geometry as the query geometry.
// Once user is done drawing a rectangle on the map
// use the rectangle to select features on the map and table
sketchViewModel.on("create", async (event) => {
if (event.state === "complete") {
// this polygon will be used to query features that intersect it
const geometries = polygonGraphicsLayer.graphics.map(function (graphic) {
return graphic.geometry;
});
const queryGeometry = await geometryEngineAsync.union(geometries.toArray());
selectFeatures(queryGeometry);
}
});
// This function is called when user completes drawing a rectangle
// on the map. Use the rectangle to select features in the layer and table
function selectFeatures(geometry) {
if (csvLayerView) {
// create a query and set its geometry parameter to the
// rectangle that was drawn on the view
const query = {
geometry: geometry,
outFields: ["*"]
};
// query graphics from the csv layer view. Geometry set for the query
// can be polygon for point features and only intersecting geometries are returned
csvLayerView
.queryFeatures(query)
.then((results) => {
if (results.features.length === 0) {
clearSelection();
} else {
featureTable.highlightIds.removeAll();
let highlightIds = [];
// filter the table based on the selection and only show those rows
featureTable.filterGeometry = geometry;
// Iterate through the features and push each individual result's OBJECTID to the highlightIds array
results.features.forEach((feature) => {
highlightIds.push(feature.attributes.__OBJECTID);
});
// Set the highlightIds array to the highlightIds property of the featureTable
featureTable.highlightIds.addMany(highlightIds);
}
})
.catch(errorCallback);
}
}
The app also watches for changes on FeatureTable's highlightIds. In the function, the app will update the
CSVLayerView.featureEffect property to match the rows selected in the table. Features that are selected remain unaffected visually while features that are outside
of the rectangle will have blur(5px) grayscale(90%) opacity(40%)
effects applied.
// Check if the highlights are being changed on the table
// update the features array to match the table highlights
let features = [];
featureTable.highlightIds.on("change", async (event) => {
// this array will keep track of selected feature objectIds to
// sync the layerview feature effects and feature table selection
// set excluded effect on the features that are not selected in the table
event.removed.forEach((item) => {
const data = features.find((data) => {
return data === item;
});
if (data) {
features.splice(features.indexOf(data), 1);
}
});
// If the selection is added, push all added selections to array
event.added.forEach((item) => {
features.push(item);
});
csvLayerView.featureEffect = {
filter: {
objectIds: features
},
excludedEffect: "blur(5px) grayscale(90%) opacity(40%)"
};
});