Skip to content

Commit

Permalink
Merge branch 'develop' into feature/composer_api_env_var
Browse files Browse the repository at this point in the history
  • Loading branch information
ddelpiano authored Jul 5, 2024
2 parents 663192b + 0e575a0 commit 8e70e0a
Show file tree
Hide file tree
Showing 27 changed files with 1,284 additions and 339 deletions.
8 changes: 8 additions & 0 deletions public/order.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"http://purl.obolibrary.org/obo/UBERON_0005844": [
"http://purl.obolibrary.org/obo/UBERON_0002726",
"http://purl.obolibrary.org/obo/UBERON_0003038",
"http://purl.obolibrary.org/obo/UBERON_0002792",
"http://purl.obolibrary.org/obo/UBERON_0005843"
]
}
33 changes: 17 additions & 16 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
fetchJSON,
fetchKnowledgeStatements,
fetchMajorNerves,
fetchOrderJson,
} from './services/fetchService.ts';
import { getUniqueMajorNerves } from './services/filterValuesService.ts';
import {
Expand Down Expand Up @@ -62,25 +63,25 @@ const App = () => {
}, [LayoutComponent, dispatch]);

useEffect(() => {
fetchJSON()
.then((data) => {
setHierarchicalNodes(getHierarchicalNodes(data));
setOrgans(getOrgans(data));
})
.catch((error) => {
// TODO: We should give feedback to the user
console.error('Failed to fetch JSON data:', error);
});
const fetchData = async () => {
try {
const [jsonData, orderData, majorNervesData] = await Promise.all([
fetchJSON(),
fetchOrderJson(),
fetchMajorNerves(),
]);

fetchMajorNerves()
.then((data) => {
setMajorNerves(getUniqueMajorNerves(data));
})
.catch((error) => {
setHierarchicalNodes(getHierarchicalNodes(jsonData, orderData));
setOrgans(getOrgans(jsonData));
setMajorNerves(getUniqueMajorNerves(majorNervesData));
} catch (error) {
// TODO: We should give feedback to the user
console.error('Failed to fetch major nerves data:', error);
console.error('Failed to fetch data:', error);
setMajorNerves(undefined);
});
}
};

fetchData();
}, []);

