From 1a503f08313e47514d1a24f4ac35a3f0d620cf2a Mon Sep 17 00:00:00 2001 From: Umar Farooq Ghumman <46414488+mail4umar@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:39:09 -0500 Subject: [PATCH] QueryProfilerComparison - UI update (#1288) * Added functionality to synchronize side-by-side view * added hour glass for waiting * Added session parameter display --- .../performance/vertica/qprof_interface.py | 121 ++++++++++++++++-- 1 file changed, 111 insertions(+), 10 deletions(-) diff --git a/verticapy/performance/vertica/qprof_interface.py b/verticapy/performance/vertica/qprof_interface.py index 7aad12262..d4f321129 100644 --- a/verticapy/performance/vertica/qprof_interface.py +++ b/verticapy/performance/vertica/qprof_interface.py @@ -125,7 +125,8 @@ def __init__( ] ) self.update_query_display() - + self.session_param_display = [] + self.update_session_param_display() self.index_widget = widgets.IntText( description="Index:", value=self.transactions_idx ) @@ -270,6 +271,7 @@ def get_qplan_tree(self, use_javascript=True, hide_settings=False, **style_kwarg ), "Tree style": widgets.VBox(tree_settings), "Query text": self.query_display, + "Session Parameters": self.session_param_display, } query_text_index = list(accordion_items.keys()).index("Query text") self.accordions = Visualizer._accordion( @@ -328,15 +330,37 @@ def update_qplan_tree( """ Callback function that displays the Query Plan Tree. """ + # Create an output widget to hold the hourglass and the tree + output = widgets.Output() + display(output) + + # Show hourglass in the output before starting long-running task + with output: + output.clear_output(wait=True) # Clear any previous content + # Create the hourglass icon + hourglass_icon = widgets.HTML( + value='', + layout=widgets.Layout(display="flex", justify_content="center"), + ) + vbox = widgets.VBox( + [hourglass_icon], + layout=widgets.Layout(justify_content="center", align_items="center"), + ) + display(vbox) + + # Processing the inputs and generate the tree (long running task) metric = [ QprofUtility._get_metrics_name(i, inv=True) for i in [metric1, metric2] ] if len(metric) == 0: metric = ["rows"] + graph_id = "g" + str(uuid.uuid4()) self.query_select_button_selected(index) if self.pathid_dropdown.get_child_attr("disabled"): path_id = None + + # Ensure the hourglass stays displayed during the processing of get_qplan_tree if self.use_javascript == False: graph = super().get_qplan_tree( metric=metric, @@ -353,10 +377,18 @@ def update_qplan_tree( display_tooltip_descriptors=display_tooltip_descriptors, **self.style_kwargs, ) # type: ignore - html_widget = widgets.HTML(value=graph.pipe(format="svg").decode("utf-8")) - box = widgets.HBox([html_widget]) - box.layout.justify_content = "center" - display(box) + + # After long-running task is done, update output with the result + with output: + output.clear_output( + wait=True + ) # Clear the hourglass before displaying the tree + html_widget = widgets.HTML( + value=graph.pipe(format="svg").decode("utf-8") + ) + box = widgets.HBox([html_widget]) + box.layout.justify_content = "center" + display(box) else: raw = super().get_qplan_tree( metric=metric, @@ -374,11 +406,19 @@ def update_qplan_tree( display_tooltip_descriptors=display_tooltip_descriptors, **self.style_kwargs, ) - output = read_package_file("html/index.html") - output = replace_value(output, "var dotSrc = [];", f"var dotSrc = `{raw}`;") - output = replace_value(output, 'id="graph"', f'id="{graph_id}"') - output = replace_value(output, "#graph", f"#{graph_id}") - display(HTML(output)) + + output_html = read_package_file("html/index.html") + output_html = replace_value( + output_html, "var dotSrc = [];", f"var dotSrc = `{raw}`;" + ) + output_html = replace_value(output_html, 'id="graph"', f'id="{graph_id}"') + output_html = replace_value(output_html, "#graph", f"#{graph_id}") + + with output: + output.clear_output(wait=True) # Clear the hourglass + display(HTML(output_html)) + + # Update the header after the tree is displayed self.qpt_header.value = ( f"