From 0939aef44604858c0a5c64987f56736563135c68 Mon Sep 17 00:00:00 2001 From: Olzhas Mukayev Date: Fri, 23 Aug 2024 15:24:07 +0500 Subject: [PATCH] feat: add line chart to the Study View --- src/pages/studyView/StudyViewConfig.ts | 15 ++ src/pages/studyView/StudyViewPageStore.ts | 5 + .../studyView/chartHeader/ChartHeader.tsx | 127 +++++++---- src/pages/studyView/charts/ChartContainer.tsx | 25 +++ .../studyView/charts/barChart/BarChart.tsx | 2 +- .../studyView/charts/lineChart/LineChart.tsx | 200 ++++++++++++++++++ src/pages/studyView/tabs/SummaryTab.tsx | 88 ++++++++ 7 files changed, 418 insertions(+), 44 deletions(-) create mode 100644 src/pages/studyView/charts/lineChart/LineChart.tsx diff --git a/src/pages/studyView/StudyViewConfig.ts b/src/pages/studyView/StudyViewConfig.ts index 166ef974a1f..968a7a791ac 100644 --- a/src/pages/studyView/StudyViewConfig.ts +++ b/src/pages/studyView/StudyViewConfig.ts @@ -61,9 +61,14 @@ export type StudyViewFrontEndConfig = { export type StudyViewConfig = StudyView & StudyViewFrontEndConfig; +export type ChangeChartOptionsMap = { + [chartType in ChartTypeEnum]?: ChartType[]; +}; + export enum ChartTypeEnum { PIE_CHART = 'PIE_CHART', BAR_CHART = 'BAR_CHART', + LINE_CHART = 'LINE_CHART', SURVIVAL = 'SURVIVAL', TABLE = 'TABLE', SCATTER = 'SCATTER', @@ -88,6 +93,7 @@ export enum ChartTypeEnum { export enum ChartTypeNameEnum { PIE_CHART = 'pie chart', BAR_CHART = 'bar chart', + LINE_CHART = 'line chart', SURVIVAL = 'survival plot', TABLE = 'table', SCATTER = 'density plot', @@ -186,6 +192,10 @@ const studyViewFrontEnd = { w: 2, h: 1, }, + [ChartTypeEnum.LINE_CHART]: { + w: 2, + h: 1, + }, [ChartTypeEnum.SCATTER]: { w: 2, h: 2, @@ -312,3 +322,8 @@ export const STUDY_VIEW_CONFIG: StudyViewConfig = _.assign( studyViewFrontEnd, (getServerConfig() || {}).study_view ); + +export const chartChangeOptionsMap: ChangeChartOptionsMap = { + [ChartTypeEnum.LINE_CHART]: [ChartTypeEnum.BAR_CHART], + [ChartTypeEnum.BAR_CHART]: [ChartTypeEnum.LINE_CHART], +}; diff --git a/src/pages/studyView/StudyViewPageStore.ts b/src/pages/studyView/StudyViewPageStore.ts index 98d9da7d788..1c23e52d791 100644 --- a/src/pages/studyView/StudyViewPageStore.ts +++ b/src/pages/studyView/StudyViewPageStore.ts @@ -2155,6 +2155,11 @@ export class StudyViewPageStore ChartDimension >(); + @observable public availableChartTypes = observable.map< + ChartUniqueKey, + ChartType[] + >(); + @observable public chartsType = observable.map(); private newlyAddedCharts = observable.array(); diff --git a/src/pages/studyView/chartHeader/ChartHeader.tsx b/src/pages/studyView/chartHeader/ChartHeader.tsx index 83a273aa57d..cf7465f5e00 100644 --- a/src/pages/studyView/chartHeader/ChartHeader.tsx +++ b/src/pages/studyView/chartHeader/ChartHeader.tsx @@ -8,7 +8,11 @@ import { import classnames from 'classnames'; import { action, computed, makeObservable, observable } from 'mobx'; import { observer } from 'mobx-react'; -import { ChartTypeEnum } from '../StudyViewConfig'; +import { + ChartTypeEnum, + ChartTypeNameEnum, + chartChangeOptionsMap, +} from '../StudyViewConfig'; import { ChartMeta, getClinicalAttributeOverlay } from '../StudyViewUtils'; import { DataType, @@ -82,6 +86,7 @@ export interface ChartControls { showSwapAxes?: boolean; showSurvivalPlotLeftTruncationToggle?: boolean; survivalPlotLeftTruncationChecked?: boolean; + showChartChangeOptions?: boolean; } @observer @@ -90,6 +95,7 @@ export class ChartHeader extends React.Component { @observable downloadSubmenuOpen = false; @observable comparisonSubmenuOpen = false; @observable showCustomBinModal: boolean = false; + @observable showChartChangeOptions: boolean = false; private closeMenuTimeout: number | undefined = undefined; constructor(props: IChartHeaderProps) { @@ -444,54 +450,89 @@ export class ChartHeader extends React.Component { ); } - if ( - this.props.chartControls && - !!this.props.chartControls.showTableIcon - ) { + if (this.props.chartControls?.showChartChangeOptions) { + const submenuWidth = 120; + const availableCharts = [ + ...new Set( + ( + this.props.store.availableChartTypes.get( + this.props.chartMeta.uniqueKey + ) || [] + ).concat(chartChangeOptionsMap[this.props.chartType] || []) + ), + ]; items.push( -
  • - - this.props.changeChartType(ChartTypeEnum.TABLE) +
  • +