Skip to content

Selection Architecture Refactor

Claire Tang edited this page Nov 22, 2017 · 3 revisions

The goal of the selection architecture refactor is to clarify the roles of the models and behaviors involved in selection/inspection (i.e. tools, glyph renderers, selections, and policies; hit-testing, rendering selection/non-selection/hover visuals, rendering tooltips) and make it possible to add new policies, such as inspecting from only selected points, and new behaviors, such as better handling of hovering over multiple points.

Part of the refactor will be to create a Selection model, which will replace the current "plain dict" representation for selections. This will allow selections to use the model property change-detection machinery. It will also make it easier for users to programmatically set selections.

The Selection model represents selections and inspections through its indices (what is currently 1d indices). A data source's selected property will be a Selection and its inspected property will a object/map mapping GlyphRenderers to Selections. The selected selection is shared by all GlyphRenderers which have a common data source, but the inspected selection is renderer-specific, which will allow for tooltips on multiple renderers.

In the middle of diagram below, the Selection and Inspection indices are shown contained in the ColumnDataSource. A dotted line runs through to separate the things that happen leading up to the setting of the selection/inspections from the things that happen based on those indices.

Selection Refactor Diagram

Below the dotted line: Rendering based on Selections

The rendering of selection/non-selection/hover glyph visuals will be based solely on the selected and inspected Selections of the data source being used by that GlyphRenderer. The selected and inspected can also be used for new behaviors, such as some way to refine a selection when many points are selected that are close to one another, when combined with information about the plot (proximity of the points, space in the plot).

Above the dotted line: Setting Selections

Setting Selections happens in two ways, through tools and programmatically.

1. Setting Selections through Tools

The first way is through select/inspect tools. The tools construct a geometry based on which tool it is and the user interaction which is then used for hit-testing. Hit-testing is first renderer-specific (glyph vs. graph). In the GraphRenderer case, different policies determine which glyphs (nodes or edges) will be hit-test against.

Hit-testing is secondly glyph-specific and called through the GlyphRenderers, but the SelectionManager should be the one to coordinate the hit-testing and set the selected on the data source. Currently, because the GlyphRenderer sets the selected, the behavior is not correct when there are multiple renderers sharing a data source because the indices hit from multiple renderers do not get unioned and instead are set to indices hit by one renderer. So, hit-test results cannot just be set as selected and inspected. Instead, the hit-test results need to be turned into the corrected selected and inspected indices through policies. For example, in the NodesAndLinkedEdges GraphRenderer case, the hit-test result contains the nodes that were hit which are used by the policy to set the correct selected property on the edge_renderer. In the GlyphRenderer case, the policy for selection should be to union the indices when multiple renderers are hit. For inspection with Line glyphs, a policy should determine which indices are inspected.

2. Setting Selections programatically

The second way a Selection can be set is explicitly by a user. A Selection model can be created and set to a data source's selected or inspected. Then it might also be possible for certain policies to fix up the indices, like the example of NodesAndLinkedEdges above. If a user sets selected nodes and that policy, the policy could set the selected edges correctly. If a user sets selected nodes and edges with that policy, the policy could overwrite the user-set selected edges. If they set both selected nodes and edges and no policy, then the user-set selected nodes and edges would be used.

Other notes

Tooltips

Currently, it's not possible to set inspected and have a tooltip appear. The tooltip is currently attached to the HoverTool and only appears when the HoverTool is actively hitting something. At the implementation level, the tooltip relies on the hover tool receiving an inspect signal from a GlyphRenderer that contains the GlyphRendererView and the geometry of the inspection event. The hover tool then takes the geometry to figure out where to place the tooltips based on what kind of glyph was hit and which policy to use. It could be possible to change this so that the hover tool hands off the geometry to the SelectionManager and the manager handles delegating hit-testing to the renderers and receives back which indices were hit, and then sets the inspected indices based on inspection policies. Then the inspected indices would drive the tooltips which could potentially belong to GlyphRenderers. Removing the tooltips from the hover tool will allow for tooltips to be displayed programmatically.

Distinction between HitTestPolicies and Selection/InspectionPolicies