Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collapse button for floating viz controls #535

Merged
merged 12 commits into from
Oct 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type DraggablePanelStyleOverrides = {
resize?: CSSProperties['resize'];
width?: CSSProperties['width'];
zIndex?: CSSProperties['zIndex'];
overflow?: CSSProperties['overflow'];
};

export type HeightAndWidthInPixels = {
Expand Down Expand Up @@ -205,7 +206,7 @@ export default function DraggablePanel({
css={css`
// Hey, so you need to explicitly set overflow wherever
// you plan to use resize.
overflow: auto;
overflow: ${styleOverrides?.overflow ?? 'auto'};
resize: ${styleOverrides?.resize ?? 'none'};
border-radius: 7px;
// We want the content to render below the drag handle, so let's put this
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { CSSProperties } from 'react';
import { FilledButton } from '@veupathdb/coreui';
import { CSSProperties, useState } from 'react';
import { FloatingDiv } from '../../../map/analysis/FloatingDiv';
import { RequiredInputsPrompt } from './RequiredInputPrompts';

Expand All @@ -7,6 +8,7 @@ import { LayoutProps } from './types';
export interface Props extends LayoutProps {
showRequiredInputsPrompt?: boolean;
isMosaicPlot?: boolean;
hideControls?: boolean;
}

const defaultContainerStyles: CSSProperties = {
Expand All @@ -27,15 +29,18 @@ export function FloatingLayout({
plotStyles,
showRequiredInputsPrompt,
isMosaicPlot,
hideControls,
}: Props) {
return (
<div style={{ ...defaultContainerStyles, ...containerStyles }}>
<div style={{ ...defaultPlotStyles, ...plotStyles }}>
{showRequiredInputsPrompt && (
<RequiredInputsPrompt isMosaicPlot={isMosaicPlot} />
)}
{plotNode}
{controlsNode}
<div>
{showRequiredInputsPrompt && (
<RequiredInputsPrompt isMosaicPlot={isMosaicPlot} />
)}
{plotNode}
{!hideControls && controlsNode}
</div>
</div>
</div>
);
Expand Down
1 change: 1 addition & 0 deletions packages/libs/eda/src/lib/core/components/layouts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface LayoutProps {
plotStyles?: CSSProperties;
tableGroupNode: ReactNode;
tableGroupStyles?: CSSProperties;
hideControls?: boolean;
}

export type StyleProps<P> = Pick<P, keyof P & `${string}Styles`>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ import {
} from '../../types/visualization';
import { JobStatus } from '../computations/ComputeJobStatusHook';

export interface PlotContainerStyleOverrides
extends Omit<React.CSSProperties, 'width' | 'height'> {
width?: number;
height?: number;
}

/**
* Props passed to viz components
*/
Expand All @@ -31,6 +37,8 @@ export interface VisualizationProps<Options = undefined> {
geoConfigs: GeoConfig[];
otherVizOverviews: VisualizationOverview[];
computeJobStatus?: JobStatus;
hideInputsAndControls?: boolean;
plotContainerStyleOverrides?: PlotContainerStyleOverrides;
}

export interface IsEnabledInPickerParams {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import { RunComputeButton, StatusIcon } from '../computations/RunComputeButton';
import { JobStatus } from '../computations/ComputeJobStatusHook';
import { ComputationStepContainer } from '../computations/ComputationStepContainer';
import { ComputationPlugin } from '../computations/Types';
import { PlotContainerStyleOverrides } from './VisualizationTypes';

const cx = makeClassNameHelper('VisualizationsContainer');

Expand All @@ -66,6 +67,8 @@ interface Props {
createComputeJob?: () => void;
/** optional dynamic plugins */
plugins?: Partial<Record<string, ComputationPlugin>>;
hideInputsAndControls?: boolean;
plotContainerStyleOverrides?: PlotContainerStyleOverrides;
}

/**
Expand Down Expand Up @@ -449,7 +452,9 @@ type FullScreenVisualizationPropKeys =
| 'disableThumbnailCreation'
| 'computeJobStatus'
| 'createComputeJob'
| 'plugins';
| 'plugins'
| 'hideInputsAndControls'
| 'plotContainerStyleOverrides';

interface FullScreenVisualizationProps
extends Pick<Props, FullScreenVisualizationPropKeys> {
Expand Down Expand Up @@ -479,6 +484,8 @@ export function FullScreenVisualization(props: FullScreenVisualizationProps) {
computeJobStatus,
createComputeJob,
plugins = staticPlugins,
hideInputsAndControls,
plotContainerStyleOverrides,
} = props;
const themePrimaryColor = useUITheme()?.palette.primary;
const history = useHistory();
Expand Down Expand Up @@ -643,20 +650,24 @@ export function FullScreenVisualization(props: FullScreenVisualizationProps) {
</ContentError>
) : (
<div>
<h3>
<SaveableTextEditor
value={viz.displayName ?? 'unnamed visualization'}
onSave={(value) => {
if (value)
analysisState.updateVisualization({
...viz,
displayName: value,
});
}}
/>
</h3>
<div className="Subtitle">{overview?.displayName}</div>
{plugin && analysisState.analysis && (
{!hideInputsAndControls && (
<>
<h3>
<SaveableTextEditor
value={viz.displayName ?? 'unnamed visualization'}
onSave={(value) => {
if (value)
analysisState.updateVisualization({
...viz,
displayName: value,
});
}}
/>
</h3>
<div className="Subtitle">{overview?.displayName}</div>
</>
)}
{!hideInputsAndControls && plugin && analysisState.analysis && (
<div
style={{
display: 'flex',
Expand Down Expand Up @@ -719,6 +730,8 @@ export function FullScreenVisualization(props: FullScreenVisualizationProps) {
geoConfigs={geoConfigs}
otherVizOverviews={overviews.others}
computeJobStatus={computeJobStatus}
hideInputsAndControls={hideInputsAndControls}
plotContainerStyleOverrides={plotContainerStyleOverrides}
/>
</div>
</ComputationStepContainer>
Expand All @@ -741,6 +754,8 @@ export function FullScreenVisualization(props: FullScreenVisualizationProps) {
geoConfigs={geoConfigs}
otherVizOverviews={overviews.others}
computeJobStatus={computeJobStatus}
hideInputsAndControls={hideInputsAndControls}
plotContainerStyleOverrides={plotContainerStyleOverrides}
/>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,20 @@ function BarplotViz(props: VisualizationProps<Options>) {
toggleStarredVariable,
totalCounts,
filteredCounts,
hideInputsAndControls,
plotContainerStyleOverrides,
} = props;
const studyMetadata = useStudyMetadata();
const { id: studyId } = studyMetadata;
const entities = useStudyEntities(filters);
const dataClient: DataClient = useDataClient();
const finalPlotContainerStyles = useMemo(
() => ({
...plotContainerStyles,
...plotContainerStyleOverrides,
}),
[plotContainerStyleOverrides]
);

// use useVizConfig hook
const [vizConfig, updateVizConfig] = useVizConfig(
Expand Down Expand Up @@ -632,7 +641,7 @@ function BarplotViz(props: VisualizationProps<Options>) {

const plotRef = useUpdateThumbnailEffect(
updateThumbnail,
plotContainerStyles,
finalPlotContainerStyles,
// The dependencies for needing to generate a new thumbnail
[
data,
Expand All @@ -652,7 +661,9 @@ function BarplotViz(props: VisualizationProps<Options>) {
// these props are passed to either a single plot
// or by FacetedPlot to each individual facet plot (where some will be overridden)
const plotProps: BarplotProps = {
containerStyles: !isFaceted(data.value) ? plotContainerStyles : undefined,
containerStyles: !isFaceted(data.value)
? finalPlotContainerStyles
: undefined,
spacingOptions: !isFaceted(data.value) ? plotSpacingOptions : undefined,
orientation: 'vertical',
barLayout: 'group',
Expand Down Expand Up @@ -892,40 +903,45 @@ function BarplotViz(props: VisualizationProps<Options>) {
return (
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div style={{ display: 'flex', alignItems: 'center', zIndex: 1 }}>
<InputVariables
inputs={inputs}
entities={entities}
selectedVariables={selectedVariables}
onChange={handleInputVariableChange}
constraints={dataElementConstraints}
dataElementDependencyOrder={dataElementDependencyOrder}
starredVariables={starredVariables}
enableShowMissingnessToggle={
(overlayVariable != null || facetVariable != null) &&
data.value?.completeCasesAllVars !==
data.value?.completeCasesAxesVars
}
toggleStarredVariable={toggleStarredVariable}
// this can be used to show and hide no data control
onShowMissingnessChange={
computation.descriptor.type === 'pass'
? onShowMissingnessChange
: undefined
}
showMissingness={vizConfig.showMissingness}
outputEntity={outputEntity}
/>
{!hideInputsAndControls && (
<InputVariables
inputs={inputs}
entities={entities}
selectedVariables={selectedVariables}
onChange={handleInputVariableChange}
constraints={dataElementConstraints}
dataElementDependencyOrder={dataElementDependencyOrder}
starredVariables={starredVariables}
enableShowMissingnessToggle={
(overlayVariable != null || facetVariable != null) &&
data.value?.completeCasesAllVars !==
data.value?.completeCasesAxesVars
}
toggleStarredVariable={toggleStarredVariable}
// this can be used to show and hide no data control
onShowMissingnessChange={
computation.descriptor.type === 'pass'
? onShowMissingnessChange
: undefined
}
showMissingness={vizConfig.showMissingness}
outputEntity={outputEntity}
/>
)}
</div>

<PluginError error={data.error} outputSize={outputSize} />
<OutputEntityTitle entity={outputEntity} outputSize={outputSize} />
{!hideInputsAndControls && (
<OutputEntityTitle entity={outputEntity} outputSize={outputSize} />
)}
<LayoutComponent
isFaceted={isFaceted(data.value)}
plotNode={plotNode}
controlsNode={controlsNode}
legendNode={showOverlayLegend ? legendNode : null}
tableGroupNode={tableGroupNode}
showRequiredInputsPrompt={!areRequiredInputsSelected}
hideControls={hideInputsAndControls}
/>
</div>
);
Expand Down
Loading