Skip to content

Commit

Permalink
Merge pull request hms-dbmi-cellenics#951 from biomage-org/91-single-…
Browse files Browse the repository at this point in the history
…sample-default-elbow

Set single sample as default
  • Loading branch information
cosa65 authored Nov 28, 2023
2 parents 66e61ea + e4ab164 commit 2ac56d0
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import React from 'react';
import { Provider } from 'react-redux';
import '__test__/test-utils/setupTests';
import { screen, render, waitFor } from '@testing-library/react';
import {
screen, render, waitFor, within,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import _ from 'lodash';
import fake from '__test__/test-utils/constants';
Expand Down Expand Up @@ -204,4 +206,31 @@ describe('DataIntegration', () => {
// The legend alert plot text should appear
expect(screen.getByText(/We have hidden the plot legend, because it is too large and it interferes with the display of the plot/)).toBeInTheDocument();
});

it('Renders the elbow plot by default when the experiment is single sample', async () => {
// Remove all sample other than the first one.
// This way, getIsUnisample() will detect the exp as unisample
const unisampleCellSetsData = _.cloneDeep(cellSetsData);
_.find(unisampleCellSetsData.cellSets, { key: 'sample' }).children.splice(1);

const mockSingleSampleApiResponses = {
...generateDefaultMockAPIResponses(fake.EXPERIMENT_ID),
[`experiments/${fake.EXPERIMENT_ID}/cellSets$`]: () => promiseResponse(
JSON.stringify(unisampleCellSetsData),
),
};

fetchMock
.mockReset()
.mockIf(/.*/, mockAPI(mockSingleSampleApiResponses));

storeState = makeStore();
await storeState.dispatch(loadBackendStatus(fake.EXPERIMENT_ID));
await storeState.dispatch(loadProcessingSettings(fake.EXPERIMENT_ID));
await storeState.dispatch(loadCellSets(fake.EXPERIMENT_ID));

await renderDataIntegration(storeState);

expect(screen.getByRole('radio', { name: 'Elbow plot showing principal components' })).toBeChecked();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
} from 'antd';
import SelectData from 'components/plots/styling/embedding-continuous/SelectData';

import { isUnisample } from 'utils/experimentPredicates';
import { getIsUnisample } from 'utils/experimentPredicates';

import CategoricalEmbeddingPlot from 'components/plots/CategoricalEmbeddingPlot';
import ContinuousEmbeddingPlot from 'components/plots/ContinuousEmbeddingPlot';
Expand Down Expand Up @@ -135,11 +135,11 @@ const ConfigureEmbedding = (props) => {
const { loading, data: plotData, error } = cellMeta[colouring];
const modifiedConfig = {
...config,
axes:{
axes: {
...config.axes,
yAxisText: config.axes.yAxisText || plotColouring,
}
}
},
};
return (
<ViolinFilterPlot
experimentId={experimentId}
Expand Down Expand Up @@ -406,7 +406,7 @@ const ConfigureEmbedding = (props) => {
);
}

if (plotColouring === 'sample' && cellSets.accessible && isUnisample(cellSets.hierarchy)
if (plotColouring === 'sample' && cellSets.accessible && getIsUnisample(cellSets.hierarchy)
) {
return (
<center>
Expand Down
15 changes: 10 additions & 5 deletions src/components/data-processing/DataIntegration/DataIntegration.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, {
useState, useEffect, useRef, useCallback,
useState, useEffect, useRef, useCallback, useMemo,
} from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
Expand All @@ -24,7 +24,7 @@ import ElbowPlot from 'components/plots/ElbowPlot';
import { generateDataProcessingPlotUuid } from 'utils/generateCustomPlotUuid';
import EmptyPlot from 'components/plots/helpers/EmptyPlot';
import PlotStyling from 'components/plots/styling/PlotStyling';
import { isUnisample } from 'utils/experimentPredicates';
import { getIsUnisample } from 'utils/experimentPredicates';
import PlotLegendAlert, { MAX_LEGEND_ITEMS } from 'components/plots/helpers/PlotLegendAlert';
import CalculationConfig from './CalculationConfig';

Expand All @@ -33,9 +33,14 @@ const DataIntegration = (props) => {
const {
experimentId, onConfigChange, stepDisabled, stepHadErrors, disableDataIntegration,
} = props;
const [selectedPlot, setSelectedPlot] = useState('embedding');
const [plot, setPlot] = useState(null);

const cellSets = useSelector(getCellSets());

const isUnisample = useMemo(() => getIsUnisample(cellSets.hierarchy));

const [selectedPlot, setSelectedPlot] = useState(isUnisample ? 'elbow' : 'embedding');
const [plot, setPlot] = useState(null);

const filterName = 'dataIntegration';
const configureEmbeddingFilterName = 'configureEmbedding';

Expand Down Expand Up @@ -275,7 +280,7 @@ const DataIntegration = (props) => {
);
}

if ((selectedPlot === 'embedding' || selectedPlot === 'frequency') && cellSets.accessible && isUnisample(cellSets.hierarchy)
if ((selectedPlot === 'embedding' || selectedPlot === 'frequency') && cellSets.accessible && isUnisample
) {
return (
<center>
Expand Down
4 changes: 2 additions & 2 deletions src/utils/experimentPredicates.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const isUnisample = (hierarchy) => hierarchy.find((rootNode) => rootNode.key === 'sample')?.children?.length === 1;
const getIsUnisample = (hierarchy) => hierarchy.find((rootNode) => rootNode.key === 'sample')?.children?.length === 1;

// eslint-disable-next-line import/prefer-default-export
export { isUnisample };
export { getIsUnisample };

0 comments on commit 2ac56d0

Please sign in to comment.