Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
102 changes: 69 additions & 33 deletions src/components/ForestPlot.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import Help from '@material-ui/icons/Help';
import { pvalThreshold } from '../constants';

function traitFilterOptions(data, selectedCategories) {
let all_categories = _.sortBy(_.uniq(data.map(d => d.traitCategory)), d => d);
// color scale
let colorScale = d3
.scaleOrdinal()
.domain(selectedCategories)
.domain(all_categories)
.range(d3.schemeCategory10);
return _.sortBy(
_.uniq(data.map(d => d.traitCategory)).map(d => {
Expand All @@ -42,7 +43,8 @@ const cfg = {
minBoxSize: 5,
maxBoxSize: 20,
maxPlotHeight: 800,
plotMargin: 100,
top_axis: 27,
bottom_axis: 52,
treeColor: '#5A5F5F',
evenRowColor: '#fff',
unevenRowColor: '#f2f1f1',
Expand Down Expand Up @@ -78,8 +80,9 @@ const ForestPlot = ({
);

const plot_height =
cfg.plotMargin + traits.length * cfg.rowHeight < cfg.maxPlotHeight
? cfg.plotMargin + traits.length * cfg.rowHeight
traits.length * cfg.rowHeight + cfg.top_axis + cfg.bottom_axis <
cfg.maxPlotHeight
? traits.length * cfg.rowHeight + cfg.top_axis + cfg.bottom_axis
: cfg.maxPlotHeight;

// draw the plot
Expand All @@ -104,9 +107,15 @@ const ForestPlot = ({
d3.select('#topRow')
.selectAll('*')
.remove();
d3.select('#topRowTable')
.selectAll('*')
.remove();
d3.select('#bottomRow')
.selectAll('*')
.remove();
d3.select('#table')
.selectAll('*')
.remove();

// get component width
cfg.component_width = d3
Expand All @@ -131,30 +140,42 @@ const ForestPlot = ({
const svg = d3
.select(refs.current)
.attr('width', cfg.svgW)
.attr('height', traits.length * cfg.rowHeight + 3 * cfg.rowHeight)
.attr('height', traits.length * cfg.rowHeight + 2 * cfg.rowHeight)
.style('position', 'absolute')
.style('top', cfg.top_axis)
.append('g');

// set top row svg size and sticky
const topRowSvg = d3
.select('#topRow')
.attr('width', cfg.svgW - 45)
.attr('height', cfg.rowHeight + 5)
.attr('height', cfg.top_axis)
.style('position', 'absolute')
.style('flex-shrink', 0)
.style('flex-grow', 0)
.style('top', '0')
.style('z-index', '2');

// set top row table size and sticky
const topRowTable = d3
.select('#topRowTable')
.attr('width', cfg.tableW)
.attr('height', cfg.top_axis)
.style('position', 'sticky')
.style('top', '0');
.style('flex-shrink', 0)
.style('flex-grow', 0)
.style('left', '0')
.style('z-index', '3');

// set bottom row svg size and sticky
const bottomRowSvg = d3
.select('#bottomRow')
.attr('width', cfg.svgW)
.attr('height', 2 * cfg.rowHeight)
.style('position', 'sticky')
.style(
'top',
plot_height <= 800
? plot_height - 3 * cfg.rowHeight
: plot_height - 2 * cfg.rowHeight
)
.style('flex-shrink', 0)
.style('flex-grow', 0)
.style('top', plot_height - 2 * cfg.rowHeight)
.style('background-color', 'white');

// clip trait name text (row width)
Expand All @@ -166,17 +187,17 @@ const ForestPlot = ({
.attr('width', cfg.traitnameW);

// add top row of table
topRowSvg
topRowTable
.append('g')
.classed('topRow', true)
.classed('topRowTable', true)
.append('rect')
.attr('height', cfg.rowHeight)
.attr('width', cfg.tableW)
.attr('fill', cfg.unevenRowColor);

// trait
topRowSvg
.select('.topRow')
topRowTable
.select('.topRowTable')
.append('text')
.text('Trait')
.attr('clip-path', 'url(#clip1)')
Expand All @@ -187,8 +208,8 @@ const ForestPlot = ({
.attr('dx', 8);

// pval
topRowSvg
.select('.topRow')
topRowTable
.select('.topRowTable')
.append('text')
.text('P-value')
.style('font-size', '17px')
Expand All @@ -198,30 +219,36 @@ const ForestPlot = ({
.attr('dx', cfg.traitnameW + 8);

// add horizontal line to separate top row from other rows
topRowSvg
topRowTable
.append('line')
.attr('x2', cfg.tableW)
.attr('y1', cfg.rowHeight)
.attr('y2', cfg.rowHeight)
.attr('stroke', 'black');

// add vertical line to separate trait and pval columns
topRowSvg
topRowTable
.append('line')
.attr('x1', cfg.traitnameW)
.attr('x2', cfg.traitnameW)
.attr('y2', cfg.rowHeight)
.attr('stroke', 'black');

// create table
let table = svg.append('g').attr('id', 'forestTable');
const table = d3
.select('#table')
.attr('width', 500)
.attr('height', traits.length === 0 ? 0 : cfg.rowHeight)
.style('position', 'sticky')
.style('left', '0')
.style('overflow', 'visible');

// add vertical line to separate trait and pval columns
table
.append('line')
.attr('x1', cfg.traitnameW)
.attr('x2', cfg.traitnameW)
.attr('y2', traits.length * cfg.rowHeight + cfg.rowHeight)
.attr('y2', traits.length * cfg.rowHeight)
.attr('stroke', 'black');

// add rows to table
Expand All @@ -231,10 +258,7 @@ const ForestPlot = ({
.enter()
.append('g')
.classed('row', true)
.attr(
'transform',
(d, i) => 'translate(0,' + cfg.rowHeight * (i + 1) + ')'
);
.attr('transform', (d, i) => 'translate(0,' + cfg.rowHeight * i + ')');

rows
.append('rect')
Expand Down Expand Up @@ -340,7 +364,7 @@ const ForestPlot = ({
let transf = n[i].parentNode.attributes.transform.nodeValue;
return axisLines
.append(() => n[i])
.attr('y2', traits.length * cfg.rowHeight + cfg.rowHeight)
.attr('y2', traits.length * cfg.rowHeight)
.attr('transform', transf);
});

Expand Down Expand Up @@ -399,10 +423,7 @@ const ForestPlot = ({
.enter()
.append('g')
.classed('tree', true)
.attr(
'transform',
(d, i) => 'translate(0,' + (i + 1) * cfg.rowHeight + ')'
)
.attr('transform', (d, i) => 'translate(0,' + i * cfg.rowHeight + ')')
.attr('id', (d, i) => i);

// create confidence intervals
Expand Down Expand Up @@ -469,6 +490,8 @@ const ForestPlot = ({
width: cfg.component_width,
height: plot_height,
margin: 'none',
display: 'flex',
'flex-direction': 'column',
}}
>
<svg ref={refs} />
Expand All @@ -487,7 +510,20 @@ const ForestPlot = ({
transform={`translate(${cfg.svgW - 40},0)`}
/>
</Tooltip>
<svg id="topRow" />
<div
style={{
position: 'sticky',
top: '0px',
display: 'flex',
flexDirection: 'row',
zIndex: 2,
width: cfg.svgW - 45,
}}
>
<svg id="topRowTable" />
<svg id="topRow" />
</div>
<svg id="table" />
<svg id="bottomRow" />
<ListTooltip open={open} anchorEl={anchor} dataList={dataList} />
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/PheWASSection.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ function PheWASSection({
ref={pheWASPlot}
/>
</DownloadSVGPlot>
<SectionHeading subheading="Forest Plot" />
<ForestPlot
refs={forestPlot}
data={pheWASAssociationsFiltered}
Expand Down