Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connects to #369. PASS1AC-06 phenotype data analysis (initial phase). #382

Merged
merged 29 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
17deca7
Convert this component to a parent component with tabs containing chi…
jimmyzhen Dec 19, 2024
44e8ebc
Initial commit of new pass1b pheno data analysis component
jimmyzhen Dec 19, 2024
7b05289
Initial commit of new pass1a-06 pheno data analysis wrapper component
jimmyzhen Dec 19, 2024
88a0c1f
Initial commit of pass1a-06 pheno data analysis box and scatter plot …
jimmyzhen Dec 19, 2024
6054121
Initial commit of pass1a-06 pheno data anaylsis section content wrapp…
jimmyzhen Dec 19, 2024
6cee2dc
Initial commit of pass1a-06 pheno data analysis plot wrapper component
jimmyzhen Dec 19, 2024
1cee2e8
Initial commit of pass1a-06 pheno data analysis plot library of share…
jimmyzhen Dec 19, 2024
656d5a7
Initial commit of pass1a-06 pheno data analysis category menu component
jimmyzhen Dec 19, 2024
923a033
Initial commit of pass1a-06 pheno data analysis wrapper component for…
jimmyzhen Dec 19, 2024
a0ad118
Update styles for pheno data analysis UI changes due to the addition …
jimmyzhen Dec 19, 2024
0ab010c
Add support to show/hide pass1a-06 pheno data analysis plots by category
jimmyzhen Dec 19, 2024
ca4520a
Adjust plot width and remove unused implementation of states
jimmyzhen Dec 19, 2024
0e62094
Adjust plot width
jimmyzhen Dec 19, 2024
7669124
Add category section content component for overall correlation matrix…
jimmyzhen Dec 19, 2024
d979bd8
Initial commit of correlation analyses plot wrapper components
jimmyzhen Dec 19, 2024
15b30ec
Remove implementation for groupi plots
jimmyzhen Dec 19, 2024
644ecec
Import Highcharts heatmap module
jimmyzhen Dec 19, 2024
6c52435
Add handling to disable checkbox if it's the only unchecked checkbox
jimmyzhen Dec 19, 2024
13d3c02
Add base correlation matrix chart options
jimmyzhen Dec 19, 2024
c1230cb
Initial commit of plot component for overall correlation matrix in pa…
jimmyzhen Dec 19, 2024
0dfbb80
Install dependencies
jimmyzhen Dec 19, 2024
69e4566
Merge branch 'dev' of github.com:MoTrPAC/motrpac-frontend into 369_JZ…
jimmyzhen Dec 19, 2024
d4e08dc
Initial commit of mocked pass1a-06 pheno data
jimmyzhen Dec 19, 2024
f797981
Add dependency
jimmyzhen Dec 19, 2024
50c1ccd
Update src/AnalysisPage/Phenotype/Components/Pass1ac-06/SummaryStatis…
jimmyzhen Dec 19, 2024
2233299
Update src/AnalysisPage/Phenotype/Components/Pass1ac-06/SummaryStatis…
jimmyzhen Dec 19, 2024
6227711
Enlarge data label text and remove their outline
jimmyzhen Dec 19, 2024
036acf1
Add release note info
jimmyzhen Dec 19, 2024
d13a7f2
Merge branch '369_JZ_Dawg_Pac_Pheno_Data_Analysis' of github.com:MoTr…
jimmyzhen Dec 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"react-wordcloud": "^1.2.7",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"simple-statistics": "^7.8.7",
"tocbot": "^4.25.0",
"victory": "37.0.2",
"vis-network-react": "DinerIsmail/vis-network-react"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React from 'react';
import { useSelector } from 'react-redux';
import SectionWeightDistribution from './sectionWeightDistribution';
import SectionLactateChange from './sectionLactateChange';
import SectionRatWork from './sectionRatWork';

