@@ -65,6 +65,9 @@ def _collect_names(all_experiments, **kwargs):
6565def _collect_rows (
6666 base_rev ,
6767 experiments ,
68+ all_headers ,
69+ metric_headers ,
70+ param_headers ,
6871 metric_names ,
6972 param_names ,
7073 deps_names ,
@@ -87,24 +90,26 @@ def _collect_rows(
8790
8891 new_checkpoint = True
8992 for i , (rev , results ) in enumerate (experiments .items ()):
93+ fill_value = FILL_VALUE_ERRORED if results .get ("error" ) else fill_value
94+ row_dict = {k : fill_value for k in all_headers }
95+
9096 exp = results .get ("data" , {})
97+
9198 if exp .get ("running" ):
9299 state = "Running"
93100 elif exp .get ("queued" ):
94101 state = "Queued"
95102 else :
96103 state = fill_value
97- executor = exp . get ( "executor" , fill_value )
104+
98105 is_baseline = rev == "baseline"
99106
100107 if is_baseline :
101108 name_rev = base_rev [:7 ] if Git .is_sha (base_rev ) else base_rev
102109 else :
103110 name_rev = rev [:7 ]
104111
105- exp_name = exp .get ("name" , "" )
106112 tip = exp .get ("checkpoint_tip" )
107-
108113 parent_rev = exp .get ("checkpoint_parent" , "" )
109114 parent_exp = experiments .get (parent_rev , {}).get ("data" , {})
110115 parent_tip = parent_exp .get ("checkpoint_tip" )
@@ -130,26 +135,28 @@ def _collect_rows(
130135 if not is_baseline :
131136 new_checkpoint = not (tip and tip == parent_tip )
132137
133- row = [
134- exp_name ,
135- name_rev ,
136- typ ,
137- _format_time ( exp .get ("timestamp" ), fill_value , iso ),
138- parent ,
139- state ,
140- executor ,
141- ]
142- fill_value = FILL_VALUE_ERRORED if results . get ( "error" ) else fill_value
138+ row_dict [ "Experiment" ] = exp . get ( "name" , "" )
139+ row_dict [ "rev" ] = name_rev
140+ row_dict [ "typ" ] = typ
141+ row_dict [ "Created" ] = _format_time (
142+ exp .get ("timestamp" ), fill_value , iso
143+ )
144+ row_dict [ "parent" ] = parent
145+ row_dict [ "State" ] = state
146+ row_dict [ "Executor" ] = exp . get ( "executor" , fill_value )
147+
143148 _extend_row (
144- row ,
149+ row_dict ,
145150 metric_names ,
151+ metric_headers ,
146152 exp .get ("metrics" , {}).items (),
147153 precision ,
148154 fill_value = fill_value ,
149155 )
150156 _extend_row (
151- row ,
157+ row_dict ,
152158 param_names ,
159+ param_headers ,
153160 exp .get ("params" , {}).items (),
154161 precision ,
155162 fill_value = fill_value ,
@@ -158,8 +165,8 @@ def _collect_rows(
158165 hash_info = exp .get ("deps" , {}).get (dep , {}).get ("hash" )
159166 if hash_info is not None :
160167 hash_info = hash_info [:7 ]
161- row . append ( hash_info or fill_value )
162- yield row
168+ row_dict [ dep ] = hash_info
169+ yield list ( row_dict . values ())
163170
164171
165172def _sort_column (sort_by , metric_names , param_names ):
@@ -225,13 +232,9 @@ def _format_time(datetime_obj, fill_value=FILL_VALUE, iso=False):
225232 return datetime_obj .strftime (fmt )
226233
227234
228- def _extend_row (row , names , items , precision , fill_value = FILL_VALUE ):
235+ def _extend_row (row , names , headers , items , precision , fill_value = FILL_VALUE ):
229236 from dvc .compare import _format_field , with_value
230237
231- if not items :
232- row .extend (fill_value for keys in names .values () for _ in keys )
233- return
234-
235238 for fname , data in items :
236239 item = data .get ("data" , {})
237240 item = flatten (item ) if isinstance (item , dict ) else {fname : item }
@@ -243,7 +246,11 @@ def _extend_row(row, names, items, precision, fill_value=FILL_VALUE):
243246 # wrap field data in ui.rich_text, otherwise rich may
244247 # interpret unescaped braces from list/dict types as rich
245248 # markup tags
246- row .append (ui .rich_text (str (_format_field (value , precision ))))
249+ value = ui .rich_text (str (_format_field (value , precision )))
250+ if name in headers :
251+ row [name ] = value
252+ else :
253+ row [f"{ fname } :{ name } " ] = value
247254
248255
249256def experiments_table (
@@ -264,14 +271,15 @@ def experiments_table(
264271
265272 from dvc .compare import TabularData
266273
267- td = TabularData (
268- lconcat (headers , metric_headers , param_headers , deps_names ),
269- fill_value = fill_value ,
270- )
274+ all_headers = lconcat (headers , metric_headers , param_headers , deps_names )
275+ td = TabularData (all_headers , fill_value = fill_value )
271276 for base_rev , experiments in all_experiments .items ():
272277 rows = _collect_rows (
273278 base_rev ,
274279 experiments ,
280+ all_headers ,
281+ metric_headers ,
282+ param_headers ,
275283 metric_names ,
276284 param_names ,
277285 deps_names ,
0 commit comments