11import cx from 'classnames'
22import React , {
3- MouseEvent ,
43 useEffect ,
54 DetailedHTMLProps ,
65 HTMLAttributes ,
@@ -12,23 +11,12 @@ import { Section } from 'dvc/src/plots/webview/contract'
1211import { MessageFromWebviewType } from 'dvc/src/webview/contract'
1312import { PlotsPicker , PlotsPickerProps } from './PlotsPicker'
1413import styles from './styles.module.scss'
15- import { Icon } from '../../shared/components/Icon'
16- import { IconMenu } from '../../shared/components/iconMenu/IconMenu'
1714import { IconMenuItemProps } from '../../shared/components/iconMenu/IconMenuItem'
1815import { sendMessage } from '../../shared/vscode'
19- import Tooltip from '../../shared/components/tooltip/Tooltip'
20- import {
21- ChevronDown ,
22- ChevronRight ,
23- Info ,
24- Lines ,
25- Add ,
26- Trash
27- } from '../../shared/components/icons'
28- import { isSelecting } from '../../util/strings'
29- import { isTooltip } from '../../util/helpers'
16+ import { Lines , Add , Trash } from '../../shared/components/icons'
3017import { MinMaxSlider } from '../../shared/components/slider/MinMaxSlider'
3118import { PlotsState } from '../store'
19+ import { SectionContainer } from '../../shared/components/sectionContainer/SectionContainer'
3220
3321export interface PlotsContainerProps {
3422 sectionCollapsed : boolean
@@ -43,58 +31,6 @@ export interface PlotsContainerProps {
4331 hasItems ?: boolean
4432}
4533
46- export const SectionDescription = {
47- // "Trends"
48- [ Section . CHECKPOINT_PLOTS ] : (
49- < span data-testid = "tooltip-checkpoint-plots" >
50- Automatically generated and updated linear plots that show metric value
51- per epoch if{ ' ' }
52- < a href = "https://dvc.org/doc/user-guide/experiment-management/checkpoints" >
53- checkpoints
54- </ a > { ' ' }
55- are enabled.
56- </ span >
57- ) ,
58- // "Custom"
59- [ Section . CUSTOM_PLOTS ] : (
60- < span data-testid = "tooltip-custom-plots" >
61- Generated custom linear plots comparing chosen metrics and params in all
62- experiments in the table.
63- </ span >
64- ) ,
65- // "Images"
66- [ Section . COMPARISON_TABLE ] : (
67- < span data-testid = "tooltip-comparison-plots" >
68- Images (e.g. any < code > .jpg</ code > , < code > .svg</ code > , or
69- < code > .png</ code > file) rendered side by side across experiments. They
70- should be registered as{ ' ' }
71- < a href = "https://dvc.org/doc/user-guide/experiment-management/visualizing-plots" >
72- plots
73- </ a >
74- .
75- </ span >
76- ) ,
77- // "Data Series"
78- [ Section . TEMPLATE_PLOTS ] : (
79- < span data-testid = "tooltip-template-plots" >
80- Any < code > JSON</ code > , < code > YAML</ code > , < code > CSV</ code > , or{ ' ' }
81- < code > TSV</ code > file(s) with data points, visualized using{ ' ' }
82- < a href = "https://dvc.org/doc/user-guide/experiment-management/visualizing-plots#plot-templates-data-series-only" >
83- plot templates
84- </ a >
85- . Either predefined (e.g. confusion matrix, linear) or{ ' ' }
86- < a href = "https://dvc.org/doc/command-reference/plots/templates#custom-templates" >
87- custom Vega-lite templates
88- </ a >
89- .
90- </ span >
91- )
92- }
93-
94- const InfoIcon = ( ) => (
95- < Icon icon = { Info } width = { 16 } height = { 16 } className = { styles . infoIcon } />
96- )
97-
9834export const PlotsContainer : React . FC < PlotsContainerProps > = ( {
9935 sectionCollapsed,
10036 sectionKey,
@@ -143,28 +79,6 @@ export const PlotsContainer: React.FC<PlotsContainerProps> = ({
14379 } )
14480 }
14581
146- const tooltipContent = (
147- < div className = { styles . infoTooltip } >
148- < InfoIcon />
149- { SectionDescription [ sectionKey ] }
150- </ div >
151- )
152-
153- const toggleSection = ( e : MouseEvent ) => {
154- e . preventDefault ( )
155- if (
156- ! isSelecting ( [ title , SectionDescription [ sectionKey ] . props . children ] ) &&
157- ! isTooltip ( e . target as Element , [ 'SUMMARY' , 'BODY' ] )
158- ) {
159- sendMessage ( {
160- payload : {
161- [ sectionKey ] : ! sectionCollapsed
162- } ,
163- type : MessageFromWebviewType . TOGGLE_PLOTS_SECTION
164- } )
165- }
166- }
167-
16882 const handleResize = useCallback (
16983 ( nbItems : number ) => {
17084 if ( changeNbItemsPerRow ) {
@@ -183,66 +97,55 @@ export const PlotsContainer: React.FC<PlotsContainerProps> = ({
18397 [ dispatch , changeNbItemsPerRow , sectionKey ]
18498 )
18599
100+ const toggleSection = ( ) =>
101+ sendMessage ( {
102+ payload : {
103+ [ sectionKey ] : ! sectionCollapsed
104+ } ,
105+ type : MessageFromWebviewType . TOGGLE_PLOTS_SECTION
106+ } )
107+
186108 return (
187- < div className = { styles . plotsContainerWrapper } data-testid = "plots-container" >
188- < details open = { open } className = { styles . plotsContainer } >
189- < summary onClick = { toggleSection } >
190- < Icon
191- icon = { open ? ChevronDown : ChevronRight }
192- data-testid = "plots-container-details-chevron"
193- width = { 20 }
194- height = { 20 }
195- className = { styles . detailsIcon }
109+ < SectionContainer
110+ menuItems = { menuItems }
111+ sectionCollapsed = { sectionCollapsed }
112+ sectionKey = { sectionKey }
113+ title = { title }
114+ onToggleSection = { toggleSection }
115+ >
116+ { changeNbItemsPerRow && hasItems && maxNbPlotsPerRow > 1 && (
117+ < div
118+ className = { styles . nbItemsPerRowSlider }
119+ data-testid = "nb-items-per-row-slider"
120+ >
121+ < MinMaxSlider
122+ maximum = { - 1 }
123+ minimum = { - maxNbPlotsPerRow }
124+ label = "Plot Width"
125+ onChange = { handleResize }
126+ defaultValue = { - nbItemsPerRow }
196127 />
197- { title }
198- < Tooltip content = { tooltipContent } placement = "bottom-end" interactive >
199- < div
200- className = { styles . infoTooltipToggle }
201- data-testid = "info-tooltip-toggle"
128+ </ div >
129+ ) }
130+ { open && (
131+ < div
132+ className = { cx ( {
133+ [ styles . plotsWrapper ] : sectionKey !== Section . COMPARISON_TABLE ,
134+ [ styles . smallPlots ] : nbItemsPerRow >= 4
135+ } ) }
136+ style = {
137+ {
138+ '--nbPerRow' : nbItemsPerRow
139+ } as DetailedHTMLProps <
140+ HTMLAttributes < HTMLDivElement > ,
141+ HTMLDivElement
202142 >
203- < InfoIcon />
204- </ div >
205- </ Tooltip >
206- </ summary >
207- { changeNbItemsPerRow && hasItems && maxNbPlotsPerRow > 1 && (
208- < div
209- className = { styles . nbItemsPerRowSlider }
210- data-testid = "nb-items-per-row-slider"
211- >
212- < MinMaxSlider
213- maximum = { - 1 }
214- minimum = { - maxNbPlotsPerRow }
215- label = "Plot Width"
216- onChange = { handleResize }
217- defaultValue = { - nbItemsPerRow }
218- />
219- </ div >
220- ) }
221- { open && (
222- < div
223- className = { cx ( {
224- [ styles . plotsWrapper ] : sectionKey !== Section . COMPARISON_TABLE ,
225- [ styles . smallPlots ] : nbItemsPerRow >= 4
226- } ) }
227- style = {
228- {
229- '--nbPerRow' : nbItemsPerRow
230- } as DetailedHTMLProps <
231- HTMLAttributes < HTMLDivElement > ,
232- HTMLDivElement
233- >
234- }
235- data-testid = "plots-wrapper"
236- >
237- { children }
238- </ div >
239- ) }
240- </ details >
241- { menuItems . length > 0 && (
242- < div className = { styles . iconMenu } >
243- < IconMenu items = { menuItems } />
143+ }
144+ data-testid = "plots-wrapper"
145+ >
146+ { children }
244147 </ div >
245148 ) }
246- </ div >
149+ </ SectionContainer >
247150 )
248151}
0 commit comments