diff --git a/docs/user_guide/nad_widget.md b/docs/user_guide/nad_widget.md index 759e9bc..c677322 100644 --- a/docs/user_guide/nad_widget.md +++ b/docs/user_guide/nad_widget.md @@ -50,6 +50,7 @@ update_nad(nadwidget, svg, invalid_lf: bool = False, enable_callbacks: bool = Fa - invalid_lf: when True the opacity style for some of the displayed info's (e.g., active and reactive power) is decreased, making them barely visible in the diagram. - enable_callbacks: if True, enable the callbacks for selecting nodes (through a SHIFT+CLICK on a node) and moving nodes. Please note that this feature is working with versions of PyPowSyBl equal to or greater than v1.8.1. - grayout: if True, changes the diagram elements' color to gray. +- keep_viewbox: if True, keeps the current diagram content, including pan and zoom settings. ## Customize widget's interactions By default, only the pan and zoom interactions with the diagram are active. diff --git a/js/nadwidget.ts b/js/nadwidget.ts index c9a55b2..6cb6bce 100644 --- a/js/nadwidget.ts +++ b/js/nadwidget.ts @@ -77,10 +77,12 @@ function render({ model, el }: RenderProps) { model.send({ event: 'move_text_node' }); }; - function render_diagram(model: any): any { + function render_diagram( + model: any, + diagram_svg: string, + diagram_meta: string | null + ): any { const diagram_data = model.get('diagram_data'); - const svg_data = diagram_data['svg_data']; - const metadata = diagram_data['metadata']; const is_invalid_lf = diagram_data['invalid_lf']; const is_grayout = diagram_data['grayout']; const is_enabled_callbacks = diagram_data['enable_callbacks']; @@ -94,8 +96,8 @@ function render({ model, el }: RenderProps) { new NetworkAreaDiagramViewer( el_div, - svg_data, - metadata ? JSON.parse(metadata) : null, + diagram_svg, + diagram_meta ? JSON.parse(diagram_meta) : null, 800, 600, 800, @@ -119,12 +121,29 @@ function render({ model, el }: RenderProps) { return el_div; } - const diagram_element = render_diagram(model); + const diagram_element = render_diagram( + model, + model.get('diagram_data')['svg_data'], + model.get('diagram_data')['metadata'] + ); el.appendChild(diagram_element); model.on('change:diagram_data', () => { + const diagram_data = model.get('diagram_data'); + const keep_viewbox = diagram_data['keep_viewbox']; + let diagram_svg = ''; + let diagram_meta = null; + const nodes = el.querySelectorAll('.svg-nad-viewer-widget')[0]; - const new_el = render_diagram(model); + + if (keep_viewbox) { + diagram_svg = nodes.querySelector(':scope > svg')?.outerHTML ?? ''; + } else { + diagram_svg = diagram_data['svg_data']; + diagram_meta = diagram_data['metadata']; + } + + const new_el = render_diagram(model, diagram_svg, diagram_meta); el.replaceChild(new_el, nodes); }); } diff --git a/src/pypowsybl_jupyter/nadwidget.py b/src/pypowsybl_jupyter/nadwidget.py index c9b71a7..1f66959 100644 --- a/src/pypowsybl_jupyter/nadwidget.py +++ b/src/pypowsybl_jupyter/nadwidget.py @@ -88,7 +88,7 @@ def display_nad(svg, invalid_lf: bool = False, enable_callbacks: bool = False, g svg_metadata = "" if not enable_callbacks else _get_svg_metadata(svg) return NadWidget(diagram_data= {"svg_data": svg_value, "metadata": svg_metadata, "invalid_lf": invalid_lf, "enable_callbacks": enable_callbacks, "grayout": grayout}) -def update_nad(nadwidget, svg, invalid_lf: bool = False, enable_callbacks: bool = False, grayout: bool = False): +def update_nad(nadwidget, svg, invalid_lf: bool = False, enable_callbacks: bool = False, grayout: bool = False, keep_viewbox: bool = False): """ Updates an existing NAD widget with a new SVG content @@ -98,6 +98,7 @@ def update_nad(nadwidget, svg, invalid_lf: bool = False, enable_callbacks: bool invalid_lf: when True the opacity style for some of the displayed info's (e.g., active and reactive power) is decreased, making them barely visible in the diagram. enable_callbacks: if True, enable the callbacks for moving and selecting nodes in the diagram. Please note that this feature is working with versions of PyPowSyBl equal or greater than v1.8.1. grayout: if True, changes the diagram elements' color to gray. + keep_viewbox: if True, keeps the current diagram content, including pan and zoom settings. Examples: @@ -108,4 +109,4 @@ def update_nad(nadwidget, svg, invalid_lf: bool = False, enable_callbacks: bool svg_value=_get_svg_string(svg) svg_metadata = "" if not enable_callbacks else _get_svg_metadata(svg) - nadwidget.diagram_data= {"svg_data": svg_value, "metadata": svg_metadata, "invalid_lf": invalid_lf, "enable_callbacks": enable_callbacks, "grayout": grayout} + nadwidget.diagram_data= {"svg_data": svg_value, "metadata": svg_metadata, "invalid_lf": invalid_lf, "enable_callbacks": enable_callbacks, "grayout": grayout, "keep_viewbox": keep_viewbox} diff --git a/src/pypowsybl_jupyter/networkexplorer.py b/src/pypowsybl_jupyter/networkexplorer.py index 1926e95..331984a 100644 --- a/src/pypowsybl_jupyter/networkexplorer.py +++ b/src/pypowsybl_jupyter/networkexplorer.py @@ -225,13 +225,13 @@ def compute_nad_data(el, depth=0): current_nad_data = compute_nad_data(None) - def update_nad_widget(new_diagram_data, enable_callbacks=True, grayout=False): + def update_nad_widget(new_diagram_data, enable_callbacks=True, grayout=False, keep_viewbox=False): nonlocal nad_widget if nad_widget==None: nad_widget=display_nad(new_diagram_data, enable_callbacks=enable_callbacks, grayout=grayout) nad_widget.on_select_node(lambda event : go_to_vl_from_nad(event)) else: - update_nad(nad_widget,new_diagram_data, enable_callbacks=enable_callbacks, grayout=grayout) + update_nad(nad_widget,new_diagram_data, enable_callbacks=enable_callbacks, grayout=grayout, keep_viewbox=keep_viewbox) in_progress_widget=widgets.HTML(value=PROGRESS_EMPTY_SVG, layout=widgets.Layout(width='30', justify_content='flex-end', margin='0px 20px 0px 0px')) @@ -254,9 +254,9 @@ def disable_in_progress(): def update_nad_diagram(el): nonlocal current_nad_data, nad_displayed_vl_id if nad_widget != None: - enable_in_progress() - update_nad_widget(current_nad_data, enable_callbacks=False, grayout=True) + update_nad_widget('', enable_callbacks=False, grayout=True, keep_viewbox=True) display(nad_widget) + enable_in_progress() update_sld_widget(current_sld_data, True, enable_callbacks=False) display(sld_widget) if map_widget != None: