Skip to content

Commit

Permalink
Merge pull request #133 from kbase/hist_scatter
Browse files Browse the repository at this point in the history
RE2022-278 RE2022-280 add basic histogram and scatter
  • Loading branch information
dakotablair authored Mar 4, 2024
2 parents 75ba40d + 944ac35 commit f668cc9
Show file tree
Hide file tree
Showing 8 changed files with 4,702 additions and 4,778 deletions.
9,101 changes: 4,327 additions & 4,774 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,24 @@
"@types/dompurify": "^3.0.0",
"@types/leaflet": "^1.9.3",
"@types/marked": "^4.0.8",
"@types/plotly.js": "^2.12.30",
"@types/react-plotly.js": "^2.6.3",
"ajv": "^8.12.0",
"canvas": "^2.11.2",
"d3-zoom": "^3.0.0",
"dompurify": "^3.0.1",
"downsample-lttb-ts": "^0.0.6",
"jest-fetch-mock": "^3.0.3",
"leaflet": "^1.9.4",
"marked": "^4.2.12",
"node-sass": "^9.0.0",
"plotly.js": "^2.27.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-boundary": "^3.1.4",
"react-hook-form": "^7.47.0",
"react-hot-toast": "^2.4.1",
"react-plotly.js": "^2.6.0",
"react-popper": "^2.3.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.11.1",
Expand Down
58 changes: 58 additions & 0 deletions src/common/api/collectionsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,15 @@ interface CollectionsResults {
data?: null;
count?: number;
};
getAttribHistogram: {
bins: number[];
values: number[];
};
getAttribScatter: {
xcolumn: string;
ycolumn: string;
data: { x: number; y: number }[];
};
getGenomeAttribsMeta: {
count: number;
columns: Array<ColumnMeta>;
Expand Down Expand Up @@ -377,6 +386,23 @@ interface CollectionsParams {
collection_id: Collection['id'];
load_ver_override?: Collection['ver_tag'];
};
getAttribHistogram: {
collection_id: Collection['id'];
column: string;
match_id?: Match['match_id'];
selection_id?: Selection['selection_id'];
load_ver_override?: Collection['ver_tag'];
filters?: Record<string, string>;
};
getAttribScatter: {
collection_id: Collection['id'];
xcolumn: string;
ycolumn: string;
match_id?: Match['match_id'];
selection_id?: Selection['selection_id'];
load_ver_override?: Collection['ver_tag'];
filters?: Record<string, string>;
};
getMicroTrait: {
collection_id: Collection['id'];
start_after?: KBaseId;
Expand Down Expand Up @@ -683,6 +709,36 @@ export const collectionsApi = baseApi.injectEndpoints({
}),
}),

getAttribHistogram: builder.query<
CollectionsResults['getAttribHistogram'],
CollectionsParams['getAttribHistogram']
>({
query: ({ collection_id, ...options }) =>
collectionsService({
method: 'GET',
url: encode`/collections/${collection_id}/data_products/genome_attribs/hist`,
params: options,
headers: {
authorization: `Bearer ${store.getState().auth.token}`,
},
}),
}),

getAttribScatter: builder.query<
CollectionsResults['getAttribScatter'],
CollectionsParams['getAttribScatter']
>({
query: ({ collection_id, ...options }) =>
collectionsService({
method: 'GET',
url: encode`/collections/${collection_id}/data_products/genome_attribs/scatter`,
params: options,
headers: {
authorization: `Bearer ${store.getState().auth.token}`,
},
}),
}),

getMicroTrait: builder.query<
CollectionsResults['getMicroTrait'],
CollectionsParams['getMicroTrait']
Expand Down Expand Up @@ -876,6 +932,8 @@ export const {
listTaxaCountRanks,
getTaxaCountRank,
getGenomeAttribs,
getAttribHistogram,
getAttribScatter,
getGenomeAttribsMeta,
getMicroTrait,
getMicroTraitMeta,
Expand Down
39 changes: 37 additions & 2 deletions src/common/components/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { faSpinner } from '@fortawesome/free-solid-svg-icons';
import {
faExclamationCircle,
faSpinner,
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Box, Chip, Stack } from '@mui/material';

/**
* Component for rendering loading states
Expand All @@ -13,8 +17,29 @@ export const Loader = (props: {
children?: React.ReactNode | React.ReactNode[];
/** Overrides the loader style to render a custom loader*/
render?: React.ReactNode | React.ReactNode[];
size?: [width: string, height: string];
error?: string;
}) => {
if (props.loading ?? true) {
const isLoading = props.loading ?? true;
if (props.size && (isLoading || props.error)) {
const {
size: [width, height],
...forwardProps
} = props;
return (
<Box sx={{ width, height, position: 'relative' }}>
<Stack
direction="row"
justifyContent="center"
alignItems="center"
sx={{ width: 1, height: '100%' }}
>
<Loader {...forwardProps} />
</Stack>
</Box>
);
}
if (isLoading) {
if (props.render !== undefined) return <>{props.render}</>;
switch (props.type) {
case 'text':
Expand All @@ -23,6 +48,16 @@ export const Loader = (props: {
default:
return <FontAwesomeIcon icon={faSpinner} spin />;
}
}
if (props.error) {
return (
<Chip
icon={<FontAwesomeIcon icon={faExclamationCircle} />}
variant="outlined"
color="error"
label={props.error}
/>
);
} else {
return <>{props.children}</>;
}
Expand Down
59 changes: 59 additions & 0 deletions src/features/collections/data_products/AttribHistogram.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ComponentProps, useMemo } from 'react';
import Plot from 'react-plotly.js';
import { getAttribHistogram } from '../../../common/api/collectionsApi';
import { parseError } from '../../../common/api/utils/parseError';
import { Loader } from '../../../common/components/Loader';
import { useFilters } from '../collectionsSlice';
import { useTableViewParams } from './GenomeAttribs';

export const AttribHistogram = ({
collection_id,
column,
size = [600, 600],
}: {
collection_id: string;
column: string;
size?: [width: number, height: number];
}) => {
const { filterMatch, filterSelection, columnMeta } =
useFilters(collection_id);
const viewParams = useTableViewParams(collection_id, {
filtered: true,
selected: Boolean(filterMatch),
matched: Boolean(filterSelection),
});
const { data, isLoading, error } = getAttribHistogram.useQuery({
...viewParams,
column,
});
const plotData: ComponentProps<typeof Plot>['data'] = useMemo(() => {
if (!data) return [];
const bins = data.bins ?? [];
const values = data.values ?? [];
const binStarts = bins.slice(0, -1);
const binWidths = bins.slice(1).map((end, index) => end - bins[index]);
return [{ type: 'bar', x: binStarts, width: binWidths, y: values }];
}, [data]);
if (plotData && !isLoading && !error) {
return (
<Plot
data={plotData}
layout={{
height: size[1],
width: size[0],
title: column,
xaxis: { title: { text: columnMeta?.[column]?.display_name } },
yaxis: { title: { text: 'Count' } },
}}
/>
);
} else {
return (
<Loader
loading={isLoading}
size={[`${size[0]}px`, `${size[1]}px`]}
error={error ? parseError(error).message : undefined}
/>
);
}
};
Loading

0 comments on commit f668cc9

Please sign in to comment.