8686"""
8787
8888
89+ def generate_download_plot_js (metric_name : str ) -> str :
90+ """Generate JavaScript code for downloading plot data as JSON."""
91+ safe_filename = metric_name .replace ("/" , "_" ).replace ("\\ " , "_" )
92+ return f"""(data) => {{
93+ const jsonStr = JSON.stringify(data.value, null, 2);
94+ const blob = new Blob([jsonStr], {{type: 'application/json'}});
95+ const url = URL.createObjectURL(blob);
96+ const a = document.createElement('a');
97+ a.href = url;
98+ a.download = '{ safe_filename } .json';
99+ document.body.appendChild(a);
100+ a.click();
101+ document.body.removeChild(a);
102+ URL.revokeObjectURL(url);
103+ return [];
104+ }}"""
105+
106+
89107def get_runs (project ) -> list [str ]:
90108 if not project :
91109 return []
@@ -1049,6 +1067,7 @@ def update_dashboard(
10491067 x_lim_value ,
10501068 )
10511069 if not metric_df .empty :
1070+ download_btn = gr .Button ("📄" )
10521071 plot = gr .LinePlot (
10531072 downsampled_df ,
10541073 x = x_column ,
@@ -1060,10 +1079,16 @@ def update_dashboard(
10601079 title = metric_name ,
10611080 key = f"plot-{ metric_idx } " ,
10621081 preserved_by_key = None ,
1063- buttons = ["fullscreen" , "export" ],
1082+ buttons = [download_btn , "fullscreen" , "export" ],
10641083 x_lim = updated_x_lim ,
10651084 min_width = 400 ,
10661085 )
1086+ download_btn .click (
1087+ None ,
1088+ inputs = [plot ],
1089+ outputs = [],
1090+ js = generate_download_plot_js (metric_name ),
1091+ )
10671092 plot .select (
10681093 update_x_lim ,
10691094 outputs = x_lim ,
@@ -1114,6 +1139,7 @@ def update_dashboard(
11141139 x_lim_value ,
11151140 )
11161141 if not metric_df .empty :
1142+ download_btn = gr .Button ("📄" )
11171143 plot = gr .LinePlot (
11181144 downsampled_df ,
11191145 x = x_column ,
@@ -1125,10 +1151,20 @@ def update_dashboard(
11251151 title = metric_name ,
11261152 key = f"plot-{ metric_idx } " ,
11271153 preserved_by_key = None ,
1128- buttons = ["fullscreen" , "export" ],
1154+ buttons = [
1155+ download_btn ,
1156+ "fullscreen" ,
1157+ "export" ,
1158+ ],
11291159 x_lim = updated_x_lim ,
11301160 min_width = 400 ,
11311161 )
1162+ download_btn .click (
1163+ None ,
1164+ inputs = [plot ],
1165+ outputs = [],
1166+ js = generate_download_plot_js (metric_name ),
1167+ )
11321168 plot .select (
11331169 update_x_lim ,
11341170 outputs = x_lim ,
0 commit comments