Skip to content

Commit

Permalink
Implement Conformation Errors graphs based on resolution and time
Browse files Browse the repository at this point in the history
Two new components, ConformationErrorsVsResolution and ConformationErrorsVsYear are added to visualize conformational anomalies. They include state management and PDB toggle functionalities to enhance user interaction. These implementations provide additional analytical depth into the datasets.

Signed-off-by: Jordan Dialpuri <44945647+Dialpuri@users.noreply.github.com>
  • Loading branch information
Dialpuri committed Jan 20, 2024
1 parent 2952758 commit 0268a11
Show file tree
Hide file tree
Showing 7 changed files with 434 additions and 17 deletions.
189 changes: 189 additions & 0 deletions webapp/src/statistics/Graphs/ConformationErrorsVsYear.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
import React, { useEffect, useState } from 'react';
import Loading from '../../shared/Loading/Loading.tsx';
import Plot from 'react-plotly.js';

export default function ConformationErrorsVsYear(props: { database: string }) {
const [totalTrace, setTotalTrace] = useState();
const [errorTrace, setErrorTrace] = useState();
const [relativeTrace, setRelativeTrace] = useState();

Check warning on line 8 in webapp/src/statistics/Graphs/ConformationErrorsVsYear.tsx

View workflow job for this annotation

GitHub Actions / build

'relativeTrace' is assigned a value but never used. Allowed unused vars must match /^_/u

// const [depositedTrace, setDepositedTrace] = useState();
const d = new Date();

const [data, setData] = useState<Record<
string,
Record<string, Record<string, number>>
> | null>(null);

const [width, setWidth] = useState(1000);
const [height, setHeight] = useState(1000);
const [legendDown, setLegendDown] = useState(false);

useEffect(() => {
const url =
'https://raw.githubusercontent.com/Dialpuri/PrivateerDatabase/master/stats/conformational_errors_per_year.json';

fetch(url)
.then(async (response) => await response.json())
.then((data) => {
setData(
data as Record<
string,
Record<string, Record<string, number>>
>
);
})
.catch((error) => {
console.error('Error:', error);
});

function handleResize() {
const currentWidth = window.innerWidth;

if (currentWidth < 1000) {
setWidth(0.75 * currentWidth);
setHeight(600);
setLegendDown(true);
} else {
setWidth(Math.max(0.75 * currentWidth, 1000));
setHeight(0.5 * Math.max(0.75 * currentWidth, 1000));

setLegendDown(false);
}
}

window.addEventListener('resize', handleResize);
handleResize();
}, []);

useEffect(() => {
if (data === null) return;
const newTotalTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return e.totalChair + e.totalNonChair;
}),
type: 'scatter',
mode: 'lines',
// marker: {color: 'red'},
name: 'Total Sugars',
};

setTotalTrace(newTotalTrace);

const newErrorTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return e.totalNonChair;
}),
type: 'scatter',
mode: 'lines',
// marker: {color: 'green'},
name: 'Non Chair Sugars',
};

setErrorTrace(newErrorTrace);

const newRelativeTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return (100 * e.totalErrors) / e.totalGlycans;
}),
type: 'scatter',
mode: 'lines',
yaxis: 'y2',
// marker: {color: 'green'},
name: 'Relative Validation Errors ',
};

setRelativeTrace(newRelativeTrace);
}, [data, props.database]);

return (
<>
{data === null ? (
<Loading loadingText={'Crunching latest data...'} />
) : (
<Plot
data={[
totalTrace,
errorTrace,
// relativeTrace
]}
layout={{
autosize: true,
width,
height,
title: {
text: `Conformational Anomalies in ${
props.database === 'pdbredo'
? 'PDB-REDO'
: 'the PDB'
} over time`,
x: 0.5,
// y: 1.1,
xanchor: 'auto', // or 'auto', which matches 'left' in this case
yanchor: 'bottom',
xref: 'paper',
yref: 'paper',
},
plot_bgcolor: '#FFFFFF',
paper_bgcolor: 'rgba(0,0,0,0)',
modebar: {
bgcolor: 'rgba(0,0,0,0)',
color: 'gray',
activecolor: 'black',
},
yaxis: {
title: {
text: 'Number',
},
tickformat: ',.0f',
linewidth: 2,
mirror: true,
automargin: true,
ticksuffix: ' ',
tickprefix: ' ',
range: [-50, 35000],
},
yaxis2: {
overlaying: 'y',
tickformat: ',.0f',
tickmode: 'auto',
// anchor: 'free',
side: 'right',
automargin: true,
tickprefix: ' ',
range: [0, 100],
},
xaxis: {
title: {
text: 'Year',
},
linecolor: 'black',
linewidth: 2,
mirror: true,
tickmode: 'auto',
range: [1980, d.getFullYear()],
},

legend: {
x: legendDown ? 0 : 1.15,
y: legendDown ? -0.6 : 0.5,
// bgcolor: '#FFFFFF',
},
}}
config={{
toImageButtonOptions: {
format: 'svg',
filename: 'validationErrorsOverTime',
height: 1000,
width: 1500,
scale: 1,
},
}}
/>
)}
</>
);
}
191 changes: 191 additions & 0 deletions webapp/src/statistics/Graphs/ConformationalErrorsVsResolution.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
import React, { lazy, useEffect, useState } from 'react';

