59 if( ladderize_tree ) {
62 init_tree_( orig_tree );
93 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
101 if( strokes.empty() ) {
108 throw std::runtime_error(
"Edge stroke vector has wrong size." );
110 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
117 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
125 if( strokes.empty() ) {
132 throw std::runtime_error(
"Edge stroke vector has wrong size." );
134 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
141 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
157 if( strokes.empty() ) {
168 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
171 }
else if( strokes.size() == tree_.
node_count() -1 ) {
174 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
184 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
192 throw std::runtime_error(
193 "Edge stroke vector has wrong size. Has to be either tree.node_count(), "
194 "tree.node_count() - 1, or leaf_edge_count( tree )."
205 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
213 if( shapes.empty() ) {
220 throw std::runtime_error(
"Edge shape vector has wrong size." );
222 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
229 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
237 if( shapes.empty() ) {
244 throw std::runtime_error(
"Node shape vector has wrong size." );
246 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
255 void LayoutBase::init_tree_(
Tree const& orig_tree )
258 for(
size_t i = 0; i < tree_.
node_count(); ++i ) {
260 auto const& orig_node = orig_tree.
node_at(i);
263 assert( node.index() == i && orig_node.index() == i );
270 if( orig_node_data_ptr ) {
276 for(
size_t i = 0; i < tree_.
edge_count(); ++i ) {
278 auto const& orig_edge = orig_tree.
edge_at(i);
281 assert( edge.index() == i && orig_edge.index() == i );
287 auto orig_edge_data_ptr = orig_edge.data_cast<CommonEdgeData>();
288 if( orig_edge_data_ptr ) {
289 edge.data<CommonEdgeData>().branch_length = orig_edge_data_ptr->branch_length;
297 void LayoutBase::init_layout_()
299 if(
tree().empty() ) {
306 auto& node_data = tree_.
node_at( it.node().index() ).
data<LayoutNodeData>();
307 if( node_data.parent_index == -1 ) {
308 node_data.parent_index = parent;
310 parent = it.node().index();
315 set_node_distances_cladogram_();
317 set_node_distances_phylogram_();
319 throw std::runtime_error(
"Invalid LayoutType value." );
324 set_node_spreadings_leaves_();
326 set_node_spreadings_all_( inner_node_spreading_ );
330 void LayoutBase::set_node_spreadings_leaves_()
337 size_t leaf_count = 0;
339 auto& node_data = tree_.
node_at( it.node().index() ).
data<LayoutNodeData>();
341 auto const lcd =
static_cast<double>( leaf_count );
342 auto const nld =
static_cast<double>( num_leaves );
343 node_data.spreading = lcd / nld;
347 assert( leaf_count == num_leaves + 1 );
351 auto chrn_min_s = std::vector<double>(
tree().
node_count(), -1.0 );
352 auto chrn_max_s = std::vector<double>(
tree().
node_count(), -1.0 );
356 auto const node_index = it.node().index();
357 auto& node_data = tree_.
node_at( node_index ).
data<LayoutNodeData>();
358 auto const prnt_index = node_data.parent_index;
360 if( node_data.spreading < 0.0 ) {
362 assert( chrn_min_s[ node_index ] > -1.0 );
363 assert( chrn_max_s[ node_index ] > -1.0 );
365 auto min_max_diff = chrn_max_s[ node_index ] - chrn_min_s[ node_index ];
366 node_data.spreading = chrn_min_s[ node_index ] + min_max_diff / 2.0;
369 if( chrn_min_s[ prnt_index ] < 0.0 || chrn_min_s[ prnt_index ] > node_data.spreading ) {
370 chrn_min_s[ prnt_index ] = node_data.spreading;
372 if( chrn_max_s[ prnt_index ] < 0.0 || chrn_max_s[ prnt_index ] < node_data.spreading ) {
373 chrn_max_s[ prnt_index ] = node_data.spreading;
380 assert( ! tree_.
empty() );
382 throw std::invalid_argument(
383 "Tree is not bifurcating. Cannot draw with inner node spreading."
398 auto visits = std::vector<size_t>( tree_.
node_count(), 0 );
399 size_t node_counter = 0;
402 auto& node_data = it.node().data<LayoutNodeData>();
403 auto const node_index = it.node().index();
407 ++visits[ node_index ];
408 assert( visits[ node_index ] <= 3 );
412 }
else if(
is_leaf( it.node() ) || visits[ node_index ] == 2 ) {
413 auto const ncd =
static_cast<double>( node_counter );
414 auto const nnd =
static_cast<double>( num_nodes );
415 node_data.spreading = ncd / nnd;
419 assert( node_counter == num_nodes + 1 );
426 auto& root_data = root.
data<LayoutNodeData>();
427 auto const degr =
degree( root );
431 auto const& l_data = root.link().outer().node().data<LayoutNodeData>();
432 auto const& r_data = root.link().next().outer().node().data<LayoutNodeData>();
433 root_data.spreading = ( l_data.spreading + r_data.spreading ) / 2.0;
436 auto const& l_data = root.link().outer().node().data<LayoutNodeData>();
437 auto const& r_data = root.link().next().next().outer().node().data<LayoutNodeData>();
438 root_data.spreading = ( l_data.spreading + r_data.spreading ) / 2.0;
446 void LayoutBase::set_node_distances_phylogram_()
452 assert( ! node_dists.empty() );
453 auto const max_d = *std::max_element( node_dists.begin(), node_dists.end() );
455 for(
size_t i = 0; i < node_dists.size(); ++i ) {
456 tree_.
node_at(i).
data<LayoutNodeData>().distance = node_dists[i] / max_d;
460 void LayoutBase::set_node_distances_cladogram_()
469 auto const root_height =
static_cast<double>( heights[
tree().
root_node().
index() ] );
474 if( it.is_first_iteration() ) {
479 auto const height =
static_cast<double>( heights[ it.node().index() ]);
480 assert(
height <= root_height );
483 auto const distance = ( root_height -
height ) / root_height;
484 tree_.
node_at( it.node().index() ).data<LayoutNodeData>().distance = distance;
494 type_ = drawing_type;
495 if( ! tree_.
empty() ) {
507 inner_node_spreading_ = value;
508 if( ! tree_.
empty() ) {
515 return inner_node_spreading_;
520 align_labels_ = value;
525 return align_labels_;
530 extra_spacer_ = value;
535 return extra_spacer_;
545 return text_template_;
550 return text_template_;