+def _tpc_generate_html_table(header, data, out_file_name, legend=u"",
+ footnote=u""):
+ """Generate html table from input data with simple sorting possibility.
+
+ :param header: Table header.
+ :param data: Input data to be included in the table. It is a list of lists.
+ Inner lists are rows in the table. All inner lists must be of the same
+ length. The length of these lists must be the same as the length of the
+ header.
+ :param out_file_name: The name (relative or full path) where the
+ generated html table is written.
+ :param legend: The legend to display below the table.
+ :param footnote: The footnote to display below the table (and legend).
+ :type header: list
+ :type data: list of lists
+ :type out_file_name: str
+ :type legend: str
+ :type footnote: str
+ """
+
+ try:
+ idx = header.index(u"Test Case")
+ except ValueError:
+ idx = 0
+ params = {
+ u"align-hdr": ([u"left", u"center"], [u"left", u"left", u"center"]),
+ u"align-itm": ([u"left", u"right"], [u"left", u"left", u"right"]),
+ u"width": ([28, 9], [4, 24, 10])
+ }
+
+ df_data = pd.DataFrame(data, columns=header)
+
+ df_sorted = [df_data.sort_values(
+ by=[key, header[idx]], ascending=[True, True]
+ if key != header[idx] else [False, True]) for key in header]
+ df_sorted_rev = [df_data.sort_values(
+ by=[key, header[idx]], ascending=[False, True]
+ if key != header[idx] else [True, True]) for key in header]
+ df_sorted.extend(df_sorted_rev)
+
+ fill_color = [[u"#d4e4f7" if idx % 2 else u"#e9f1fb"
+ for idx in range(len(df_data))]]
+ table_header = dict(
+ values=[f"<b>{item}</b>" for item in header],
+ fill_color=u"#7eade7",
+ align=params[u"align-hdr"][idx]
+ )
+
+ fig = go.Figure()
+
+ for table in df_sorted:
+ columns = [table.get(col) for col in header]
+ fig.add_trace(
+ go.Table(
+ columnwidth=params[u"width"][idx],
+ header=table_header,
+ cells=dict(
+ values=columns,
+ fill_color=fill_color,
+ align=params[u"align-itm"][idx]
+ )
+ )
+ )
+
+ buttons = list()
+ menu_items = [f"<b>{itm}</b> (ascending)" for itm in header]
+ menu_items_rev = [f"<b>{itm}</b> (descending)" for itm in header]
+ menu_items.extend(menu_items_rev)
+ for idx, hdr in enumerate(menu_items):
+ visible = [False, ] * len(menu_items)
+ visible[idx] = True
+ buttons.append(
+ dict(
+ label=hdr.replace(u" [Mpps]", u""),
+ method=u"update",
+ args=[{u"visible": visible}],
+ )
+ )
+
+ fig.update_layout(
+ updatemenus=[
+ go.layout.Updatemenu(
+ type=u"dropdown",
+ direction=u"down",
+ x=0.0,
+ xanchor=u"left",
+ y=1.045,
+ yanchor=u"top",
+ active=len(menu_items) - 1,
+ buttons=list(buttons)
+ )
+ ]
+ )
+
+ ploff.plot(
+ fig,
+ show_link=False,
+ auto_open=False,
+ filename=f"{out_file_name}_in.html"
+ )
+
+ file_name = out_file_name.split(u"/")[-1]
+ if u"vpp" in out_file_name:
+ path = u"_tmp/src/vpp_performance_tests/comparisons/"
+ else:
+ path = u"_tmp/src/dpdk_performance_tests/comparisons/"
+ with open(f"{path}{file_name}.rst", u"wt") as rst_file:
+ rst_file.write(
+ u"\n"
+ u".. |br| raw:: html\n\n <br />\n\n\n"
+ u".. |prein| raw:: html\n\n <pre>\n\n\n"
+ u".. |preout| raw:: html\n\n </pre>\n\n"
+ )
+ rst_file.write(
+ u".. raw:: html\n\n"
+ f' <iframe frameborder="0" scrolling="no" '
+ f'width="1600" height="1000" '
+ f'src="../..{out_file_name.replace(u"_build", u"")}_in.html">'
+ f'</iframe>\n\n'
+ )
+ if legend:
+ rst_file.write(legend[1:].replace(u"\n", u" |br| "))
+ if footnote:
+ rst_file.write(footnote.replace(u"\n", u" |br| ")[1:])
+
+
+def table_perf_comparison(table, input_data):
+ """Generate the table(s) with algorithm: table_perf_comparison