/**
* Function component for the summary statistics category of PASS1AC-06 phenotypic data analysis
*
* @param {array} phenoData Curated phenotypic data
*
* @returns JSX element of the summary statistics category
*/
function CategorySummaryStatistics() {
const analysisState = useSelector((state) => state.analysis);

return (
<div className="w-100 analysis-category-content-container">
<h2>Summary Statistics</h2>
<p>
In this section, various summary statistics and visualizations that
explore key variables across the phenotypic data are presented. The
analysis covers weight distribution, electric shocks (both number
and duration), distance covered during the acute test, and lactate
changes due to exercise. Each variable is visualized through a
combination of boxplots, histograms, and density plots, broken down
by relevant factors such as sex, phase, and intervention group.
Additionally, we analyze the time taken to freeze tissues, including
comparisons across different groups and a detailed look at the order
in which tissues were frozen for each animal. These visualizations
help to identify patterns and trends within the phenotypic data.
</p>
{/* weight distribution section */}
{analysisState.pass1ac06AnalysisCategoryOptions.summaryStatistics.weight_distribution && (
<SectionWeightDistribution />
)}
{/* lactate change section */}
{analysisState.pass1ac06AnalysisCategoryOptions.summaryStatistics.lactate_change && (
<SectionLactateChange />
)}
{/* rat work section */}
{analysisState.pass1ac06AnalysisCategoryOptions.summaryStatistics.rat_work && (
<SectionRatWork />
)}
</div>
);
}

export default CategorySummaryStatistics;
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, { useMemo } from 'react';
import {
COLORS,
defaultChartOptions,
allBoxPlotDataByPhaseSexIntervention,
allScatterPlotDataByPhaseSex,
} from '../sharedLib';
import Chart from '../chartWrapper';

/**
* Renders summary statistics plots for lactate change
*
* @returns JSX representation of Highcharts plots for rat work - boxplots and scatter plots
*/
function PlotLactateChange() {
// Base chart options
const baseChartOptions = defaultChartOptions('Intervention', 'Lactate Change', 'Lactate Change: {point.y}');

// Function to collect lactate change data for box plot
const getLactateChangeData = (data) => data.map((item) => parseFloat(item.lactate_change));
const boxPlotData = useMemo(() => allBoxPlotDataByPhaseSexIntervention(getLactateChangeData), []);

// Scatter plot data for pass1a and pass1c (both male and female)
const scatterData = useMemo(() => allScatterPlotDataByPhaseSex(getLactateChangeData), []);

// Highcharts options for the plots
const chartOptions = useMemo(() => {
const createChartOptions = (gender, titleText) => {
const allData = [
...boxPlotData[`pass1a${gender}Acute`],
...boxPlotData[`pass1c${gender}Acute`],
...boxPlotData[`pass1a${gender}Control`],
...boxPlotData[`pass1c${gender}Control`],
...scatterData.pass1a[gender.toLowerCase()].map(([, y]) => y),
...scatterData.pass1c[gender.toLowerCase()].map(([, y]) => y),
];

const minValue = Math.min(...allData);
const maxValue = Math.max(...allData);
const padding = 0.1 * (maxValue - minValue);

return {
...baseChartOptions,
title: {
align: 'left',
style: { fontSize: '1.5rem' },
text: titleText,
},
xAxis: {
...baseChartOptions.xAxis,
categories: ['Acute', 'Control'],
},
yAxis: {
...baseChartOptions.yAxis,
min: minValue - padding,
max: maxValue + padding,
},
series: [
{
name: 'PASS1A-06 Lactate Change Distribution',
type: 'boxplot',
legendSymbol: 'areaMarker',
data: [
boxPlotData[`pass1a${gender}Acute`],
boxPlotData[`pass1a${gender}Control`],
],
fillColor: COLORS.pass1a.fill,
},
{
name: 'PASS1C-06 Lactate Change Distribution',
type: 'boxplot',
legendSymbol: 'areaMarker',
data: [
boxPlotData[`pass1c${gender}Acute`],
boxPlotData[`pass1c${gender}Control`],
],
fillColor: COLORS.pass1c.fill,
},
{
name: 'PASS1A-06 Scatter',
type: 'scatter',
data: scatterData.pass1a[gender.toLowerCase()],
color: COLORS.pass1a.scatter,
jitter: { x: 0.1 },
showInLegend: false,
},
{
name: 'PASS1C-06 Scatter',
type: 'scatter',
data: scatterData.pass1c[gender.toLowerCase()],
color: COLORS.pass1c.scatter,
jitter: { x: 0.1 },
showInLegend: false,
},
],
};
};

return {
male: createChartOptions('Male', 'Distribution of LACTATE CHANGE by INTERVENTION and MALE'),
female: createChartOptions('Female', 'Distribution of LACTATE CHANGE by INTERVENTION and FEMALE'),
};
}, [baseChartOptions, boxPlotData, scatterData]);

return (
<div className="col-lg-11 h-90">
<Chart options={chartOptions.male} className="phenotype-plot-container" />
<Chart options={chartOptions.female} className="phenotype-plot-container" />
</div>
);
}

