X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=csit.infra.dash%2Fapp%2Fcdash%2Freport%2Flayout.py;h=ec17dec7e87d324250017cbc0d15b68ddcc46f92;hb=f578663642305f144f76ddadf0370701147f18ff;hp=2f954b611be39f4b531399e26300e9fd8b61a2ec;hpb=f226df6bcb9af9b40a39ba8d03762ef4dffcc47a;p=csit.git diff --git a/csit.infra.dash/app/cdash/report/layout.py b/csit.infra.dash/app/cdash/report/layout.py index 2f954b611b..ec17dec7e8 100644 --- a/csit.infra.dash/app/cdash/report/layout.py +++ b/csit.infra.dash/app/cdash/report/layout.py @@ -31,7 +31,7 @@ from ..utils.constants import Constants as C from ..utils.control_panel import ControlPanel from ..utils.trigger import Trigger from ..utils.utils import show_tooltip, label, sync_checklists, gen_new_url, \ - generate_options, get_list_group_items + generate_options, get_list_group_items, graph_hdrh_latency from ..utils.url_processing import url_decode from .graphs import graph_iterative, select_iterative_data @@ -125,7 +125,7 @@ class Layout: if dut == "dpdk": area = "dpdk" else: - area = "-".join(lst_test_id[3:-2]) + area = ".".join(lst_test_id[3:-2]) suite = lst_test_id[-2].replace("2n1l-", "").replace("1n1l-", "").\ replace("2n-", "") test = lst_test_id[-1] @@ -279,6 +279,20 @@ class Layout: self._add_ctrl_col(), self._add_plotting_col() ] + ), + dbc.Spinner( + dbc.Offcanvas( + class_name="w-50", + id="offcanvas-metadata", + title="Throughput And Latency", + placement="end", + is_open=False, + children=[ + dbc.Row(id="metadata-tput-lat"), + dbc.Row(id="metadata-hdrh-graph") + ] + ), + delay_show=C.SPINNER_DELAY ) ] ) @@ -905,7 +919,7 @@ class Layout: try: store_sel = literal_eval(url_params["store_sel"][0]) normalize = literal_eval(url_params["norm"][0]) - except (KeyError, IndexError): + except (KeyError, IndexError, AttributeError): pass if store_sel: row_card_sel_tests = C.STYLE_ENABLED @@ -1298,7 +1312,7 @@ class Layout: Input("plot-btn-download", "n_clicks"), prevent_initial_call=True ) - def _download_trending_data(store_sel, _): + def _download_iterative_data(store_sel, _): """Download the data :param store_sel: List of tests selected by user stored in the @@ -1320,3 +1334,112 @@ class Layout: df = pd.concat([df, sel_data], ignore_index=True) return dcc.send_data_frame(df.to_csv, C.REPORT_DOWNLOAD_FILE_NAME) + + @app.callback( + Output("metadata-tput-lat", "children"), + Output("metadata-hdrh-graph", "children"), + Output("offcanvas-metadata", "is_open"), + Input({"type": "graph", "index": ALL}, "clickData"), + prevent_initial_call=True + ) + def _show_metadata_from_graphs(graph_data: dict) -> tuple: + """Generates the data for the offcanvas displayed when a particular + point in a graph is clicked on. + + :param graph_data: The data from the clicked point in the graph. + :type graph_data: dict + :returns: The data to be displayed on the offcanvas and the + information to show the offcanvas. + :rtype: tuple(list, list, bool) + """ + + trigger = Trigger(callback_context.triggered) + + try: + idx = 0 if trigger.idx == "tput" else 1 + graph_data = graph_data[idx]["points"] + except (IndexError, KeyError, ValueError, TypeError): + raise PreventUpdate + + def _process_stats(data: list, param: str) -> list: + """Process statistical data provided by plot.ly box graph. + + :param data: Statistical data provided by plot.ly box graph. + :param param: Parameter saying if the data come from "tput" or + "lat" graph. + :type data: list + :type param: str + :returns: Listo of tuples where the first value is the + statistic's name and the secont one it's value. + :rtype: list + """ + if len(data) == 7: + stats = ("max", "upper fence", "q3", "median", "q1", + "lower fence", "min") + elif len(data) == 9: + stats = ("outlier", "max", "upper fence", "q3", "median", + "q1", "lower fence", "min", "outlier") + elif len(data) == 1: + if param == "lat": + stats = ("Average Latency at 50% PDR", ) + else: + stats = ("Throughput", ) + else: + return list() + unit = " [us]" if param == "lat" else str() + return [(f"{stat}{unit}", f"{value['y']:,.0f}") + for stat, value in zip(stats, data)] + + graph = list() + if trigger.idx == "tput": + title = "Throughput" + elif trigger.idx == "lat": + title = "Latency" + if len(graph_data) == 1: + hdrh_data = graph_data[0].get("customdata", None) + if hdrh_data: + graph = [dbc.Card( + class_name="gy-2 p-0", + children=[ + dbc.CardHeader(hdrh_data.pop("name")), + dbc.CardBody(children=[ + dcc.Graph( + id="hdrh-latency-graph", + figure=graph_hdrh_latency( + hdrh_data, self._graph_layout + ) + ) + ]) + ]) + ] + else: + raise PreventUpdate + metadata = [ + dbc.Card( + class_name="gy-2 p-0", + children=[ + dbc.CardHeader(children=[ + dcc.Clipboard( + target_id="tput-lat-metadata", + title="Copy", + style={"display": "inline-block"} + ), + title + ]), + dbc.CardBody( + id="tput-lat-metadata", + class_name="p-0", + children=[dbc.ListGroup( + [ + dbc.ListGroupItem([dbc.Badge(k), v]) + for k, v in _process_stats( + graph_data, trigger.idx) + ], + flush=True) + ] + ) + ] + ) + ] + + return metadata, graph, True