Commit b65db1f2 authored by Tiago Peixoto's avatar Tiago Peixoto
Browse files

draw_hierarchy(): Improve efficiency of "hshortcuts" option

parent 61c4bfed
...@@ -2150,7 +2150,7 @@ struct enum_from_int ...@@ -2150,7 +2150,7 @@ struct enum_from_int
}; };
void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos, void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos,
boost::any obeta, boost::any octs, bool); boost::any obeta, boost::any octs, bool, size_t);
BOOST_PYTHON_MODULE(libgraph_tool_draw) BOOST_PYTHON_MODULE(libgraph_tool_draw)
{ {
......
...@@ -128,7 +128,8 @@ void get_control_points(vector<size_t>& path, PosProp pos, double beta, ...@@ -128,7 +128,8 @@ void get_control_points(vector<size_t>& path, PosProp pos, double beta,
} }
template <class Graph> template <class Graph>
void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path) void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path,
size_t max_depth)
{ {
vector<size_t> s_root; vector<size_t> s_root;
vector<size_t> t_root; vector<size_t> t_root;
...@@ -138,7 +139,7 @@ void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path) ...@@ -138,7 +139,7 @@ void tree_path(Graph& g, size_t s, size_t t, vector<size_t>& path)
size_t v = s; size_t v = s;
size_t u = t; size_t u = t;
while (v != u) while (v != u && s_root.size() < max_depth)
{ {
typename graph_traits<Graph>::in_edge_iterator e, e_end; typename graph_traits<Graph>::in_edge_iterator e, e_end;
tie(e, e_end) = in_edges(v, g); tie(e, e_end) = in_edges(v, g);
...@@ -200,7 +201,8 @@ void pack(vector<point_t>& cp, vector<T>& ncp) ...@@ -200,7 +201,8 @@ void pack(vector<point_t>& cp, vector<T>& ncp)
struct do_get_cts struct do_get_cts
{ {
template <class Graph, class Tree, class PosProp, class BProp, class CMap> template <class Graph, class Tree, class PosProp, class BProp, class CMap>
void operator()(Graph& g, Tree* t, PosProp tpos, BProp beta, CMap cts, bool is_tree) const void operator()(Graph& g, Tree* t, PosProp tpos, BProp beta, CMap cts,
bool is_tree, size_t max_depth) const
{ {
vector<size_t> path; vector<size_t> path;
vector<point_t> cp; vector<point_t> cp;
...@@ -215,7 +217,7 @@ struct do_get_cts ...@@ -215,7 +217,7 @@ struct do_get_cts
path.clear(); path.clear();
if (is_tree) if (is_tree)
tree_path(*t, u, v, path); tree_path(*t, u, v, path, max_depth);
else else
graph_path(*t, u, v, path); graph_path(*t, u, v, path);
cp.clear(); cp.clear();
...@@ -239,7 +241,7 @@ struct get_pointers ...@@ -239,7 +241,7 @@ struct get_pointers
}; };
void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos, void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos,
boost::any obeta, boost::any octs, bool is_tree) boost::any obeta, boost::any octs, bool is_tree, size_t max_depth)
{ {
typedef property_map_type::apply<vector<double>, typedef property_map_type::apply<vector<double>,
GraphInterface::edge_index_map_t>::type GraphInterface::edge_index_map_t>::type
...@@ -253,7 +255,7 @@ void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos, ...@@ -253,7 +255,7 @@ void get_cts(GraphInterface& gi, GraphInterface& tgi, boost::any otpos,
run_action<>() run_action<>()
(gi, std::bind(do_get_cts(), placeholders::_1, placeholders::_2, (gi, std::bind(do_get_cts(), placeholders::_1, placeholders::_2,
placeholders::_3, beta, cts, is_tree), placeholders::_3, beta, cts, is_tree, max_depth),
get_pointers::apply<graph_tool::detail::always_directed>::type(), get_pointers::apply<graph_tool::detail::always_directed>::type(),
vertex_scalar_vector_properties()) vertex_scalar_vector_properties())
(tgi.GetGraphView(), otpos); (tgi.GetGraphView(), otpos);
......
...@@ -1226,7 +1226,8 @@ def transform_scale(M, scale): ...@@ -1226,7 +1226,8 @@ def transform_scale(M, scale):
scale / np.sqrt(2)) scale / np.sqrt(2))
return np.sqrt(p[0] ** 2 + p[1] ** 2) return np.sqrt(p[0] ** 2 + p[1] ** 2)
def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True): def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True,
max_depth=None):
r"""Return the Bézier spline control points for the edges in ``g``, given the hierarchical structure encoded in graph `t`. r"""Return the Bézier spline control points for the edges in ``g``, given the hierarchical structure encoded in graph `t`.
Parameters Parameters
...@@ -1253,6 +1254,9 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True): ...@@ -1253,6 +1254,9 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True):
is_tree : ``bool`` (optional, default: ``True``) is_tree : ``bool`` (optional, default: ``True``)
If ``True``, ``t`` must be a directed tree, otherwise it can be any If ``True``, ``t`` must be a directed tree, otherwise it can be any
connected graph. connected graph.
max_depth : ``int`` (optional, default: ``None``)
If supplied, only the first ``max_depth`` bottom levels of the hierarchy
will be used.
Returns Returns
...@@ -1326,13 +1330,16 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True): ...@@ -1326,13 +1330,16 @@ def get_hierarchy_control_points(g, t, tpos, beta=0.8, cts=None, is_tree=True):
else: else:
beta = beta.copy("double") beta = beta.copy("double")
if max_depth is None:
max_depth = t.num_vertices()
tu = GraphView(tu, skip_vfilt=True) tu = GraphView(tu, skip_vfilt=True)
libgraph_tool_draw.get_cts(u._Graph__graph, libgraph_tool_draw.get_cts(u._Graph__graph,
tu._Graph__graph, tu._Graph__graph,
_prop("v", tu, tpos), _prop("v", tu, tpos),
_prop("e", u, beta), _prop("e", u, beta),
_prop("e", u, cts), _prop("e", u, cts),
is_tree) is_tree, max_depth)
return cts return cts
# #
...@@ -1590,24 +1597,13 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1590,24 +1597,13 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
dist = shortest_distance(t, source=root) dist = shortest_distance(t, source=root)
hvvisible.fa = dist.fa >= hide hvvisible.fa = dist.fa >= hide
hevisible = t.new_edge_property("bool", True)
if hshortcuts > 0:
root = t.vertex(t.num_vertices() - 1)
dist = shortest_distance(t, source=root)
nodes = [v for v in t.vertices() if dist[v] <= hshortcuts]
for v in nodes:
for u in nodes:
if u == v:
continue
t.add_edge(u, v)
pos = g.own_property(tpos.copy()) pos = g.own_property(tpos.copy())
if verbose: if verbose:
print("getting cts...") print("getting cts...")
cts = get_hierarchy_control_points(g, t, tpos, beta, cts = get_hierarchy_control_points(g, t, tpos, beta,
is_tree=hshortcuts == 0) max_depth=len(state.levels) - hshortcuts)
if verbose: if verbose:
print("done.") print("done.")
...@@ -1679,8 +1675,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4, ...@@ -1679,8 +1675,7 @@ def draw_hierarchy(state, pos=None, layout="radial", beta=0.8, ealpha=0.4,
t_orig = t t_orig = t
t = GraphView(t, t = GraphView(t,
vfilt=lambda v: int(v) >= g.num_vertices(True) and hvvisible[v], vfilt=lambda v: int(v) >= g.num_vertices(True) and hvvisible[v])
efilt=hevisible)
if verbose: if verbose:
print("joining graphs") print("joining graphs")
props = [(pos, tpos), props = [(pos, tpos),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment