Skip to content

Commit

Permalink
Violin plot table adjustments (#4199)
Browse files Browse the repository at this point in the history
Adjustments to study view violin plot 

Signed-off-by: Adam Abeshouse <abeshoua@mskcc.org>
  • Loading branch information
adamabeshouse authored Mar 8, 2022
1 parent 668702a commit c6d8a3b
Show file tree
Hide file tree
Showing 8 changed files with 405 additions and 119 deletions.
4 changes: 4 additions & 0 deletions src/globalStyles/global.scss
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,10 @@ h6.blackHeader {
white-space: nowrap;
}

.nomouse {
pointer-events: none;
}

h2.divider {
margin: 40px 0 !important;
padding-bottom: 10px;
Expand Down
55 changes: 37 additions & 18 deletions src/pages/studyView/StudyViewPageStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7061,34 +7061,53 @@ export class StudyViewPageStore
chartInfo: XvsYViolinChart;
violinLogScale: boolean;
},
ClinicalViolinPlotData
{
data: ClinicalViolinPlotData;
violinLogScale: boolean;
}
>(
q => ({
invoke: () =>
internalClient.fetchClinicalDataViolinPlotsUsingPOST({
categoricalAttributeId:
q.chartInfo.categoricalAttr.clinicalAttributeId,
numericalAttributeId:
q.chartInfo.numericalAttr.clinicalAttributeId,
logScale: q.violinLogScale,
sigmaMultiplier: 4,
studyViewFilter: excludeFiltersForAttribute(
this.filters,
q.chartInfo.categoricalAttr.clinicalAttributeId
),
}),
invoke: async () => ({
data: await internalClient.fetchClinicalDataViolinPlotsUsingPOST(
{
categoricalAttributeId:
q.chartInfo.categoricalAttr.clinicalAttributeId,
numericalAttributeId:
q.chartInfo.numericalAttr.clinicalAttributeId,
logScale: q.violinLogScale,
sigmaMultiplier: 4,
studyViewFilter: excludeFiltersForAttribute(
this.filters,
[
q.chartInfo.categoricalAttr.clinicalAttributeId,
q.chartInfo.numericalAttr.clinicalAttributeId,
]
),
}
),
violinLogScale: q.violinLogScale,
}),
default: {
axisStart: -1,
axisEnd: -1,
rows: [],
data: {
axisStart: -1,
axisEnd: -1,
rows: [],
},
violinLogScale: false,
},
}),
q => {
return (
`Category:${q.chartInfo.categoricalAttr.clinicalAttributeId}/` +
`Numerical:${q.chartInfo.numericalAttr.clinicalAttributeId}/` +
`violinDomain:${JSON.stringify(q.chartInfo.violinDomain)}/` +
`violinLog:${q.violinLogScale}`
`violinLog:${q.violinLogScale}/` +
`Filters:${JSON.stringify(
excludeFiltersForAttribute(this.filters, [
q.chartInfo.categoricalAttr.clinicalAttributeId,
q.chartInfo.numericalAttr.clinicalAttributeId,
])
)}` // make sure we don't update unless other filters change
);
}
);
Expand Down
13 changes: 11 additions & 2 deletions src/pages/studyView/StudyViewUtils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3689,11 +3689,20 @@ export function isQueriedStudyAuthorized(study: CancerStudy) {

export function excludeFiltersForAttribute(
filters: StudyViewFilter,
clinicalAttributeId: string
clinicalAttributeId: string | string[]
) {
let { clinicalDataFilters, ...rest } = filters;
const clinicalAttributeIds = new Set();
if (typeof clinicalAttributeId === 'string') {
clinicalAttributeIds.add(clinicalAttributeId);
} else {
for (const id of clinicalAttributeId) {
clinicalAttributeIds.add(id);
}
}

clinicalDataFilters = clinicalDataFilters?.filter(
f => f.attributeId !== clinicalAttributeId
f => !clinicalAttributeIds.has(f.attributeId)
);
return { clinicalDataFilters, ...rest };
}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/studyView/addChartButton/AddChartButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ class AddChartTabs extends React.Component<IAddChartTabsProps, {}> {
(attr1.datatype === 'NUMBER' && attr2.datatype === 'STRING') ||
(attr1.datatype === 'STRING' && attr2.datatype === 'NUMBER')
) {
text = 'Add violin plot table';
text = 'Add violin/box plot table';
type = 'violin';

if (attr1.datatype === 'STRING') {
Expand Down
19 changes: 10 additions & 9 deletions src/pages/studyView/charts/ChartContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1036,12 +1036,13 @@ export class ChartContainer extends React.Component<IChartContainerProps, {}> {
)!;
return () => {
const isLoading =
!this.props.store.clinicalDataBinPromises[
(this.props.store.clinicalDataBinPromises[
chartInfo.numericalAttr.clinicalAttributeId
] ||
this.props.store.clinicalDataBinPromises[
chartInfo.numericalAttr.clinicalAttributeId
].isPending;
] &&
this.props.store.clinicalDataBinPromises[
chartInfo.numericalAttr.clinicalAttributeId
].isPending) ||
this.props.promise.isPending;
return (
<StudyViewViolinPlotTable
dimension={this.props.dimension}
Expand All @@ -1056,13 +1057,13 @@ export class ChartContainer extends React.Component<IChartContainerProps, {}> {
categoryColumnName={this.props.axisLabelX!}
violinColumnName={this.props.axisLabelY!}
violinBounds={{
min: this.props.promise.result.axisStart,
max: this.props.promise.result.axisEnd,
min: this.props.promise.result.data.axisStart,
max: this.props.promise.result.data.axisEnd,
}}
rows={this.props.promise.result.rows || []}
rows={this.props.promise.result.data.rows || []}
showViolin={this.props.violinPlotChecked!}
showBox={this.props.boxPlotChecked!}
logScale={chartSettings?.violinLogScale!}
logScale={this.props.promise.result.violinLogScale}
setFilters={this.props.onValueSelection}
selectedCategories={this.props.selectedCategories!}
isLoading={isLoading}
Expand Down
29 changes: 18 additions & 11 deletions src/pages/studyView/charts/violinPlotTable/StudyViewViolinPlot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export interface IStudyViewViolinPlotProps {
mouseX: number,
mouseY: number
) => void;
onMouseOverBoxPlot: (mouseX: number, mouseY: number) => void;
onMouseOverBackground: () => void;
}

Expand Down Expand Up @@ -117,11 +118,12 @@ export default class StudyViewViolinPlot extends React.Component<
}

renderBox() {
const whiskerStrokeWidth = 0.5;
const center = violinPlotSvgHeight / 2;
const whiskerLowerX = this.x(this.props.boxData.whiskerLower);
const whiskerUpperX = this.x(this.props.boxData.whiskerUpper);
const whiskerTop = center; //10;
const whiskerBottom = center; //height - 10;
const whiskerTop = center - 3;
const whiskerBottom = center + 3;

const boxWidth =
this.x(this.props.boxData.q3) - this.x(this.props.boxData.q1);
Expand All @@ -140,7 +142,7 @@ export default class StudyViewViolinPlot extends React.Component<
y1={whiskerTop}
y2={whiskerBottom}
stroke="black"
strokeWidth={1.5}
strokeWidth={whiskerStrokeWidth}
/>
{/*connecting line*/}
<line
Expand All @@ -149,6 +151,7 @@ export default class StudyViewViolinPlot extends React.Component<
y1={center}
y2={center}
stroke="black"
strokeWidth={whiskerStrokeWidth}
/>
{/*right whisker*/}
<line
Expand All @@ -157,7 +160,7 @@ export default class StudyViewViolinPlot extends React.Component<
y1={whiskerTop}
y2={whiskerBottom}
stroke="black"
strokeWidth={1.5}
strokeWidth={whiskerStrokeWidth}
/>
{/*box*/}
<rect
Expand All @@ -168,6 +171,9 @@ export default class StudyViewViolinPlot extends React.Component<
fill={'#dddddd'}
stroke={'black'}
strokeWidth={0.2}
onMouseOver={e =>
this.props.onMouseOverBoxPlot(e.pageX, e.pageY)
}
/>
{/*median*/}
<line
Expand Down Expand Up @@ -204,10 +210,6 @@ export default class StudyViewViolinPlot extends React.Component<
);
}

@computed get onlyPoints() {
return this.props.curveMagnitudes.length === 0;
}

render() {
return (
<svg
Expand All @@ -218,15 +220,20 @@ export default class StudyViewViolinPlot extends React.Component<
}}
>
{this.renderGridLines()}
{this.props.showViolin && this.renderCurve()}
{!this.onlyPoints && this.props.showBox && this.renderBox()}
{this.props.curveMagnitudes.length > 0 &&
this.props.showViolin &&
this.renderCurve()}
<rect
width={this.svgWidth}
height={violinPlotSvgHeight}
fillOpacity={0}
onMouseMove={this.props.onMouseOverBackground}
/>
{this.renderPoints()}
{this.props.curveMagnitudes.length > 0 &&
this.props.showBox &&
this.renderBox()}
{(this.props.showViolin || this.props.showBox) &&
this.renderPoints()}
</svg>
);
}
Expand Down
Loading

0 comments on commit c6d8a3b

Please sign in to comment.