Skip to content

Commit 1513aa0

Browse files
authored
Fix Comparison Plot "Image By Step" height (#4458)
1 parent 820942f commit 1513aa0

File tree

4 files changed

+68
-4
lines changed

4 files changed

+68
-4
lines changed
-8.55 KB
Loading

webview/src/plots/components/comparisonTable/ComparisonTableRow.tsx

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComparisonPlot } from 'dvc/src/plots/webview/contract'
2-
import React, { useState } from 'react'
2+
import React, { useState, useEffect, useRef } from 'react'
33
import cx from 'classnames'
44
import { useSelector } from 'react-redux'
55
import styles from './styles.module.scss'
@@ -27,9 +27,13 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
2727
nbColumns,
2828
pinnedColumn
2929
}) => {
30+
const plotsRowRef = useRef<HTMLTableRowElement>(null)
3031
const draggedId = useSelector(
3132
(state: PlotsState) => state.dragAndDrop.draggedRef?.itemId
3233
)
34+
const comparisonWidth = useSelector(
35+
(state: PlotsState) => state.comparison.width
36+
)
3337
const [isShown, setIsShown] = useState(true)
3438

3539
const toggleIsShownState = () => {
@@ -39,6 +43,37 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
3943
setIsShown(!isShown)
4044
}
4145

46+
const updateMultiImgHeight = (image: HTMLImageElement) => {
47+
const aspectRatio = image.naturalWidth / image.naturalHeight
48+
const width = image.clientWidth
49+
const calculatedHeight = Number.parseFloat((width / aspectRatio).toFixed(2))
50+
51+
plotsRowRef.current?.style.setProperty(
52+
'--img-height',
53+
`${calculatedHeight}px`
54+
)
55+
}
56+
57+
useEffect(() => {
58+
const img: HTMLImageElement | null | undefined =
59+
plotsRowRef.current?.querySelector(`.${styles.multiImageWrapper} img`)
60+
if (!img) {
61+
return
62+
}
63+
64+
if (img.complete) {
65+
updateMultiImgHeight(img)
66+
return
67+
}
68+
img.addEventListener(
69+
'load',
70+
() => {
71+
updateMultiImgHeight(img)
72+
},
73+
{ once: true }
74+
)
75+
}, [comparisonWidth])
76+
4277
return (
4378
<>
4479
<tr>
@@ -62,7 +97,7 @@ export const ComparisonTableRow: React.FC<ComparisonTableRowProps> = ({
6297
</td>
6398
{nbColumns > 1 && pinnedColumn && <td colSpan={nbColumns - 1}></td>}
6499
</tr>
65-
<tr>
100+
<tr ref={plotsRowRef}>
66101
{plots.map(plot => {
67102
const isPinned = pinnedColumn === plot.id
68103
return (

webview/src/plots/components/comparisonTable/styles.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ $gap: 4px;
176176
.multiImageWrapper {
177177
.image,
178178
.noImageContent {
179-
height: 380px;
180179
object-fit: contain;
180+
height: var(--img-height);
181181
}
182182
}
183183

webview/src/stories/Plots.stories.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { configureStore } from '@reduxjs/toolkit'
22
import React from 'react'
33
import { Provider, useDispatch } from 'react-redux'
44
import type { StoryFn, Meta } from '@storybook/react'
5-
import { userEvent, within } from '@storybook/testing-library'
5+
import { userEvent, within, fireEvent } from '@storybook/testing-library'
66
import {
77
PlotsData,
88
DEFAULT_SECTION_COLLAPSED,
@@ -227,6 +227,35 @@ AllSmall.args = {
227227
}
228228
AllSmall.parameters = CHROMATIC_VIEWPORTS_WITH_DELAY
229229

230+
export const WithMixedMultiImgHeight = Template.bind({})
231+
WithMixedMultiImgHeight.args = {
232+
data: {
233+
comparison: {
234+
...comparisonPlotsFixture,
235+
plots: comparisonPlotsFixture.plots.filter(({ path }) =>
236+
path.includes('image')
237+
)
238+
}
239+
}
240+
}
241+
WithMixedMultiImgHeight.play = async ({ canvasElement }) => {
242+
const plotSizeSliders = await within(canvasElement).findByTestId(
243+
'size-sliders'
244+
)
245+
246+
const sizeSlider = within(plotSizeSliders).getByRole('slider')
247+
248+
fireEvent.change(sizeSlider, { target: { value: -5 } })
249+
250+
const multiImgCells = await within(canvasElement).findAllByTestId(
251+
'multi-image-cell'
252+
)
253+
254+
const multiImgSlider = within(multiImgCells[1]).getByRole('slider')
255+
fireEvent.change(multiImgSlider, { target: { value: 7 } })
256+
}
257+
WithMixedMultiImgHeight.parameters = { chromatic: { delay: 2000 } }
258+
230259
export const VirtualizedPlots = Template.bind({})
231260
VirtualizedPlots.args = {
232261
data: {

0 commit comments

Comments
 (0)