import * as React from 'react'; import styles from './styles.module.scss'; import { If } from 'react-if'; import { ChartType, NumericalGroupComparisonType, } from 'pages/studyView/StudyViewUtils'; import classnames from 'classnames'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; import { ChartTypeEnum } from '../StudyViewConfig'; import { ChartMeta, getClinicalAttributeOverlay } from '../StudyViewUtils'; import { DataType, DefaultTooltip, DownloadControls, DownloadControlsButton, } from 'cbioportal-frontend-commons'; import FlexAlignedCheckbox from '../../../shared/components/FlexAlignedCheckbox'; import CustomBinsModal from 'pages/studyView/charts/barChart/CustomBinsModal'; import { StudyViewPageStore } from 'pages/studyView/StudyViewPageStore'; import { ISurvivalDescription } from 'pages/resultsView/survival/SurvivalDescriptionTable'; import ComparisonVsIcon from 'shared/components/ComparisonVsIcon'; import { getComparisonParamsForTable } from 'pages/studyView/StudyViewComparisonUtils'; import { AppContext } from 'cbioportal-frontend-commons'; export interface IChartHeaderProps { chartMeta: ChartMeta; chartType: ChartType; store: StudyViewPageStore; title: string; height: number; placement: 'left' | 'right'; active: boolean; resetChart: () => void; deleteChart: () => void; selectedRowsKeys?: string[]; toggleLogScale?: () => void; toggleLogScaleX?: () => void; toggleLogScaleY?: () => void; toggleBoxPlot?: () => void; toggleViolinPlot?: () => void; toggleNAValue?: () => void; isLeftTruncationAvailable?: boolean; toggleSurvivalPlotLeftTruncation?: () => void; swapAxes?: () => void; hideLabel?: boolean; chartControls?: ChartControls; changeChartType: (chartType: ChartType) => void; getSVG?: () => Promise; getData?: | ((dataType?: DataType) => Promise) | ((dataType?: DataType) => string); downloadTypes?: DownloadControlsButton[]; description?: ISurvivalDescription; openComparisonPage: (params: { categorizationType?: NumericalGroupComparisonType; hugoGeneSymbols?: string[]; treatmentUniqueKeys?: string[]; }) => void; } export interface ChartControls { showResetIcon?: boolean; showTableIcon?: boolean; showPieIcon?: boolean; showComparisonPageIcon?: boolean; showLogScaleToggle?: boolean; logScaleChecked?: boolean; showLogScaleXToggle?: boolean; logScaleXChecked?: boolean; showLogScaleYToggle?: boolean; logScaleYChecked?: boolean; showBoxPlotToggle?: boolean; boxPlotChecked?: boolean; showViolinPlotToggle?: boolean; violinPlotChecked?: boolean; isShowNAChecked?: boolean; showNAToggle?: boolean; showSwapAxes?: boolean; showSurvivalPlotLeftTruncationToggle?: boolean; survivalPlotLeftTruncationChecked?: boolean; } @observer export class ChartHeader extends React.Component { @observable menuOpen = false; @observable downloadSubmenuOpen = false; @observable comparisonSubmenuOpen = false; @observable showCustomBinModal: boolean = false; private closeMenuTimeout: number | undefined = undefined; constructor(props: IChartHeaderProps) { super(props); makeObservable(this); } @computed get fileName() { return this.props.chartMeta.displayName.replace(/[ \t]/g, '_'); } @action.bound private openMenu() { this.menuOpen = true; window.clearTimeout(this.closeMenuTimeout); this.closeMenuTimeout = undefined; } @action.bound private closeMenu() { if (!this.closeMenuTimeout) { this.closeMenuTimeout = window.setTimeout(() => { this.menuOpen = false; this.closeMenuTimeout = undefined; }, 125); } } @computed get active() { return this.menuOpen || this.props.active; } @computed get comparisonButton() { const submenuWidth = 120; switch (this.props.chartType) { case ChartTypeEnum.BAR_CHART: return (
(this.comparisonSubmenuOpen = true)} onMouseLeave={() => (this.comparisonSubmenuOpen = false) } >
Compare Groups
{this.comparisonSubmenuOpen && ( )}
); case ChartTypeEnum.MUTATED_GENES_TABLE: case ChartTypeEnum.CNA_GENES_TABLE: case ChartTypeEnum.STRUCTURAL_VARIANT_GENES_TABLE: case ChartTypeEnum.SAMPLE_TREATMENT_GROUPS_TABLE: case ChartTypeEnum.SAMPLE_TREATMENTS_TABLE: case ChartTypeEnum.PATIENT_TREATMENT_GROUPS_TABLE: case ChartTypeEnum.PATIENT_TREATMENTS_TABLE: return ( { if (this.props.selectedRowsKeys!.length >= 2) { this.props.openComparisonPage( getComparisonParamsForTable( this.props.selectedRowsKeys!, this.props.chartType ) ); } }} style={{ display: 'flex', alignItems: 'center' }} > Compare Groups ); default: return ( this.props.openComparisonPage({})} style={{ display: 'flex', alignItems: 'center' }} > Compare Groups ); } } @computed get showDownload() { return ( this.props.chartControls && this.props.downloadTypes && this.props.downloadTypes.length > 0 && this.context.showDownloadControls === true ); } @computed get menuItems() { const items = []; if ( this.props.chartControls && this.props.chartControls.showLogScaleToggle && this.props.toggleLogScale ) { items.push(
  • Log Scale } style={{ marginTop: 1, marginBottom: -3 }} />
  • ); } if ( this.props.chartControls && this.props.chartControls.showSwapAxes && this.props.swapAxes ) { items.push(
  • {` Swap Axes `}
  • ); } if ( this.props.chartControls && this.props.chartControls.showLogScaleXToggle && this.props.toggleLogScaleX ) { items.push(
  • Log Scale X } style={{ marginTop: 1, marginBottom: -3 }} />
  • ); } if ( this.props.chartControls && this.props.chartControls.showLogScaleYToggle && this.props.toggleLogScaleY ) { items.push(
  • Log Scale Y } style={{ marginTop: 1, marginBottom: -3 }} />
  • ); } if ( this.props.chartControls && this.props.chartControls.showViolinPlotToggle && this.props.toggleViolinPlot ) { items.push(
  • Show Violin Plot } style={{ marginTop: 1, marginBottom: -3 }} />
  • ); } if ( this.props.chartControls && this.props.chartControls.showBoxPlotToggle && this.props.toggleBoxPlot ) { items.push(
  • Show Box Plot } style={{ marginTop: 1, marginBottom: -3 }} />
  • ); } if ( this.props.chartControls && !!this.props.chartControls.showTableIcon ) { items.push(
  • this.props.changeChartType(ChartTypeEnum.TABLE) } >