-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
EDA in WDK: Integrate EDA scatterplot in WDK record page (#1325)
* checkpoint * Add type annotations to remove inferred `any` type. * Allow an analysis descriptor to be provided to `useAnalysis` * Only update state if the next param value is different than the previous param value * Extract useAnalysisState to allow external state tracking of analysis object * Use useAnalysisState, add counts, etc * Add stubbed question page with custom name * Allow hiding starred variable feature * fix typo * Use global memoization * Encapsulate creation of eda api clients * Adhere to lastest "api" for GenesByEdaSubset * Stub in eda scatterplot for phenotype dataset * Allow html formatting in search page header * Enable override for GenesByEdaSubset and set question page heading dynamically. * use more specific query name * update query name * use dynamic import for plotly, to keep it out of the main bundle * replace "EdaSubsetting" with "EdaSubset" * dont wrap sentence * fix label in user comment upload form * Fix volcano plot thumbnail out of sync (#1299) * fix for thumnails not rendering * replace mutating state with better check of filters * Allow html formatting in search page header * Enable override for GenesByEdaSubset and set question page heading dynamically. * use more specific query name * Use alphabetic ordering when displaying a flattened list of eda entities (#1323) * only order variable tree entities alphabetically (#1324) * Add annotations to plotly plots (#1321) * added plot annotations functionality * improve scatter annotation story * added histogram annotation story * introduce VEuPathDBAnnotation type * fix annotation types in histogram * update query name * use dynamic import for plotly, to keep it out of the main bundle * replace "EdaSubsetting" with "EdaSubset" * Revert to injecting script and link tags in document head * Export type * Expand type to include ReactHTML elements * Allow className to be overridden * Add EdaDatasetGraph component * Use EdaDatasetGraph component with EdaPhenotypeGraphsDataTable * simplify layout and add warning message for genes not in experiment * Add parentheses * Wire up highlightIds * Highlight graph_ids * Allow arbitrary variable values to be highlighted * Specify gene variable values to highlight --------- Co-authored-by: aurreco-uga <[email protected]> Co-authored-by: Cristina Aurrecoechea <[email protected]> Co-authored-by: Ann Sizemore Blevins <[email protected]>
- Loading branch information
1 parent
398f43d
commit cdf3a33
Showing
8 changed files
with
412 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
194 changes: 194 additions & 0 deletions
194
packages/libs/web-common/src/components/EdaDatasetGraph.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,194 @@ | ||
import { | ||
RecordClass, | ||
RecordInstance, | ||
TableField, | ||
TableValue, | ||
} from '@veupathdb/wdk-client/lib/Utils/WdkModel'; | ||
import * as t from 'io-ts'; | ||
import { useState } from 'react'; | ||
import { EdaScatterPlot } from './eda/EdaScatterPlot'; | ||
import { Link } from 'react-router-dom'; | ||
import { CollapsibleSection } from '@veupathdb/wdk-client/lib/Components'; | ||
|
||
const PlotConfig = t.type({ | ||
plotName: t.string, | ||
plotType: t.string, | ||
xAxisEntityId: t.string, | ||
xAxisVariableId: t.string, | ||
yAxisEntityId: t.string, | ||
yAxisVariableId: t.string, | ||
}); | ||
|
||
const PlotConfigs = t.array(PlotConfig); | ||
|
||
type RowData = TableValue[number]; | ||
|
||
interface RecordTableProps { | ||
record: RecordInstance; | ||
recordClass: RecordClass; | ||
value: TableValue; | ||
table: TableField; | ||
className?: string; | ||
searchTerm?: string; | ||
onSearchTermChange?: (searchTerm: string) => void; | ||
} | ||
|
||
interface DataTable { | ||
value: TableValue; | ||
table: TableField; | ||
record: RecordInstance; | ||
recordClass: RecordClass; | ||
DefaultComponent: React.ComponentType<RecordTableProps>; | ||
} | ||
|
||
interface Props { | ||
rowIndex: number; | ||
rowData: RowData; | ||
dataTable: DataTable; | ||
} | ||
|
||
export function EdaDatasetGraph(props: Props) { | ||
const { | ||
rowData: { | ||
plot_configs_json, | ||
dataset_id, | ||
dataset_name, | ||
graph_ids, | ||
source_id, | ||
default_graph_id, | ||
}, | ||
dataTable, | ||
} = props; | ||
|
||
const plotConfigs = parseJson(plot_configs_json as string); | ||
|
||
const [selectedPlotsIndex, setSelectedPlotsIndex] = useState([0]); | ||
const [dataTableCollapsed, setDataTableCollapsed] = useState(true); | ||
|
||
if (plotConfigs == null) { | ||
return <div>Could not parse plot_configs_json</div>; | ||
} | ||
|
||
const graphIds = graph_ids?.toString().split(/\s*,\s*/); | ||
|
||
const selectedPlotConfigs = plotConfigs.filter((_, index) => | ||
selectedPlotsIndex.includes(index) | ||
); | ||
|
||
return ( | ||
<div> | ||
<h4>Choose graph(s) to display</h4> | ||
{plotConfigs.map((plotConfig, index) => { | ||
return ( | ||
<label key={plotConfig.plotName}> | ||
<input | ||
type="checkbox" | ||
checked={selectedPlotsIndex.includes(index)} | ||
onChange={(e) => { | ||
setSelectedPlotsIndex((current) => { | ||
return e.target.checked | ||
? current.concat(index).sort() | ||
: current.filter((i) => i !== index); | ||
}); | ||
}} | ||
/>{' '} | ||
{plotConfig.plotName}{' '} | ||
</label> | ||
); | ||
})} | ||
|
||
{default_graph_id !== source_id ? ( | ||
<div> | ||
<strong style={{ color: 'firebrick' }}>WARNING</strong>: This Gene ( | ||
{source_id as string}) does not have data for this experiment. | ||
Instead, we are showing data for this same gene(s) from the reference | ||
strain for this species. This may or may NOT accurately represent the | ||
gene you are interested in.{' '} | ||
</div> | ||
) : null} | ||
|
||
<div | ||
style={{ | ||
display: 'flex', | ||
flexWrap: 'wrap', | ||
}} | ||
> | ||
{selectedPlotConfigs.map((plotConfig) => { | ||
const xAxisVariable = { | ||
entityId: plotConfig.xAxisEntityId, | ||
variableId: plotConfig.xAxisVariableId, | ||
}; | ||
const yAxisVariable = { | ||
entityId: plotConfig.yAxisEntityId, | ||
variableId: plotConfig.yAxisVariableId, | ||
}; | ||
return ( | ||
<div style={{ width: 500 }}> | ||
<EdaScatterPlot | ||
datasetId={dataset_id as string} | ||
xAxisVariable={xAxisVariable} | ||
yAxisVariable={yAxisVariable} | ||
highlightSpec={ | ||
graphIds && { | ||
ids: graphIds, | ||
// gene id | ||
variableId: 'VAR_bdc8e679', | ||
entityId: plotConfig.xAxisEntityId, | ||
} | ||
} | ||
/> | ||
</div> | ||
); | ||
})} | ||
</div> | ||
<div> | ||
<div style={{ display: 'flex', gap: '3ex' }}> | ||
<h4> | ||
<Link | ||
to={`/workspace/analyses/${dataset_id}/new/visualizations/new`} | ||
> | ||
Use the Study Explorer for more advanced plot options | ||
</Link> | ||
</h4> | ||
<h4> | ||
<Link to={`/record/dataset/${dataset_id}`}> | ||
See the full dataset description | ||
</Link> | ||
</h4> | ||
</div> | ||
|
||
{props.dataTable && ( | ||
<CollapsibleSection | ||
className={'eupathdb-' + props.dataTable.table.name + 'Container'} | ||
headerContent="Data table" | ||
headerComponent="h4" | ||
isCollapsed={dataTableCollapsed} | ||
onCollapsedChange={setDataTableCollapsed} | ||
> | ||
<dataTable.DefaultComponent | ||
record={dataTable.record} | ||
recordClass={dataTable.recordClass} | ||
table={dataTable.table} | ||
value={dataTable.value.filter( | ||
(dat) => dat.dataset_id === dataset_name | ||
)} | ||
/> | ||
</CollapsibleSection> | ||
)} | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function parseJson(json: string) { | ||
try { | ||
const object = JSON.parse(json); | ||
if (PlotConfigs.is(object)) { | ||
return object; | ||
} | ||
return undefined; | ||
} catch (error) { | ||
console.error(error); | ||
return undefined; | ||
} | ||
} |
Oops, something went wrong.