+ return fig_tput, fig_lat
+
+
+def graph_hdrh_latency(data: dict, layout: dict) -> go.Figure:
+ """
+ """
+
+ fig = None
+
+ traces = list()
+ for idx, (lat_name, lat_hdrh) in enumerate(data.items()):
+ try:
+ decoded = hdrh.histogram.HdrHistogram.decode(lat_hdrh)
+ except (hdrh.codec.HdrLengthException, TypeError) as err:
+ continue
+ previous_x = 0.0
+ prev_perc = 0.0
+ xaxis = list()
+ yaxis = list()
+ hovertext = list()
+ for item in decoded.get_recorded_iterator():
+ # The real value is "percentile".
+ # For 100%, we cut that down to "x_perc" to avoid
+ # infinity.
+ percentile = item.percentile_level_iterated_to
+ x_perc = min(percentile, PERCENTILE_MAX)
+ xaxis.append(previous_x)
+ yaxis.append(item.value_iterated_to)
+ hovertext.append(
+ f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
+ f"Direction: {(u'W-E', u'E-W')[idx % 2]}<br>"
+ f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
+ f"Latency: {item.value_iterated_to}uSec"
+ )
+ next_x = 100.0 / (100.0 - x_perc)
+ xaxis.append(next_x)
+ yaxis.append(item.value_iterated_to)
+ hovertext.append(
+ f"<b>{_GRAPH_LAT_HDRH_DESC[lat_name]}</b><br>"
+ f"Direction: {(u'W-E', u'E-W')[idx % 2]}<br>"
+ f"Percentile: {prev_perc:.5f}-{percentile:.5f}%<br>"
+ f"Latency: {item.value_iterated_to}uSec"
+ )
+ previous_x = next_x
+ prev_perc = percentile
+
+ traces.append(
+ go.Scatter(
+ x=xaxis,
+ y=yaxis,
+ name=_GRAPH_LAT_HDRH_DESC[lat_name],
+ mode=u"lines",
+ legendgroup=_GRAPH_LAT_HDRH_DESC[lat_name],
+ showlegend=bool(idx % 2),
+ line=dict(
+ color=_COLORS[int(idx/2)],
+ dash=u"solid",
+ width=1 if idx % 2 else 2
+ ),
+ hovertext=hovertext,
+ hoverinfo=u"text"
+ )
+ )
+ if traces:
+ fig = go.Figure()
+ fig.add_traces(traces)
+ layout_hdrh = layout.get("plot-hdrh-latency", None)
+ if lat_hdrh:
+ fig.update_layout(layout_hdrh)