Simple filter proposal - labsquare/cutevariant GitHub Wiki

This is the proposal for implementing a simplified filter plugin, more limited but also much more intuitive for new users than the currently available plugin. It won't necessarily replace the current plugin.

User interface

Mockup of the proposed filter plugin

The widget contains filter categories which themselves contain filter items. Each filter item is linked to a field of the variant view, has a title (not necessarily the same as the name of the column although the name of the column should be shown in a tooltip) and a control adapted to correctly set a filter on the field. For instance :

  • a float field (such as allele frequency) could present a double ended slider to set a minimum and a maximum
  • a text field with many values (such a the gene symbol) could present a free text field with autocompletion populated with the possible values of the field

All selected filters are applied additively (with ANDs). Each filter should have a reset button. There should also be a button to reset all filters.

Code structure

Controllers

Each type of filter item is a Controller class (for instance : a double-ended slider, a dropdown list...), which implements the widget and the filtering behavior (for instance : by default the dropdown list should collect all possible values of the field , the double ended slider).

No specific effort will be made to make controllers generic as each field would have some specificity at least in the filtering behavior of the controller. However if some opportunity for easy genericity appears it is by no means discouraged.

Consequently, if a controller needs an interface element not implementable with standard QT widgets, the widgets should be implemented in cutevariant.gui.widgets rather than in the controller itself so that they are reusable. For instance, the double-ended slider will be implemented as a generic widget and then used by several different Controllers.

Implementation

Controllers are classes inheriting from QWidget. In their init method, they should set up their GUI as with any widget, cable their signals to respond to user input adequately (but most input methods should be disabled at this point, as no project is loaded).

They should implement the following signals :

  • changed : listened by the ControllerManager, emitted when the filter setup of the controller changes. The ControllerManager will then call get_filter.

They should implement the following methods :

  • setup(conn) : called by the ControllerManager each time a new project is opened. The conn argument is a database connection. In this method, the Controller should reset completely, then set up any element dependent on the database (for instance autofill values) as well as enable interactivity if it was disabled before.
  • get_filter() : called by the ControllerManager once the Controller has triggered the changed event. Should return the filter setup of the Controller as a dict.
  • reset() : reset the controller to its default state and disable any active filtering. This may be called by the ControllerManager when doing a global reset, or internally when the individual reset button is pressed.

ControllerManager

Manages all of the controllers in the widgets. Responsible to instantiate them according to the configuration, to dispatch global signals (project loaded, reset all).

Maybe it is the actual plugin ???? or maybe juste something in between

The ControllerManager listens on the changed signal on all of its controllers. When a controller has changed, it should pull the filter from that controller into a cache (replacing the previous one if it exists) and then build a global query by chaining the individual filters with ANDs, and setting the filter state to that.

When the filtering context changes externally (i.e the query is edited by hand), the widget interface will not be updated accordingly. This is because the widget interface cannot represent all filtering queries (for instance ORs are out of the question).

Containing Widget

TBD

List of Specific controllers to implement

  • TBD