Skip to content

Commit

Permalink
Merge pull request #263 from microbiomedata/display-result-with-pagin…
Browse files Browse the repository at this point in the history
…ation-datatable

Display result with pagination datatable
  • Loading branch information
yxu-lanl authored Jul 18, 2024
2 parents b6c5951 + 92cbb8c commit 19bbaba
Show file tree
Hide file tree
Showing 18 changed files with 920 additions and 323 deletions.
42 changes: 42 additions & 0 deletions webapp/client/src/common/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,46 @@ export const userTypeColors= {
export const userTypeNames= {
'user': 'User',
'admin': 'Admin',
};

export const handleTableNumberFilter = (term, dataIn) => {
const data = Number(dataIn);
//remove spaces
term = term.replace(/\s+/, '');
if (term.match(/^>\d/)) {
const value = Number(term.replace(/^>/, ''));
return data > value
? true
: false;
}
if (term.match(/^>=\d/)) {
const value = Number(term.replace(/^>=/, ''));
console.log(term, value, data)
return data >= value
? true
: false;
}
if (term.match(/^<\d/)) {
const value = Number(term.replace(/^</, ''));
return data < value
? true
: false;
}
if (term.match(/^<=\d/)) {
const value = Number(term.replace(/^<=/, ''));
return data <= value
? true
: false;
}
if (term.match(/^=\d/)) {
const value = Number(term.replace(/^=/, ''));
return data === value
? true
: false;
}

return dataIn.toLowerCase().includes(term.toLowerCase())
? true
: false;

};
102 changes: 102 additions & 0 deletions webapp/client/src/pipelines/MetaT/Workflow/Results/Annotation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import React, { useEffect, useState } from 'react';
import { Card, CardBody, Collapse } from 'reactstrap';
import { JsonTable, StatsTable } from '../../../../common/Tables';
import { Header } from '../../../Common/Results/CardHeader';

function Annotation(props) {
const [collapseCard, setCollapseCard] = useState(true);
const [seqStatsData, setSeqStatsData] = useState([]);
const [seqStatsHeaders, setSeqStatsHeaders] = useState([]);
const [seqOpen, setSeqOpen] = useState(true);
const [geneStatsData, setGeneStatsData] = useState([]);
const [geneStatsHeaders, setGeneStatsHeaders] = useState([]);
const [geneOpen, setGeneOpen] = useState(true);
const [infoStats, setInfoStats] = useState({});
const [infoOpen, setInfoOpen] = useState(true);

useEffect(() => {
const stats = props.result;

setInfoStats(stats["General Quality Info"]);

let seqStatsArray = [];
const seqStats = stats["Processed Sequences Statistics"];
Object.keys(seqStats).forEach((type, index) => {
let data = seqStats[type];
data = { 'Data type': type, ...data };
seqStatsArray.push(data);
});

setSeqStatsData(seqStatsArray);
setSeqStatsHeaders(Object.keys(seqStatsArray[0]));

let geneStatsArray = [];
const geneStats = stats["Predicted Genes Statistics"];
Object.keys(geneStats).forEach((feature, index) => {
let array = geneStats[feature];
let i = 0;
for (i = 0; i < array.length; i++) {
let mystats = array[i];
let method = Object.keys(mystats)[0];
let data = mystats[method];
data = { 'Feature type': feature, 'Prediction method': method, ...data };
geneStatsArray.push(data);
}
});

setGeneStatsData(geneStatsArray);
setGeneStatsHeaders(Object.keys(geneStatsArray[0]));

}, [props.result]);

const toggleCard = () => {
setCollapseCard(!collapseCard);
}

useEffect(() => {
if (props.allExpand > 0) {
setCollapseCard(false);
}
}, [props.allExpand]);

useEffect(() => {
if (props.allClosed > 0) {
setCollapseCard(true);
}
}, [props.allClosed]);

return (
<Card className='workflow-result-card'>
<Header toggle={true} toggleParms={toggleCard} title={props.title} collapseParms={collapseCard} />
<Collapse isOpen={!collapseCard} >
<CardBody>
<br></br>
<span className="edge-link-large" onClick={() => setSeqOpen(!seqOpen)}>Processed Sequences Statistics</span>
<br></br><br></br>
{seqOpen && <>
<JsonTable data={seqStatsData} headers={seqStatsHeaders} />
<br></br>
</>
}
<span className="edge-link-large" onClick={() => setGeneOpen(!geneOpen)}>Predicted Genes Statistics</span>
<br></br><br></br>
{geneOpen && <>
<JsonTable data={geneStatsData} headers={geneStatsHeaders} />
<br></br>
</>
}
<span className="edge-link-large" onClick={() => setInfoOpen(!infoOpen)}>General Quality Info</span>
<br></br><br></br>
{infoOpen && <>
<StatsTable data={infoStats} headers={["Name", "Status"]} />
<br></br>
</>
}
</CardBody>
</Collapse>
</Card>

);
}

export default Annotation;
40 changes: 40 additions & 0 deletions webapp/client/src/pipelines/MetaT/Workflow/Results/Assembly.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { useEffect, useState } from 'react';
import { Card, CardBody, Collapse } from 'reactstrap';
import { StatsTable } from '../../../../common/Tables';
import { Header } from '../../../Common/Results/CardHeader';

function Assembly(props) {
const [collapseCard, setCollapseCard] = useState(true);

const toggleCard = () => {
setCollapseCard(!collapseCard);
}

useEffect(() => {
if (props.allExpand > 0) {
setCollapseCard(false);
}
}, [props.allExpand]);

useEffect(() => {
if (props.allClosed > 0) {
setCollapseCard(true);
}
}, [props.allClosed]);

return (

<Card className='workflow-result-card'>
<Header toggle={true} toggleParms={toggleCard} title={props.title} collapseParms={collapseCard} />
<Collapse isOpen={!collapseCard} >
<CardBody>
<br></br>
<StatsTable data={props.result} headers={["Name", "Status"]} />
</CardBody>
</Collapse>
</Card>

);
}

export default Assembly;
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { useEffect, useState } from 'react';
import MaterialTable from "material-table";
import { MuiThemeProvider } from '@material-ui/core';
import { tableIcons, theme, handleTableNumberFilter } from '../../../../common/table';

function FeaturesTable(props) {
const [featureData, setFeatureData] = useState([]);

const featureColumns = [
{
title: 'seqid', field: 'seqid',
},
{
title: 'featuretype', field: 'featuretype',
},
{
title: 'start', field: 'start',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['start']),
},
{
title: 'end', field: 'end',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['end']),
},
{
title: 'length', field: 'length',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['length']),
},
{
title: 'strand', field: 'strand',
},
{
title: 'product', field: 'product',
},
{
title: 'read_count', field: 'read_count',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['read_count']),
},
{
title: 'rpkm', field: 'rpkm',
},
{
title: 'id', field: 'id', hidden: true
},
{
title: 'source', field: 'source', hidden: true
},
{
title: 'cog', field: 'Cog', hidden: true
},
{
title: 'pfam', field: 'pfam', hidden: true
},
{
title: 'ko', field: 'ko', hidden: true
},
{
title: 'ec_number', field: 'ec_number', hidden: true
},
];
//componentDidMount()
useEffect(() => {
setFeatureData(props.data);
}, [props.data]);