useEffect(() => {
Expand Down
128 changes: 92 additions & 36 deletions src/components/Connections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { ArrowRightIcon } from './icons';
import { vars } from '../theme/variables';
import {
HierarchicalItem,
PhenotypeKsIdMap,
KsPerPhenotype,
SummaryType,
KsMapType,
KsRecord,
Option,
} from './common/Types';
import { useDataContext } from '../context/DataContext.ts';
import {
Expand All @@ -22,6 +23,9 @@ import {
import {
getYAxis,
getKnowledgeStatementMap,
filterYAxis,
getEmptyColumns,
filterConnectionsMap,
} from '../services/heatmapService.ts';
import SummaryHeader from './connections/SummaryHeader';
import SummaryInstructions from './connections/SummaryInstructions.tsx';
Expand Down Expand Up @@ -50,60 +54,88 @@ const styles = {
};

function Connections() {
const {
selectedConnectionSummary,
majorNerves,
hierarchicalNodes,
knowledgeStatements,
filters,
} = useDataContext();

const [showConnectionDetails, setShowConnectionDetails] =
useState<SummaryType>(SummaryType.Instruction);
const [connectionsMap, setConnectionsMap] = useState<
Map<string, PhenotypeKsIdMap[]>
Map<string, KsPerPhenotype[]>
>(new Map());
const [filteredConnectionsMap, setFilteredConnectionsMap] = useState<
Map<string, KsPerPhenotype[]>
>(new Map());
const [connectionPage, setConnectionPage] = useState(1); // represents the page number / index of the connections - if (x,y) has 4 connections, then connectionPage will be 1, 2, 3, 4
const [yAxis, setYAxis] = useState<HierarchicalItem[]>([]);
const [xAxis, setXAxis] = useState<string[]>([]);
const [filteredYAxis, setFilteredYAxis] = useState<HierarchicalItem[]>([]);
const [filteredXAxis, setFilteredXAxis] = useState<string[]>([]);
const [selectedCell, setSelectedCell] = useState<{
x: number;
y: number;
} | null>(null); // useful for coordinates
const [knowledgeStatementsMap, setKnowledgeStatementsMap] =
useState<KsMapType>({});
const [xAxis, setXAxis] = useState<string[]>([]);
useState<KsRecord>({});
const [nerveFilters, setNerveFilters] = useState<Option[]>([]);
const [phenotypeFilters, setPhenotypeFilters] = useState<Option[]>([]);

const {
selectedConnectionSummary,
majorNerves,
hierarchicalNodes,
knowledgeStatements,
summaryFilters,
} = useDataContext();
const summaryFilters = useMemo(
() => ({
...filters,
Nerve: nerveFilters,
Phenotype: phenotypeFilters,
}),
[filters, nerveFilters, phenotypeFilters],
);

useEffect(() => {
// By default on the first render, show the instruction/summary
if (selectedConnectionSummary) {
setShowConnectionDetails(SummaryType.Summary);
} else {
setShowConnectionDetails(SummaryType.Instruction);
}
}, [selectedConnectionSummary]);

// Values from the selected connection - In the SummaryType.summary
const viasConnection = getAllViasFromConnections(
selectedConnectionSummary?.connections || ({} as KsMapType),
selectedConnectionSummary?.filteredKnowledgeStatements || ({} as KsRecord),
);
const viasStatement = convertViaToString(Object.values(viasConnection));
const totalConnectionCount = Object.keys(
selectedConnectionSummary?.connections || ({} as KsMapType),
selectedConnectionSummary?.filteredKnowledgeStatements || ({} as KsRecord),
).length;
const nerves = getNerveFilters(viasConnection, majorNerves);

const availableNerves = getNerveFilters(viasConnection, majorNerves);
const availablePhenotypes = useMemo(
() =>
selectedConnectionSummary
? getAllPhenotypes(
selectedConnectionSummary.filteredKnowledgeStatements,
)
: [],
[selectedConnectionSummary],
);

useEffect(() => {
// calculate the connectionsMap for the secondary heatmap
if (
selectedConnectionSummary &&
selectedConnectionSummary.hierarchy &&
selectedConnectionSummary.hierarchicalNode &&
hierarchicalNodes
) {
const destinations = getDestinations(selectedConnectionSummary);
const connections = calculateSecondaryConnections(
hierarchicalNodes,
destinations,
knowledgeStatements,
selectedConnectionSummary.filteredKnowledgeStatements,
summaryFilters,
selectedConnectionSummary.hierarchy,
selectedConnectionSummary.hierarchicalNode,
);
setConnectionsMap(connections);
}
Expand All @@ -114,11 +146,6 @@ function Connections() {
knowledgeStatements,
]);

const selectedPhenotypes = useMemo(
() => getAllPhenotypes(connectionsMap),
[connectionsMap],
);

useEffect(() => {
// set the xAxis for the heatmap
if (selectedConnectionSummary) {
Expand All @@ -133,8 +160,8 @@ function Connections() {
// set the yAxis for the heatmap
if (selectedConnectionSummary && hierarchicalNodes) {
const hierarchyNode = {
[selectedConnectionSummary.hierarchy.id]:
selectedConnectionSummary.hierarchy,
[selectedConnectionSummary.hierarchicalNode.id]:
selectedConnectionSummary.hierarchicalNode,
};
const yHierarchicalItem = getYAxis(hierarchicalNodes, hierarchyNode);
setYAxis(yHierarchicalItem);
Expand All @@ -144,7 +171,7 @@ function Connections() {
const handleCellClick = (x: number, y: number, yId: string): void => {
// when the heatmap cell is clicked
setSelectedCell({ x, y });
const row = connectionsMap.get(yId);
const row = filteredConnectionsMap.get(yId);
if (row) {
setConnectionPage(1);
const ksIds = Object.values(row[x]).reduce((acc, phenotypeData) => {
Expand All @@ -153,7 +180,9 @@ function Connections() {

if (
selectedConnectionSummary &&
Object.keys(selectedConnectionSummary.connections).length !== 0
Object.keys(selectedConnectionSummary.filteredKnowledgeStatements)
.length !== 0 &&
ksIds.length > 0
) {
setShowConnectionDetails(SummaryType.DetailedSummary);
const ksMap = getKnowledgeStatementMap(ksIds, knowledgeStatements);
Expand All @@ -162,10 +191,33 @@ function Connections() {
}
};

const heatmapData = useMemo(() => {
return getSecondaryHeatmapData(yAxis, connectionsMap);
}, [yAxis, connectionsMap]);
useEffect(() => {
// Filter yAxis
const filteredYAxis = filterYAxis(yAxis, connectionsMap);

// Determine columns with data
const columnsWithData = getEmptyColumns(filteredYAxis, connectionsMap);

// Filter connections map
const filteredConnectionsMap = filterConnectionsMap(
filteredYAxis,
connectionsMap,
columnsWithData,
);

// Filter xAxis
const filteredXAxis = xAxis.filter((_, index) =>
columnsWithData.has(index),
);

setFilteredYAxis(filteredYAxis);
setFilteredXAxis(filteredXAxis);
setFilteredConnectionsMap(filteredConnectionsMap);
}, [yAxis, xAxis, connectionsMap]);

const heatmapData = useMemo(() => {
return getSecondaryHeatmapData(filteredYAxis, filteredConnectionsMap);
}, [filteredYAxis, filteredConnectionsMap]);
return (
<Box display="flex" flexDirection="column" minHeight={1}>
<SummaryHeader
Expand Down Expand Up @@ -196,7 +248,7 @@ function Connections() {
Connection origin
</Typography>
<TextField
value={selectedConnectionSummary?.origin || ''}
value={selectedConnectionSummary?.hierarchicalNode.name || ''}
fullWidth
/>
</Box>
Expand Down Expand Up @@ -255,13 +307,17 @@ function Connections() {
</Typography>
</Box>
<SummaryFiltersDropdown
nerves={nerves}
phenotypes={selectedPhenotypes}
nerves={availableNerves}
nerveFilters={nerveFilters}
setNerveFilters={setNerveFilters}
phenotypes={availablePhenotypes}
phenotypeFilters={phenotypeFilters}
setPhenotypeFilters={setPhenotypeFilters}
/>
<HeatmapGrid
yAxis={yAxis}
yAxis={filteredYAxis}
setYAxis={setYAxis}
xAxis={xAxis}
xAxis={filteredXAxis}
onCellClick={handleCellClick}
selectedCell={selectedCell}
secondaryHeatmapData={heatmapData}
Expand All @@ -270,7 +326,7 @@ function Connections() {
/>
</Box>

<PhenotypeLegend phenotypes={selectedPhenotypes} />
<PhenotypeLegend phenotypes={availablePhenotypes} />
</>
)}
</Box>
Expand Down
Loading

0 comments on commit 8e70e0a

Please sign in to comment.