From 542e3fb4630e0030382b9bd2d254c065b153c25e Mon Sep 17 00:00:00 2001 From: Sanjeev Lakhwani Date: Mon, 24 Jul 2023 13:36:10 -0400 Subject: [PATCH] code refactor --- src/components/charts/CustomPieChart.js | 80 ++++----- src/components/charts/Histogram.js | 37 ++-- src/components/overview/ClinicalSummary.js | 32 +--- src/components/overview/ExperimentsSummary.js | 166 ++++++++---------- 4 files changed, 136 insertions(+), 179 deletions(-) diff --git a/src/components/charts/CustomPieChart.js b/src/components/charts/CustomPieChart.js index 45c8e6845..4b678e4e6 100644 --- a/src/components/charts/CustomPieChart.js +++ b/src/components/charts/CustomPieChart.js @@ -1,69 +1,57 @@ -import React from "react"; +import React, { useCallback } from "react"; import PropTypes from "prop-types"; import { useHistory } from "react-router-dom"; import { PieChart } from "bento-charts"; - import { Empty } from "antd"; -const titleStyle = { - fontStyle: "italic", - padding: "0", - marginBottom: "-15px", -}; - const CustomPieChart = ({ title, - data, - chartHeight, - setAutoQueryPageTransition, - autoQueryDataType, - fieldLabel, - sort = true, + data = [], + chartHeight = 300, + onAutoQueryTransition, + dataType, + labelKey, + sortData = true, }) => { const history = useHistory(); - const onClick = (data) => { - if (!setAutoQueryPageTransition || data.skipAutoquery) { - return; - } - console.log("data", data); - setAutoQueryPageTransition(window.location.href, autoQueryDataType, fieldLabel, data.name); + const handleChartClick = useCallback( + (pointData) => { + if (!onAutoQueryTransition || pointData.skipAutoquery) return; - // Navigate to Explorer - history.push("/data/explorer/search"); - }; + onAutoQueryTransition(window.location.href, dataType, labelKey, pointData.name); + history.push("/data/explorer/search"); + }, + [onAutoQueryTransition, dataType, labelKey, history] + ); - if (!data || data.length === 0) { - return ; + if (!data.length) { + return ; } + const pieChartData = data.map(({ name, value }) => ({ x: name, y: value })); + return ( - <> -
-

{title}

- ({ x: name, y: value }))} - height={chartHeight} - onClick={onClick} - sort={sort} - /> -
- +
+

{title}

+ +
); }; CustomPieChart.propTypes = { - title: PropTypes.string, - data: PropTypes.array, + title: PropTypes.string.isRequired, + data: PropTypes.arrayOf( + PropTypes.shape({ + name: PropTypes.string, + value: PropTypes.number, + }) + ), chartHeight: PropTypes.number, - setAutoQueryPageTransition: PropTypes.func, - autoQueryDataType: PropTypes.string, - sort: PropTypes.bool, - fieldLabel: PropTypes.string, + onAutoQueryTransition: PropTypes.func, + dataType: PropTypes.string, + labelKey: PropTypes.string, + sortData: PropTypes.bool, }; export default CustomPieChart; diff --git a/src/components/charts/Histogram.js b/src/components/charts/Histogram.js index fae91bee0..d68bea623 100644 --- a/src/components/charts/Histogram.js +++ b/src/components/charts/Histogram.js @@ -3,43 +3,36 @@ import PropTypes from "prop-types"; import { Empty } from "antd"; import { BarChart } from "bento-charts"; -const titleStyle = { +const TITLE_STYLE = { fontStyle: "italic", padding: "0", marginBottom: "-15px", }; -const titleHeaderHeight = 31; +const Histogram = ({ title = "Histogram", data = [], chartHeight = 300 }) => { + const transformedData = useMemo(() => transformData(data), [data]); + + if (!transformedData.length) { + return ; + } -const Histogram = ({ title, data, chartHeight, chartAspectRatio }) => { - data = data.map(({ ageBin, count }) => ({ x: ageBin, y: count })); return (
-

{title}

- {data.length !== 0 ? ( - - ) : ( -
- -
- )} +

{title}

+
); }; Histogram.propTypes = { title: PropTypes.string, - data: PropTypes.array, + data: PropTypes.arrayOf( + PropTypes.shape({ + ageBin: PropTypes.string, + count: PropTypes.number, + }) + ), chartHeight: PropTypes.number, - chartAspectRatio: PropTypes.number, }; export default Histogram; diff --git a/src/components/overview/ClinicalSummary.js b/src/components/overview/ClinicalSummary.js index 85928a66a..e808e1708 100644 --- a/src/components/overview/ClinicalSummary.js +++ b/src/components/overview/ClinicalSummary.js @@ -15,9 +15,7 @@ const ClinicalSummary = () => { dispatch(setAutoQueryPageTransition(priorPageUrl, type, field, value)); const { data, isFetching } = useSelector((state) => state.overviewSummary); - const otherThresholdPercentage = useSelector( - (state) => state.explorer.otherThresholdPercentage, - ); + const otherThresholdPercentage = useSelector((state) => state.explorer.otherThresholdPercentage); const statistics = [ { @@ -45,19 +43,13 @@ const ClinicalSummary = () => { const charts = [ { title: "Individuals", - data: mapNameValueFields( - data.data_type_specific?.individuals?.sex, - -1, - ), + data: mapNameValueFields(data.data_type_specific?.individuals?.sex, -1), fieldLabel: "[dataset item].subject.sex", type: "PIE", }, { title: "Diseases", - data: mapNameValueFields( - data.data_type_specific?.diseases?.term, - otherThresholdPercentage / 100, - ), + data: mapNameValueFields(data.data_type_specific?.diseases?.term, otherThresholdPercentage / 100), fieldLabel: "[dataset item].diseases.[item].term.label", type: "PIE", }, @@ -70,7 +62,7 @@ const ClinicalSummary = () => { title: "Biosamples", data: mapNameValueFields( data.data_type_specific?.biosamples?.sampled_tissue, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ), fieldLabel: "[dataset item].biosamples.[item].sampled_tissue.label", type: "PIE", @@ -79,7 +71,7 @@ const ClinicalSummary = () => { title: "Phenotypic Features", data: mapNameValueFields( data.data_type_specific?.phenotypic_features?.type, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ), fieldLabel: "[dataset item].phenotypic_features.[item].type.label", type: "PIE", @@ -91,9 +83,7 @@ const ClinicalSummary = () => { return ( <> - - Clinical/Phenotypic Data - + Clinical/Phenotypic Data {statistics.map((s, i) => ( @@ -115,13 +105,9 @@ const ClinicalSummary = () => { data={c.data} chartHeight={chartHeight} chartAspectRatio={chartAspectRatio} - fieldLabel={c.fieldLabel} - setAutoQueryPageTransition={ - setAutoQueryPageTransitionFunc - } - autoQueryDataType={ - autoQueryDataType - } + labelKey={c.fieldLabel} + onAutoQueryTransition={setAutoQueryPageTransitionFunc} + dataType={autoQueryDataType} /> ) : ( ({ +const mapStateToProps = (state) => ({ overviewSummary: state.overviewSummary, otherThresholdPercentage: state.explorer.otherThresholdPercentage, }); @@ -19,7 +17,6 @@ const actionCreators = { }; class ExperimentsSummary2 extends Component { - static propTypes = { overviewSummary: PropTypes.shape({ isFetching: PropTypes.bool, @@ -32,163 +29,156 @@ class ExperimentsSummary2 extends Component { constructor(props) { super(props); this.state = { - chartPadding: "1rem", + chartPadding: "1rem", chartHeight: 300, - chartAspectRatio: 1.8, chartLabelPaddingTop: 3, chartLabelPaddingLeft: 3, }; } render() { - const {overviewSummary, otherThresholdPercentage} = this.props; - const {data, isFetching} = overviewSummary; + const { overviewSummary, otherThresholdPercentage } = this.props; + const { data, isFetching } = overviewSummary; // TODO: most of these have "other" categories, so counts here are ambiguous or simply incorrect const numExperiments = overviewSummary.data?.data_type_specific?.experiments?.count; const numExperimentTypes = Object.keys( - overviewSummary.data?.data_type_specific?.experiments?.experiment_type || {}, + overviewSummary.data?.data_type_specific?.experiments?.experiment_type || {} ).length; const numMoleculesUsed = Object.keys( - overviewSummary.data?.data_type_specific?.experiments?.molecule || {}, + overviewSummary.data?.data_type_specific?.experiments?.molecule || {} ).length; const numLibraryStrategies = Object.keys( - overviewSummary.data?.data_type_specific?.experiments?.library_strategy || {}, + overviewSummary.data?.data_type_specific?.experiments?.library_strategy || {} ).length; // extract data in pie chart format const experimentTypeData = mapNameValueFields( data.data_type_specific?.experiments?.experiment_type, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ); const studyTypeData = mapNameValueFields( data.data_type_specific?.experiments?.study_type, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ); const moleculeData = mapNameValueFields( data.data_type_specific?.experiments?.molecule, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ); const libraryStrategyData = mapNameValueFields( data.data_type_specific?.experiments?.library_strategy, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ); const librarySelectionData = mapNameValueFields( data.data_type_specific?.experiments?.library_selection, - otherThresholdPercentage / 100, + otherThresholdPercentage / 100 ); const autoQueryDataType = "experiment"; - const pieRowStyle = {display: "flex", flexWrap: "wrap"}; + const pieRowStyle = { display: "flex", flexWrap: "wrap" }; - return <> - - - Experiments - - - - - - - - - - - - - - - - - - - - - - - - - + return ( + <> + + Experiments + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + - + - + + - - ; + + ); } } export default connect(mapStateToProps, actionCreators)(ExperimentsSummary2); - -