Dashboard: Solution Filtering
Relevant source files
The following files were used as context for generating this wiki page:
- frontend/src/components/dashboard/Analyzer.tsx
- frontend/src/components/dashboard/filter/AnalyzerFilterForm.tsx
- frontend/src/components/dashboard/AppliedFilters.tsx
- frontend/src/components/dashboard/Analysis.tsx
- frontend/src/components/dashboard/hooks/useManualGrouping.ts
- frontend/src/components/dashboard/CodeComparison.tsx
The Solution Filtering feature provides a dynamic mechanism for educators to sift through and isolate student solutions on the session analysis dashboard. By applying one or more criteria, users can narrow down the dataset of student code submissions to focus on specific patterns or characteristics. This allows for a more targeted investigation of student work, helping to identify common trends, misconceptions, or exemplary solutions within a large group.
The filtering system is primarily managed within the Analyzer component, which orchestrates state, data fetching, and rendering of the analysis chart and comparison views. Filters are applied to the full set of solution analyses, and the results are immediately reflected in the visualization.
Architecture and Data Flow
The filtering process is managed by the main Analyzer component and its child components. The state for active filters is held in the Analyzer's state and is updated via a reducer pattern. When filters are added, removed, or modified, a memoized calculation re-evaluates all solutions against the active filter set.
The following diagram illustrates the data flow when filters are applied.
This diagram shows that user interactions with the filter forms update the central filters state. This change triggers the useMemo hook, which uses the runFilter utility to process each solution, producing a filteredAnalyses array that child components like the chart and code comparison views consume.
Sources: frontend/src/components/dashboard/Analyzer.tsx:106-141
Core Logic
The core filtering logic resides within a useMemo hook in the Analyzer.tsx component. This hook is dependent on the list of solution analyses and the state.filters array.
- It initializes a boolean array
matchesAllFilterswithtruefor every solution. - It iterates through each active filter defined in
state.filters. - For each filter, it calls the
runFilterfunction, passing the filter configuration and the list of all solutions. - The
runFilterfunction returns an object containingmatchesFilter(a boolean array indicating which solutions passed that specific filter) andparameters(calculated values like min/max for the criterion). - The
matchesFilterresult is used to update the mainmatchesAllFiltersarray using a logical AND operation. This ensures that a solution must pass all active filters to remain visible. - The final output is
filteredAnalyses, an array where each object contains the original solutionanalysisand amatchesAllFiltersflag. This flag is later used for categorization and visualization.
Sources: frontend/src/components/dashboard/Analyzer.tsx:106-141
Key Components
The filtering UI and logic are distributed across several React components.
| Component | Role | File |
|---|---|---|
Analyzer.tsx | The main orchestrator. Manages the filters state via analyzerStateReducer and applies the filtering logic. | frontend/src/components/dashboard/Analyzer.tsx |
AnalyzerFilterForm.tsx | Renders the dropdown to add new filter criteria. It dispatches actions to update the filters state. | frontend/src/components/dashboard/filter/AnalyzerFilterForm.tsx |
AppliedFilters.tsx | Displays the list of currently active filters. Allows users to modify filter parameters or remove a filter. | frontend/src/components/dashboard/AppliedFilters.tsx |
CriterionFilterForm.tsx | (Inferred) A generic form component rendered by AppliedFilters.tsx to configure the specific values for a given criterion (e.g., a range slider). | frontend/src/components/dashboard/AppliedFilters.tsx:75-80 |
Component Interaction
The relationship between these components is hierarchical, with state and dispatch functions passed down from the parent.
Filter Management
Adding a Filter
A user adds a filter by selecting an option from the "Filtering Criteria" dropdown, which is rendered by the AnalyzerFilterForm component.
- The
Selectcomponent'soptionsare populated from afilterCriteriaarray, excluding criteria that are already in use. - When a user selects a new criterion, the
onChangeevent handler is triggered. - It calls
getInitialFilterValues(type)to create a default filter object for the selected criterion type. - It then calls
setFiltersto add this new filter object to thefiltersarray in theAnalyzercomponent's state.
Sources: frontend/src/components/dashboard/filter/AnalyzerFilterForm.tsx:40-54
Configuring and Removing Filters
Once a filter is added, it appears in the AppliedFilters component.
- Configuration: For each filter,
AppliedFiltersrenders aCriterionFilterForm. This form component receives the current filter object and thesetFiltersfunction, allowing the user to change its specific parameters (e.g., adjusting a min/max range). - Removal: Each filter in the list has a remove icon (
faXmark). Clicking this icon filters thefiltersstate array, removing the selected filter and triggering a re-render and re-calculation.
Sources: frontend/src/components/dashboard/AppliedFilters.tsx:66-72
Filtering and Categorization
The result of the filtering process is a matchesAllFilters flag for each solution analysis. This flag is used in the useManualGrouping hook to determine the visual category of each data point on the analysis chart.
The getCategory function checks this flag. If matchesAllFilters is true, the Category.matchesFilters bit is set for that solution. This directly influences how the solution is rendered (e.g., its color or pattern) on the chart, distinguishing it from solutions that were filtered out.
Sources: frontend/src/components/dashboard/hooks/useManualGrouping.ts:28-35