From 87da2be3281eab2ac6daba7b28f53730d63b6763 Mon Sep 17 00:00:00 2001 From: Axel Bocciarelli Date: Tue, 15 Nov 2022 16:24:14 +0100 Subject: [PATCH] Replace `visRatio` and `layout` props with `aspect` prop --- apps/storybook/src/HeatmapVis.stories.tsx | 6 ++--- .../src/HeatmapVisDisplay.stories.tsx | 13 +++++++--- apps/storybook/src/SelectToZoom.stories.tsx | 2 +- .../src/TiledHeatmapMesh.stories.tsx | 10 ++------ apps/storybook/src/VisCanvas.stories.tsx | 13 +++++++--- .../vis-packs/core/complex/ComplexToolbar.tsx | 10 ++++---- .../core/complex/MappedComplexVis.tsx | 4 +-- .../vis-packs/core/heatmap/HeatmapToolbar.tsx | 10 ++++---- .../core/heatmap/MappedHeatmapVis.tsx | 4 +-- .../app/src/vis-packs/core/heatmap/config.tsx | 25 +++++++++++-------- .../src/vis-packs/core/rgb/MappedRgbVis.tsx | 4 +-- .../app/src/vis-packs/core/rgb/RgbToolbar.tsx | 16 ++++++++---- .../app/src/vis-packs/core/rgb/config.tsx | 10 ++++---- packages/app/src/vis-packs/core/utils.ts | 5 ++-- .../containers/NxComplexImageContainer.tsx | 4 +-- .../nexus/containers/NxImageContainer.tsx | 4 +-- .../app/src/vis-packs/nexus/utils.test.ts | 20 +++++++-------- packages/app/src/vis-packs/nexus/utils.ts | 7 +++--- packages/lib/src/index.ts | 3 ++- packages/lib/src/vis/heatmap/HeatmapVis.tsx | 14 +++++------ packages/lib/src/vis/models.ts | 2 ++ packages/lib/src/vis/rgb/RgbVis.tsx | 13 ++++------ packages/lib/src/vis/shared/VisCanvas.tsx | 10 +++++--- packages/lib/src/vis/utils.ts | 19 ++++++++++++++ 24 files changed, 131 insertions(+), 97 deletions(-) diff --git a/apps/storybook/src/HeatmapVis.stories.tsx b/apps/storybook/src/HeatmapVis.stories.tsx index 4e50d8dbf..a80397193 100644 --- a/apps/storybook/src/HeatmapVis.stories.tsx +++ b/apps/storybook/src/HeatmapVis.stories.tsx @@ -123,7 +123,7 @@ export default { args: { colorMap: 'Viridis', scaleType: ScaleType.Linear, - layout: 'cover', + aspect: 'equal', showGrid: true, }, argTypes: { @@ -140,9 +140,9 @@ export default { ScaleType.Sqrt, ], }, - layout: { + aspect: { control: { type: 'inline-radio' }, - options: ['cover', 'fill'], + options: ['auto', 'equal'], }, }, } as Meta; diff --git a/apps/storybook/src/HeatmapVisDisplay.stories.tsx b/apps/storybook/src/HeatmapVisDisplay.stories.tsx index 28fe20a57..e246f43a7 100644 --- a/apps/storybook/src/HeatmapVisDisplay.stories.tsx +++ b/apps/storybook/src/HeatmapVisDisplay.stories.tsx @@ -15,11 +15,18 @@ const domain = getDomain(dataArray.data); const Template: Story = (args) => ; -export const Fill = Template.bind({}); -Fill.args = { +export const AutoAspectRatio = Template.bind({}); +AutoAspectRatio.args = { dataArray, domain, - layout: 'fill', + aspect: 'auto', +}; + +export const CustomAspectRatio = Template.bind({}); +CustomAspectRatio.args = { + dataArray, + domain, + aspect: 1, }; export const FlipYAxis = Template.bind({}); diff --git a/apps/storybook/src/SelectToZoom.stories.tsx b/apps/storybook/src/SelectToZoom.stories.tsx index 9607b0443..274bf3a00 100644 --- a/apps/storybook/src/SelectToZoom.stories.tsx +++ b/apps/storybook/src/SelectToZoom.stories.tsx @@ -25,7 +25,7 @@ const Template: Story = (args) => { diff --git a/apps/storybook/src/TiledHeatmapMesh.stories.tsx b/apps/storybook/src/TiledHeatmapMesh.stories.tsx index ba6be3e90..a26e4e0a2 100644 --- a/apps/storybook/src/TiledHeatmapMesh.stories.tsx +++ b/apps/storybook/src/TiledHeatmapMesh.stories.tsx @@ -178,10 +178,7 @@ const Template: Story = (args) => { @@ -308,10 +305,7 @@ export const WithTransforms: Story = (args) => { diff --git a/apps/storybook/src/VisCanvas.stories.tsx b/apps/storybook/src/VisCanvas.stories.tsx index f6026630c..183cb52b8 100644 --- a/apps/storybook/src/VisCanvas.stories.tsx +++ b/apps/storybook/src/VisCanvas.stories.tsx @@ -32,11 +32,18 @@ LogScales.args = { }, }; -export const AspectRatio = Template.bind({}); -AspectRatio.args = { +export const EqualAspectRatio = Template.bind({}); +EqualAspectRatio.args = { abscissaConfig: { visDomain: [0, 20], showGrid: true, isIndexAxis: true }, ordinateConfig: { visDomain: [0, 10], showGrid: true, isIndexAxis: true }, - visRatio: 20 / 10, + aspect: 'equal', +}; + +export const CustomAspectRatio = Template.bind({}); +CustomAspectRatio.args = { + abscissaConfig: { visDomain: [0, 20], showGrid: true, isIndexAxis: true }, + ordinateConfig: { visDomain: [0, 10], showGrid: true, isIndexAxis: true }, + aspect: 1, }; export const NoGrid = Template.bind({}); diff --git a/packages/app/src/vis-packs/core/complex/ComplexToolbar.tsx b/packages/app/src/vis-packs/core/complex/ComplexToolbar.tsx index 77e96c817..eeb373bff 100644 --- a/packages/app/src/vis-packs/core/complex/ComplexToolbar.tsx +++ b/packages/app/src/vis-packs/core/complex/ComplexToolbar.tsx @@ -31,19 +31,19 @@ function ComplexToolbar(props: Props) { customDomain, colorMap, scaleType, - layout, + keepRatio, showGrid, invertColorMap, setCustomDomain, setColorMap, setScaleType, - setLayout, + toggleKeepRatio, toggleGrid, toggleColorMapInversion, } = heatmapConfig; return ( - + setLayout(layout === 'cover' ? 'fill' : 'cover')} + value={keepRatio} + onToggle={toggleKeepRatio} /> + setLayout(layout === 'cover' ? 'fill' : 'cover')} + value={keepRatio} + onToggle={toggleKeepRatio} /> diff --git a/packages/app/src/vis-packs/core/heatmap/MappedHeatmapVis.tsx b/packages/app/src/vis-packs/core/heatmap/MappedHeatmapVis.tsx index ca3190db0..31f40a24d 100644 --- a/packages/app/src/vis-packs/core/heatmap/MappedHeatmapVis.tsx +++ b/packages/app/src/vis-packs/core/heatmap/MappedHeatmapVis.tsx @@ -37,7 +37,7 @@ function MappedHeatmapVis(props: Props) { customDomain, colorMap, scaleType, - layout, + keepRatio, showGrid, invertColorMap, flipYAxis, @@ -80,7 +80,7 @@ function MappedHeatmapVis(props: Props) { domain={safeDomain} colorMap={colorMap} scaleType={scaleType} - layout={layout} + aspect={keepRatio ? 'equal' : 'auto'} showGrid={showGrid} invertColorMap={invertColorMap} abscissaParams={{ diff --git a/packages/app/src/vis-packs/core/heatmap/config.tsx b/packages/app/src/vis-packs/core/heatmap/config.tsx index 2aa4f6334..fb8d4f22b 100644 --- a/packages/app/src/vis-packs/core/heatmap/config.tsx +++ b/packages/app/src/vis-packs/core/heatmap/config.tsx @@ -1,4 +1,4 @@ -import type { CustomDomain, Layout } from '@h5web/lib'; +import type { CustomDomain } from '@h5web/lib'; import { isDefined, ScaleType } from '@h5web/shared'; import { useMap } from '@react-hookz/web'; import type { StoreApi } from 'zustand'; @@ -25,8 +25,8 @@ export interface HeatmapConfig { showGrid: boolean; toggleGrid: () => void; - layout: Layout; - setLayout: (layout: Layout) => void; + keepRatio: boolean; + toggleKeepRatio: () => void; flipYAxis: boolean; toggleYAxisFlip: () => void; @@ -55,8 +55,9 @@ function createStore() { showGrid: true, toggleGrid: () => set((state) => ({ showGrid: !state.showGrid })), - layout: 'cover', - setLayout: (layout: Layout) => set({ layout }), + keepRatio: true, + toggleKeepRatio: () => + set((state) => ({ keepRatio: !state.keepRatio })), flipYAxis: false, toggleYAxisFlip: () => @@ -79,7 +80,7 @@ export function HeatmapConfigProvider(props: ConfigProviderProps) { export function useHeatmapConfig( initialSuggestedOpts: Partial< - Pick + Pick > = {} ): HeatmapConfig { const suggestedOpts = useMap( @@ -87,8 +88,10 @@ export function useHeatmapConfig( ); const persistedConfig = useStore(); - const { setScaleType: setPersistedScaleType, setLayout: setPersistedLayout } = - persistedConfig; + const { + setScaleType: setPersistedScaleType, + toggleKeepRatio: togglePersistedKeepRatio, + } = persistedConfig; return { ...persistedConfig, @@ -97,9 +100,9 @@ export function useHeatmapConfig( setPersistedScaleType(scaleType); suggestedOpts.delete('scaleType'); }, - setLayout: (layout: Layout) => { - setPersistedLayout(layout); - suggestedOpts.delete('layout'); + toggleKeepRatio: () => { + togglePersistedKeepRatio(); + suggestedOpts.delete('keepRatio'); }, }; } diff --git a/packages/app/src/vis-packs/core/rgb/MappedRgbVis.tsx b/packages/app/src/vis-packs/core/rgb/MappedRgbVis.tsx index d72a5eb9b..2db7a4432 100644 --- a/packages/app/src/vis-packs/core/rgb/MappedRgbVis.tsx +++ b/packages/app/src/vis-packs/core/rgb/MappedRgbVis.tsx @@ -31,7 +31,7 @@ function MappedRgbVis(props: Props) { config, } = props; - const { showGrid, layout, imageType } = config; + const { showGrid, keepRatio, imageType } = config; const { shape: dims } = dataset; const [slicedDims, slicedMapping] = useSlicedDimsAndMapping(dims, dimMapping); @@ -47,7 +47,7 @@ function MappedRgbVis(props: Props) { dataArray={dataArray} title={title} showGrid={showGrid} - layout={layout} + aspect={keepRatio ? 'equal' : 'auto'} imageType={imageType} abscissaParams={{ label: axisLabels?.[xDimIndex], diff --git a/packages/app/src/vis-packs/core/rgb/RgbToolbar.tsx b/packages/app/src/vis-packs/core/rgb/RgbToolbar.tsx index dfb45773d..c3545cb3c 100644 --- a/packages/app/src/vis-packs/core/rgb/RgbToolbar.tsx +++ b/packages/app/src/vis-packs/core/rgb/RgbToolbar.tsx @@ -13,11 +13,17 @@ import { getImageInteractions } from '../utils'; import { useRgbConfig } from './config'; function RgbToolbar() { - const { layout, setLayout, showGrid, toggleGrid, imageType, setImageType } = - useRgbConfig((state) => state, shallow); + const { + imageType, + keepRatio, + showGrid, + setImageType, + toggleKeepRatio, + toggleGrid, + } = useRgbConfig((state) => state, shallow); return ( - + setLayout(layout === 'cover' ? 'fill' : 'cover')} + value={keepRatio} + onToggle={toggleKeepRatio} /> diff --git a/packages/app/src/vis-packs/core/rgb/config.tsx b/packages/app/src/vis-packs/core/rgb/config.tsx index f09db1cac..631cb8981 100644 --- a/packages/app/src/vis-packs/core/rgb/config.tsx +++ b/packages/app/src/vis-packs/core/rgb/config.tsx @@ -1,4 +1,3 @@ -import type { Layout } from '@h5web/lib'; import { ImageType } from '@h5web/lib'; import type { StoreApi } from 'zustand'; import create from 'zustand'; @@ -11,8 +10,8 @@ export interface RgbVisConfig { showGrid: boolean; toggleGrid: () => void; - layout: Layout; - setLayout: (layout: Layout) => void; + keepRatio: boolean; + toggleKeepRatio: () => void; imageType: ImageType; setImageType: (channels: ImageType) => void; @@ -25,8 +24,9 @@ function createStore() { showGrid: false, toggleGrid: () => set((state) => ({ showGrid: !state.showGrid })), - layout: 'cover', - setLayout: (layout: Layout) => set({ layout }), + keepRatio: true, + toggleKeepRatio: () => + set((state) => ({ keepRatio: !state.keepRatio })), imageType: ImageType.RGB, setImageType: (imageType: ImageType) => set({ imageType }), diff --git a/packages/app/src/vis-packs/core/utils.ts b/packages/app/src/vis-packs/core/utils.ts index 6dd8e156d..19edfa277 100644 --- a/packages/app/src/vis-packs/core/utils.ts +++ b/packages/app/src/vis-packs/core/utils.ts @@ -1,4 +1,3 @@ -import type { Layout } from '@h5web/lib'; import type { Domain } from '@h5web/shared'; import { createArrayFromView } from '@h5web/shared'; import { isNumber } from 'lodash'; @@ -81,6 +80,6 @@ export function getSliceSelection( return dimMapping.map((dim) => (isAxis(dim) ? ':' : dim)).join(','); } -export function getImageInteractions(layout: Layout) { - return layout === 'fill' ? INTERACTIONS_WITH_AXIAL_ZOOM : BASE_INTERACTIONS; +export function getImageInteractions(keepRatio: boolean) { + return keepRatio ? INTERACTIONS_WITH_AXIAL_ZOOM : BASE_INTERACTIONS; } diff --git a/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx b/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx index 66f2ae7b0..c26d88a92 100644 --- a/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx +++ b/packages/app/src/vis-packs/nexus/containers/NxComplexImageContainer.tsx @@ -10,7 +10,7 @@ import { getSliceSelection } from '../../core/utils'; import type { VisContainerProps } from '../../models'; import NxValuesFetcher from '../NxValuesFetcher'; import { useNxData } from '../hooks'; -import { assertComplexSignal, getBestLayout } from '../utils'; +import { assertComplexSignal, guessKeepRatio } from '../utils'; function NxComplexImageContainer(props: VisContainerProps) { const { entity, toolbarContainer } = props; @@ -30,7 +30,7 @@ function NxComplexImageContainer(props: VisContainerProps) { const config = useComplexConfig(); const heatmapConfig = useHeatmapConfig({ scaleType: silxStyle.signalScaleType, - layout: getBestLayout(xAxisDef, yAxisDef), + keepRatio: guessKeepRatio(xAxisDef, yAxisDef), }); return ( diff --git a/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx b/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx index edcb712f7..77e58aeae 100644 --- a/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx +++ b/packages/app/src/vis-packs/nexus/containers/NxImageContainer.tsx @@ -9,7 +9,7 @@ import { getSliceSelection } from '../../core/utils'; import type { VisContainerProps } from '../../models'; import NxValuesFetcher from '../NxValuesFetcher'; import { useNxData } from '../hooks'; -import { assertNumericSignal, getBestLayout } from '../utils'; +import { assertNumericSignal, guessKeepRatio } from '../utils'; function NxImageContainer(props: VisContainerProps) { const { entity, toolbarContainer } = props; @@ -28,7 +28,7 @@ function NxImageContainer(props: VisContainerProps) { const config = useHeatmapConfig({ scaleType: silxStyle.signalScaleType, - layout: getBestLayout(xAxisDef, yAxisDef), + keepRatio: guessKeepRatio(xAxisDef, yAxisDef), }); return ( diff --git a/packages/app/src/vis-packs/nexus/utils.test.ts b/packages/app/src/vis-packs/nexus/utils.test.ts index 248202c3f..fbafb8fc0 100644 --- a/packages/app/src/vis-packs/nexus/utils.test.ts +++ b/packages/app/src/vis-packs/nexus/utils.test.ts @@ -1,30 +1,30 @@ import { intType, makeDataset } from '@h5web/shared/src/mock/metadata-utils'; -import { getBestLayout } from './utils'; +import { guessKeepRatio } from './utils'; const dataset = makeDataset('foo', intType, [5]); const defNoUnit = { label: 'foo', unit: undefined, dataset }; const defUnitX = { label: 'foo', unit: 'mm', dataset }; const defUnitY = { label: 'foo', unit: 'degrees', dataset }; -describe('getBestLayout', () => { +describe('guessKeepRatio', () => { it('should return `cover` if units of both axes are provided and equal', () => { - expect(getBestLayout(defUnitX, defUnitX)).toBe('cover'); + expect(guessKeepRatio(defUnitX, defUnitX)).toBe(true); }); it('should return `fill` if units of both axes are provided but different', () => { - expect(getBestLayout(defUnitX, defUnitY)).toBe('fill'); + expect(guessKeepRatio(defUnitX, defUnitY)).toBe(false); }); it('should return `fill` if unit is provided for only one axis', () => { - expect(getBestLayout(defUnitX, undefined)).toBe('fill'); - expect(getBestLayout(undefined, defUnitY)).toBe('fill'); + expect(guessKeepRatio(defUnitX, undefined)).toBe(false); + expect(guessKeepRatio(undefined, defUnitY)).toBe(false); }); it('should return `undefined` if both axis defs/units are undefined', () => { - expect(getBestLayout(undefined, undefined)).toBeUndefined(); - expect(getBestLayout(defNoUnit, undefined)).toBeUndefined(); - expect(getBestLayout(undefined, defNoUnit)).toBeUndefined(); - expect(getBestLayout(defNoUnit, defNoUnit)).toBeUndefined(); + expect(guessKeepRatio(undefined, undefined)).toBeUndefined(); + expect(guessKeepRatio(defNoUnit, undefined)).toBeUndefined(); + expect(guessKeepRatio(undefined, defNoUnit)).toBeUndefined(); + expect(guessKeepRatio(defNoUnit, defNoUnit)).toBeUndefined(); }); }); diff --git a/packages/app/src/vis-packs/nexus/utils.ts b/packages/app/src/vis-packs/nexus/utils.ts index db816efd5..3a01a523c 100644 --- a/packages/app/src/vis-packs/nexus/utils.ts +++ b/packages/app/src/vis-packs/nexus/utils.ts @@ -1,4 +1,3 @@ -import type { Layout } from '@h5web/lib'; import { assertArray, assertArrayShape, @@ -248,15 +247,15 @@ export function getDatasetInfo( }; } -export function getBestLayout( +export function guessKeepRatio( xAxisDef: AxisDef | undefined, yAxisDef: AxisDef | undefined -): Layout | undefined { +): boolean | undefined { if (!xAxisDef?.unit && !yAxisDef?.unit) { return undefined; } - return xAxisDef?.unit === yAxisDef?.unit ? 'cover' : 'fill'; + return xAxisDef?.unit === yAxisDef?.unit; } export function assertNumericSignal( diff --git a/packages/lib/src/index.ts b/packages/lib/src/index.ts index bf2ffb5a3..84ff4d4be 100644 --- a/packages/lib/src/index.ts +++ b/packages/lib/src/index.ts @@ -128,6 +128,7 @@ export { MouseButton } from './interactions/models'; export type { Domain, Dims } from '@h5web/shared'; export type { + Aspect, DomainErrors, CustomDomain, Size, @@ -137,7 +138,7 @@ export type { HistogramParams, } from './vis/models'; -export type { D3Interpolator, ColorMap, Layout } from './vis/heatmap/models'; +export type { D3Interpolator, ColorMap } from './vis/heatmap/models'; export type { ScatterAxisParams } from './vis/scatter/models'; // Mock data and utilities diff --git a/packages/lib/src/vis/heatmap/HeatmapVis.tsx b/packages/lib/src/vis/heatmap/HeatmapVis.tsx index f28928931..64f1ac857 100644 --- a/packages/lib/src/vis/heatmap/HeatmapVis.tsx +++ b/packages/lib/src/vis/heatmap/HeatmapVis.tsx @@ -12,7 +12,7 @@ import type { DefaultInteractionsConfig } from '../../interactions/DefaultIntera import DefaultInteractions from '../../interactions/DefaultInteractions'; import ResetZoomButton from '../../toolbar/floating/ResetZoomButton'; import { useAxisDomain, useValueToIndexScale } from '../hooks'; -import type { AxisParams, VisScaleType } from '../models'; +import type { Aspect, AxisParams, VisScaleType } from '../models'; import TooltipMesh from '../shared/TooltipMesh'; import VisCanvas from '../shared/VisCanvas'; import { DEFAULT_DOMAIN, formatNumType } from '../utils'; @@ -20,14 +20,14 @@ import ColorBar from './ColorBar'; import HeatmapMesh from './HeatmapMesh'; import styles from './HeatmapVis.module.css'; import { usePixelEdgeValues, useTextureSafeNdArray } from './hooks'; -import type { ColorMap, Layout, TooltipData } from './models'; +import type { ColorMap, TooltipData } from './models'; interface Props { dataArray: NdArray; domain: Domain | undefined; colorMap?: ColorMap; scaleType?: VisScaleType; - layout?: Layout; + aspect?: Aspect; showGrid?: boolean; title?: string; dtype?: NumericType; @@ -47,7 +47,7 @@ function HeatmapVis(props: Props) { domain = DEFAULT_DOMAIN, colorMap = 'Viridis', scaleType = ScaleType.Linear, - layout = 'cover', + aspect = 'equal', showGrid = false, invertColorMap = false, title, @@ -78,13 +78,11 @@ function HeatmapVis(props: Props) { const safeDataArray = useTextureSafeNdArray(dataArray); const safeAlphaArray = useTextureSafeNdArray(alpha?.array); - const keepRatio = layout !== 'fill'; - return (
- + ; - layout?: Layout; + aspect?: Aspect; showGrid?: boolean; title?: string; imageType?: ImageType; @@ -33,7 +32,7 @@ interface Props { function RgbVis(props: Props) { const { dataArray, - layout = 'cover', + aspect = 'equal', showGrid = false, title, imageType = ImageType.RGB, @@ -57,13 +56,11 @@ function RgbVis(props: Props) { const safeDataArray = useMemo(() => toRgbSafeNdArray(dataArray), [dataArray]); - const keepRatio = layout !== 'fill'; - return (
- + diff --git a/packages/lib/src/vis/shared/VisCanvas.tsx b/packages/lib/src/vis/shared/VisCanvas.tsx index ce5bc6485..1d2018b05 100644 --- a/packages/lib/src/vis/shared/VisCanvas.tsx +++ b/packages/lib/src/vis/shared/VisCanvas.tsx @@ -3,8 +3,8 @@ import type { PropsWithChildren } from 'react'; import { useRef } from 'react'; import InteractionsProvider from '../../interactions/InteractionsProvider'; -import type { AxisConfig } from '../models'; -import { getAxisOffsets } from '../utils'; +import type { Aspect, AxisConfig } from '../models'; +import { getAxisOffsets, getVisRatio } from '../utils'; import AxisSystem from './AxisSystem'; import AxisSystemProvider from './AxisSystemProvider'; import RatioEnforcer from './RatioEnforcer'; @@ -16,7 +16,7 @@ const NO_OFFSETS = { left: 0, right: 0, top: 0, bottom: 0 }; interface Props { title?: string; - visRatio?: number | undefined; + aspect?: Aspect; abscissaConfig: AxisConfig; ordinateConfig: AxisConfig; raycasterThreshold?: number; @@ -26,7 +26,7 @@ interface Props { function VisCanvas(props: PropsWithChildren) { const { title, - visRatio, + aspect = 'auto', abscissaConfig, ordinateConfig, raycasterThreshold, @@ -34,6 +34,8 @@ function VisCanvas(props: PropsWithChildren) { children, } = props; + const visRatio = getVisRatio(aspect, abscissaConfig, ordinateConfig); + const axisOffsets = showAxes ? getAxisOffsets({ left: !!ordinateConfig.label, diff --git a/packages/lib/src/vis/utils.ts b/packages/lib/src/vis/utils.ts index 3332d6435..e6a1f9ac8 100644 --- a/packages/lib/src/vis/utils.ts +++ b/packages/lib/src/vis/utils.ts @@ -26,6 +26,7 @@ import type { ScaleGammaConfig, VisxScaleConfig, VisScaleType, + Aspect, } from './models'; import { H5WEB_SCALES } from './scales'; @@ -268,6 +269,24 @@ export function getCombinedDomain( ]); } +export function getVisRatio( + aspect: Aspect, + abscissaConfig: AxisConfig, + ordinateConfig: AxisConfig +): number | undefined { + if (aspect === 'auto') { + return undefined; + } + + if (aspect === 'equal') { + const [xMin, xMax] = abscissaConfig.visDomain; + const [yMin, yMax] = ordinateConfig.visDomain; + return Math.abs(xMax - xMin) / Math.abs(yMax - yMin); + } + + return aspect; +} + export function getAxisOffsets( hasLabel: Partial, boolean>> = {} ) {