export default PlotLactateChange;
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import React, { useMemo } from 'react';
import {
COLORS,
defaultChartOptions,
allBoxPlotDataByPhaseSexIntervention,
allScatterPlotDataByPhaseSex,
} from '../sharedLib';
import Chart from '../chartWrapper';

/**
* Renders summary statistics plots for rat work
*
* @returns JSX representation of Highcharts plots for rat work - boxplots and scatter plots
*/
function PlotRatWork() {
// Base chart options
const baseChartOptions = defaultChartOptions('Intervention', 'Work', 'Work: {point.y} joules');

// Function to collect lactate change data for box plot
const getRatWorkData = (data) => data.map((item) => {
const weight = parseInt(item.weight, 10) / 1000;
const distance = parseInt(item.distance, 10);
return weight * distance * 0.087 * 9.80665;
});
const boxPlotData = useMemo(() => allBoxPlotDataByPhaseSexIntervention(getRatWorkData), []);

// Scatter plot data for pass1a and pass1c (both male and female)
const scatterData = useMemo(() => allScatterPlotDataByPhaseSex(getRatWorkData), []);

// Highcharts options for the plots
const chartOptions = useMemo(() => {
const createChartOptions = (gender, titleText) => {
const allData = [
...boxPlotData[`pass1a${gender}Acute`],
...boxPlotData[`pass1c${gender}Acute`],
...boxPlotData[`pass1a${gender}Control`],
...boxPlotData[`pass1c${gender}Control`],
...scatterData.pass1a[gender.toLowerCase()].map(([, y]) => y),
...scatterData.pass1c[gender.toLowerCase()].map(([, y]) => y),
];

const minValue = Math.min(...allData);
const maxValue = Math.max(...allData);
const padding = 0.1 * (maxValue - minValue);

return {
...baseChartOptions,
title: {
align: 'left',
style: { fontSize: '1.5rem' },
text: titleText,
},
xAxis: {
...baseChartOptions.xAxis,
categories: ['Acute', 'Control'],
},
yAxis: {
...baseChartOptions.yAxis,
min: minValue - padding,
max: maxValue + padding,
},
series: [
{
name: 'PASS1A-06 Work Distribution',
type: 'boxplot',
legendSymbol: 'areaMarker',
data: [
boxPlotData[`pass1a${gender}Acute`],
boxPlotData[`pass1a${gender}Control`],
],
fillColor: COLORS.pass1a.fill,
},
{
name: 'PASS1C-06 Work Distribution',
type: 'boxplot',
legendSymbol: 'areaMarker',
data: [
boxPlotData[`pass1c${gender}Acute`],
boxPlotData[`pass1c${gender}Control`],
],
fillColor: COLORS.pass1c.fill,
},
{
name: 'PASS1A-06 Scatter',
type: 'scatter',
data: scatterData.pass1a[gender.toLowerCase()],
color: COLORS.pass1a.scatter,
jitter: { x: 0.1 },
showInLegend: false,
},
{
name: 'PASS1C-06 Scatter',
type: 'scatter',
data: scatterData.pass1c[gender.toLowerCase()],
color: COLORS.pass1c.scatter,
jitter: { x: 0.1 },
showInLegend: false,
},
],
};
};

return {
male: createChartOptions('Male', 'Distribution of WORK by INTERVENTION and MALE'),
female: createChartOptions('Female', 'Distribution of WORK by INTERVENTION and FEMALE'),
};
}, [baseChartOptions, boxPlotData, scatterData]);

return (
<div className="col-lg-11 h-90">
<Chart options={chartOptions.male} className="phenotype-plot-container" />
<Chart options={chartOptions.female} className="phenotype-plot-container" />
</div>
);
}

export default PlotRatWork;
Loading
Loading