return (
<>
<MuiThemeProvider theme={theme}>
<MaterialTable
title="features"
columns={featureColumns}
icons={tableIcons}
data={featureData}
options={{
exportButton: false,
exportFileName: 'metaT_features',
columnsButton: true,
grouping: false,
search: true,
filtering: true,
paging: true,
pageSize: 10,
pageSizeOptions: [10, 20, 50, 100],
emptyRowsWhenPaging: false,
showTitle: false,
}}
/>
</MuiThemeProvider>
<br></br><br></br>
</>

);
}

export default FeaturesTable;
88 changes: 88 additions & 0 deletions webapp/client/src/pipelines/MetaT/Workflow/Results/MapBackTable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useEffect, useState } from 'react';
import MaterialTable from "material-table";
import { MuiThemeProvider } from '@material-ui/core';
import { tableIcons, theme, handleTableNumberFilter } from '../../../../common/table';

function MapBackTable(props) {
const [featureData, setFeatureData] = useState([]);

const featureColumns = [
{
title: 'ID', field: '#ID',
},
{
title: 'Avg_fold', field: 'Avg_fold',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Avg_fold']),
},
{
title: 'Length', field: 'Length',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Length']),
},
{
title: 'Ref_GC', field: 'Ref_GC',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Ref_GC']),
},
{
title: 'Covered_percent', field: 'Covered_percent',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Covered_percent']),
},
{
title: 'Covered_bases', field: 'Covered_bases',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Covered_bases']),
},
{
title: 'Plus_reads', field: 'Plus_reads',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Plus_reads']),
},
{
title: 'Minus_reads', field: 'Minus_reads',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Minus_reads']),
},
{
title: 'Read_GC', field: 'Read_GC',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Read_GC']),
},
{
title: 'Median_fold', field: 'Median_fold',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Median_fold']),
},
{
title: 'Std_Dev', field: 'Std_Dev',
customFilterAndSearch: (term, rowData) => handleTableNumberFilter(term, rowData['Std_Dev']),
},
];
//componentDidMount()
useEffect(() => {
setFeatureData(props.data);
}, [props.data]);

return (
<>
<MuiThemeProvider theme={theme}>
<MaterialTable
title="MapBack"
columns={featureColumns}
icons={tableIcons}
data={featureData}
options={{
exportButton: false,
exportFileName: 'metaT_MapBack',
columnsButton: true,
grouping: false,
search: true,
filtering: true,
paging: true,
pageSize: 10,
pageSizeOptions: [10, 20, 50, 100],
emptyRowsWhenPaging: false,
showTitle: false,
}}
/>
</MuiThemeProvider>
<br></br><br></br>
</>

);
}

export default MapBackTable;
Loading

0 comments on commit 19bbaba

Please sign in to comment.