bpp-phyl3 3.0.0
CladogramPlot.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 "CladogramPlot.h"
7
8// From the STL:
9#include <memory>
10
11using namespace bpp;
12using namespace std;
13
14CladogramDrawBranchEvent::CladogramDrawBranchEvent(const TreeDrawing* source, GraphicDevice* gd, const INode* node, double length, const Cursor& cursor, short orientation) :
15 DrawIBranchEvent(source, gd, node, cursor), orientation_(), length_(length)
16{
18}
19
21{
22 double offset = 0;
23 if (getINode()->hasDistanceToFather())
24 {
25 offset = orientation_ * length_ * position;
26 }
27 return getCursor().getTranslation(offset, 0);
28}
29
31{
33 if (hasTree())
34 totalDepth_ = static_cast<double>(TreeTemplateTools::getDepth(*tree_->getRootNode()));
35}
36
38{
39 if (hasTree())
40 {
41 DrawTreeEvent treeEvent(this, &gDevice);
42 fireBeforeTreeEvent_(treeEvent);
43 unsigned int tipCounter = 0;
44 double y;
45 recursivePlot_(gDevice, *const_cast<INode*>(tree_->getRootNode()),
47 y,
50 tipCounter);
51 fireAfterTreeEvent_(treeEvent);
52 }
53}
54
55void CladogramPlot::recursivePlot_(GraphicDevice& gDevice, INode& node, double x, double& y, double hDirection, double vDirection, unsigned int& tipCounter) const
56{
57 double depth = static_cast<double>(TreeTemplateTools::getDepth(node));
58 double x2 = ((getHorizontalOrientation() == ORIENTATION_LEFT_TO_RIGHT ? totalDepth_ : 0) - depth) * getXUnit() * hDirection;
59 unique_ptr<Cursor> cursor;
60 unique_ptr<DrawINodeEvent> nodeEvent;
61 unique_ptr<DrawIBranchEvent> branchEvent;
63 if (node.isLeaf())
64 {
65 y = ((getVerticalOrientation() == ORIENTATION_TOP_TO_BOTTOM ? 0 : getHeight()) + static_cast<double>(tipCounter) * vDirection) * getYUnit();
66 tipCounter++;
67 cursor.reset(new Cursor(x2, y, 0, hpos));
68 nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
69 fireBeforeNodeEvent_(*nodeEvent);
70 }
71 else if (node.getInfos().isCollapsed())
72 {
73 y = ((getVerticalOrientation() == ORIENTATION_TOP_TO_BOTTOM ? 0 : getHeight()) + static_cast<double>(tipCounter) * vDirection) * getYUnit();
74 tipCounter++;
75 cursor.reset(new Cursor(x2, y, 0, hpos));
76 nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
77 fireBeforeNodeEvent_(*nodeEvent);
78 }
79 else
80 {
81 // Vertical line. Call the method on son nodes first:
82 double miny = 1000000; // (unsigned int)(-log(0));
83 double maxy = 0;
84 for (unsigned int i = 0; i < node.getNumberOfSons(); i++)
85 {
86 double yson;
87 recursivePlot_(gDevice, *node.getSon(i), x2, yson, hDirection, vDirection, tipCounter);
88 if (yson < miny)
89 miny = yson;
90 if (yson > maxy)
91 maxy = yson;
92 }
93 y = (maxy + miny) / 2.;
94 cursor.reset(new Cursor(x2, y, 0, hpos));
95 nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
96 fireBeforeNodeEvent_(*nodeEvent);
97 gDevice.drawLine(x2, miny, x2, maxy);
98 }
99 // Actualize node infos:
100 node.getInfos().setX(x2);
101 node.getInfos().setY(y);
102 nodeEvent.reset(new DrawINodeEvent(this, &gDevice, &node, *cursor));
103 fireAfterNodeEvent_(*nodeEvent);
104
105 // Horizontal line
106 branchEvent.reset(new CladogramDrawBranchEvent(this, &gDevice, &node, x2 - x, *cursor, getHorizontalOrientation()));
107 fireBeforeBranchEvent_(*branchEvent);
108 gDevice.drawLine(x, y, x2, y);
109 fireAfterBranchEvent_(*branchEvent);
110}
void fireBeforeBranchEvent_(const DrawIBranchEvent &event) const
const Tree & tree() const override
double getXUnit() const override
double getYUnit() const override
void setTree(const Tree &tree) override
std::unique_ptr< TreeTemplate< INode > > tree_
void fireAfterTreeEvent_(const DrawTreeEvent &event) const
void fireBeforeNodeEvent_(const DrawINodeEvent &event) const
void fireAfterNodeEvent_(const DrawINodeEvent &event) const
bool hasTree() const override
void fireBeforeTreeEvent_(const DrawTreeEvent &event) const
void fireAfterBranchEvent_(const DrawIBranchEvent &event) const
Cursor getBranchCursor(double position) const
void recursivePlot_(GraphicDevice &gDevice, INode &node, double x, double &y, double hDirection, double vDirection, unsigned int &tipCounter) const
double getWidth() const override
Definition: CladogramPlot.h:55
double getHeight() const override
Definition: CladogramPlot.h:56
void drawDendrogram_(GraphicDevice &gDevice) const override
void setTree(const Tree &tree) override
Data structure describing a plotting direction.
Definition: TreeDrawing.h:54
Cursor getTranslation(double x, double y) const
Definition: TreeDrawing.h:75
virtual const Cursor & getCursor() const
Definition: TreeDrawing.h:159
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:172
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
virtual const NodeInfos & getInfos() const
Definition: NodeTemplate.h:144
const NodeTemplate< NodeInfos > * getSon(size_t i) const
Definition: NodeTemplate.h:108
virtual bool isLeaf() const
Definition: Node.h:679
virtual size_t getNumberOfSons() const
Definition: Node.h:355
Basal interface for tree drawing classes.
Definition: TreeDrawing.h:223
static unsigned int getDepth(const Node &node)
Get the depth of the subtree defined by node 'node', i.e. the maximum number of sons 'generations'.
Interface for phylogenetic tree objects.
Definition: Tree.h:115
Defines the basic types of data flow nodes.