Ejemplo n.º 1
0
// assumes, that the Graphs of MultilevelGraph and GA are the same, not copies!
void MultilevelGraph::exportAttributesSimple(GraphAttributes &GA) const
{
	OGDF_ASSERT(&(GA.constGraph()) == m_G);

	prepareGraphAttributes(GA);

	for(node v : m_G->nodes) {
		GA.x(v) =  m_GA->x(v);
		GA.y(v) =  m_GA->y(v);
		//TODO: Check what this w,h computation does
		double w = GA.width(v);
		double h = GA.height(v);
		if(w > 0 || h > 0) {
			double factor =  m_radius[v] / sqrt(w*w + h*h) * 2.0f;
			w *= factor;
			h *= factor;
		} else {
			w = h = m_radius[v] * sqrt(2.0f);
		}
		GA.width(v) = w;
		GA.height(v) = h;
		GA.weight(v) = m_reverseNodeMergeWeight[v->index()];
	}

	for(edge e : m_G->edges) {
		GA.doubleWeight(e) = m_weight[e];
	}
}
Ejemplo n.º 2
0
void MultilevelGraph::importAttributesSimple(const GraphAttributes &GA)
{
	OGDF_ASSERT(&(GA.constGraph()) == m_G);

	m_avgRadius = 0.0;

	for(node v : m_G->nodes) {
		double w = GA.width(v);
		double h = GA.height(v);
		if(w > 0 || h > 0) {
			m_radius[v] = sqrt(w*w + h*h) / 2.0f;
		} else {
			m_radius[v] = 1.0f;
		}
		m_avgRadius += m_radius[v];
		m_GA->x(v) = GA.x(v);
		m_GA->y(v) = GA.y(v);
		m_GA->width(v) = GA.width(v);
		m_GA->height(v) = GA.height(v);
	}
	m_avgRadius /= m_G->numberOfNodes();

	for(edge e : m_G->edges) {
		m_weight[e] = GA.doubleWeight(e);
	}
}
Ejemplo n.º 3
0
void FastMultipoleMultilevelEmbedder::computeAutoEdgeLength(const GraphAttributes& GA, EdgeArray<float>& edgeLength, float factor)
{
	for(edge e : GA.constGraph().edges)
	{
		node v = e->source();
		node w = e->target();
		float radius_v = (float)sqrt(GA.width(v)*GA.width(v) + GA.height(v)*GA.height(v)) * 0.5f;
		float radius_w = (float)sqrt(GA.width(w)*GA.width(w) + GA.height(w)*GA.height(w)) * 0.5f;
		float sum = radius_v + radius_w;
		if (OGDF_GEOM_ET.equal(sum, (float) 0))
			sum = 1.0;
		edgeLength[e] = factor*(sum);
	}
}
Ejemplo n.º 4
0
//the vertices with degree zero are placed below all other vertices on a horizontal
// line centered with repect to the rest of the drawing
void DavidsonHarel::placeIsolatedNodes(GraphAttributes &AG) const {
	double minX = 0.0;
	double minY = 0.0;
	double maxX = 0.0;

	if (!m_nonIsolatedNodes.empty()) {
		//compute a rectangle that includes all non-isolated vertices
		node vFirst = m_nonIsolatedNodes.front();
		minX = AG.x(vFirst);
		minY = AG.y(vFirst);
		maxX = minX;
		double maxY = minY;
		for (node v : m_nonIsolatedNodes) {
			double xVal = AG.x(v);
			double yVal = AG.y(v);
			double halfHeight = AG.height(v) / 2.0;
			double halfWidth = AG.width(v) / 2.0;
			if (xVal - halfWidth < minX) minX = xVal - halfWidth;
			if (xVal + halfWidth > maxX) maxX = xVal + halfWidth;
			if (yVal - halfHeight < minY) minY = yVal - halfHeight;
			if (yVal + halfHeight > maxY) maxY = yVal + halfHeight;
		}
	}

	// compute the width and height of the largest isolated node
	List<node> isolated;
	const Graph &G = AG.constGraph();
	double maxWidth = 0;
	double maxHeight = 0;
	for (node v : G.nodes)
	if (v->degree() == 0) {
		isolated.pushBack(v);
		if (AG.height(v) > maxHeight) maxHeight = AG.height(v);
		if (AG.width(v) > maxWidth) maxWidth = AG.width(v);
	}
	// The nodes are placed on a line in the middle under the non isolated vertices.
	// Each node gets a box sized 2 maxWidth.
	double boxWidth = 2.0*maxWidth;
	double commonYCoord = minY - (1.5*maxHeight);
	double XCenterOfDrawing = minX + ((maxX - minX) / 2.0);
	double startXCoord = XCenterOfDrawing - 0.5*(isolated.size()*boxWidth);
	double xcoord = startXCoord;
	for (node v : isolated) {
		AG.x(v) = xcoord;
		AG.y(v) = commonYCoord;
		xcoord += boxWidth;
	}
}
Ejemplo n.º 5
0
void RadialTreeLayout::ComputeDiameters(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();

	m_diameter.init(G);
	m_nodes.init(m_numLevels);
	m_width.init(m_numLevels);
	m_width.fill(0);

	for(node v : G.nodes)
	{
		int i = m_level[v];
		m_nodes[i].pushBack(v);

		double w = AG.width(v);
		double h = AG.height(v);

		m_diameter[v] = sqrt(w*w+h*h);

		double m = max(w, h);
		m = max(m, sqrt(w*w+h*h));

		if(m_diameter[v] > m_width[i])
			m_width[i] = m_diameter[v];
	}
}
Ejemplo n.º 6
0
void FastMultipoleEmbedder::call(GraphAttributes &GA)
{
	EdgeArray<float> edgeLength(GA.constGraph());
	NodeArray<float> nodeSize(GA.constGraph());

	for(node v : GA.constGraph().nodes)
	{
		nodeSize[v] = (float)sqrt(GA.width(v)*GA.width(v) + GA.height(v)*GA.height(v)) * 0.5f;
	}

	for(edge e : GA.constGraph().edges)
	{
		edgeLength[e] = nodeSize[e->source()] + nodeSize[e->target()];
	}
	call(GA, edgeLength, nodeSize);
}
Ejemplo n.º 7
0
static inline bool readVizAttribute(
	GraphAttributes &GA,
	node v,
	const pugi::xml_node tag)
{
	const long attrs = GA.attributes();

	if(string(tag.name()) == "viz:position") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute xAttr = tag.attribute("x");
			pugi::xml_attribute yAttr = tag.attribute("y");
			pugi::xml_attribute zAttr = tag.attribute("z");

			if(!xAttr || !yAttr) {
				GraphIO::logger.lout() << "Missing \"x\" or \"y\" in position tag." << std::endl;
				return false;
			}

			GA.x(v) = xAttr.as_int();
			GA.y(v) = yAttr.as_int();

			// z attribute is optional and avaliable only in \a threeD mode
			GA.y(v) = yAttr.as_int();
			if (zAttr && (attrs & GraphAttributes::threeD)) {
				GA.z(v) = zAttr.as_int();
			}
		}
	} else if(string(tag.name()) == "viz:size") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute valueAttr = tag.attribute("value");
			if (!valueAttr) {
				GraphIO::logger.lout() << "\"size\" attribute is missing a value." << std::endl;
				return false;
			}

			double size = valueAttr.as_double();
			GA.width(v) = size * LayoutStandards::defaultNodeWidth();
			GA.height(v) = size * LayoutStandards::defaultNodeHeight();
		}
	} else if(string(tag.name()) == "viz:shape") {
		if(attrs & GraphAttributes::nodeGraphics) {
			pugi::xml_attribute valueAttr = tag.attribute("value");
			if(!valueAttr) {
				GraphIO::logger.lout() << "\"shape\" attribute is missing a value." << std::endl;
				return false;
			}

			GA.shape(v) = toShape(valueAttr.value());
		}
	} else if(string(tag.name()) == "viz:color") {
		if(attrs & GraphAttributes::nodeStyle) {
			return readColor(GA.fillColor(v), tag);
		}
	} else {
		GraphIO::logger.lout() << "Incorrect tag: \"" << tag.name() << "\"." << std::endl;
		return false;
	}

	return true;
}
Ejemplo n.º 8
0
void DominanceLayout::compact(const UpwardPlanRep &UPR, GraphAttributes &GA)
{
	double maxNodeSize = 0;
	for(node v : GA.constGraph().nodes) {
		if (GA.width(v) > maxNodeSize || GA.height(v) > maxNodeSize)
			maxNodeSize = max(GA.width(v), GA.height(v));
	}

	int gridDist = m_grid_dist;
	if (gridDist < maxNodeSize+1)
		gridDist = (int) maxNodeSize+1;

	xCoord.init(UPR);
	yCoord.init(UPR);

	//ASSIGN X COORDINATE

	OGDF_ASSERT(!xNodes.empty());

	node v = xNodes.popFrontRet();
	xCoord[v] = 0;
	while (!xNodes.empty()) {
		node u = xNodes.popFrontRet();
		if ( (yPreCoord[v] > yPreCoord[u]) || (firstout[v] == lastout[v] && firstin[u] == lastin[u] && m_L <= m_R)) {
			xCoord[u] = xCoord[v] + gridDist;
		}
		else
			xCoord[u] = xCoord[v];
		v = u;
	}

	//ASSIGN Y COORDINATE
	OGDF_ASSERT(!yNodes.empty());

	v = yNodes.popFrontRet();
	yCoord[v] = 0;
	while (!yNodes.empty()) {
		node u = yNodes.popFrontRet();
		if ( (xPreCoord[v] > xPreCoord[u]) || (firstout[v] == lastout[v] && firstin[u] == lastin[u] && m_L > m_R)) {
			yCoord[u] = yCoord[v] + gridDist;
		}
		else
			yCoord[u] = yCoord[v];
		v = u;
	}
}
Ejemplo n.º 9
0
void MultilevelGraph::importAttributes(const GraphAttributes &GA)
{
	OGDF_ASSERT(GA.constGraph().numberOfNodes() == m_G->numberOfNodes());
	OGDF_ASSERT(GA.constGraph().numberOfEdges() == m_G->numberOfEdges());

	m_avgRadius = 0.0;

	std::vector<node> tempNodeAssociations;
	const Graph &cG = GA.constGraph();
	tempNodeAssociations.resize(cG.maxNodeIndex()+1, nullptr);
	for(node v : cG.nodes) {
		tempNodeAssociations[v->index()] = v;
	}

	for(node v : m_G->nodes) {

		double w = GA.width(tempNodeAssociations[m_nodeAssociations[v]]);
		double h = GA.height(tempNodeAssociations[m_nodeAssociations[v]]);
		if(w > 0 || h > 0) {
			m_radius[v] = sqrt(w*w + h*h) / 2.0f;
		} else {
			m_radius[v] = 1.0f;
		}

		m_avgRadius += m_radius[v];

		m_GA->x(v) = GA.x(tempNodeAssociations[m_nodeAssociations[v]]);
		m_GA->y(v) = GA.y(tempNodeAssociations[m_nodeAssociations[v]]);
		m_GA->width(v) = GA.width(tempNodeAssociations[m_nodeAssociations[v]]);
		m_GA->height(v) = GA.height(tempNodeAssociations[m_nodeAssociations[v]]);
	}

	m_avgRadius /= m_G->numberOfNodes();

	std::vector<edge> tempEdgeAssociations;
	tempEdgeAssociations.resize(cG.maxEdgeIndex()+1, nullptr);
	for(edge e : cG.edges) {
		tempEdgeAssociations[e->index()] = e;
	}

	for(edge e : m_G->edges) {
		m_weight[e] = GA.doubleWeight(tempEdgeAssociations[m_edgeAssociations[e]]);
	}
}
Ejemplo n.º 10
0
void TutteLayout::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();

	List<node> fixedNodes;
	List<DPoint> positions;

	double diam =
	sqrt((m_bbox.width()) * (m_bbox.width())
		 + (m_bbox.height()) * (m_bbox.height()));

	// handle graphs with less than two nodes
	switch (G.numberOfNodes()) {
		case 0:
			return;
		case 1:
			node v = G.firstNode();

			DPoint center(0.5 * m_bbox.width(),0.5 * m_bbox.height());
			center = center + m_bbox.p1();

			AG.x(v) = center.m_x;
			AG.y(v) = center.m_y;

			return;
	}

	// increase radius to have no overlap on the outer circle
	node v = G.firstNode();

	double r        = diam/2.8284271;
	int n           = G.numberOfNodes();
	double nodeDiam = 2.0*sqrt((AG.width(v)) * (AG.width(v))
			 + (AG.height(v)) * (AG.height(v)));

	if(r<nodeDiam/(2*sin(2*Math::pi/n))) {
		r=nodeDiam/(2*sin(2*Math::pi/n));
		m_bbox = DRect (0.0, 0.0, 2*r, 2*r);
	}

	setFixedNodes(G,fixedNodes,positions,r);

	doCall(AG,fixedNodes,positions);
}
void ComponentSplitterLayout::call(GraphAttributes &GA)
{
	// Only do preparations and call if layout is valid
	if (m_secondaryLayout.valid())
	{
		//first we split the graph into its components
		const Graph& G = GA.constGraph();

		NodeArray<int> componentNumber(G);
		m_numberOfComponents = connectedComponents(G, componentNumber);
		if (m_numberOfComponents == 0) {
			return;
		}

		//std::vector< std::vector<node> > componentArray;
		//componentArray.resize(numComponents);
		//Array<GraphAttributes *> components(numComponents);
		//

		// intialize the array of lists of nodes contained in a CC
		nodesInCC.init(m_numberOfComponents);

		node v;
		forall_nodes(v,G)
			nodesInCC[componentNumber[v]].pushBack(v);

		 // Create copies of the connected components and corresponding
		 // GraphAttributes
		 GraphCopy GC;
		 GC.createEmpty(G);

		 EdgeArray<edge> auxCopy(G);

		 for (int i = 0; i < m_numberOfComponents; i++)
		 {
			 GC.initByNodes(nodesInCC[i],auxCopy);
			 GraphAttributes cGA(GC);
			 //copy information into copy GA
			 forall_nodes(v, GC)
			 {
				cGA.width(v) = GA.width(GC.original(v));
				cGA.height(v) = GA.height(GC.original(v));
				cGA.x(v) = GA.x(GC.original(v));
				cGA.y(v) = GA.y(GC.original(v));
			 }
			 m_secondaryLayout.get().call(cGA);

			 //copy layout information back into GA
			 forall_nodes(v, GC)
			 {
				 node w = GC.original(v);
				 if (w != 0)
					 GA.x(w) = cGA.x(v);
				 GA.y(w) = cGA.y(v);
			 }
		 }
Ejemplo n.º 12
0
void MultilevelGraph::exportAttributes(GraphAttributes &GA) const
{
	OGDF_ASSERT(GA.constGraph().numberOfNodes() == m_G->numberOfNodes());
	OGDF_ASSERT(GA.constGraph().numberOfEdges() == m_G->numberOfEdges());

	prepareGraphAttributes(GA);

	std::vector<node> tempNodeAssociations;
	const Graph &cG = GA.constGraph();
	tempNodeAssociations.resize(cG.maxNodeIndex()+1, nullptr);

	for(node v : cG.nodes) {
		tempNodeAssociations[v->index()] = v;
	}

	for(node v : m_G->nodes) {
		GA.x(tempNodeAssociations[m_nodeAssociations[v]]) =  m_GA->x(v);
		GA.y(tempNodeAssociations[m_nodeAssociations[v]]) =  m_GA->y(v);
		double w = GA.width(tempNodeAssociations[m_nodeAssociations[v]]);
		double h = GA.height(tempNodeAssociations[m_nodeAssociations[v]]);
		if(w > 0 || h > 0) {
			double factor =  m_radius[v] / sqrt(w*w + h*h) * 2.0f;
			w *= factor;
			h *= factor;
		} else {
			w = h = m_radius[v] * sqrt(2.0f);
		}
		GA.width(tempNodeAssociations[m_nodeAssociations[v]]) = w;
		GA.height(tempNodeAssociations[m_nodeAssociations[v]]) = h;
		GA.weight(tempNodeAssociations[m_nodeAssociations[v]]) = m_reverseNodeMergeWeight[v->index()];
	}

	std::vector<edge> tempEdgeAssociations;
	tempEdgeAssociations.resize(cG.maxEdgeIndex()+1, nullptr);
	for(edge e :cG.edges) {
		tempEdgeAssociations[e->index()] = e;
	}

	for(edge e : m_G->edges) {
		GA.doubleWeight(tempEdgeAssociations[m_edgeAssociations[e]]) = m_weight[e];
	}
}
Ejemplo n.º 13
0
static void compute_bounding_box(const GraphAttributes &A, double &xmin, double &ymin, double &xmax, double &ymax)
{
	const Graph &G = A.constGraph();
	if(G.numberOfNodes() == 0) {
		xmin = xmax = ymin = ymax = 0;
		return;
	}

	node v = G.firstNode();
	xmin = xmax = A.x(v),
	ymin = ymax = A.y(v);

	forall_nodes(v, G) {
		double lw = (A.attributes() & GraphAttributes::nodeStyle) ? 0.5*A.strokeWidth(v) : 0.5;

		xmax = max(xmax, A.x(v) + A.width (v)/2 + lw);
		ymax = max(ymax, A.y(v) + A.height(v)/2 + lw);
		xmin = min(xmin, A.x(v) - A.width (v)/2 - lw);
		ymin = min(ymin, A.y(v) - A.height(v)/2 - lw);
	}
Ejemplo n.º 14
0
inline void FMMMLayout :: import_NodeAttributes(const Graph& G, GraphAttributes& GA,
						NodeArray<NodeAttributes>& A)
{
 node v;
 DPoint position;

 forall_nodes(v,G)
   {
     position.m_x = GA.x(v);
     position.m_y = GA.y(v);
     A[v].set_NodeAttributes(GA.width(v),GA.height(v),position,NULL,NULL); 
   }
Ejemplo n.º 15
0
void GridLayoutModule::mapGridLayout(const Graph &G,
	GridLayout &gridLayout,
	GraphAttributes &AG)
{
	double maxWidth = 0; // maximum width of columns and rows;
	double yMax = 0;

	node v;
	forall_nodes(v,G) {
		if (AG.width (v) > maxWidth) maxWidth = AG.width (v);
		if (AG.height(v) > maxWidth) maxWidth = AG.height(v);
		if (gridLayout.y(v) > yMax) yMax = gridLayout.y(v);
	}

	maxWidth += m_separation;

	// set position of nodes
	forall_nodes(v,G) {
		AG.x(v) = gridLayout.x(v) * maxWidth;
		AG.y(v) = (yMax - gridLayout.y(v)) * maxWidth;
	}
Ejemplo n.º 16
0
static inline void writeAttributes(
	std::ostream &out,
	const GraphAttributes &GA, const node &v)
{
	const long flags = GA.attributes();

	out << "[";

	bool separator = false; // Wheter to put separator before attribute.

	if(flags & GraphAttributes::nodeId) {
		writeAttribute(out, separator, "id", GA.idNode(v));
	}

	if(flags & GraphAttributes::nodeLabel) {
		writeAttribute(out, separator, "label", GA.label(v));
	}

	if(flags & GraphAttributes::nodeTemplate) {
		writeAttribute(out, separator, "comment", GA.templateNode(v));
	}

	if(flags & GraphAttributes::nodeGraphics) {
		writeAttribute(out, separator, "width", GA.width(v));
		writeAttribute(out, separator, "height", GA.height(v));
		writeAttribute(out, separator, "shape", dot::toString(GA.shape(v)));

		out << ", pos=\"" << GA.x(v) << "," << GA.y(v);
		if(flags & GraphAttributes::threeD) {
			out << "," << GA.z(v);
		}
		out << "\"";
	}

	if(flags & GraphAttributes::nodeStyle) {
		writeAttribute(out, separator, "color", GA.strokeColor(v));
		writeAttribute(out, separator, "fillcolor", GA.fillColor(v));
		writeAttribute(out, separator, "stroketype", toString(GA.strokeType(v)));
		writeAttribute(out, separator, "strokewidth", GA.strokeWidth(v));
		writeAttribute(out, separator, "fillpattern", toString(GA.fillPattern(v)));
	}

	if(flags & GraphAttributes::nodeType) {
		writeAttribute(out, separator, "type", int(GA.type(v)));
	}

	if(flags & GraphAttributes::nodeWeight) {
		writeAttribute(out, separator, "weight", GA.weight(v));
	}

	out << "]";
}
Ejemplo n.º 17
0
void FastMultipoleMultilevelEmbedder::initFinestLevel(GraphAttributes &GA, const EdgeArray<float>& edgeLength)
{
#if 0
	NodeArray<float> perimeter(GA.constGraph(), 0.0);
#endif
	for(node v : GA.constGraph().nodes)
	{
		GalaxyMultilevel::LevelNodeInfo& nodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[v];
		nodeInfo.mass = 1.0;
		float r = (float)sqrt(GA.width(v)*GA.width(v) + GA.height(v)*GA.height(v)) * 0.5f;
		nodeInfo.radius = r;
	}

	for(edge e : GA.constGraph().edges)
	{
		GalaxyMultilevel::LevelEdgeInfo& edgeInfo = (*(m_pFinestLevel->m_pEdgeInfo))[e];
		node v = e->source();
		node w = e->target();
		GalaxyMultilevel::LevelNodeInfo& vNodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[v];
		GalaxyMultilevel::LevelNodeInfo& wNodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[w];
		edgeInfo.length = (vNodeInfo.radius +  wNodeInfo.radius) + edgeLength[e];
	}
}
Ejemplo n.º 18
0
void GridLayoutModule::mapGridLayout(const Graph &G,
	GridLayout &gridLayout,
	GraphAttributes &AG)
{
	// maximum width of columns and rows
	double maxWidth = 0;
	double yMax = 0;

	for(node v : G.nodes) {
		Math::updateMax<double>(maxWidth, AG.width(v));
		Math::updateMax<double>(maxWidth, AG.height(v));
		Math::updateMax<double>(yMax, gridLayout.y(v));
	}

	maxWidth += m_separation;

	// set position of nodes
	for(node v : G.nodes) {
		AG.x(v) = gridLayout.x(v) * maxWidth;
		AG.y(v) = (yMax - gridLayout.y(v)) * maxWidth;
	}

	// transform bend points of edges
	for(edge e : G.edges) {
		IPolyline ipl = gridLayout.polyline(e);

		// Remove superfluous bendpoints
		node v = e->source();
		while(!ipl.empty() && ipl.front() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
			ipl.popFront();
		}
		v = e->target();
		while(!ipl.empty() && ipl.back() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
			ipl.popBack();
		}

		DPolyline &dpl = AG.bends(e);
		dpl.clear();

		for (const IPoint &ip : ipl) {
			dpl.pushBack(DPoint(ip.m_x*maxWidth, (yMax-ip.m_y)*maxWidth));
		}

		dpl.normalize();
	}
}
Ejemplo n.º 19
0
static inline void writeAttributes(
	std::ostream &out,
	const GraphAttributes &GA, const node &v)
{
	const long flags = GA.attributes();

	out << "[";

	bool separator = false; // Wheter to put separator before attribute.

	if(flags & GraphAttributes::nodeId) {
		writeAttribute(out, separator, "id", GA.idNode(v));
	}

	if(flags & GraphAttributes::nodeLabel) {
		writeAttribute(out, separator, "label", GA.label(v));
	}

	if(flags & GraphAttributes::nodeTemplate) {
		writeAttribute(out, separator, "comment", GA.templateNode(v));
	}

	if(flags & GraphAttributes::nodeGraphics) {
		writeAttribute(out, separator, "width", GA.width(v));
		writeAttribute(out, separator, "height", GA.height(v));
		writeAttribute(out, separator, "shape", dot::toString(GA.shape(v)));

		out << ", pos=\"" << GA.x(v) << "," << GA.y(v);
		if(flags & GraphAttributes::threeD) {
			out << "," << GA.z(v);
		}
		out << "\"";
	}

	if(flags & GraphAttributes::nodeStyle) {
		writeAttribute(out, separator, "color", GA.strokeColor(v));
		writeAttribute(out, separator, "fillcolor", GA.fillColor(v));
	}

	// NOTE: Node type is weird and (probably) cannot be mapped to DOT.
	// NOTE: Node weight is not supported.

	out << "]";
}
Ejemplo n.º 20
0
Archivo: svg.cpp Proyecto: ogdf/ogdf
void createDocument(GraphAttributes attr, pugi::xml_document &doc, GraphIO::SVGSettings *settings = nullptr, bool reassignPositions = true) {
	std::ostringstream write;

	if(reassignPositions) {
		int i = 0;
		for(node v : attr.constGraph().nodes) {
			attr.x(v) = attr.y(v) = i++ * 100;
			attr.width(v) = attr.height(v) = 10;
		}
	}

	if(settings == nullptr) {
		GraphIO::drawSVG(attr, write);
	} else {
		GraphIO::drawSVG(attr, write, *settings);
	}

	pugi::xml_parse_result result =  doc.load_string(write.str().c_str());
	AssertThat((bool) result, IsTrue());
}
Ejemplo n.º 21
0
bool GmlParser::read(Graph &G, GraphAttributes &AG)
{
	OGDF_ASSERT(&G == &(AG.constGraph()))

	G.clear();

	int minId = m_mapToNode.low();
	int maxId = m_mapToNode.high();
	int notDefined = minId-1; //indicates not defined id key

	DPolyline bends;

	GmlObject *son = m_graphObject->m_pFirstSon;
	for(; son; son = son->m_pBrother) {

		switch(id(son)) {
		case nodePredefKey: {
			if (son->m_valueType != gmlListBegin) break;

			// set attributes to default values
			int vId = notDefined;
			double x = 0, y = 0, w = 0, h = 0;
			String label;
			String templ;
			String fill;  // the fill color attribute
			String line;  // the line color attribute
			String shape; //the shape type
			double lineWidth = 1.0; //node line width
			int    pattern = 1; //node brush pattern
			int    stipple = 1; //line style pattern

			// read all relevant attributes
			GmlObject *nodeSon = son->m_pFirstSon;
			for(; nodeSon; nodeSon = nodeSon->m_pBrother) {
				switch(id(nodeSon)) {
				case idPredefKey:
					if(nodeSon->m_valueType != gmlIntValue) break;
					vId = nodeSon->m_intValue;
					break;

				case graphicsPredefKey: {
					if (nodeSon->m_valueType != gmlListBegin) break;

					GmlObject *graphicsObject = nodeSon->m_pFirstSon;
					for(; graphicsObject;
						graphicsObject = graphicsObject->m_pBrother)
					{
						switch(id(graphicsObject)) {
						case xPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							x = graphicsObject->m_doubleValue;
							break;

						case yPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							y = graphicsObject->m_doubleValue;
							break;

						case wPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							w = graphicsObject->m_doubleValue;
							break;

						case hPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							h = graphicsObject->m_doubleValue;
							break;

						case fillPredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
                            fill = graphicsObject->m_stringValue;
							break;

						case linePredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
                            line = graphicsObject->m_stringValue;
							break;

						case lineWidthPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
                            lineWidth = graphicsObject->m_doubleValue;
							break;

						case typePredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
                            shape = graphicsObject->m_stringValue;
							break;
						case patternPredefKey: //fill style
							if(graphicsObject->m_valueType != gmlIntValue) break;
							pattern = graphicsObject->m_intValue;
						case stipplePredefKey: //line style
							if(graphicsObject->m_valueType != gmlIntValue) break;
							stipple = graphicsObject->m_intValue;
						}
					}
					break; }

				case templatePredefKey:
					if (nodeSon->m_valueType != gmlStringValue) break;

					templ = nodeSon->m_stringValue;
					break;

				case labelPredefKey:
					if (nodeSon->m_valueType != gmlStringValue) break;

					label = nodeSon->m_stringValue;
					break;
				}
			}

			// check if everything required is defined correctly
			if (vId == notDefined) {
				setError("node id not defined");
				return false;
			}

			// create new node if necessary and assign attributes
			if (m_mapToNode[vId] == 0) m_mapToNode[vId] = G.newNode();
			if (AG.attributes() & GraphAttributes::nodeGraphics)
			{
				AG.x(m_mapToNode[vId]) = x;
				AG.y(m_mapToNode[vId]) = y;
				AG.width (m_mapToNode[vId]) = w;
				AG.height(m_mapToNode[vId]) = h;
				if (shape == "oval")
					AG.shapeNode(m_mapToNode[vId]) = GraphAttributes::oval;
				else AG.shapeNode(m_mapToNode[vId]) = GraphAttributes::rectangle;
			}
			if ( (AG.attributes() & GraphAttributes::nodeColor) &&
				 (AG.attributes() & GraphAttributes::nodeGraphics) )
			{
				AG.colorNode(m_mapToNode[vId]) = fill;
				AG.nodeLine(m_mapToNode[vId]) = line;
			}
			if (AG.attributes() & GraphAttributes::nodeLabel)
				AG.labelNode(m_mapToNode[vId]) = label;
			if (AG.attributes() & GraphAttributes::nodeTemplate)
				AG.templateNode(m_mapToNode[vId]) = templ;
            if (AG.attributes() & GraphAttributes::nodeId)
                AG.idNode(m_mapToNode[vId]) = vId; 
			if (AG.attributes() & GraphAttributes::nodeStyle)
			{
				AG.nodePattern(m_mapToNode[vId]) = 
					GraphAttributes::intToPattern(pattern);
				AG.styleNode(m_mapToNode[vId]) = 
					GraphAttributes::intToStyle(stipple);
				AG.lineWidthNode(m_mapToNode[vId]) =
					lineWidth;
			}
							}//node
			//Todo: line style set stipple value
			break;

        case edgePredefKey: {
            String arrow; // the arrow type attribute
			String fill;  //the color fill attribute
			int stipple = 1;  //the line style
			double lineWidth = 1.0;
			double edgeWeight = 1.0;
			int subGraph = 0; //edgeSubGraph attribute
			String label; // label attribute

            if (son->m_valueType != gmlListBegin) break;

			// set attributes to default values
			int sourceId = notDefined, targetId = notDefined;
			Graph::EdgeType umlType = Graph::association;

			// read all relevant attributes
			GmlObject *edgeSon = son->m_pFirstSon;
			for(; edgeSon; edgeSon = edgeSon->m_pBrother) {

				switch(id(edgeSon)) {
				case sourcePredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					sourceId = edgeSon->m_intValue;
					break;

				case targetPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					targetId = edgeSon->m_intValue;
					break;

				case subGraphPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					subGraph = edgeSon->m_intValue;
					break;

				case labelPredefKey:
					if (edgeSon->m_valueType != gmlStringValue) break;
					label = edgeSon->m_stringValue;
					break;

				case graphicsPredefKey: {
					if (edgeSon->m_valueType != gmlListBegin) break;

					GmlObject *graphicsObject = edgeSon->m_pFirstSon;
					for(; graphicsObject;
						graphicsObject = graphicsObject->m_pBrother)
					{
						if(id(graphicsObject) == LinePredefKey &&
							graphicsObject->m_valueType == gmlListBegin)
						{
							readLineAttribute(graphicsObject->m_pFirstSon,bends);
						}
                        if(id(graphicsObject) == arrowPredefKey &&
                            graphicsObject->m_valueType == gmlStringValue)
                                arrow = graphicsObject->m_stringValue;
						if(id(graphicsObject) == fillPredefKey &&
							graphicsObject->m_valueType == gmlStringValue)
								fill = graphicsObject->m_stringValue;
						if (id(graphicsObject) == stipplePredefKey && //line style
							graphicsObject->m_valueType == gmlIntValue) 
								stipple = graphicsObject->m_intValue;
						if (id(graphicsObject) == lineWidthPredefKey && //line width
							graphicsObject->m_valueType == gmlDoubleValue) 
								lineWidth = graphicsObject->m_doubleValue;
						if (id(graphicsObject) == edgeWeightPredefKey &&
							graphicsObject->m_valueType == gmlDoubleValue)
							edgeWeight = graphicsObject->m_doubleValue;
					}//for graphics
				}

				case generalizationPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					umlType = (edgeSon->m_intValue == 0) ?
						Graph::association : Graph::generalization;
					break;

				}
			}

			// check if everything required is defined correctly
			if (sourceId == notDefined || targetId == notDefined) {
				setError("source or target id not defined");
				return false;

			} else if (sourceId < minId || maxId < sourceId ||
				targetId < minId || maxId < targetId) {
				setError("source or target id out of range");
				return false;
			}

			// create adjacent nodes if necessary and new edge
			if (m_mapToNode[sourceId] == 0) m_mapToNode[sourceId] = G.newNode();
			if (m_mapToNode[targetId] == 0) m_mapToNode[targetId] = G.newNode();

			edge e = G.newEdge(m_mapToNode[sourceId],m_mapToNode[targetId]);
			if (AG.attributes() & GraphAttributes::edgeGraphics)
				AG.bends(e).conc(bends);
			if (AG.attributes() & GraphAttributes::edgeType)
				AG.type(e) = umlType;
			if(AG.attributes() & GraphAttributes::edgeSubGraph)
			        AG.subGraphBits(e) = subGraph;
			if (AG.attributes() & GraphAttributes::edgeLabel)
				AG.labelEdge(e) = label;

            if (AG.attributes() & GraphAttributes::edgeArrow)
                if (arrow == "none")
                    AG.arrowEdge(e) = GraphAttributes::none;
                else if (arrow == "last")
                    AG.arrowEdge(e) = GraphAttributes::last;
                else if (arrow == "first")
                    AG.arrowEdge(e) = GraphAttributes::first;
                else if (arrow == "both")
                    AG.arrowEdge(e) = GraphAttributes::both;
                else
                    AG.arrowEdge(e) = GraphAttributes::undefined;
			if (AG.attributes() & GraphAttributes::edgeColor)
				AG.colorEdge(e) = fill;
			if (AG.attributes() & GraphAttributes::edgeStyle)
			{
				AG.styleEdge(e) = AG.intToStyle(stipple);
				AG.edgeWidth(e) = lineWidth;
			}

			if (AG.attributes() & GraphAttributes::edgeDoubleWeight)
				AG.doubleWeight(e) = edgeWeight;

            break; }
		case directedPredefKey: {
			if(son->m_valueType != gmlIntValue) break;
			AG.directed(son->m_intValue > 0);
			break; }
		}
	}

	return true;
}//read
Ejemplo n.º 22
0
//*************************************************************
// returns GraphAttributes associated with basic graph i
//
void SimDraw::getBasicGraphAttributes(int i, GraphAttributes &GA, Graph &G)
{
    G = m_G;
    GA.init(G,m_GA.attributes());
    
    List<edge> LE;
    m_G.allEdges(LE);
    forall_listiterators(edge,it,LE)
	if(m_GA.inSubGraph(*it,i))
	{
	    node v;
	    forall_nodes(v,G)
	    {
		if(compare(GA,v,m_GA,(*it)->source()))
		{
		    if(m_GA.attributes() & GraphAttributes::nodeGraphics)
		    {
			GA.x(v) = m_GA.x((*it)->source());
			GA.y(v) = m_GA.y((*it)->source());
			GA.height(v) = m_GA.height((*it)->source());
			GA.width(v) = m_GA.width((*it)->source());
		    }
				
		    if(m_GA.attributes() & GraphAttributes::nodeId)
			GA.idNode(v) = m_GA.idNode((*it)->source());
		    
		    if(m_GA.attributes() & GraphAttributes::nodeLabel)
			GA.labelNode(v) = m_GA.labelNode((*it)->source());
		}
			
		if(compare(GA,v,m_GA,(*it)->target()))
		{
		    if(m_GA.attributes() & GraphAttributes::nodeGraphics)
		    {
			GA.x(v) = m_GA.x((*it)->target());
			GA.y(v) = m_GA.y((*it)->target());
			GA.height(v) = m_GA.height((*it)->target());
			GA.width(v) = m_GA.width((*it)->target());
		    }
				
		    if(m_GA.attributes() & GraphAttributes::nodeId)
			GA.idNode(v) = m_GA.idNode((*it)->target());
		    
		    if(m_GA.attributes() & GraphAttributes::nodeLabel)
			GA.labelNode(v) = m_GA.labelNode((*it)->target());
		}
	    }
	    
	    edge e;
	    forall_edges(e,G)
	    {
		if(compare(GA,e->source(),m_GA,(*it)->source())
		&& compare(GA,e->target(),m_GA,(*it)->target()))
		{
		    if(m_GA.attributes() & GraphAttributes::edgeIntWeight)
			GA.intWeight(e) = m_GA.intWeight(*it);
		    
		    if(m_GA.attributes() & GraphAttributes::edgeLabel)
			GA.labelEdge(e) = m_GA.labelEdge(*it);
		    
		    if(m_GA.attributes() & GraphAttributes::edgeColor)
			GA.colorEdge(e) = m_GA.colorEdge(*it);
		    
		    if(m_GA.attributes() & GraphAttributes::edgeGraphics)
			GA.bends(e) = m_GA.bends(*it);
		}
	    }
	}
Ejemplo n.º 23
0
void SpringEmbedderFR::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();
	if(G.empty())
		return;

	// all edges straight-line
	AG.clearAllBends();

	GraphCopy GC;
	GC.createEmpty(G);

	// compute connected component of G
	NodeArray<int> component(G);
	int numCC = connectedComponents(G,component);

	// intialize the array of lists of nodes contained in a CC
	Array<List<node> > nodesInCC(numCC);

	node v;
	forall_nodes(v,G)
		nodesInCC[component[v]].pushBack(v);

	EdgeArray<edge> auxCopy(G);
	Array<DPoint> boundingBox(numCC);

	int i;
	for(i = 0; i < numCC; ++i)
	{
		GC.initByNodes(nodesInCC[i],auxCopy);

		GraphCopyAttributes AGC(GC,AG);
		node vCopy;
		forall_nodes(vCopy, GC) {
			node vOrig = GC.original(vCopy);
			AGC.x(vCopy) = AG.x(vOrig);
			AGC.y(vCopy) = AG.y(vOrig);
		}

		// original
		if (initialize(GC, AGC) == true)
		{
			for(int i = 1; i <= m_iterations; i++)
				mainStep(GC, AGC);

		}
		cleanup();
		// end original

		node vFirst = GC.firstNode();
		double minX = AGC.x(vFirst), maxX = AGC.x(vFirst),
			minY = AGC.y(vFirst), maxY = AGC.y(vFirst);

		forall_nodes(vCopy,GC) {
			node v = GC.original(vCopy);
			AG.x(v) = AGC.x(vCopy);
			AG.y(v) = AGC.y(vCopy);

			if(AG.x(v)-AG.width (v)/2 < minX) minX = AG.x(v)-AG.width(v) /2;
			if(AG.x(v)+AG.width (v)/2 > maxX) maxX = AG.x(v)+AG.width(v) /2;
			if(AG.y(v)-AG.height(v)/2 < minY) minY = AG.y(v)-AG.height(v)/2;
			if(AG.y(v)+AG.height(v)/2 > maxY) maxY = AG.y(v)+AG.height(v)/2;
		}
Ejemplo n.º 24
0
void ComponentSplitterLayout::call(GraphAttributes &GA)
{
	// Only do preparations and call if layout is valid
	if (m_secondaryLayout.valid())
	{
		//first we split the graph into its components
		const Graph& G = GA.constGraph();

		NodeArray<int> componentNumber(G);
		int numberOfComponents = connectedComponents(G, componentNumber);
		if (numberOfComponents == 0) {
			return;
		}

		// intialize the array of lists of nodes contained in a CC
		Array<List<node> > nodesInCC(numberOfComponents);

		for(node v : G.nodes)
			nodesInCC[componentNumber[v]].pushBack(v);

		// Create copies of the connected components and corresponding
		// GraphAttributes
		GraphCopy GC;
		GC.createEmpty(G);

		EdgeArray<edge> auxCopy(G);

		for (int i = 0; i < numberOfComponents; i++)
		{
			GC.initByNodes(nodesInCC[i],auxCopy);
			GraphAttributes cGA(GC, GA.attributes());
			//copy information into copy GA
			for(node v : GC.nodes)
			{
				cGA.width(v) = GA.width(GC.original(v));
				cGA.height(v) = GA.height(GC.original(v));
				cGA.x(v) = GA.x(GC.original(v));
				cGA.y(v) = GA.y(GC.original(v));
			}
			// copy information on edges
			if (GA.attributes() & GraphAttributes::edgeDoubleWeight) {
				for (edge e : GC.edges) {
					cGA.doubleWeight(e) = GA.doubleWeight(GC.original(e));
				}
			}
			m_secondaryLayout.get().call(cGA);

			//copy layout information back into GA
			for(node v : GC.nodes)
			{
				node w = GC.original(v);
				if (w != nullptr)
				{
					GA.x(w) = cGA.x(v);
					GA.y(w) = cGA.y(v);
					if (GA.attributes() & GraphAttributes::threeD) {
						GA.z(w) = cGA.z(v);
					}
				}
			}
		}

		// rotate component drawings and call the packer
		reassembleDrawings(GA, nodesInCC);

	}//if valid
}
Ejemplo n.º 25
0
void VisibilityLayout::layout(GraphAttributes &GA, const UpwardPlanRep &UPROrig)
{
	UpwardPlanRep UPR = UPROrig;

	//clear some data
	for(edge e : GA.constGraph().edges) {
		GA.bends(e).clear();
	}

	int minGridDist = 1;
	for(node v : GA.constGraph().nodes) {
		if (minGridDist < max(GA.height(v), GA.width(v)))
			minGridDist = (int) max(GA.height(v), GA.width(v));
	}
	minGridDist = max(minGridDist*2+1, m_grid_dist);

	CombinatorialEmbedding &gamma = UPR.getEmbedding();
	//add edge (s,t)
	adjEntry adjSrc = nullptr;
	for(adjEntry adj : UPR.getSuperSource()->adjEntries) {
		if (gamma.rightFace(adj) == gamma.externalFace())
			adjSrc = adj;
			break;
	}

	OGDF_ASSERT(adjSrc != nullptr);

	edge e_st = UPR.newEdge(adjSrc, UPR.getSuperSink()); // on the right
	gamma.computeFaces();
	gamma.setExternalFace(gamma.rightFace(e_st->adjSource()));

	constructVisibilityRepresentation(UPR);

	// the preliminary postion
	NodeArray<int> xPos(UPR);
	NodeArray<int> yPos(UPR);

	// node Position
	for(node v : UPR.nodes) {
		NodeSegment vVis = nodeToVis[v];
		int x = (int) (vVis.x_l + vVis.x_r)/2 ; // median positioning
		xPos[v] = x;
		yPos[v] = vVis.y;

		if (UPR.original(v) != nullptr) {
			node vOrig = UPR.original(v);
			//final position
			GA.x(vOrig) = x * minGridDist;
			GA.y(vOrig)	= vVis.y * minGridDist;
		}
	}

	//compute bendpoints
	for(edge e : GA.constGraph().edges) {
		const List<edge> &chain = UPR.chain(e);
		for(edge eUPR : chain) {
			EdgeSegment eVis = edgeToVis[eUPR];
			if (chain.size() == 1) {
				if ((yPos[eUPR->target()] - yPos[eUPR->source()]) > 1) {
					DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist);
					DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist);
					GA.bends(e).pushBack(p1);
					if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1)
						GA.bends(e).pushBack(p2);
				}
			}
			else {
				//short edge
				if ((yPos[eUPR->target()] - yPos[eUPR->source()]) == 1) {
					if (UPR.original(eUPR->target()) == nullptr) {
						node tgtUPR = eUPR->target();
						DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist);
						GA.bends(e).pushBack(p);
					}
				}
				//long edge
				else {
					DPoint p1(eVis.x*minGridDist, (yPos[eUPR->source()]+1)*minGridDist);
					DPoint p2(eVis.x*minGridDist, (yPos[eUPR->target()]-1)*minGridDist);
					GA.bends(e).pushBack(p1);
					if (yPos[eUPR->source()]+1 != yPos[eUPR->target()]-1)
						GA.bends(e).pushBack(p2);
					if (UPR.original(eUPR->target()) == nullptr) {
						node tgtUPR = eUPR->target();
						DPoint p(xPos[tgtUPR]*minGridDist, yPos[tgtUPR]*minGridDist);
						GA.bends(e).pushBack(p);
					}
				}
			}
		}

		DPolyline &poly = GA.bends(e);
		DPoint pSrc(GA.x(e->source()), GA.y(e->source()));
		DPoint pTgt(GA.x(e->target()), GA.y(e->target()));
		poly.normalize(pSrc, pTgt);
	}
}
Ejemplo n.º 26
0
void SpringEmbedderFRExact::call(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();
	if(G.empty())
		return;

	// all edges straight-line
	AG.clearAllBends();

	ArrayGraph component(AG);
	component.m_useNodeWeight = m_useNodeWeight;

	EdgeArray<edge> auxCopy(G);
	Array<DPoint> boundingBox(component.numberOfCCs());

	int i;
	for(i = 0; i < component.numberOfCCs(); ++i)
	{
		component.initCC(i);

		if (component.numberOfNodes() >= 2)
		{
			initialize(component);

#ifdef OGDF_SSE3_EXTENSIONS
			if(System::cpuSupports(cpufSSE3))
				mainStep_sse3(component);
			else
#endif
				mainStep(component);
		}

		double minX, maxX, minY, maxY;
		minX = maxX = component.m_x[0];
		minY = maxY = component.m_y[0];

		for(int vCopy = 0; vCopy < component.numberOfNodes(); ++vCopy) {
			node v = component.original(vCopy);
			AG.x(v) = component.m_x[vCopy];
			AG.y(v) = component.m_y[vCopy];

			if(AG.x(v)-AG.width (v)/2 < minX) minX = AG.x(v)-AG.width(v) /2;
			if(AG.x(v)+AG.width (v)/2 > maxX) maxX = AG.x(v)+AG.width(v) /2;
			if(AG.y(v)-AG.height(v)/2 < minY) minY = AG.y(v)-AG.height(v)/2;
			if(AG.y(v)+AG.height(v)/2 > maxY) maxY = AG.y(v)+AG.height(v)/2;
		}

		minX -= m_minDistCC;
		minY -= m_minDistCC;

		for(int vCopy = 0; vCopy < component.numberOfNodes(); ++vCopy) {
			node v = component.original(vCopy);
			AG.x(v) -= minX;
			AG.y(v) -= minY;
		}

		boundingBox[i] = DPoint(maxX - minX, maxY - minY);
	}

	Array<DPoint> offset(component.numberOfCCs());
	TileToRowsCCPacker packer;
	packer.call(boundingBox,offset,m_pageRatio);

	// The arrangement is given by offset to the origin of the coordinate
	// system. We still have to shift each node and edge by the offset
	// of its connected component.

	for(i = 0; i < component.numberOfCCs(); ++i)
	{
		const SList<node> &nodes = component.nodesInCC(i);

		const double dx = offset[i].m_x;
		const double dy = offset[i].m_y;

		// iterate over all nodes in ith CC
		for(node v : nodes)
		{
			AG.x(v) += dx;
			AG.y(v) += dy;
		}
	}
}
Ejemplo n.º 27
0
//*************************************************************
// returns GraphAttributes associated with basic graph i
//
void SimDraw::getBasicGraphAttributes(int i, GraphAttributes &GA, Graph &G)
{
	G = m_G;
	GA.init(G,m_GA.attributes());

	List<edge> LE;
	m_G.allEdges(LE);
	for(edge eLE : LE)
		if(m_GA.inSubGraph(eLE,i))
		{
			for(node v : G.nodes)
			{
				if(compare(GA,v,m_GA,eLE->source()))
				{
					if(m_GA.attributes() & GraphAttributes::nodeGraphics)
					{
						GA.x(v) = m_GA.x(eLE->source());
						GA.y(v) = m_GA.y(eLE->source());
						GA.height(v) = m_GA.height(eLE->source());
						GA.width(v) = m_GA.width(eLE->source());
					}

					if(m_GA.attributes() & GraphAttributes::nodeId)
						GA.idNode(v) = m_GA.idNode(eLE->source());

					if(m_GA.attributes() & GraphAttributes::nodeLabel)
						GA.label(v) = m_GA.label(eLE->source());
				}

				if(compare(GA,v,m_GA,eLE->target()))
				{
					if(m_GA.attributes() & GraphAttributes::nodeGraphics)
					{
						GA.x(v) = m_GA.x(eLE->target());
						GA.y(v) = m_GA.y(eLE->target());
						GA.height(v) = m_GA.height(eLE->target());
						GA.width(v) = m_GA.width(eLE->target());
					}

					if(m_GA.attributes() & GraphAttributes::nodeId)
						GA.idNode(v) = m_GA.idNode(eLE->target());

					if(m_GA.attributes() & GraphAttributes::nodeLabel)
						GA.label(v) = m_GA.label(eLE->target());
				}
			}

			for(edge e : G.edges)
			{
				if(compare(GA,e->source(),m_GA,eLE->source())
					&& compare(GA,e->target(),m_GA,eLE->target()))
				{
					if(m_GA.attributes() & GraphAttributes::edgeIntWeight)
						GA.intWeight(e) = m_GA.intWeight(eLE);

					if(m_GA.attributes() & GraphAttributes::edgeLabel)
						GA.label(e) = m_GA.label(eLE);

					if(m_GA.attributes() & GraphAttributes::edgeStyle)
						GA.strokeColor(e) = m_GA.strokeColor(eLE);

					if(m_GA.attributes() & GraphAttributes::edgeGraphics)
						GA.bends(e) = m_GA.bends(eLE);
				}
			}
		}
		else
		{
			List<edge> LE2;
			G.allEdges(LE2);
			for(edge e2 : LE2)
			{
				if(compare(GA,e2->source(),m_GA,eLE->source())
					&& compare(GA,e2->target(),m_GA,eLE->target()))
				{
					G.delEdge(e2);
				}
			}
		}

		//remove all Nodes with degree == 0
		//this can change the IDs of the nodes in G.
		List<node> LN;
		G.allNodes(LN);
		for(node v : LN)
			if(v->degree() == 0)
				G.delNode(v);

}//end getBasicGraphAttributes
Ejemplo n.º 28
0
static void write_ogml_layout_nodes_edges(const GraphAttributes &A, ostream &os)
{
	const Graph &G = A.constGraph();

	if (A.has(GraphAttributes::nodeGraphics | GraphAttributes::nodeStyle))
	{
		for(node v : G.nodes) {
			GraphIO::indent(os,4) << "<nodeStyle idRef=\"n" << v->index() << "\">\n";

			if(A.has(GraphAttributes::nodeGraphics)) {
				GraphIO::indent(os,5) << "<location x=\"" << A.x(v)-0.5*A.width(v) << "\" y=\""<< A.y(v)-0.5*A.height(v) << "\" />\n";
				GraphIO::indent(os,5) << "<shape type=\"";
				switch (A.shape(v)) {
				case shRect:
					os << "rect";
					break;
				case shRoundedRect:
					os << "roundedRect";
					break;
				case shEllipse:
					os << "ellipse";
					break;
				case shTriangle:
					os << "triangle";
					break;
				case shPentagon:
					os << "pentagon";
					break;
				case shHexagon:
					os << "hexagon";
					break;
				case shOctagon:
					os << "octagon";
					break;
				case shRhomb:
					os << "rhomb";
					break;
				case shTrapeze:
					os << "trapeze";
					break;
				case shParallelogram:
					os << "parallelogram";
					break;
				case shInvTriangle:
					os << "invTriangle";
					break;
				case shInvTrapeze:
					os << "invTrapeze";
					break;
				case shInvParallelogram:
					os << "invParallelogram";
					break;
				case shImage:
					os << "image";
					break;
				}
				os << "\" width=\"" << A.width(v) << "\" height=\"" << A.height(v) << "\" />\n";
			}

			if(A.has(GraphAttributes::nodeStyle)) {
				// fill-tag
				GraphIO::indent(os,5) << "<fill";

				// color-attribute of fill-tag
				os << " color=\"" << A.fillColor(v) << "\"";

				// pattern- and patternColor-attribute of fill-tag (closing)
				os << " pattern=\"" << fillPatternToOGML(A.fillPattern(v)) << "\" patternColor=\"" << A.fillBgColor(v) << "\" />\n";
				// line-tag
				GraphIO::indent(os,5) << "<line type=\"" << edgeStyleToOGML(A.strokeType(v)) <<  "\" width=\"" << A.strokeWidth(v) << "\""
					<< " color=\"" << A.strokeColor(v) << "\"";

				// closing fill-tag
				os << " />\n";
			}

			GraphIO::indent(os,4) << "</nodeStyle>\n";
		}
	}

	if (A.has(GraphAttributes::edgeGraphics | GraphAttributes::edgeStyle))
	{
		int pointId = 0;

		for(edge e : G.edges) {
			GraphIO::indent(os,4) << "<edgeStyle idRef=\"e" << e->index() << "\">\n";

			if(A.has(GraphAttributes::edgeStyle)) {
				GraphIO::indent(os,5) << "<line ";
				if (A.has(GraphAttributes::edgeStyle)) {
					os << "type=\"" << edgeStyleToOGML(A.strokeType(e)) << "\" width=\"" << A.strokeWidth(e) << "\" ";
					os << "color=\"" << A.strokeColor(e) << "\" />\n";
				} else 	{
					os << " />\n";
				}
			}

			// TODO review the handling of edge arrows
			if(A.has(GraphAttributes::edgeArrow))
			{
				switch(A.arrowType(e)) {
				case eaNone:
					GraphIO::indent(os,5) << "<sourceStyle type=\"none\" color=\"#000000\" size=\"1\" />\n";
					GraphIO::indent(os,5) << "<targetStyle type=\"none\" color=\"#000000\" size=\"1\" />\n";
					break;
				case eaLast:
					GraphIO::indent(os,5) << "<sourceStyle type=\"none\" color=\"#000000\" size=\"1\" />\n";
					GraphIO::indent(os,5) << "<targetStyle type=\"arrow\" color=\"#000000\" size=\"1\" />\n";
					break;
				case eaFirst:
					GraphIO::indent(os,5) << "<sourceStyle type=\"arrow\" color=\"#000000\" size=\"1\" />\n";
					GraphIO::indent(os,5) << "<targetStyle type=\"none\" color=\"#000000\" size=\"1\" />\n";
					break;
				case eaBoth:
					GraphIO::indent(os,5) << "<sourceStyle type=\"arrow\" color=\"#000000\" size=\"1\" />\n";
					GraphIO::indent(os,5) << "<targetStyle type=\"arrow\" color=\"#000000\" size=\"1\" />\n";
					break;
				case eaUndefined:
					// do nothing
					break;
				default:
					// do nothing
					break;
				}
			}

			// handling of points
			// TODO: Revise for new OGML specification
			const DPolyline &dpl = A.bends(e);
			if (!dpl.empty()) {
				// handle source
				node v = e->source();
				if(dpl.front().m_x < A.x(v) - A.width(v)/2 ||
					dpl.front().m_x > A.x(v) + A.width(v)/2 ||
					dpl.front().m_y < A.y(v) - A.height(v)/2 ||
					dpl.front().m_y > A.y(v) + A.height(v)/2)	{
						GraphIO::indent(os,5) << "<point id=\"p" << pointId++ << "\" x=\"" << A.x(e->source()) << "\" y=\"" << A.y(e->source()) << "\" />\n";
				}
				// handle points
				for(const DPoint &dp : dpl) {
					GraphIO::indent(os,5) << "<point id=\"p" << pointId++ << "\" x=\"" << dp.m_x << "\" y=\"" << dp.m_y << "\" />\n";
				}
				// handle target
				v = e->target();
				if(dpl.back().m_x < A.x(v) - A.width(v)/2 ||
					dpl.back().m_x > A.x(v) + A.width(v)/2 ||
					dpl.back().m_y < A.y(v) - A.height(v)/2 ||
					dpl.back().m_y > A.y(v) + A.height(v)/2) {
						GraphIO::indent(os,5) << "<point id=\"p" << pointId++ << "\" x=\"" << A.x(e->target()) << "\" y=\"" << A.y(e->target()) << "\" />\n";
				}
			}

			GraphIO::indent(os,4) << "</edgeStyle>\n";
		}
	}
}
Ejemplo n.º 29
0
bool GraphMLParser::readData(
	GraphAttributes &GA,
	const node &v, 
	const pugi::xml_node nodeData)
{
	pugi::xml_attribute keyId = nodeData.attribute("key");

	if (!keyId) {
		GraphIO::logger.lout() << "Node data does not have a key." << endl;
		return false;
	}

	const long attrs = GA.attributes();

	pugi::xml_text text = nodeData.text();

	switch (graphml::toAttribute(m_attrName[keyId.value()])) {
	case graphml::a_nodeLabel:
		if(attrs & GraphAttributes::nodeLabel) {
			GA.label(v) = text.get();
		}
		break;
	case graphml::a_x:
		if(attrs & GraphAttributes::nodeGraphics) {
			GA.x(v) = text.as_double();
		}
		break;
	case graphml::a_y:
		if(attrs & GraphAttributes::nodeGraphics) {
			GA.y(v) = text.as_double();;
		}
		break;
	case graphml::a_width:
		if(attrs & GraphAttributes::nodeGraphics) {
			GA.width(v) = text.as_double();
		}
		break;
	case graphml::a_height:
		if(attrs & GraphAttributes::nodeGraphics) {
			GA.height(v) = text.as_double();
		}
		break;
	case graphml::a_size:
		if(attrs & GraphAttributes::nodeGraphics) {
			double size = text.as_double();

			// We want to set a new size only if width and height was not set.
			if (GA.height(v) == GA.width(v)) {
				GA.height(v) = GA.width(v) = size;
			}
		}
		break;
	case graphml::a_shape:
		if(attrs & GraphAttributes::nodeGraphics) {
			GA.shape(v) = graphml::toShape(text.get());
		}
		break;
	case graphml::a_z:
		if(attrs & GraphAttributes::threeD) {
			GA.z(v) = text.as_double();
		}
		break;
	case graphml::a_r:
		if (attrs & GraphAttributes::nodeStyle
		 && !GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { GA.fillColor(v).red(val); })) {
			return false;
		}
		break;
	case graphml::a_g:
		if(attrs & GraphAttributes::nodeStyle
		 && !GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { GA.fillColor(v).green(val); })) {
			return false;
		}
		break;
	case graphml::a_b:
		if(attrs & GraphAttributes::nodeStyle
		 && !GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { GA.fillColor(v).blue(val); })) {
			return false;
		}
		break;
	case graphml::a_nodeFill:
		if(attrs & GraphAttributes::nodeStyle) {
			GA.fillColor(v) = text.get();
		}
		break;
	case graphml::a_nodeStroke:
		if(attrs & GraphAttributes::nodeStyle) {
			GA.strokeColor(v) = text.get();
		}
		break;
	case graphml::a_nodeType:
		if(attrs & GraphAttributes::nodeType) {
			GA.type(v) = graphml::toNodeType(text.get());
		}
		break;
	case graphml::a_template:
		if(attrs & GraphAttributes::nodeTemplate) {
			GA.templateNode(v) = text.get();
		}
		break;
	case graphml::a_nodeWeight:
		if(attrs & GraphAttributes::nodeWeight) {
			GA.weight(v) = text.as_int();
		}
		break;
	default:
		GraphIO::logger.lout(Logger::LL_MINOR) << "Unknown node attribute: \"" << keyId.value() << "\"." << endl;
	}

	return true;
}
Ejemplo n.º 30
0
bool GmlParser::read(Graph &G, GraphAttributes &AG)
{
	OGDF_ASSERT(&G == &(AG.constGraph()))

	G.clear();

	int minId = m_mapToNode.low();
	int maxId = m_mapToNode.high();
	int notDefined = minId-1; //indicates not defined id key

	HashArray<string,Shape> strToShape(shRect);
	strToShape["rectangle"]        = shRect;
	strToShape["rect"]             = shRect;
	strToShape["roundedRect"]      = shRoundedRect;
	strToShape["oval"]             = shEllipse;
	strToShape["ellipse"]          = shEllipse;
	strToShape["triangle"]         = shTriangle;
	strToShape["pentagon"]         = shPentagon;
	strToShape["hexagon"]          = shHexagon;
	strToShape["octagon"]          = shOctagon;
	strToShape["rhomb"]            = shRhomb;
	strToShape["trapeze"]          = shTrapeze;
	strToShape["parallelogram"]    = shParallelogram;
	strToShape["invTriangle"]      = shInvTriangle;
	strToShape["invTrapeze"]       = shInvTrapeze;
	strToShape["invParallelogram"] = shInvParallelogram;
	strToShape["image"]            = shImage;

	DPolyline bends;

	GmlObject *son = m_graphObject->m_pFirstSon;
	for(; son; son = son->m_pBrother) {

		switch(id(son)) {
		case nodePredefKey: {
			if (son->m_valueType != gmlListBegin) break;

			// set attributes to default values
			int vId = notDefined;
			double x = 0, y = 0, w = 0, h = 0;
			string label;
			string templ;
			string fill;  // the fill color attribute
			string line;  // the line color attribute
			string shape; //the shape type
			float lineWidth = 1.0f; //node line width
			int pattern = 1; //node brush pattern
			int stipple = 1; //line style pattern
			int weight = 0; // node weight

			// read all relevant attributes
			GmlObject *nodeSon = son->m_pFirstSon;
			for(; nodeSon; nodeSon = nodeSon->m_pBrother) {
				switch(id(nodeSon)) {
				case idPredefKey:
					if(nodeSon->m_valueType != gmlIntValue) break;
					vId = nodeSon->m_intValue;
					break;

				case graphicsPredefKey: {
					if (nodeSon->m_valueType != gmlListBegin) break;

					GmlObject *graphicsObject = nodeSon->m_pFirstSon;
					for(; graphicsObject;
						graphicsObject = graphicsObject->m_pBrother)
					{
						switch(id(graphicsObject)) {
						case xPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							x = graphicsObject->m_doubleValue;
							break;

						case yPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							y = graphicsObject->m_doubleValue;
							break;

						case wPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							w = graphicsObject->m_doubleValue;
							break;

						case hPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							h = graphicsObject->m_doubleValue;
							break;

						case fillPredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
							fill = graphicsObject->m_stringValue;
							break;

						case linePredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
							line = graphicsObject->m_stringValue;
							break;

						case lineWidthPredefKey:
							if(graphicsObject->m_valueType != gmlDoubleValue) break;
							lineWidth = (float)graphicsObject->m_doubleValue;
							break;

						case typePredefKey:
							if(graphicsObject->m_valueType != gmlStringValue) break;
							shape = graphicsObject->m_stringValue;
							break;
						case patternPredefKey: //fill style
							if(graphicsObject->m_valueType != gmlIntValue) break;
							pattern = graphicsObject->m_intValue;
						case stipplePredefKey: //line style
							if(graphicsObject->m_valueType != gmlIntValue) break;
							stipple = graphicsObject->m_intValue;
						}
					}
					break; }

				case templatePredefKey:
					if (nodeSon->m_valueType != gmlStringValue) break;
					templ = nodeSon->m_stringValue;
					break;

				case labelPredefKey:
					if (nodeSon->m_valueType != gmlStringValue) break;
					label = nodeSon->m_stringValue;
					break;

				case edgeWeightPredefKey: //sic!
					if (nodeSon->m_valueType != gmlIntValue) break;
					weight = nodeSon->m_intValue;
					break;
				}
			}

			// check if everything required is defined correctly
			if (vId == notDefined) {
				setError("node id not defined");
				return false;
			}

			// create new node if necessary and assign attributes
			if (m_mapToNode[vId] == nullptr) m_mapToNode[vId] = G.newNode();
			node v = m_mapToNode[vId];
			if (AG.attributes() & GraphAttributes::nodeGraphics)
			{
				AG.x(v) = x;
				AG.y(v) = y;
				AG.width (v) = w;
				AG.height(v) = h;
				AG.shape(v) = strToShape[shape];
			}
			if (AG.attributes() & GraphAttributes::nodeLabel)
				AG.label(m_mapToNode[vId]) = label;
			if (AG.attributes() & GraphAttributes::nodeTemplate)
				AG.templateNode(m_mapToNode[vId]) = templ;
			if (AG.attributes() & GraphAttributes::nodeId)
				AG.idNode(m_mapToNode[vId]) = vId;
			if (AG.attributes() & GraphAttributes::nodeWeight)
				AG.weight(m_mapToNode[vId]) = weight;
			if (AG.attributes() & GraphAttributes::nodeStyle)
			{
				AG.fillColor(m_mapToNode[vId]) = fill;
				AG.strokeColor(m_mapToNode[vId]) = line;
				AG.setFillPattern(m_mapToNode[vId], intToFillPattern(pattern));
				AG.setStrokeType(m_mapToNode[vId], intToStrokeType(stipple));
				AG.strokeWidth(m_mapToNode[vId]) = lineWidth;
			}
							}//node
							//Todo: line style set stipple value
							break;

		case edgePredefKey: {
			string arrow; // the arrow type attribute
			string fill;  //the color fill attribute
			int stipple = 1;  //the line style
			float lineWidth = 1.0f;
			double edgeWeight = 1.0;
			int subGraph = 0; //edgeSubGraphs attribute
			string label; // label attribute

			if (son->m_valueType != gmlListBegin) break;

			// set attributes to default values
			int sourceId = notDefined, targetId = notDefined;
			Graph::EdgeType umlType = Graph::association;

			// read all relevant attributes
			GmlObject *edgeSon = son->m_pFirstSon;
			for(; edgeSon; edgeSon = edgeSon->m_pBrother) {

				switch(id(edgeSon)) {
				case sourcePredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					sourceId = edgeSon->m_intValue;
					break;

				case targetPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					targetId = edgeSon->m_intValue;
					break;

				case subGraphPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					subGraph = edgeSon->m_intValue;
					break;

				case labelPredefKey:
					if (edgeSon->m_valueType != gmlStringValue) break;
					label = edgeSon->m_stringValue;
					break;

				case graphicsPredefKey: {
					if (edgeSon->m_valueType != gmlListBegin) break;

					GmlObject *graphicsObject = edgeSon->m_pFirstSon;
					for(; graphicsObject;
						graphicsObject = graphicsObject->m_pBrother)
					{
						if(id(graphicsObject) == LinePredefKey &&
							graphicsObject->m_valueType == gmlListBegin)
						{
							readLineAttribute(graphicsObject->m_pFirstSon,bends);
						}
						if(id(graphicsObject) == arrowPredefKey &&
							graphicsObject->m_valueType == gmlStringValue)
							arrow = graphicsObject->m_stringValue;
						if(id(graphicsObject) == fillPredefKey &&
							graphicsObject->m_valueType == gmlStringValue)
							fill = graphicsObject->m_stringValue;
						if (id(graphicsObject) == stipplePredefKey && //line style
							graphicsObject->m_valueType == gmlIntValue)
							stipple = graphicsObject->m_intValue;
						if (id(graphicsObject) == lineWidthPredefKey && //line width
							graphicsObject->m_valueType == gmlDoubleValue)
							lineWidth = (float)graphicsObject->m_doubleValue;
						if (id(graphicsObject) == edgeWeightPredefKey &&
							graphicsObject->m_valueType == gmlDoubleValue)
							edgeWeight = graphicsObject->m_doubleValue;
					}//for graphics
										}

				case generalizationPredefKey:
					if (edgeSon->m_valueType != gmlIntValue) break;
					umlType = (edgeSon->m_intValue == 0) ?
						Graph::association : Graph::generalization;
					break;

				}
			}

			// check if everything required is defined correctly
			if (sourceId == notDefined || targetId == notDefined) {
				setError("source or target id not defined");
				return false;

			} else if (sourceId < minId || maxId < sourceId ||
				targetId < minId || maxId < targetId) {
					setError("source or target id out of range");
					return false;
			}

			// create adjacent nodes if necessary and new edge
			if (m_mapToNode[sourceId] == nullptr) m_mapToNode[sourceId] = G.newNode();
			if (m_mapToNode[targetId] == nullptr) m_mapToNode[targetId] = G.newNode();

			edge e = G.newEdge(m_mapToNode[sourceId],m_mapToNode[targetId]);
			if (AG.attributes() & GraphAttributes::edgeGraphics)
				AG.bends(e).conc(bends);
			if (AG.attributes() & GraphAttributes::edgeType)
				AG.type(e) = umlType;
			if(AG.attributes() & GraphAttributes::edgeSubGraphs)
				AG.subGraphBits(e) = subGraph;
			if (AG.attributes() & GraphAttributes::edgeLabel)
				AG.label(e) = label;

			if (AG.attributes() & GraphAttributes::edgeArrow) {
				if (arrow == "none")
					AG.arrowType(e) = eaNone;
				else if (arrow == "last")
					AG.arrowType(e) = eaLast;
				else if (arrow == "first")
					AG.arrowType(e) = eaFirst;
				else if (arrow == "both")
					AG.arrowType(e) = eaBoth;
				else
					AG.arrowType(e) = eaUndefined;
			}

			if (AG.attributes() & GraphAttributes::edgeStyle)
			{
				AG.strokeColor(e) = fill;
				AG.setStrokeType(e, intToStrokeType(stipple));
				AG.strokeWidth(e) = lineWidth;
			}

			if (AG.attributes() & GraphAttributes::edgeDoubleWeight)
				AG.doubleWeight(e) = edgeWeight;


			break; }
		case directedPredefKey: {
			if(son->m_valueType != gmlIntValue) break;
			AG.setDirected(son->m_intValue > 0);
			break; }
		}
	}

	return true;
}//read