Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filtering #47

Merged
merged 6 commits into from
Nov 16, 2019
Merged

Filtering #47

merged 6 commits into from
Nov 16, 2019

Conversation

andrico1234
Copy link
Owner

@andrico1234 andrico1234 commented Nov 16, 2019

Context

Create a filter context that exposes two methods and one field:

handleFilter: (query: string) => null
addToSkillMap: (skillMap: Record<string, string>) => null
filtersMatches: Set<string> | null

When a skill tree is rendered, a component is rendered that returns null, <AddToFilter />. This component (much like <CalculateNodeCount />, is its own component so that it can perform a potentially expensive computation and subscribe to a context, without having any children that will rerender unnecessarily.

This <AddToFilter /> component iterates recursively through the tree's nodes to generate a map where each entry is { [skillId]: [treeId] }. This is the index that the FilterContext iterates through to see which tree should be displayed.

When a user then tries to filter through the tree, via the handleFilter method. The FilterContext will go through each key and return their respective values. The returned values will then be moved into a Set so all duplicates are removed.

The trees will subscribe to any changes in the filters, and will not display if filtersMatches doesn't contain a reference to one of its child skills.

Example

There are two trees, one with an id of treeOne and another with an id of treeTwo.

treeOne has skills with ids: skillOne, skillTwo. treeTwo has skills with ids: skillThree, skillFour, skillFive.

After all components have rendered the skillMap will look like the following:

{
  `skillOne`: `treeOne`
  `skillTwo`: `treeOne`
  `skillThree`: `treeTwo`
  `skillFour`: `treeTwo`
  `skillFive`: `treeTwo`
}

A user filters the list of skills by entering a query of skillT.

The skill trees will receive the filtersMatches value, which in this case would be ['treeOne', 'treeTwo'] and determine whether or not to hide the skill tree, based on whether the tree's id exists within the array. Since both trees match the filter, neither will hide.

A user continues filtering with by finishing the query to be skillThree. The filtersMatches array will be ['treeTwo'], which means that treeOne will become hidden.

Considerations

Performance: Whenever the SkillMap is updated, a sorted list of the keys will be created and maintained. This means that I can use two binary searches to find the first and last keys that match the query, and pull out the list of values that way.

create an filter index with all each skill mapped to it's parent tree
abstract the top level skillprovider from the app context to accomodate multiple providers that need to be wrapped around the app
create stubs for filtering functionality
@andrico1234 andrico1234 self-assigned this Nov 16, 2019
skill tree listens and collapses trees when treeid doesn't match filter query
add memoization to functions for small performance iprovements
update broken type
replace mobile context
performance improvements
@andrico1234 andrico1234 changed the title [WIP] Filtering Filtering Nov 16, 2019
@andrico1234 andrico1234 merged commit 3078243 into master Nov 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant