Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#1169 | filters for visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
snyaggarwal committed Jan 10, 2022
1 parent 5929569 commit d203ff3
Show file tree
Hide file tree
Showing 3 changed files with 276 additions and 93 deletions.
9 changes: 7 additions & 2 deletions src/components/concepts/ConceptHierarchyTree.jsx
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import * as d3 from "d3";
import { tip as d3tip } from "d3-v6-tip";
import { CircularProgress } from '@mui/material';
import { isEmpty, get, reject, find } from 'lodash';
import { isEmpty, get, reject, find, merge, isEqual } from 'lodash';
import APIService from '../../services/APIService';
import { BLUE } from '../../common/constants';
import { getRandomColor } from '../../common/utils';
Expand Down Expand Up @@ -43,11 +43,16 @@ class ConceptHierarchyTree extends React.Component {
this.makeInitialTree()
}

componentDidUpdate(prevProps) {
if(!isEqual(prevProps.filters, this.props.filters))
this.setState({isLoading: true}, this.makeInitialTree)
}

getChildren = (concept, callback) => APIService
.new()
.overrideURL(concept.url)
.appendToUrl('$cascade/')
.get(null, null, {view: 'hierarchy'})
.get(null, null, merge({view: 'hierarchy'}, (this.props.filters || {})))
.then(response => callback(response.data.entry));

makeInitialTree = () => this.getChildren(this.props.concept, tree => {
Expand Down
155 changes: 155 additions & 0 deletions src/components/concepts/HierarchyTreeFilters.jsx
@@ -0,0 +1,155 @@
import React from 'react';
import {
Tooltip, Chip, Menu, MenuItem, TextField,
Button, Dialog, DialogActions, DialogContent, DialogTitle,
} from '@mui/material'
import {
FilterAlt as FilterIcon,
Cancel as CancelIcon,
Link as MappingIcon,
ArrowDropDown as DownIcon
} from '@mui/icons-material'
import { map } from 'lodash';

const LEVEL_OPTIONS = [
{id: '1', name: '1'},
{id: '2', name: '2'},
{id: '3', name: '3'},
{id: '4', name: '4'},
{id: '5', name: '5'},
{id: '*', name: 'All'},
]

const HierarchyTreeFilters = ({filters, onChange, onMapTypesFilterChange}) => {
const [mapTypes, setMapTypes] = React.useState(filters.mapTypes || '')
const [excludeMapTypes, setExcludeMapTypes] = React.useState(filters.excludeMapTypes || '')
const [levelAnchorEl, setLevelAnchorEl] = React.useState(null);
const [mapTypeAnchorEl, setMapTypeAnchorEl] = React.useState(null);
const cascadeLevelText = filters.cascadeLevels === '*' ? 'Levels: All' : `Levels: ${filters.cascadeLevels}`
const toggleLevelAnchor = event => setLevelAnchorEl(levelAnchorEl ? null : event.currentTarget)
const toggleMapTypeAnchor = event => setMapTypeAnchorEl(mapTypeAnchorEl ? null : event.currentTarget)
const onLevelChange = newLevel => {
toggleLevelAnchor()
onChange('cascadeLevels', newLevel)
}
const onMapTypesChange = () => {
toggleMapTypeAnchor()
onMapTypesFilterChange({...filters, mapTypes: mapTypes, excludeMapTypes: excludeMapTypes})
}

return (
<span className="flex-vertical-center">
<Tooltip title={cascadeLevelText} arrow placement='top'>
<Chip
color="primary"
variant="outlined"
label={cascadeLevelText}
size="small"
clickable
onClick={toggleLevelAnchor}
onDelete={toggleLevelAnchor}
deleteIcon={<DownIcon fontSize="inherit" />}
/>
</Tooltip>
<Tooltip title={filters.cascadeHierarchy ? 'Remove Hierarchy' : 'Cascade Hierarchy'} arrow placement='top'>
<Chip
color={filters.cascadeHierarchy ? "primary" : "default"}
variant="outlined"
label="Hierarchy"
size="small"
style={filters.cascadeHierarchy ? {marginLeft: '2px'} : { marginLeft: '2px', color: 'rgba(0, 0, 0, 0.5)' }}
icon={filters.cascadeHierarchy ? <CancelIcon fontSize="inherit" /> : null}
clickable
onClick={() => onChange('cascadeHierarchy', !filters.cascadeHierarchy) }
/>
</Tooltip>
<Tooltip title={filters.cascadeMappings ? 'Remove Mappings' : 'Cascade Mappings'} arrow placement='top'>
<Chip
color={filters.cascadeMappings ? "primary" : "default"}
variant="outlined"
label="Mappings"
size="small"
style={filters.cascadeMappings ? {marginLeft: '2px'} : { color: 'rgba(0, 0, 0, 0.5)', marginLeft: '2px' }}
icon={filters.cascadeMappings ? <CancelIcon fontSize="inherit" /> : null}
clickable
onClick={() => onChange('cascadeMappings', !filters.cascadeMappings) }
/>
</Tooltip>
{
filters.cascadeMappings &&
<Tooltip title="Include/Exclude MapTypes" arrow placement='top'>
<Chip
color={(filters.mapTypes || filters.excludeMapTypes) ? "primary" : "default"}
variant="outlined"
label="MapTypes"
size="small"
clickable
deleteIcon={<FilterIcon />}
icon={<MappingIcon />}
onDelete={toggleMapTypeAnchor}
onClick={toggleMapTypeAnchor}
style={{marginLeft: '2px'}}
/>
</Tooltip>
}
<Menu
id="hierarchy-tree-filter-level-menu"
anchorEl={levelAnchorEl}
keepMounted
open={Boolean(levelAnchorEl)}
onClose={toggleLevelAnchor}
>
{
map(LEVEL_OPTIONS, ({id, name}) => (
<MenuItem key={id} value={id} onClick={() => onLevelChange(id)} selected={filters.cascadeLevels === id}>
{name}
</MenuItem>
))
}
</Menu>
<Dialog open={Boolean(mapTypeAnchorEl)} onClose={toggleMapTypeAnchor}>
<DialogTitle>
Include/Exclude Map Types from Results
</DialogTitle>
<DialogContent style={{minWidth: '400px'}}>
<div className='col-xs-12 no-side-padding'>
<div className='col-xs-12 no-side-padding' style={{fontWeight: 'bold', marginBottom: '5px'}}>
Include MapTypes
</div>
<div className='col-xs-12 no-side-padding'>
<TextField
fullWidth
value={mapTypes}
onChange={event => setMapTypes(event.target.value)}
placeholder='e.g. SAME-AS,NARROWER-THAN,CONCEPT-SET'
/>
</div>
</div>
<div className='col-xs-12 no-side-padding' style={{marginTop: '15px'}}>
<div className='col-xs-12 no-side-padding' style={{fontWeight: 'bold', marginBottom: '5px'}}>
Exclude MapTypes
</div>
<div className='col-xs-12 no-side-padding'>
<TextField
fullWidth
value={excludeMapTypes}
onChange={event => setExcludeMapTypes(event.target.value)}
placeholder='e.g. SAME-AS,NARROWER-THAN,CONCEPT-SET'
/>
</div>
</div>
</DialogContent>
<DialogActions>
<Button onClick={toggleMapTypeAnchor} variant='outlined' color='secondary'>
Close
</Button>
<Button onClick={onMapTypesChange} color="primary" variant='outlined'>
Apply
</Button>
</DialogActions>
</Dialog>
</span>
);
}

export default HierarchyTreeFilters;

0 comments on commit d203ff3

Please sign in to comment.