Check warning on line 1 in webapp/src/statistics/Graphs/ConformationalErrorsVsResolution.tsx

View workflow job for this annotation

GitHub Actions / build

'lazy' is defined but never used. Allowed unused vars must match /^_/u
import Loading from '../../shared/Loading/Loading.tsx';
import Plot from 'react-plotly.js';

export default function ConformationalErrorsVsResolution(props: {
database: string;
}) {
const [totalTrace, setTotalTrace] = useState();
const [errorTrace, setErrorTrace] = useState();
const [relativeTrace, setRelativeTrace] = useState();

Check warning on line 10 in webapp/src/statistics/Graphs/ConformationalErrorsVsResolution.tsx

View workflow job for this annotation

GitHub Actions / build

'relativeTrace' is assigned a value but never used. Allowed unused vars must match /^_/u

// const [depositedTrace, setDepositedTrace] = useState();

const [data, setData] = useState<Record<
string,
Record<string, Record<string, number>>
> | null>(null);

const [width, setWidth] = useState(1000);
const [height, setHeight] = useState(1000);
const [legendDown, setLegendDown] = useState(false);

useEffect(() => {
const url =
'https://raw.githubusercontent.com/Dialpuri/PrivateerDatabase/master/stats/conformational_errors_per_resolution.json';

fetch(url)
.then(async (response) => await response.json())
.then((data) => {
setData(
data as Record<
string,
Record<string, Record<string, number>>
>
);
})
.catch((error) => {
console.error('Error:', error);
});

function handleResize() {
const currentWidth = window.innerWidth;

if (currentWidth < 1000) {
setWidth(0.75 * currentWidth);
setHeight(600);
setLegendDown(true);
} else {
setWidth(Math.max(0.75 * currentWidth, 1000));
setHeight(0.5 * Math.max(0.75 * currentWidth, 1000));

setLegendDown(false);
}
}

window.addEventListener('resize', handleResize);
handleResize();
}, []);

useEffect(() => {
if (data === null) return;
const newTotalTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return e.totalChair + e.totalNonChair;
}),
type: 'scatter',
mode: 'lines',
// marker: {color: 'red'},
name: 'Total Sugars',
};

setTotalTrace(newTotalTrace);

const newErrorTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return e.totalNonChair;
}),
type: 'scatter',
mode: 'lines',
// marker: {color: 'green'},
name: 'Total Non-chair Sugars',
};

setErrorTrace(newErrorTrace);

const newRelativeTrace = {
x: Object.keys(data[props.database]),
y: Object.values(data[props.database]).map((e) => {
return (100 * e.totalErrors) / e.totalGlyco;
}),
type: 'scatter',
mode: 'lines',
// marker: {color: 'green'},
yaxis: 'y2',
name: 'Validation Errors',
};

setRelativeTrace(newRelativeTrace);
}, [data, props.database]);

return (
<>
{data === null ? (
<Loading loadingText={'Crunching latest data...'} />
) : (
<Plot
data={[
totalTrace,
errorTrace,
// relativeTrace
]}
layout={{
autosize: true,
width,
height,
title: {
text: `Conformational Anomalies in ${
props.database === 'pdbredo'
? 'PDB-REDO'
: 'the PDB'
} with resolution`,
x: 0.5,
// y: 1.1,
xanchor: 'auto', // or 'auto', which matches 'left' in this case
yanchor: 'bottom',
xref: 'paper',
yref: 'paper',
},
plot_bgcolor: '#FFFFFF',
paper_bgcolor: 'rgba(0,0,0,0)',
modebar: {
bgcolor: 'rgba(0,0,0,0)',
color: 'gray',
activecolor: 'black',
},
yaxis: {
title: {
text: 'Number',
},
tickformat: ',.0f',
linewidth: 2,
mirror: true,
automargin: true,
ticksuffix: ' ',
tickprefix: ' ',
range: [-50, 14000],
// type: 'log'
},
yaxis2: {
overlaying: 'y',
tickformat: ',.0f',
tickmode: 'auto',
// anchor: 'free',
side: 'right',
automargin: true,
tickprefix: ' ',
range: [0, 100],
},
xaxis: {
title: {
text: 'Resolution / Å',
},
linecolor: 'black',
linewidth: 2,
mirror: true,
tickmode: 'auto',
range: [0, 5],
},

legend: {
x: legendDown ? 0 : 1.15,
y: legendDown ? -0.6 : 0.5,
// bgcolor: '#FFFFFF',
},
}}
config={{
toImageButtonOptions: {
format: 'svg',
filename: 'validationErrorsWithResolution',
height: 1000,
width: 1500,
scale: 1,
},
}}
/>
)}
</>
);
}
2 changes: 1 addition & 1 deletion webapp/src/statistics/Graphs/ErrorsVsResolution.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export default function ErrorsVsResolution(props: { database: string }) {
modebar: {
bgcolor: 'rgba(0,0,0,0)',
color: 'gray',
activecolor: 'black'
activecolor: 'black',
},
yaxis: {
title: {
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/statistics/Graphs/ErrorsVsYear.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export default function ErrorsVsYear(props: { database: string }) {
modebar: {
bgcolor: 'rgba(0,0,0,0)',
color: 'gray',
activecolor: 'black'
activecolor: 'black',
},
yaxis: {
title: {
Expand Down
Loading

0 comments on commit 0268a11

Please sign in to comment.