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

Go to the SVN repository for this file.

1 /* $Id: layout.cpp 26082 2012-07-18 18:05:51Z katargir $
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: Mike DiCuccio
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
34 #include <corelib/ncbiutil.hpp>
35 
36 
38 
39 
40 //
41 //
42 // CLayoutObject
43 //
44 //
45 
46 
48  : m_Selected(false)
49  , m_bHorz(true)
50  , m_bFlipStrand(false)
51  , m_bInlineChildren(false)
52  , m_Parent(NULL)
53 {
54 }
55 
56 
57 // virtual dtor for our layout objects
59 {
60 }
61 
62 
64 {
65  return m_Selected;
66 }
67 
68 
70 {
71  m_Selected = flag;
72 }
73 
74 
76 {
77  return m_Rect;
78 }
79 
80 
82 {
83  m_Rect = rc;
84 }
85 
86 
88 {
89  m_bHorz = horz;
90 }
91 
92 
94 {
95  return m_bHorz;
96 }
97 
98 
100 {
101  m_bFlipStrand = b_flip;
102 }
103 
104 
106 {
107  return m_bFlipStrand;
108 }
109 
110 
111 // Accessors for parent-child relationships in features
113 {
114  return m_Parent;
115 }
116 
117 
119 {
120  return m_Children;
121 }
122 
123 
125 {
126  m_Parent = feat;
127 }
128 
129 
131 {
132  return m_Children;
133 }
134 
135 
137 {
138  m_bInlineChildren = type == eInline ? true : false;
139 }
140 
141 
143 {
145 }
146 
147 
149 {
150 }
151 
152 
153 // Access the sub-intervals in this object
154 const vector<TSeqRange>& CLayoutObject::GetIntervals(void) const
155 {
156  if (m_Intervals.size() == 0) {
157  x_CalcIntervals();
158  }
159  return m_Intervals;
160 }
161 
162 //
163 //
164 //
165 // CLayout
166 //
167 //
168 //
169 
170 
171 // clear opur internal list of objects
172 void CLayout::Clear(void)
173 {
174  m_Layout.clear();
175 }
176 
177 
178 // access the entire layout
180 {
181  return m_Layout;
182 }
183 
184 
186 {
187  return m_Layout;
188 }
189 
190 
191 // access a row of the layout
192 const CLayout::TLayoutRow& CLayout::GetRow(size_t row) const
193 {
194  _ASSERT(row < m_Layout.size());
195  return m_Layout[row];
196 }
197 
198 
200 {
201  _ASSERT(row < m_Layout.size());
202  return m_Layout[row];
203 }
204 
205 
206 // add a new row to the layout
208 {
209  return AddRow(TLayoutRow());
210 }
211 
212 
213 // add a new row to the layout
215 {
216  m_Layout.push_back(row);
217  return m_Layout.back();
218 }
219 
220 
221 void CLayout::Append(const CLayout& layout)
222 {
223  ITERATE (TLayout, row_iter, layout.GetLayout()) {
224  m_Layout.push_back(*row_iter);
225  }
226 }
227 
228 
229 void CLayout::Insert(const CLayout& layout, size_t row)
230 {
231  TLayout::iterator it = m_Layout.begin() + row;
232  ITERATE (TLayout, row_iter, layout.GetLayout()) {
233  m_Layout.insert(it, *row_iter);
234  it++;
235  }
236 }
237 
238 
239 bool CLayout::IsEmpty() const
240 {
241  return m_Layout.size() == 0;
242 }
243 
244 
245 
246 //
247 //
248 //
249 // C2DLayoutEngine
250 //
251 //
252 //
253 
254 ///
255 /// sorting functor for finding a range inside a collection of layout objects
256 ///
258 {
259  bool operator()(const CRef<CLayoutObject>& obj1,
260  const CRef<CLayoutObject>& obj2) const
261  {
262  //return (obj1->GetRange().GetToOpen() < obj2->GetRange().GetFrom());
263  return (obj1->GetRange() < obj2->GetRange() &&
264  obj1->GetRange().GetTo() < obj2->GetRange().GetFrom());
265  }
266 };
267 
269 {
270 public:
272  {
273  }
274 
275  void SetRange(const TSeqRange& range)
276  {
277  m_Range = range;
278  }
279 
280  /// access the position of this object.
281  TSeqRange GetRange(void) const
282  {
283  return m_Range;
284  }
285 
286  ///
287  /// all other interfaces to this class throw an exception
288  ///
289 
290  /// access the position of this object.
291  const objects::CSeq_loc& GetLocation(void) const
292  {
293  throw runtime_error("GetLocation() not implemented");
294  }
295 
296  /// compare this object to another, based on position
297  bool LessByPos (const CLayoutObject&) const
298  {
299  throw runtime_error("LessByPos() not implemented");
300  }
301 
302  /// compare this object to another, based on size
303  bool LessBySize(const CLayoutObject&) const
304  {
305  throw runtime_error("LessBySize() not implemented");
306  }
307 
308  /// access our core component - we wrap an object(s) of some sort.
309  /// This returns the object at a given sequence position; this is useful if
310  /// the layout object wraps more than one object
312  {
313  throw runtime_error("GetObject() not implemented");
314  }
315 
316  /// retrieve CObjects corresponding to this CLayoutObject
317  void GetObjects(vector<CConstRef<CObject> >& /*objs*/) const
318  {
319  throw runtime_error("GetObjects() not implemented");
320  }
321 
322  /// check if the wrapped object(s) is the one
324  {
325  throw runtime_error("HasObject() not implemented");
326  }
327 
328  /// retrieve the type of this object
329  EType GetType() const
330  {
331  throw runtime_error("GetType() not implemented");
332  }
333 
334 private:
336 };
337 
338 
339 // perform 2D layout
340 // this arranges a set of layout objects into a non-overlapping series of rows
341 void C2DLayoutEngine::Layout(TObjects& objs, CLayout& layout, bool side_label)
342 {
343  //typedef list< CRangeCollection<TSeqPos> > TRowRanges;
344  //TObjects objs(objects);
345  std::sort(objs.begin(), objs.end(), SLayoutBySize());
346 
347  SRangeSorter func;
348 
349  layout.Clear();
350 
351  CDummyLayoutObject range_holder;
352  CRef<CLayoutObject> ref_obj(&range_holder);
353 
354  TObjects::const_reverse_iterator riter(objs.end());
355  TObjects::const_reverse_iterator rend (objs.begin());
356  for ( ; riter != rend; ++riter) {
357  CRef<CLayoutObject> ref(*riter);
358  bool need_extra_space = false;
359 // const CLayoutFeat* feat =
360 // dynamic_cast<const CLayoutFeat*>(ref.GetPointer());
361 // if (feat &&
362 // feat->GetFeature().GetData().GetSubtype() ==
363 // objects::CSeqFeatData::eSubtype_gene
364 // && !feat->GetChildren().empty()) {
365 // need_extra_space = true;
366 // }
367 
368  TSeqRange intersect_range = ref->GetRange();
369  {{
370  TSeqPos from_off = m_MinDist * (need_extra_space ? 2 : 1);
371  if (side_label) {
372  from_off += m_SideSpace;
373  }
374  if (intersect_range.GetFrom() > from_off) {
375  intersect_range.SetFrom(intersect_range.GetFrom() - from_off);
376  } else {
377  intersect_range.SetFrom(0);
378  }
379  }}
380  {{
381  TSeqPos expanded_to = intersect_range.GetTo() +
382  m_MinDist * (need_extra_space ? 2 : 1);
383  if (side_label) {
384  expanded_to += m_SideSpace;
385  }
386  if (expanded_to > intersect_range.GetTo()) {
387  /// guard against problems with whole ranges
388  intersect_range.SetTo(expanded_to);
389  }
390  }}
391 
392  range_holder.SetRange(intersect_range);
393 
394  bool inserted = false;
395  NON_CONST_ITERATE (CLayout::TLayout, iter, layout.SetLayout()) {
396  bool intersects = false;
397 
398  CLayout::TLayoutRow::iterator row_iter =
399  std::lower_bound(iter->begin(), iter->end(), ref_obj, func); /* NCBI_FAKE_WARNING: WorkShop */
400 
401  CRef<CLayoutObject> ref_row_iter;
402  TSeqRange total_range = TSeqRange::GetWhole();
403  if (row_iter != iter->end()) {
404  ref_row_iter = *row_iter;
405  total_range = (*row_iter)->GetRange();
406  intersects =
407  intersect_range.IntersectingWith
408  ((*row_iter)->GetRange());
409  }
410  if ( !intersects ) {
411  inserted = true;
412  iter->insert(row_iter, ref);
413  break;
414  }
415  }
416  if ( !inserted ) {
417  CLayout::TLayoutRow& row = layout.AddRow();
418  row.push_back(ref);
419  }
420  /**/
421 
422  /**
423  CRef<CLayoutObject> obj = *riter;
424  TSeqRange range = obj->GetLocation().GetTotalRange();
425  TSeqRange test_range(range);
426  if (test_range.GetFrom() > m_MinDist) {
427  test_range.SetFrom(test_range.GetFrom() - m_MinDist);
428  } else {
429  test_range.SetFrom(0);
430  }
431  test_range.SetTo(test_range.GetTo() + m_MinDist);
432 
433  bool placed = false;
434  size_t row = 0;
435  TRowRanges::iterator row_iter = ranges.begin();
436  for ( ; row_iter != ranges.end(); ++row_iter, ++row) {
437  if ( !row_iter->IntersectingWith(test_range) ) {
438  break;
439  }
440  }
441 
442  if (row_iter == ranges.end()) {
443  // begin an entirely new row
444  layout.AddRow();
445  ranges.push_back(CRangeCollection<TSeqPos>());
446  row_iter = ranges.end();
447  --row_iter;
448  }
449 
450  CLayout::TLayoutRow& lr = layout.SetRow(row);
451  lr.push_back(obj);
452  *row_iter += range;
453  **/
454  }
455 
456 
457 
458 #if 0
459  // clear our layout to start
460  layout.Clear();
461 
462  // for each member in the incoming list...
463  ITERATE (TObjects, iter, objects) {
464  TSeqRange new_range;
465  try {
466  new_range = (*iter)->GetRange();
467  }
468  catch (CException&) {
469  continue;
470  }
471 
472  TSignedSeqPos start = 0;
473  TSignedSeqPos end = 0;
474  if (new_range.GetFrom() < new_range.GetTo()) {
475  start = new_range.GetFrom() - m_MinDist;
476  end = new_range.GetTo() + m_MinDist;
477  } else {
478  start = new_range.GetTo() - m_MinDist;
479  end = new_range.GetFrom() + m_MinDist;
480  }
481 
482  // scan the current layout
483  bool inserted = false;
484  NON_CONST_ITERATE (CLayout::TLayout, row_iter, layout.SetLayout()) {
485  // ... and try to insert at the end
486  // since we're sorted by position, we only need to check the end
487  const CLayoutObject& last_obj = *row_iter->back();
488  const TSeqRange& last_range = last_obj.GetRange();
489  if (last_range.GetFrom() < last_range.GetTo()) {
490  if (TSignedSeqPos(last_range.GetTo()) <= start) {
491  row_iter->push_back(*iter);
492  inserted = true;
493  break;
494  }
495  } else {
496  if (TSignedSeqPos(last_range.GetFrom()) <= start) {
497  row_iter->push_back(*iter);
498  inserted = true;
499  break;
500  }
501  }
502  }
503 
504  // insert our interval info as we need
505  if ( !inserted ) {
506  // begin an entirely new row
507  CLayout::TLayoutRow& row = layout.AddRow();
508  row.push_back(*iter);
509  }
510  }
511 
512 #endif
513 
514 #if 0
515  {
516  int i;
517  int j;
518 
519  _TRACE("\n" << features.size() << " items, spacing = " << spacing);
520  for (i = 0; i < features.size(); ++i) {
521  _TRACE(i + 1 << ": "
522  << features[i]->GetTextId() << ": {"
523  << features[i]->GetExtent().GetFrom() << " - "
524  << features[i]->GetExtent().GetTo() << "}");
525  }
526 
527  for (i = 0; i < pack.size(); ++i) {
528  _TRACE(i + 1 << ":");
529  for (j = 0; j < pack[i].size(); ++j) {
530 
531  dumpRecursive(*pack[i][j]);
532  }
533  cerr << endl;
534  }
535  cerr << endl;
536  }
537 #endif
538 }
539 
540 
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
TSeqRange m_Range
Definition: layout.cpp:335
bool LessBySize(const CLayoutObject &) const
compare this object to another, based on size
Definition: layout.cpp:303
const objects::CSeq_loc & GetLocation(void) const
all other interfaces to this class throw an exception
Definition: layout.cpp:291
bool LessByPos(const CLayoutObject &) const
compare this object to another, based on position
Definition: layout.cpp:297
bool HasObject(CConstRef< CObject >) const
check if the wrapped object(s) is the one
Definition: layout.cpp:323
EType GetType() const
retrieve the type of this object
Definition: layout.cpp:329
CConstRef< CObject > GetObject(TSeqPos) const
access our core component - we wrap an object(s) of some sort.
Definition: layout.cpp:311
void SetRange(const TSeqRange &range)
Definition: layout.cpp:275
TSeqRange GetRange(void) const
access the position of this object.
Definition: layout.cpp:281
void GetObjects(vector< CConstRef< CObject > > &) const
retrieve CObjects corresponding to this CLayoutObject
Definition: layout.cpp:317
class CLayoutObject defines an interface that wraps a rectilinear abstract object.
Definition: layout.hpp:61
class CLayout is a container of objects laid out in a series of rows or tracks.
Definition: layout.hpp:229
CRef –.
Definition: ncbiobj.hpp:618
static const char * pack(const char *fmt,...)
Definition: genparams.c:254
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
int TSignedSeqPos
Type for signed sequence position.
Definition: ncbimisc.hpp:887
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define NULL
Definition: ncbistd.hpp:225
#define _TRACE(message)
Definition: ncbidbg.hpp:122
TObjects & SetChildren(void)
Definition: layout.cpp:130
TSeqPos m_MinDist
the minimum distance we permit two items to be within
Definition: layout.hpp:304
void SetModelRect(const TModelRect &rect)
Definition: layout.cpp:81
void Clear(void)
clear opur internal list of objects
Definition: layout.cpp:172
bool m_bInlineChildren
Definition: layout.hpp:158
bool IsFlippedStrand() const
Definition: layout.cpp:105
bool IsSelected() const
object is selected
Definition: layout.cpp:63
bool m_bFlipStrand
Definition: layout.hpp:157
TLayoutRow & SetRow(size_t row)
Definition: layout.cpp:199
vector< TLayoutRow > TLayout
Definition: layout.hpp:232
void SetParent(CLayoutObject *feat)
Definition: layout.cpp:124
const TLayoutRow & GetRow(size_t row) const
access a row of the layout
Definition: layout.cpp:192
bool IsEmpty() const
Definition: layout.cpp:239
vector< CRef< CLayoutObject > > TObjects
Definition: layout.hpp:63
const TLayout & GetLayout(void) const
access the entire layout
Definition: layout.cpp:179
TModelRect GetModelRect() const
area rectangle of the object in model space
Definition: layout.cpp:75
bool IsHorizontal() const
Definition: layout.cpp:93
vector< TSeqRange > m_Intervals
Definition: layout.hpp:167
TObjects m_Children
Definition: layout.hpp:162
CLayoutObject * m_Parent
Definition: layout.hpp:161
virtual void Layout(TObjects &objects, CLayout &layout, bool side_label=false)
Definition: layout.cpp:341
void SetHorizontal(bool b_horz)
Definition: layout.cpp:87
bool m_Selected
Definition: layout.hpp:155
vector< CRef< CObject > > TObjects
Definition: objects.hpp:63
virtual ~CLayoutObject()
Definition: layout.cpp:58
EType
type of layout objects currently supported
Definition: layout.hpp:67
TModelRect m_Rect
Definition: layout.hpp:164
TSeqPos m_SideSpace
preserved left side space for label.
Definition: layout.hpp:305
void SetFlippedStrand(bool b_flip)
Definition: layout.cpp:99
virtual void x_CalcIntervals(void) const
Definition: layout.cpp:148
TLayout & SetLayout(void)
Definition: layout.cpp:185
const vector< TSeqRange > & GetIntervals(void) const
Definition: layout.cpp:154
virtual TSeqRange GetRange(void) const =0
access the position of this object.
TLayoutRow & AddRow(void)
add a row to the layout
Definition: layout.cpp:207
vector< CRef< CLayoutObject > > TLayoutRow
Definition: layout.hpp:231
bool m_bHorz
Definition: layout.hpp:156
void Append(const CLayout &layout)
append an entire layout to this one
Definition: layout.cpp:221
const CLayoutObject * GetParent(void) const
Definition: layout.cpp:112
EChildrenLayout GetChildrenLayout(void) const
Definition: layout.cpp:142
void SetChildrenLayout(EChildrenLayout type)
Definition: layout.cpp:136
TLayout m_Layout
our layout. This is a nested container - a set of rows.
Definition: layout.hpp:261
void Insert(const CLayout &layout, size_t row)
insert an entire layout to this one
Definition: layout.cpp:229
void SetSelected(bool flag)
Definition: layout.cpp:69
const TObjects & GetChildren(void) const
Definition: layout.cpp:118
bool IntersectingWith(const TThisType &r) const
Definition: range.hpp:331
static TThisType GetWhole(void)
Definition: range.hpp:272
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
void SetFrom(TFrom value)
Assign a value to From data member.
Definition: Range_.hpp:231
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
void SetTo(TTo value)
Assign a value to To data member.
Definition: Range_.hpp:278
int i
range(_Ty, _Ty) -> range< _Ty >
constexpr auto sort(_Init &&init)
Useful/utility classes and methods.
basic sort by size function
Definition: layout.hpp:206
sorting functor for finding a range inside a collection of layout objects
Definition: layout.cpp:258
bool operator()(const CRef< CLayoutObject > &obj1, const CRef< CLayoutObject > &obj2) const
Definition: layout.cpp:259
Definition: type.c:6
#define _ASSERT
static const char *const features[]
Modified on Sat Dec 09 04:47:03 2023 by modify_doxy.py rev. 669887