import { DownloadControls, EditableSpan } from 'cbioportal-frontend-commons'; import { numberOfLeadingDecimalZeros } from 'cbioportal-utils'; import classnames from 'classnames'; import _ from 'lodash'; import * as React from 'react'; import Slider from 'react-rangeslider'; import { computed, makeObservable } from 'mobx'; import { observer } from 'mobx-react'; import { calcYMaxInput } from '../../util/LollipopPlotUtils'; import TrackSelector, { TrackDataStatus, TrackName, TrackVisibility, } from '../track/TrackSelector'; import 'react-rangeslider/lib/index.css'; import styles from './lollipopMutationPlot.module.scss'; type LollipopMutationPlotControlsProps = { showControls: boolean; hugoGeneSymbol: string; countRange: [number, number]; bottomCountRange?: [number, number]; onYAxisMaxSliderChange: (event: any) => void; onYAxisMaxChange: (inputValue: string) => void; onBottomYAxisMaxSliderChange?: (event: any) => void; onBottomYAxisMaxChange?: (inputValue: string) => void; onYMaxInputFocused: () => void; onYMaxInputBlurred: () => void; onToggleLegend: () => void; yMaxSlider: number; yMaxSliderStep: number; yMaxSliderWidth: number; yMaxInput: number; yAxisSameScale?: boolean; bottomYMaxSlider?: number; bottomYMaxSliderStep: number; bottomYMaxInput?: number; customControls?: JSX.Element; filterResetPanel?: JSX.Element; tracks?: TrackName[]; trackVisibility?: TrackVisibility; trackDataStatus?: TrackDataStatus; showTrackSelector?: boolean; showYMaxSlider?: boolean; showLegendToggle?: boolean; showDownloadControls?: boolean; onTrackVisibilityChange?: (selectedTrackIds: string[]) => void; getSVG: () => SVGElement; }; function formatInputValue(value: number, step: number = 1) { const decimalZeros = numberOfLeadingDecimalZeros(step); const fixed = decimalZeros < 0 ? 0 : decimalZeros + 1; return value.toFixed(fixed); } @observer export default class LollipopMutationPlotControls extends React.Component< LollipopMutationPlotControlsProps, {} > { constructor(props: any) { super(props); makeObservable(this); } public static defaultProps: Partial = { showTrackSelector: true, showYMaxSlider: true, showLegendToggle: true, showDownloadControls: true, yMaxSliderWidth: 100, }; @computed get showBottomYAxisSlider() { return ( this.props.bottomCountRange && _.compact(this.props.bottomCountRange).length > 0 && this.props.onBottomYAxisMaxSliderChange && this.props.onBottomYAxisMaxChange && this.props.bottomYMaxSlider && this.props.bottomYMaxInput ); } protected maxValueSlider( countRange: [number, number], oppositeCountRange: [number, number], onYAxisMaxSliderChange: (event: any) => void, onYAxisMaxChange: (inputValue: string) => void, yMaxSlider: number, yMaxInput: number, yAxisSameScale: boolean = false, label: string = 'Y-Axis Max', width: number = 100, yMaxSliderStep: number = 1 ) { return (
{label}:
= 1} onFocus={this.props.onYMaxInputFocused} onBlur={this.props.onYMaxInputBlurred} />
); } protected get yMaxSlider() { return this.maxValueSlider( this.props.countRange, this.props.bottomCountRange!, this.props.onYAxisMaxSliderChange, this.props.onYAxisMaxChange, this.props.yMaxSlider, this.props.yMaxInput, this.props.yAxisSameScale, this.showBottomYAxisSlider ? 'Top Y-Axis Max' : 'Y-Axis Max', this.props.yMaxSliderWidth, this.props.yMaxSliderStep ); } protected get bottomYMaxSlider() { if (this.showBottomYAxisSlider) { return this.maxValueSlider( this.props.bottomCountRange!, this.props.countRange, this.props.onBottomYAxisMaxSliderChange!, this.props.onBottomYAxisMaxChange!, this.props.bottomYMaxSlider!, this.props.bottomYMaxInput!, this.props.yAxisSameScale, 'Bottom Y-Axis Max', 100, this.props.bottomYMaxSliderStep ); } else { return null; } } protected get trackSelector() { return (
); } protected get legendToggle() { return (