39 internalEdgeWeightFactor(1.),
40 desiredBoundsSet(false),
71 vector<unsigned> invalidNodes;
72 for (set<unsigned>::iterator it =
nodes.begin(); it !=
nodes.end(); ++it)
74 unsigned nodeIndex = *it;
75 if (nodeIndex < counts.size())
82 fprintf(stderr,
"Warning: Invalid node index %u specified in "
83 "cluster. Ignoring...\n", nodeIndex);
84 invalidNodes.push_back(nodeIndex);
87 for (
size_t i = 0; i < invalidNodes.size(); ++i)
89 nodes.erase(invalidNodes[i]);
92 for (vector<Cluster*>::const_iterator i =
clusters.begin();
95 (*i)->countContainedNodes(counts);
102 for (vector<Cluster*>::const_iterator i =
clusters.begin();
105 (*i)->computeBoundingRect(
rs);
107 (*i)->margin().rectangleByApplyingBox((*i)->bounds);
110 for (set<unsigned>::const_iterator i =
nodes.begin();
111 i !=
nodes.end(); ++i)
127 for (vector<Cluster*>::const_iterator i =
clusters.begin();
130 (*i)->computeVarRect(vars, dim);
141 unsigned n = 4 *
nodes.size();
142 valarray<double> X(n);
143 valarray<double> Y(n);
145 vector<unsigned> nodesVector(
nodes.begin(),
nodes.end());
146 for (
size_t i = 0; i < nodesVector.size(); ++i)
167 vector<unsigned>
hull;
173 for (
unsigned j=0;j<
hull.size();j++)
185 fprintf(fp,
" ConvexCluster *cluster%llu = new ConvexCluster();\n",
186 (
unsigned long long)
this);
187 for(set<unsigned>::const_iterator i =
nodes.begin();
188 i !=
nodes.end(); ++i)
190 fprintf(fp,
" cluster%llu->addChildNode(%u);\n",
191 (
unsigned long long)
this, *i);
193 for(vector<Cluster *>::const_iterator i =
clusters.begin();
196 (*i)->printCreationCode(fp);
197 fprintf(fp,
" cluster%llu->addChildCluster(cluster%llu);\n",
198 (
unsigned long long)
this, (
unsigned long long) *i);
204 for(vector<Cluster *>::const_iterator i =
clusters.begin();
207 (*i)->outputToSVG(fp);
214 m_rectangle_index(-1),
226 m_rectangle_index(rectIndex),
238 for (
size_t dim = 0; dim < 2; ++dim)
318 idleConstraints.push_back(sc);
321 idleConstraints.push_back(sc);
325 idleConstraints.push_back(sc);
328 idleConstraints.push_back(sc);
334 double xMin=DBL_MAX, xMax=-DBL_MAX, yMin=DBL_MAX, yMax=-DBL_MAX;
335 for (std::set<unsigned>::iterator it =
nodes.begin();
336 it !=
nodes.end(); ++it)
338 xMin=std::min(xMin,
rs[*it]->getMinX());
339 xMax=std::max(xMax,
rs[*it]->getMaxX());
340 yMin=std::min(yMin,
rs[*it]->getMinY());
341 yMax=std::max(yMax,
rs[*it]->getMaxY());
358 fprintf(fp,
" RectangularCluster *cluster%llu = "
359 "new RectangularCluster(",
360 (
unsigned long long)
this);
368 fprintf(fp,
" cluster%llu->setMargin(",
369 (
unsigned long long)
this);
375 fprintf(fp,
" cluster%llu->setPadding(",
376 (
unsigned long long)
this);
380 for(set<unsigned>::const_iterator i =
nodes.begin();
381 i !=
nodes.end(); ++i)
383 fprintf(fp,
" cluster%llu->addChildNode(%u);\n",
384 (
unsigned long long)
this, *i);
386 for(vector<Cluster *>::const_iterator i =
clusters.begin();
389 (*i)->printCreationCode(fp);
390 fprintf(fp,
" cluster%llu->addChildCluster(cluster%llu);\n",
391 (
unsigned long long)
this, (
unsigned long long) *i);
400 fprintf(fp,
"<rect id=\"cluster-%llu-r\" x=\"%g\" y=\"%g\" width=\"%g\" "
401 "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
402 "fill: green; fill-opacity: 0.3;\" rx=\"%g\" ry=\"%g\" />\n",
409 fprintf(fp,
"<rect id=\"cluster-%llu\" x=\"%g\" y=\"%g\" width=\"%g\" "
410 "height=\"%g\" style=\"stroke-width: 1px; stroke: black; "
411 "fill: red; fill-opacity: 0.3;\" rx=\"%g\" ry=\"%g\" />\n",
417 for(vector<Cluster *>::const_iterator i =
clusters.begin();
420 (*i)->outputToSVG(fp);
452 fprintf(stderr,
"Warning: ignoring cluster (%u) added as child of "
461 : m_allows_multiple_parents(false)
473 currentPath.push_back(
this);
476 for (
unsigned i = 0; i <
clusters.size(); ++i)
478 clusters[i]->recPathToCluster(rootCluster, currentPath);
482 for (std::set<unsigned>::iterator it =
nodes.begin();
483 it !=
nodes.end(); ++it)
486 push_back(currentPath);
501 for (
size_t j = 1; j <
paths; ++j)
503 for (
size_t k = 0; k < j; ++k)
512 while ((lcaIndex < pathJ.size()) &&
513 (lcaIndex < pathK.size()) &&
514 (pathJ[lcaIndex] == pathK[lcaIndex]))
518 COLA_ASSERT(lcaIndex > 0);
522 size_t lcaChildJIndex = i;
523 size_t lcaChildKIndex = i;
524 Cluster *lcaChildJCluster =
nullptr;
525 Cluster *lcaChildKCluster =
nullptr;
530 COLA_ASSERT((lcaIndex < pathJ.size()) ||
531 (lcaIndex < pathK.size()));
532 if (lcaIndex < pathJ.size())
534 lcaChildJCluster = pathJ[lcaIndex];
537 if (lcaIndex < pathK.size())
539 lcaChildKCluster = pathK[lcaIndex];
547 Cluster *lcaCluster = pathJ[lcaIndex - 1];
549 ShapePair(lcaChildJIndex, lcaChildKIndex));
551 if (lcaChildJCluster)
563 if (lcaChildKCluster)
582 for (
unsigned i = 0; i <
clusters.size(); ++i)
590 fprintf(fp,
" RootCluster *cluster%llu = new RootCluster();\n",
591 (
unsigned long long)
this);
592 for(set<unsigned>::const_iterator i =
nodes.begin();
593 i !=
nodes.end(); ++i)
595 fprintf(fp,
" cluster%llu->addChildNode(%u);\n",
596 (
unsigned long long)
this, *i);
598 for(vector<Cluster *>::const_iterator i =
clusters.begin();
601 (*i)->printCreationCode(fp);
602 fprintf(fp,
" cluster%llu->addChildCluster(cluster%llu);\n",
603 (
unsigned long long)
this, (
unsigned long long) *i);
609 for(vector<Cluster *>::const_iterator i =
clusters.begin();
612 (*i)->outputToSVG(fp);
640 for (
unsigned i=0; i <
clusters.size(); ++i)
650 for (vector<Cluster*>::iterator i =
clusters.begin();
653 (*i)->createVars(dim,
rs, vars);
691 for (set<unsigned>::iterator i =
nodes.begin(); i !=
nodes.end(); ++i)
705 this->
nodes.insert(index);
712 fprintf(stderr,
"Warning: ignoring cluster added as child of itself.\n");
A box consisting of four edge values for representing padding or margins for rectangles.
void outputCode(FILE *fp) const
vpsc::Rectangle rectangleByApplyingBox(const vpsc::Rectangle rectangle) const
A cluster defines a hierarchical partitioning over the nodes which should be kept disjoint by the lay...
void updateBounds(const vpsc::Dim dim)
void addChildCluster(Cluster *cluster)
Mark a cluster as being a sub-cluster of this cluster.
std::set< unsigned > m_nodes_replaced_with_clusters
void recPathToCluster(RootCluster *rootCluster, Clusters currentPath)
std::map< unsigned, Cluster * > m_overlap_replacement_map
std::vector< Cluster * > clusters
virtual void countContainedNodes(std::vector< unsigned > &counts)
virtual cola::Box padding(void) const
double area(const vpsc::Rectangles &rs)
std::valarray< double > hullY
virtual void addChildNode(unsigned index)
Mark a rectangle as being a child of this cluster.
void unsetDesiredBounds()
std::set< ShapePair > m_cluster_cluster_overlap_exceptions
vpsc::Rectangle desiredBounds
virtual void computeBoundingRect(const vpsc::Rectangles &rs)
std::valarray< double > hullX
std::set< unsigned > nodes
void setDesiredBounds(const vpsc::Rectangle bounds)
virtual void computeVarRect(vpsc::Variables &vs, size_t dim)
virtual bool clusterIsFromFixedRectangle(void) const
void createVars(const vpsc::Dim dim, const vpsc::Rectangles &rs, vpsc::Variables &vars)
void computeBoundary(const vpsc::Rectangles &rs)
virtual void outputToSVG(FILE *fp) const
virtual void printCreationCode(FILE *fp) const
std::valarray< unsigned > hullRIDs
std::valarray< unsigned char > hullCorners
cola::Box padding(void) const
Returns the padding box for this cluster.
virtual void printCreationCode(FILE *fp) const
virtual void computeBoundingRect(const vpsc::Rectangles &rs)
virtual void outputToSVG(FILE *fp) const
RectangularCluster()
A rectangular cluster of variable size that contains its children.
virtual void countContainedNodes(std::vector< unsigned > &counts)
void setMargin(double margin)
Sets the margin size for this cluster.
virtual bool clusterIsFromFixedRectangle(void) const
vpsc::Rectangle * maxEdgeRect[2]
void setPadding(double padding)
Sets the padding size for this cluster.
virtual void addChildNode(unsigned index)
Mark a rectangle as being a child of this cluster.
vpsc::Rectangle * minEdgeRect[2]
void computeBoundary(const vpsc::Rectangles &rs)
void generateFixedRectangleConstraints(cola::CompoundConstraints &idleConstraints, vpsc::Rectangles &rc, vpsc::Variables(&vars)[2]) const
cola::Box margin(void) const
Returns the margin box for this cluster.
virtual ~RectangularCluster()
int rectangleIndex(void) const
Holds the cluster hierarchy specification for a diagram.
void computeBoundary(const vpsc::Rectangles &rs)
virtual void outputToSVG(FILE *fp) const
virtual void printCreationCode(FILE *fp) const
void calculateClusterPathsToEachNode(size_t nodesCount)
std::vector< ClustersList > m_cluster_vectors_leading_to_nodes
bool allowsMultipleParents(void) const
Returns true if this cluster hierarchy allows multiple parents, otherwise returns false.
bool m_allows_multiple_parents
void setAllowsMultipleParents(const bool value)
Set whether the cluster hierarchy should allow multiple parents.
A separation constraint specifies a simple horizontal or vertical spacing constraint between 2 nodes ...
A rectangle represents a fixed-size shape in the diagram that may be moved to prevent overlaps and sa...
void setMaxD(unsigned const d, const double val)
Rectangle unionWith(const Rectangle &rhs) const
void setMinD(unsigned const d, const double val)
A variable is comprised of an ideal position, final position and a weight.
vector< vpsc::Rectangle * > rs
vector< vector< Point > > paths
libcola: Force-directed network layout subject to separation constraints library.
std::vector< CompoundConstraint * > CompoundConstraints
A vector of pointers to CompoundConstraint objects.
std::vector< Cluster * > Clusters
void convex(const unsigned n, const double *X, const double *Y, vector< unsigned > &h)
Dim
Indicates the x- or y-dimension.
@ HORIZONTAL
The x-dimension (0).
@ XDIM
The x-dimension (0).
@ YDIM
The y-dimension (1).
std::vector< vpsc::Variable * > Variables
A vector of pointers to Variable objects.
void generateXConstraints(const Rectangles &rs, const Variables &vars, Constraints &cs, const bool useNeighbourLists)
void generateYConstraints(const Rectangles &rs, const Variables &vars, Constraints &cs)
std::vector< Rectangle * > Rectangles
A vector of pointers to Rectangle objects.