From 216e54d279dbb67d37d745e6fafaca1ac429093c Mon Sep 17 00:00:00 2001 From: Jordi Date: Fri, 9 Feb 2024 14:09:21 +0100 Subject: [PATCH] The explorer can now fix a tree that has size 0 when starting. --- ete4/smartview/gui/server.py | 20 ++++++++++++++++ ete4/smartview/gui/static/js/draw.js | 34 ++++++++++++++++++++++++---- ete4/smartview/gui/static/js/gui.js | 5 +++- 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/ete4/smartview/gui/server.py b/ete4/smartview/gui/server.py index 9ca896ce9..02075cc04 100755 --- a/ete4/smartview/gui/server.py +++ b/ete4/smartview/gui/server.py @@ -567,6 +567,26 @@ def callback(tree_id): except (AssertionError, newick.NewickError) as e: abort(400, f'cannot edit {node_id}: {e}') +@put('/trees//to_dendrogram') +def callback(tree_id): + tree_data, subtree = touch_and_get(tree_id) + node_id = req_json() + ops.to_dendrogram(tree_data.tree[subtree][node_id]) + ops.update_sizes_all(tree_data.tree) + return {'message': 'ok'} + +@put('/trees//to_ultrametric') +def callback(tree_id): + tree_data, subtree = touch_and_get(tree_id) + + try: + node_id = req_json() + ops.to_ultrametric(tree_data.tree[subtree][node_id]) + ops.update_sizes_all(tree_data.tree) + return {'message': 'ok'} + except AssertionError as e: + abort(400, f'cannot convert to ultrametric {tree_id}: {e}') + @put('/trees//update_props') def callback(tree_id): tree_data, subtree = touch_and_get(tree_id) diff --git a/ete4/smartview/gui/static/js/draw.js b/ete4/smartview/gui/static/js/draw.js index 77050e5e8..e05bf90a8 100644 --- a/ete4/smartview/gui/static/js/draw.js +++ b/ete4/smartview/gui/static/js/draw.js @@ -2,7 +2,7 @@ import { view, get_tid, on_box_click, on_box_wheel, on_box_mouseenter, on_box_mouseleave, - get_active_layouts } from "./gui.js"; + get_active_layouts, tree_command, reset_view } from "./gui.js"; import { update_minimap_visible_rect } from "./minimap.js"; import { colorize_active, get_active_class } from "./active.js"; import { colorize_searches, get_search_class } from "./search.js"; @@ -11,7 +11,8 @@ import { on_box_contextmenu } from "./contextmenu.js"; import { api } from "./api.js"; import { draw_pixi, clear_pixi } from "./pixi.js"; -export { update, draw_tree, draw_tree_scale, draw_aligned, draw, get_class_name, cartesian_shifted, update_aligned_panel_display }; +export { update, draw_tree, draw_tree_scale, draw_aligned, draw, get_class_name, + cartesian_shifted, update_aligned_panel_display }; // Update the view of all elements (gui, tree, minimap). @@ -22,7 +23,7 @@ async function update() { update_minimap_visible_rect(); } -function get_tree_params() { +async function get_tree_params() { const [zx, zy, za] = [view.zoom.x, view.zoom.y, view.zoom.a]; const [x, y] = [view.tl.x, view.tl.y]; const [w, h] = [div_tree.offsetWidth / zx, div_tree.offsetHeight / zy]; @@ -50,7 +51,32 @@ var align_drawing = false; // Ask the server for a tree in the new defined region, and draw it. async function draw_tree() { div_tree.style.cursor = "wait"; - const params = get_tree_params(); + + const params = await get_tree_params(); + + // Fix the tree if it has zero width. + if (params.w <= 0) { + const result = await Swal.fire({ + icon: "error", + html: `Cannot draw tree with width ${params.w}`, + confirmButtonText: "Convert to ultrametric (equidistant leaves)", + showDenyButton: true, + denyButtonText: "Convert to dendrogram (remove all distances)", + showCancelButton: true, + }); + + if (result.isConfirmed) { + await tree_command("to_ultrametric", []); + reset_view(); + } + else if (result.isDenied) { + await tree_command("to_dendrogram", []); + reset_view(); + } + + return; + } + const qs = new URLSearchParams(params).toString(); // "x=...&y=..." try { diff --git a/ete4/smartview/gui/static/js/gui.js b/ete4/smartview/gui/static/js/gui.js index 481ac683f..1d18dc192 100644 --- a/ete4/smartview/gui/static/js/gui.js +++ b/ete4/smartview/gui/static/js/gui.js @@ -294,7 +294,10 @@ async function tree_command(command, params=undefined) { try { await api_put(`/trees/${get_tid()}/${command}`, params); - const commands_modifying_size = ["set_outgroup", "remove", "update_props"]; + const commands_modifying_size = [ + "set_outgroup", "remove", "update_props", "edit", + "to_ultrametric", "to_dendrogram"]; + if (commands_modifying_size.includes(command)) view.tree_size = await api(`/trees/${get_tid()}/size`); }