Beispiel #1
0
void UMLGraph::undoGenMergers()
{
	SListConstIterator<edge> it;
	for(it = m_mergeEdges.begin(); it.valid(); ++it)
	{
		edge eMerge = *it;
		node u = eMerge->source();
		const DPolyline &common = bends(eMerge);

		adjEntry adj, adjSucc;
		for(adj = u->firstAdj(); adj != nullptr; adj = adjSucc) {
			adjSucc = adj->succ();

			edge e = adj->theEdge();
			if(e->target() != u) continue;

			DPolyline &dpl = bends(e);
			dpl.pushBack(DPoint(x(u),y(u)));

			ListConstIterator<DPoint> itDp;
			for(itDp = common.begin(); itDp.valid(); ++itDp)
				dpl.pushBack(*itDp);

			m_pG->moveTarget(e,eMerge->target());
		}

		m_pG->delNode(u);
	}

	m_mergeEdges.clear();
}
Beispiel #2
0
	int LayoutStatistics::numberOfBends(
		const GraphAttributes &ga,
		int *pMinBendsPerEdge,
		int *pMaxBendsPerEdge,
		double *pAvgBendsPerEdge,
		double *pStdDeviation,
		bool    considerSelfLoops)
	{
		const Graph &G = ga.constGraph();
		int m = G.numberOfEdges();

		int totalBends = 0, minBends = numeric_limits<int>::max(), maxBends = 0;

		EdgeArray<int> bends(G);
		int nSelfLoops = 0;

		for(edge e : G.edges) {
			if(!considerSelfLoops && e->isSelfLoop()) {
				nSelfLoops++;
				continue;
			}

			const DPolyline &dpl = ga.bends(e);

			bends[e] = max(0, dpl.size() - 2);

			totalBends += bends[e];
			minBends = min(minBends, bends[e]);
			maxBends = max(maxBends, bends[e]);
		}

		m -= nSelfLoops;

		double avgBends = double(totalBends) / m;
		if(pAvgBendsPerEdge) *pAvgBendsPerEdge = avgBends;
		if(pMinBendsPerEdge) *pMinBendsPerEdge = minBends;
		if(pMaxBendsPerEdge) *pMaxBendsPerEdge = maxBends;

		if(pStdDeviation) {
			double sum = 0;
			for(edge e : G.edges) {
				if(!considerSelfLoops && e->isSelfLoop())
					continue;
				double d = bends[e] - avgBends;
				sum += d*d;
			}

			*pStdDeviation = sqrt(sum / m);
		}

		return totalBends;
	}
Beispiel #3
0
DPoint Layout::computeBoundingBox(PlanRep &PG) const
{
	double maxWidth  = 0;
	double maxHeight = 0;

	// check rightmost and uppermost extension of all (original) nodes
	for(int i = PG.startNode(); i < PG.stopNode(); ++i) {
		node vG = PG.v(i);

		double maxX = x(PG.copy(vG)) + PG.widthOrig(vG)/2;
		if (maxX > maxWidth ) maxWidth  = maxX;

		double maxY = y(PG.copy(vG)) + PG.heightOrig(vG)/2;
		if (maxY > maxHeight) maxHeight = maxY;

		// check polylines of all (original) edges
		for(adjEntry adj : vG->adjEntries) {
			if ((adj->index() & 1) == 0) continue;
			edge eG = adj->theEdge();

			const List<edge> &path = PG.chain(eG);

			for(edge e : path)
			{
				// we have to check (only) all interior points, i.e., we can
				// omitt the first and last point since it lies in the box of
				// the source or target node.
				// This version checks also the first for simplicity of the loop.
				node v = e->source();
				if (x(v) > maxWidth ) maxWidth  = x(v);
				if (y(v) > maxHeight) maxHeight = y(v);

				const DPolyline &dpl = bends(e);

				for(const DPoint &dp : dpl)
				{
					if (dp.m_x > maxWidth ) maxWidth  = dp.m_x;
					if (dp.m_y > maxHeight) maxHeight = dp.m_y;
				}
			}
		}
	}

	return DPoint(maxWidth,maxHeight);
}