Closed dan-bowerman closed 6 years ago
Duplicate of https://github.com/fgpv-vpgf/fgpv-vpgf/issues/1442.
Filtering using symbology will work nicely for autogenerated
legends. With structured
legends, since the config author may override layer's symbology to provide better images for example. It can be a limitation - if you want filtering by symbology, you cannot specify your own symbols. Or maybe we can implement a mechanism of some sorts to link custom symbols with layer actual renderers to filter by.
At least for CESI, filtering on existing symbology is preferred. If the clients make any changes to their symbology, it will be through the MXD which will need to be republished. The symbols will always come from the service.
i've added some acceptance criteria to this following a conversation with @AleksueiR .
Adding to FGP project board due to original issue #1442 being created by FGP as a result of Usability testing.
Currently investigating the UniqueValueRenderer being used in the CESI FeatureLayer
.
The renderer is available through geoApi as featureRecord._layer.renderer
.
Initial tests on the method setVisualVariables
in this renderer were semi-successful. The symbol outlines remain on the map, but the colors are now gone. Here's the parameter I fed to setVisualVariables
:
[{"type": "opacityInfo",
"field": "Ozone_Symbol",
"stops": [{
"value": 0,
"opacity": 0
}, {
"value": 1,
"opacity": 0
},
{
"value": 2,
"opacity": 0
},
{
"value": 3,
"opacity": 0
},
{
"value": 4,
"opacity": 0
},
{
"value": 5,
"opacity": 0
}]}]
There are others to try such as sizeInfo
.
If this fails we can override values via addValue
. For example, addValue(0)
hides all values of 0
in the Ozone_Symbol
field (since we leave the symbol parameter undefined). We would do this for each hidden symbol. Though we would need to store the symbol properties separately and restore them manually when users are toggling symbols back to visible. I'd prefer to use setVisualVariables
as it seems more appropriate (if possible).
Or the easy way is we just document that symbol outlines can't be toggled and proceed with the above setVisualVariables
with opacity controls.
How many renderers do we want to support. CESI uses UniqueValueRenderer
so that one for sure. Do we need support for more types of renderers?
Are we ok with symbol outlines not being hidden? CESI sample service has a grey outline for all the symbols, but this could be removed. Ideally we keep them but the implementation won't be as pretty.
I can't answer #1, but for #2, if I'm understanding correctly, in the case that a layer would be comprised of opaque coloured circles, we would instead see only outlines of the circles? I think I'd be OK with that (it's a rather cool way to show that there's till data turned off... spooky ghost data), but how would this impact the data grid?
That's right, if symbols have a defined outline (the service posted above as an example has a grey outline around all symbols but its not very noticeable with the colors present) then they will remain when toggled off. I'd imagine if that's not ideal you could always remove the outline from the symbols on the service itself.
Data table would not be affected (symbols toggled off would not appear). This only affects the visual renderer.
We scrape the rendered only once and create an svg representation of the symbol to use in a symbology stack. If the renderer changes when it's toggled off, it would not affect the appearance of the generated symbol in the symbology stack.
Will toggling visibility be:
Do we strictly toggle on different symbology?
"toggleSymbology": {
"field": "OBJECTID",
"groupByValue": [[1,2], [3,4]]
},
groupByValue
above would put any points with OBJECTID
1 or 2 in the "same" symbology toggle.
Few thoughts on this.
Miles brings up a good point about for Do we strictly toggle on different symbology
. Basing this solely off the Renderer
is tricky, as the renderer can have multiple entries for the same symbol. What is shown in the layer selector is the Legend
, which is derived from the Renderer
, and that derivation includes collapsing similar entries.
Another thing is it looks like up to now we are approaching this by changing visibility via the layer renderer. I don't think this is even possible when using a non-dynamic dynamic layer. An alternate approach I think worth looking at is leveraging the current filtering engine. Essentially clicking the checkbox beside the legend entry applies a filter; this results in the map updating but also the grid reflecting the filter. Some things to consider:
Legend
field in the grid that can be filtered on but is never visible to the user.Legend
vs Renderer
, in that the filter clause would need to OR
across multiple values if they existed.I think this is a good idea to re-use the table filtering engine:
legend
filter James is talking about) that are linked to the layer symbology;So I have a working demo here. Using sample 1, open the crops symbology and check one or more symbols.
Now go to config 46, expand "Dynamic Layer with only one child with filter". Expand "Power plants" symbology and toggle one or more symbols. In this case all symbols vanish. index-mobile
page has some working and other not.
My code that sets the query is here.
I'd like to know if using self.block.definitionQuery = ...
is the right way to go. Curious as to why this fails for some layers (is code incorrect, or is it the layer?).
Note: If you open a dev console in the above demo links I'm outputting the LegendNode
and DynamicRecord
if that helps.
Problem appears to be that the query strings being generated are always being applied against the name field. The symbology/renderers are not tied to the name field; the cases where it works is when they align.
E.g. config 46, you are querying against field Facility
, but renderer is based on field PrimSource
. So nothing matches, and everything gets turned off.
Computing the query string becomes more complex — there are two main situations to deal with.
Class breaks renderers need to do a range. e.g. (renderer_field >= min_range_number AND renderer_field < max_range_number)
.
Unique value renderers need to compare against a field, but can be compared across up to three fields. e.g. of a two field UVR (renderer_field1 = ‘VALUE1’ AND renderer_field2 = ‘VALUE2’)
. These structures would be OR’d across each checked value in the legend.
Simple renderers are basically on/off for entire layer.
So the code that generates these queries will need to inspect the renderer of each layer. Additional complexity comes from having to consolidate the duplicates when going from renderer to legend (I think these would get OR’d).
Further complicating things is the geoApi proxy currently doesn’t expose the renderers (you can steal it from a feature layer esri object, but the dynamic layer children are more complex as we steal renderers from the server definition).
It might make sense to enhance the geoApi proxy’s symbology
property. It currently returns an array of objects with svgcode
and name
properties, I could add a third property called queryString
or something like that. This way all the renderer parsing remains on the geoApi (you can see similar code here that messes with renderers, but from an opposite direction). Your UI logic that generates a full query string would essentially be OR’ing each queryString
that is checked.
So take a gander at what you’re currently doing, then let me know if doing that kind of enhancement on the geoApi makes sense.
Thanks for the detailed explanation, makes much more sense now. I agree that the query string should be generated in geoApi (best spot for that kind of logic). I'm already going through each symbol and generating a query string, so this would fit in nicely.
Keep this issue updated when geoApi is updated and I'll re-work my logic
As previously discussed for CESI. The "EcoGeo" way to do this was to add the geodatabase to the service several times for each data range or symbol, and filter the geodatabase on those parameters. However, this makes the data grid impractical for CESI, so we need to develop a method for toggling ranges in the mapping interface. These selections should also toggle what is visible in the datagrid, however this is lesser priority.
Sample service: http://section917.cloudapp.net/arcgis/rest/services/CESI/CESI_Air_Ambient_OzoneAverage/MapServer
Here are some Acceptance Criteria (by @mweech):
WMS layer toggling will be considered out of scope for this issue.