bpp-phyl3  3.0.0
PhylogramPlot.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "../Tree/TreeTemplateTools.h"
6 #include "PhylogramPlot.h"
7 
8 using namespace bpp;
9 
10 #include <string>
11 
12 using namespace std;
13 
14 PhylogramDrawBranchEvent::PhylogramDrawBranchEvent(const TreeDrawing* source, GraphicDevice* gd, const INode* node, const Cursor& cursor, short orientation) :
15  DrawIBranchEvent(source, gd, node, cursor), orientation_()
16 {
18 }
19 
21 {
22  double offset = 0;
23  if (getINode()->hasDistanceToFather())
24  {
25  double l = getINode()->getDistanceToFather();
26  offset = orientation_ * l * position * getTreeDrawing()->getXUnit();
27  }
28  return getCursor().getTranslation(offset, 0);
29 }
30 
31 void PhylogramPlot::setTree(const Tree* tree)
32 {
34  if (tree)
35  {
36  getTree_()->setVoidBranchLengths(0.);
37  }
38 }
39 
41 {
42  if (hasTree())
43  {
44  DrawTreeEvent treeEvent(this, &gDevice);
45  fireBeforeTreeEvent_(treeEvent);
46  unsigned int tipCounter = 0;
47  double y;
48  recursivePlot_(gDevice, *const_cast<INode*>(getTree_()->getRootNode()),
50  y,
53  tipCounter);
54  fireAfterTreeEvent_(treeEvent);
55  }
56 }
57 
58 void PhylogramPlot::recursivePlot_(GraphicDevice& gDevice, INode& node, double x, double& y, double hDirection, double vDirection, unsigned int& tipCounter) const
59 {
60  double x2;
61  bool drawBranch = true;
62  if (node.hasDistanceToFather())
63  {
64  double length = node.hasDistanceToFather() ? node.getDistanceToFather() : 0.;
65  if (length < -10000000)
66  {
67  x2 = x;
68  drawBranch = false;
69  }
70  else
71  {
72  x2 = x + hDirection * length * getXUnit();
73  }
74  }
75  else
76  {
77  x2 = x;
78  drawBranch = false;
79  }
80 
81  unique_ptr<Cursor> cursor;
82  unique_ptr<DrawINodeEvent> nodeEvent;
83  unique_ptr<DrawIBranchEvent> branchEvent;
85  if (node.isLeaf())
86  {
87  y = ((getVerticalOrientation() == ORIENTATION_TOP_TO_BOTTOM ? 0 : getHeight()) + static_cast<double>(tipCounter) * vDirection) * getYUnit();
88  tipCounter++;
89  cursor.reset(new Cursor(x2, y, 0, hpos));
90  nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
91  fireBeforeNodeEvent_(*nodeEvent);
92  }
93  else if (node.getInfos().isCollapsed())
94  {
95  y = ((getVerticalOrientation() == ORIENTATION_TOP_TO_BOTTOM ? 0 : getHeight()) + static_cast<double>(tipCounter) * vDirection) * getYUnit();
96  tipCounter++;
97  cursor.reset(new Cursor(x2, y, 0, hpos));
98  nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
99  fireBeforeNodeEvent_(*nodeEvent);
100  }
101  else
102  {
103  // Vertical line. Call the method on son nodes first:
104  double miny = 1000000; // (unsigned int)(-log(0));
105  double maxy = 0;
106  for (unsigned int i = 0; i < node.getNumberOfSons(); i++)
107  {
108  double yson;
109  recursivePlot_(gDevice, *node.getSon(i), x2, yson, hDirection, vDirection, tipCounter);
110  if (yson < miny)
111  miny = yson;
112  if (yson > maxy)
113  maxy = yson;
114  }
115  y = (maxy + miny) / 2.;
116  cursor.reset(new Cursor(x2, y, 0, hpos));
117  nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
118  fireBeforeNodeEvent_(*nodeEvent);
119  gDevice.drawLine(x2, miny, x2, maxy);
120  }
121 
122  // Actualize node infos:
123  node.getInfos().setX(x2);
124  node.getInfos().setY(y);
125  nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
126  fireAfterNodeEvent_(*nodeEvent);
127 
128  if (drawBranch)
129  {
130  // Horizontal line
131  branchEvent.reset(new PhylogramDrawBranchEvent(this, &gDevice, &node, *cursor, getHorizontalOrientation()));
132  fireBeforeBranchEvent_(*branchEvent);
133  gDevice.drawLine(x, y, x2, y);
134  fireAfterBranchEvent_(*branchEvent);
135  }
136 }
void fireBeforeBranchEvent_(const DrawIBranchEvent &event) const
TreeTemplate< INode > * getTree_()
void fireAfterTreeEvent_(const DrawTreeEvent &event) const
void fireBeforeNodeEvent_(const DrawINodeEvent &event) const
void setTree(const Tree *tree)
void fireAfterNodeEvent_(const DrawINodeEvent &event) const
void fireBeforeTreeEvent_(const DrawTreeEvent &event) const
void fireAfterBranchEvent_(const DrawIBranchEvent &event) const
Data structure describing a plotting direction.
Definition: TreeDrawing.h:53
Cursor getTranslation(double x, double y) const
Definition: TreeDrawing.h:74
virtual const TreeDrawing * getTreeDrawing() const
Definition: TreeDrawing.h:155
virtual const Cursor & getCursor() const
Definition: TreeDrawing.h:158
Event class that uses INode object (more efficient than relying on nodes id, but less generic).
const INode * getINode() const
Event class that uses INode object (more efficient than relying on nodes id, but less generic).
Event class used by TreeDrawing classes.
Definition: TreeDrawing.h:171
static short TEXT_HORIZONTAL_LEFT
static short TEXT_HORIZONTAL_RIGHT
virtual void drawLine(double x1, double y1, double x2, double y2)=0
The NodeTemplate class.
Definition: NodeTemplate.h:39
const NodeTemplate< NodeInfos > * getSon(size_t i) const
Definition: NodeTemplate.h:108
virtual const NodeInfos & getInfos() const
Definition: NodeTemplate.h:144
virtual bool hasDistanceToFather() const
Tell is this node has a distance to the father.
Definition: Node.h:288
virtual bool isLeaf() const
Definition: Node.h:667
virtual double getDistanceToFather() const
Get the distance to the father node is there is one, otherwise throw a NodeException.
Definition: Node.h:250
virtual size_t getNumberOfSons() const
Definition: Node.h:355
Cursor getBranchCursor(double position) const
PhylogramDrawBranchEvent(const TreeDrawing *source, GraphicDevice *gd, const INode *node, const Cursor &cursor, short orientation)
void recursivePlot_(GraphicDevice &gDevice, INode &node, double x, double &y, double hDirection, double vDirection, unsigned int &tipCounter) const
double getHeight() const
Definition: PhylogramPlot.h:54
void drawDendrogram_(GraphicDevice &gDevice) const
void setTree(const Tree *tree=0)
double getWidth() const
Definition: PhylogramPlot.h:53
Basal interface for tree drawing classes.
Definition: TreeDrawing.h:223
virtual double getXUnit() const =0
Interface for phylogenetic tree objects.
Definition: Tree.h:115
Defines the basic types of data flow nodes.