NCBI C++ ToolKit
phylo_tree_label.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: phylo_tree_label.cpp 47479 2023-05-02 13:24:02Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Vladimir Tereshkov
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
35 
36 #include <gui/opengl/irender.hpp>
37 #include <gui/opengl/glutils.hpp>
38 
40 
42  CPhyloTreeNode* node,
43  IPhyloTreeLOD* lod,
44  CVect2<float>& pixel_offset) const
45 {
46  pixel_offset.X() = 0.0f;
47  pixel_offset.Y() = 0.0f;
48 
49  float defNodeSize = (float)lod->GetNodeLabelDist(node);
50 
51  const CGlTextureFont* bestFont = &m_SL->GetFont();
52 
53  // we have place to show it
54  IRender& gl = GetGl();
55 
56  CVect2<float> label_size((float)gl.TextWidth(bestFont, label.c_str()),
57  (float)gl.GetMetric(bestFont, IGlFont::eMetric_CharHeight));
58 
59  bool bLeft = cosf((**node).GetAngle()) < 0.0f;
60 
61  if (!bLeft) {
62  // 2 pixels visible distance from node
63  pixel_offset.X() = defNodeSize + 2.0f;
64  pixel_offset.Y() = -label_size.Y() / 2.0f;
65  }
66  else {
67  pixel_offset.X() = -(defNodeSize + 4.0f + label_size.X());
68  pixel_offset.Y() = -label_size.Y() / 2.0f;
69  }
70 
71  return label_size;
72 }
73 
75  CPhyloTreeNode* node,
76  IPhyloTreeLOD* lod,
77  const CVect2<float>& label_size,
78  CVect2<float>& pixel_offset) const
79 {
80  pixel_offset.X() = 0.0f;
81  pixel_offset.Y() = 0.0f;
82 
83  float defNodeSize = lod->GetNodeLabelDist(node);
84 
85  bool bLeft = cosf((**node).GetAngle()) < 0.0f;
86 
87  if (!bLeft) {
88  // 2 pixels visible distance from node
89  pixel_offset.X() = defNodeSize + 2.0f;
90  pixel_offset.Y() = -label_size.Y() / 2.0f;
91  }
92  else {
93  pixel_offset.X() = -(defNodeSize + 4.0f + label_size.X());
94  pixel_offset.Y() = -label_size.Y() / 2.0f;
95  }
96 
97  return label_size;
98 }
99 
101  const CPhyloTreeNode &node,
103 {
104  string autoLabel;
105 
106  switch (lbl){
108  {
109  autoLabel = "";
110  break;
111  }
113  {
114  int ilabel;
115 
116  if (!node.IsLeaf()) {
117  ilabel = (*node).GetPamlCounter() + 1;
118  }
119  else {
120  int ibase = static_cast<int>(tree.GetNumNodes()-1 - tree.GetRoot()->GetNumLeaves());
121  ilabel = ibase + node.GetValue().IDX().second + 1;
122  }
123 
124  autoLabel = NStr::IntToString(ilabel);
125  break;
126  }
128  {
129  int ilabel;
130 
131  if (node.IsLeaf()) {
132  ilabel = node.GetValue().IDX().second;
133  }
134  else if (!node.HasParent()) {
135  ilabel = node.GetValue().GetNumLeaves() + 1;
136  }
137  else {
138  ilabel = tree.GetRoot()->GetNumLeaves() + (*node).GetPamlCounter() + 1;
139  }
140  autoLabel = NStr::IntToString(ilabel);
141  break;
142  }
143  default:
144  autoLabel = "";
145  break;
146  }
147 
148  return autoLabel;
149 }
150 
151 string CPhyloTreeLabel::GetLabel(const CPhyloTree &tree, const CPhyloTreeNode &node) const
152 {
153  string result = (*node).GetLabel();
155 
156  // adding auto-label
157  string autoLabel = x_GenerateAutoLabel(tree, node, m_SL->GetAutoLabels());
158  if (autoLabel.length()) {
159  if (result.length()) {
160  result = " | " + result;
161  }
162  result = autoLabel + result;
163  }
164 
165  if (!node.Expanded()) {
166  //label += (" (" + NStr::IntToString((**node).CountSubnodes()) + " nodes)");
167  if (result.length()) {
168  result += " | ";
169  }
170  result += (NStr::IntToString((*node).GetNumLeaves()) + " leaves");
171  }
172 
173  if (m_SL->GetMaxLabelLength() > 0 && int(result.length()) > m_SL->GetMaxLabelLength()) {
174  result = result.substr(0, m_SL->GetMaxLabelLength()) + "...";
175  }
176 
177  return result;
178 }
179 
181 {
182  m_SL.Reset(&sl);
184 }
185 
186 void CPhyloTreeLabel::SetLabelFormat(const string &fmt, const CPhyloTree *tree)
187 {
188  if (!fmt.empty() && (m_Format!=fmt)) {
189  m_Format = fmt;
190  }
191 
192  // May be called before model is loaded. If so it will be called
193  // again during layout.
194  if (tree == NULL)
195  return;
196 
197  m_LabelFormat.reset(new CBioTreeFormatLabel(tree->GetFeatureDict(), fmt));
198 }
199 
200 string CPhyloTreeLabel::GetLabelForNode(const CPhyloTree &tree, const CPhyloTreeNode &node, const string &format)
201 {
202  string saved_format = m_Format;
204  string ready_label = m_LabelFormat->FormatLabel((*node).GetBioTreeFeatureList());
205  SetLabelFormat(saved_format, &tree);
206  return ready_label;
207 }
208 
210  const CPhyloTreeNode &node,
211  const string &format,
212  const string &line_break)
213 {
214  std::vector<std::string> arr;
215  std::string final_text;
216 
217  string ready_label = GetLabelForNode(tree, node, format);
218 
219  // Get tip text, and then remove any lines we don't need.
220  NStr::Split(ready_label, "\n", arr);
221  for (unsigned int i=0; i<arr.size(); ++i) {
222  if (arr[i].length() > 0) {
223  // This is in the title
224  if (arr[i].substr(0, 6) == "label:")
225  continue;
226  // This is visually obvious
227  if (arr[i].substr(0,16) == "$NODE_COLLAPSED:")
228  continue;
229 
230  // Remove blank features (no text after first ':')...
231  std::string::size_type idx1 = arr[i].find_first_of(":");
232  if (arr[i].length() > idx1+1) {
233  std::string::size_type idx2 = arr[i].find_first_not_of(' ', idx1+1);
234  if (idx2 != std::string::npos) {
235  final_text += arr[i];
236  final_text += line_break; // may be \n or for pdf (to put an escaped \n in the pdf) \\\\n
237  }
238  }
239  }
240  }
241 
242  return final_text;
243 }
244 
245 
247 {
248  TVPUnit h = -1;
249 
250  const CGlTextureFont* font = &m_SL->GetFont();
251 
252  IRender& gl = GetGl();
253  h = ((TVPUnit) gl.TextHeight(font) + 1);
254 
255  return h;
256 }
257 
259 {
261 
262  if (h > 0) {
263  TVPUnit visibleDistance = lod->DistanceBetweenNodes();
264  return visibleDistance >= h;
265  }
266 
267  return false;
268 }
269 
int GetNumLeaves() const
CRef< CPhyloTreeScheme > m_SL
CVect2< float > GetNodeLabelOffset(const string &label, CPhyloTreeNode *node, IPhyloTreeLOD *lod, CVect2< float > &pixel_offset) const
Get label rectangle.
std::unique_ptr< CBioTreeFormatLabel > m_LabelFormat
bool IsVisible(IPhyloTreeLOD *lod) const
string GetToolTipForNode(const CPhyloTree &tree, const CPhyloTreeNode &node, const string &format, const string &line_break)
string GetLabel(const CPhyloTree &tree, const CPhyloTreeNode &node) const
string x_GenerateAutoLabel(const CPhyloTree &tree, const CPhyloTreeNode &node, CPhyloTreeScheme::TAutoLabels lbl) const
string GetLabelForNode(const CPhyloTree &tree, const CPhyloTreeNode &node, const string &format)
void SetLabelFormat(const string &fmt, const CPhyloTree *tree)
TVPUnit GetMinVerticalSeparation() const
void SetScheme(CPhyloTreeScheme &sl, const CPhyloTree *tree)
bool Expanded() const
Return true if node is currently not collapsed.
string & SetLabelFormat(void)
int GetMaxLabelLength() const
const CGlTextureFont & GetFont(void) const
const TAutoLabels & GetAutoLabels(void) const
Tree subclass also has functions and data needed for rendering and selection.
Definition: phylo_tree.hpp:52
TData & GetValue()
Return the value object for the node.
Definition: tree_model.hpp:159
bool HasParent() const
Check if the node has a parent.
Definition: tree_model.hpp:90
bool IsLeaf() const
Report whether this is a leaf node.
Definition: tree_model.hpp:121
virtual TVPUnit DistanceBetweenNodes(void) const =0
virtual float GetNodeLabelDist(const CPhyloTreeNode *n) const
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
T & X()
Definition: vect2.hpp:107
T & Y()
Definition: vect2.hpp:109
GLdouble TModelUnit
Definition: gltypes.hpp:48
IRender & GetGl()
convenience function for getting current render manager
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
virtual TModelUnit TextWidth(const CGlTextureFont *font, const char *text) const =0
int TVPUnit
Definition: gltypes.hpp:47
virtual TModelUnit GetMetric(const CGlTextureFont *font, IGlFont::EMetric metric, const char *text=NULL, int len=-1) const =0
Calls the standard font metric functions except for pdf in which case it first replaces any bitmap fo...
@ eMetric_CharHeight
Definition: glfont.hpp:76
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3452
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
Definition: ncbistr.cpp:3192
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5086
static const char label[]
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
int i
static Format format
Definition: njn_ioutil.cpp:53
else result
Definition: token2.c:20
Modified on Thu Jul 18 16:05:12 2024 by modify_doxy.py rev. 669887