Ejemplo n.º 1
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.º 2
0
void PivotMDS::pivotMDSLayout(GraphAttributes& GA)
{
	const Graph& G = GA.constGraph();
	if (G.numberOfNodes() <= 1) {
		// make it exception save
		node v;
		forall_nodes(v,G)
		{
			GA.x(v) = 0.0;
			GA.y(v) = 0.0;
			if (DIMENSION_COUNT > 2)
				GA.z(v) = 0.0;
		}
Ejemplo n.º 3
0
void StressMinimization::copyLayout(
	const GraphAttributes& GA,
	NodeArray<double>& newX,
	NodeArray<double>& newY,
	NodeArray<double>& newZ)
{
	// copy the layout
	for(node v : GA.constGraph().nodes)
	{
		newX[v] = GA.x(v);
		newY[v] = GA.y(v);
		newZ[v] = GA.z(v);
	}
}
Ejemplo n.º 4
0
double StressMinimization::calcStress(
	const GraphAttributes& GA,
	NodeArray<NodeArray<double> >& shortestPathMatrix,
	NodeArray<NodeArray<double> >& weightMatrix)
{
	double stress = 0;
	for (node v = GA.constGraph().firstNode(); v != nullptr; v = v->succ()) {
		for (node w = v->succ(); w != nullptr; w = w->succ()) {
			double xDiff = GA.x(v) - GA.x(w);
			double yDiff = GA.y(v) - GA.y(w);
			double zDiff = 0.0;
			if (GA.has(GraphAttributes::threeD))
			{
				zDiff = GA.z(v) - GA.z(w);
			}
			double dist = sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
			if (dist != 0) {
				stress += weightMatrix[v][w] * (shortestPathMatrix[v][w] - dist)
					* (shortestPathMatrix[v][w] - dist);//
			}
		}
	}
	return stress;
}
Ejemplo n.º 5
0
// create testGraph to test criteria imlementations
void CreateGraph(Graph& G, GraphAttributes& GA) {
	// add nodes
	node zero = G.newNode();
	node one = G.newNode();
	node two = G.newNode();
	node three = G.newNode();
	node four = G.newNode();

	// set node positions
	GA.x(zero) = 4 * NODE_WIDTH;
	GA.y(zero) = 0;

	GA.x(one) = 4 * NODE_WIDTH;
	GA.y(one) = 4 * NODE_HEIGHT;

	GA.x(two) = 0;
	GA.y(two) = 2 * NODE_HEIGHT;

	GA.x(three) = 4 * NODE_WIDTH;
	GA.y(three) = 8 * NODE_HEIGHT;

	GA.x(four) = 0;
	GA.y(four) = 8 * NODE_HEIGHT;

	// add edges
	edge zero_one = G.newEdge(zero, one);
	edge zero_three = G.newEdge(zero, three);
	edge zero_four = G.newEdge(zero, four);
	edge one_two = G.newEdge(one, two);
	edge one_three = G.newEdge(one, three);
	edge two_three = G.newEdge(two, three);

	DPolyline &p = GA.bends(zero_three);
	p.pushBack(DPoint(6 * NODE_WIDTH, 2 * NODE_HEIGHT));
	p.pushBack(DPoint(6 * NODE_WIDTH, 6 * NODE_HEIGHT));
}
Ejemplo n.º 6
0
	//chooses random vertex and a new random position for it on a circle with radius m_diskRadius
	//around its previous position
	node DavidsonHarel::computeCandidateLayout(
	const GraphAttributes &AG,
	DPoint &newPos) const
	{
		int randomPos = randomNumber(0,m_nonIsolatedNodes.size()-1);
		node v = *(m_nonIsolatedNodes.get(randomPos));
		double oldx = AG.x(v);
		double oldy = AG.y(v);
		double randomAngle = randNum() * 2.0 * Math::pi;
		newPos.m_y = oldy+sin(randomAngle)*m_diskRadius;
		newPos.m_x = oldx+cos(randomAngle)*m_diskRadius;
#ifdef OGDF_DEBUG
		double dist = sqrt((newPos.m_x - oldx)*(newPos.m_x - oldx)+(newPos.m_y-oldy)*(newPos.m_y-oldy));
		OGDF_ASSERT(dist > 0.99 * m_diskRadius && dist < 1.01 * m_diskRadius);
#endif
		return v;
	}
Ejemplo n.º 7
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.º 8
0
void RadialTreeLayout::ComputeCoordinates(GraphAttributes &AG)
{
	const Graph &G = AG.constGraph();

	//double mx = m_outerRadius + 0.5*m_connectedComponentDistance;
	//double my = mx;

	for(node v : G.nodes) {
		double r = m_radius[m_level[v]];
		double alpha = m_angle[v];

		AG.x(v) = r * cos(alpha);
		AG.y(v) = r * sin(alpha);
	}

	AG.clearAllBends();
}
Ejemplo n.º 9
0
/*
 * calculate node orthogonality criterium
 *
 * TODO: calculate value '2 * NODE_SIZE' from: 
 * GCD of the set of vertical and horizontal (pixel) differences between all geometrically adjacent nodes.
 */
double NodeOrthogonalityCriterium(Graph& G, GraphAttributes& GA) {
	double width = 0, height = 0;
	for (node n : G.nodes) {
		double nodeWidth = GA.x(n) / (2 * NODE_WIDTH);
		double nodeHeight = GA.y(n) / (2 * NODE_HEIGHT);

		if (nodeWidth > width)
			width = nodeWidth;

		if (nodeHeight > height)
			height = nodeHeight;
	}

	double A = (1 + width)*(1 + height);
	double Nno = G.nodes.size() / A;

	return Nno;
}
Ejemplo n.º 10
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.º 11
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);
}
Ejemplo n.º 12
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.º 13
0
void ArrayGraph::readFrom(const GraphAttributes& GA, const EdgeArray<float>& edgeLength, const NodeArray<float>& nodeSize)
{
    const Graph& G = GA.constGraph();
    NodeArray<__uint32> nodeIndex(G);

    node v;
    m_numNodes = 0;
    m_numEdges = 0;
    m_avgNodeSize = 0;
    m_desiredAvgEdgeLength = 0;
    forall_nodes(v, G)
    {
        m_nodeXPos[m_numNodes] = (float)GA.x(v);
        m_nodeYPos[m_numNodes] = (float)GA.y(v);
        m_nodeSize[m_numNodes] = nodeSize[v];
        nodeIndex[v] = m_numNodes;
        m_avgNodeSize += nodeSize[v];
        m_numNodes++;
    };
void FMMMLayout::call(GraphAttributes &GA, const EdgeArray<double> &edgeLength)
{
  const Graph &G = GA.constGraph();
  //tms t_total;//helping variable for time measure
  double t_total;
  NodeArray<NodeAttributes> A(G);       //stores the attributes of the nodes (given by L)
  EdgeArray<EdgeAttributes> E(G);       //stores the edge attributes of G
  Graph G_reduced;                      //stores a undirected simple and loopfree copy 
                                        //of G
  EdgeArray<EdgeAttributes> E_reduced;  //stores the edge attributes of G_reduced
  NodeArray<NodeAttributes> A_reduced;  //stores the node attributes of G_reduced 

  if(G.numberOfNodes() > 1)
    {
      GA.clearAllBends();//all are edges straight line
      if(useHighLevelOptions())
	update_low_level_options_due_to_high_level_options_settings();
      import_NodeAttributes(G,GA,A);
      import_EdgeAttributes(G,edgeLength,E);
      
      //times(&t_total);
	  usedTime(t_total);
      max_integer_position = pow(2.0,maxIntPosExponent());
      init_ind_ideal_edgelength(G,A,E);  
      make_simple_loopfree(G,A,E,G_reduced,A_reduced,E_reduced);
      call_DIVIDE_ET_IMPERA_step(G_reduced,A_reduced,E_reduced);
      if(allowedPositions() != apAll)
	make_positions_integer(G_reduced,A_reduced);
      //time_total = get_time(t_total);
	  time_total = usedTime(t_total);
            
      export_NodeAttributes(G_reduced,A_reduced,GA);
    }
  else //trivial cases
    { 
      if(G.numberOfNodes() == 1 )
	{
	  node v = G.firstNode();
	  GA.x(v) = 0;
	  GA.y(v) = 0;
	} 
    }
}
Ejemplo n.º 15
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.º 16
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.º 17
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.º 18
0
bool StressMinimization::finished(
	GraphAttributes& GA,
	int numberOfPerformedIterations,
	NodeArray<double>& prevXCoords,
	NodeArray<double>& prevYCoords,
	const double prevStress,
	const double curStress)
{
	if (numberOfPerformedIterations == m_numberOfIterations) {
		return true;
	}

	switch (m_terminationCriterion)
	{
	case POSITION_DIFFERENCE:
	{
		double eucNorm = 0;
		double dividend = 0;
		// compute the translation of all nodes between
		// the consecutive layouts
		for (node v : GA.constGraph().nodes)
		{
			double diffX = prevXCoords[v] - GA.x(v);
			double diffY = prevYCoords[v] - GA.y(v);
			dividend += diffX * diffX + diffY * diffY;
			eucNorm += prevXCoords[v] * prevXCoords[v] + prevYCoords[v] * prevYCoords[v];
		}
		return sqrt(dividend) / sqrt(eucNorm) < EPSILON;
	}
	case STRESS:
		return curStress == 0 || prevStress - curStress < prevStress * EPSILON;

	default:
		return false;
	}
}
Ejemplo n.º 19
0
static inline bool readVizAttribute(
	GraphAttributes &GA, node v,
	const XmlTagObject &tag)
{
	const long attrs = GA.attributes();

	if(tag.getName() == "viz:position") {
		if(attrs & GraphAttributes::nodeGraphics) {
			XmlAttributeObject *xAttr, *yAttr, *zAttr;
			tag.findXmlAttributeObjectByName("x", xAttr);
			tag.findXmlAttributeObjectByName("y", yAttr);
			tag.findXmlAttributeObjectByName("z", zAttr);

			if(!xAttr || !yAttr) {
				OGDF_ERROR("Missing \"x\" or \"y\" on position tag "
				          << "(line " << tag.getLine() << ").");
				return false;
			}

			std::istringstream is;

			is.clear();
			is.str(xAttr->getValue());
			is >> GA.x(v);

			is.clear();
			is.str(yAttr->getValue());
			is >> GA.y(v);

			// z attribute is optional and avaliable only in \a threeD mode.
			if(zAttr && (attrs & GraphAttributes::threeD)) {
				is.clear();
				is.str(zAttr->getValue());
				is >> GA.z(v);
			}
		}
Ejemplo n.º 20
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.º 21
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.º 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);
	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.º 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
// does the actual computation. fixedNodes and fixedPositions
// contain the nodes with fixed positions.
bool TutteLayout::doCall(
	GraphAttributes &AG,
	const List<node> &fixedNodes,
	List<DPoint> &fixedPositions)
{
	//node v, w;
	//edge e;

	const Graph &G = AG.constGraph();
	GraphCopy GC(G);
	GraphCopyAttributes AGC(GC, AG);

	// mark fixed nodes and set their positions in a
	NodeArray<bool> fixed(GC, false);
	for (node v : fixedNodes) {
		fixed[v] = true;
		DPoint p = fixedPositions.popFrontRet();   // slightly dirty...
		fixedPositions.pushBack(p);          // ...

		AGC.x(v) = p.m_x;
		AGC.y(v) = p.m_y;
	}

	if (fixedNodes.size() == G.numberOfNodes()) {
		for (node v : GC.nodes) {
			AG.x(GC.original(v)) = AGC.x(v);
			AG.y(GC.original(v)) = AGC.y(v);
		}
		return true;
	}
	// all nodes have fixed positions - nothing left to do

	// collect other nodes
	List<node> otherNodes;
	for (node v : GC.nodes)
	if (!fixed[v]) otherNodes.pushBack(v);

	NodeArray<int> ind(GC);       // position of v in otherNodes and A

	int i = 0;
	for (node v : otherNodes)
		ind[v] = i++;

	int n = otherNodes.size();           // #other nodes
	Array<double> coord(n);              // coordinates (first x then y)
	Array<double> rhs(n);                // right hand side
	double oneOverD = 0.0;

	CoinPackedMatrix A(false, 0, 0);       // equations
	A.setDimensions(n, n);

	// initialize non-zero entries in matrix A
	for (node v : otherNodes) {
		oneOverD = (double) (1.0 / (v->degree()));
		edge e;
		forall_adj_edges(e, v) {
			// get second node of e
			node w = e->opposite(v);
			if (!fixed[w]) {
				A.modifyCoefficient(ind[v], ind[w], oneOverD);
			}
		}
		A.modifyCoefficient(ind[v], ind[v], -1);
	}
Ejemplo n.º 25
0
void StressMinimization::nextIteration(
	GraphAttributes& GA,
	NodeArray<NodeArray<double> >& shortestPathMatrix,
	NodeArray<NodeArray<double> >& weights)
{
	const Graph& G = GA.constGraph();

	for (node v : G.nodes)
	{
		double newXCoord = 0.0;
		double newYCoord = 0.0;
		double newZCoord = 0.0;
		double& currXCoord = GA.x(v);
		double& currYCoord = GA.y(v);
		double totalWeight = 0;
		for (node w : G.nodes)
		{
			if (v == w) {
				continue;
			}
			// calculate euclidean distance between both points
			double xDiff = currXCoord - GA.x(w);
			double yDiff = currYCoord - GA.y(w);
			double zDiff = (GA.has(GraphAttributes::threeD)) ? GA.z(v) - GA.z(w) : 0.0;
			double euclideanDist = sqrt(xDiff * xDiff + yDiff * yDiff + zDiff * zDiff);
			// get the weight
			double weight = weights[v][w];
			// get the desired distance
			double desDistance = shortestPathMatrix[v][w];
			// reset the voted x coordinate
			// if x is not fixed
			if (!m_fixXCoords) {
				double voteX = GA.x(w);
				if (euclideanDist != 0) {
					// calc the vote
					voteX += desDistance * (currXCoord - voteX) / euclideanDist;
				}
				// add the vote
				newXCoord += weight * voteX;
			}
			// reset the voted y coordinate
			// y is not fixed
			if (!m_fixYCoords) {
				double voteY = GA.y(w);
				if (euclideanDist != 0) {
					// calc the vote
					voteY += desDistance * (currYCoord - voteY) / euclideanDist;
				}
				newYCoord += weight * voteY;
			}
			if (GA.has(GraphAttributes::threeD))
			{
				// reset the voted z coordinate
				// z is not fixed
				if (!m_fixZCoords) {
					double voteZ = GA.z(w);
					if (euclideanDist != 0) {
						// calc the vote
						voteZ += desDistance * (GA.z(v) - voteZ) / euclideanDist;
					}
					newZCoord += weight * voteZ;
				}
			}
			// sum up the weights
			totalWeight += weight;
		}
		// update the positions
		if (totalWeight != 0) {
			if (!m_fixXCoords) {
				currXCoord = newXCoord / totalWeight;
			}
			if (!m_fixYCoords) {
				currYCoord = newYCoord / totalWeight;
			}
			if (GA.has(GraphAttributes::threeD))
			{
				if (!m_fixZCoords) {
					GA.z(v) = newZCoord / totalWeight;
				}
			}
		}
	}
}
Ejemplo n.º 26
0
//TODO: Regard some kind of aspect ration (input)
//(then also the rotation of a single component makes sense)
void ComponentSplitterLayout::reassembleDrawings(GraphAttributes& GA, const Array<List<node> > &nodesInCC)
{
	int numberOfComponents = nodesInCC.size();

	Array<IPoint> box;
	Array<IPoint> offset;
	Array<DPoint> oldOffset;
	Array<double> rotation;
	ConvexHull CH;

	// rotate components and create bounding rectangles

	//iterate through all components and compute convex hull
	for (int j = 0; j < numberOfComponents; j++)
	{
		//todo: should not use std::vector, but in order not
		//to have to change all interfaces, we do it anyway
		std::vector<DPoint> points;

		//collect node positions and at the same time center average
		// at origin
		double avg_x = 0.0;
		double avg_y = 0.0;
		for (node v : nodesInCC[j])
		{
			DPoint dp(GA.x(v), GA.y(v));
			avg_x += dp.m_x;
			avg_y += dp.m_y;
			points.push_back(dp);
		}
		avg_x /= nodesInCC[j].size();
		avg_y /= nodesInCC[j].size();

		//adapt positions to origin
		int count = 0;
		//assume same order of vertices and positions
		for (node v : nodesInCC[j])
		{
			//TODO: I am not sure if we need to update both
			GA.x(v) = GA.x(v) - avg_x;
			GA.y(v) = GA.y(v) - avg_y;
			points.at(count).m_x -= avg_x;
			points.at(count).m_y -= avg_y;

			count++;
		}

		// calculate convex hull
		DPolygon hull = CH.call(points);

		double best_area = numeric_limits<double>::max();
		DPoint best_normal;
		double best_width = 0.0;
		double best_height = 0.0;

		// find best rotation by using every face as rectangle border once.
		for (DPolygon::iterator j = hull.begin(); j != hull.end(); ++j) {
			DPolygon::iterator k = hull.cyclicSucc(j);

			double dist = 0.0;
			DPoint norm = CH.calcNormal(*k, *j);
			for (const DPoint &z : hull) {
				double d = CH.leftOfLine(norm, z, *k);
				if (d > dist) {
					dist = d;
				}
			}

			double left = 0.0;
			double right = 0.0;
			norm = CH.calcNormal(DPoint(0, 0), norm);
			for (const DPoint &z : hull) {
				double d = CH.leftOfLine(norm, z, *k);
				if (d > left) {
					left = d;
				}
				else if (d < right) {
					right = d;
				}
			}
			double width = left - right;

			dist = max(dist, 1.0);
			width = max(width, 1.0);

			double area = dist * width;

			if (area <= best_area) {
				best_height = dist;
				best_width = width;
				best_area = area;
				best_normal = CH.calcNormal(*k, *j);
			}
		}

		if (hull.size() <= 1) {
			best_height = 1.0;
			best_width = 1.0;
			best_area = 1.0;
			best_normal = DPoint(1.0, 1.0);
		}

		double angle = -atan2(best_normal.m_y, best_normal.m_x) + 1.5 * Math::pi;
		if (best_width < best_height) {
			angle += 0.5f * Math::pi;
			double temp = best_height;
			best_height = best_width;
			best_width = temp;
		}
		rotation.grow(1, angle);
		double left = hull.front().m_x;
		double top = hull.front().m_y;
		double bottom = hull.front().m_y;
		// apply rotation to hull and calc offset
		for (DPoint tempP : hull) {
			double ang = atan2(tempP.m_y, tempP.m_x);
			double len = sqrt(tempP.m_x*tempP.m_x + tempP.m_y*tempP.m_y);
			ang += angle;
			tempP.m_x = cos(ang) * len;
			tempP.m_y = sin(ang) * len;

			if (tempP.m_x < left) {
				left = tempP.m_x;
			}
			if (tempP.m_y < top) {
				top = tempP.m_y;
			}
			if (tempP.m_y > bottom) {
				bottom = tempP.m_y;
			}
		}
		oldOffset.grow(1, DPoint(left + 0.5 * static_cast<double>(m_border), -1.0 * best_height + 1.0 * bottom + 0.0 * top + 0.5 * (double)m_border));

		// save rect
		int w = static_cast<int>(best_width);
		int h = static_cast<int>(best_height);
		box.grow(1, IPoint(w + m_border, h + m_border));
	}// components

	offset.init(box.size());

	// call packer
	m_packer.get().call(box, offset, m_targetRatio);

	int index = 0;
	// Apply offset and rebuild Graph
	for (int j = 0; j < numberOfComponents; j++)
	{
		double angle = rotation[index];
		// apply rotation and offset to all nodes

		for (node v : nodesInCC[j])
		{
			double x = GA.x(v);
			double y = GA.y(v);
			double ang = atan2(y, x);
			double len = sqrt(x*x + y*y);
			ang += angle;
			x = cos(ang) * len;
			y = sin(ang) * len;

			x += static_cast<double>(offset[index].m_x);
			y += static_cast<double>(offset[index].m_y);

			x -= oldOffset[index].m_x;
			y -= oldOffset[index].m_y;

			GA.x(v) = x;
			GA.y(v) = y;

		}// while nodes in component

		index++;
	} // for components

	//now we center the whole graph again
	//TODO: why?
	//const Graph& G = GA.constGraph();
	//for(node v : G.nodes)
	//MLG.moveToZero();
}
Ejemplo n.º 27
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.º 28
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.º 29
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
Ejemplo n.º 30
0
static inline void writeAttributes(
	std::ostream &out, int depth,
	const GraphAttributes &GA, node v)
{
	const long attrs = GA.attributes();

	if(attrs & GraphAttributes::nodeGraphics) {
		const double z = (attrs & GraphAttributes::threeD) ? GA.z(v) : 0.0;
		GraphIO::indent(out, depth) << "<viz:position "
		                            << "x=\"" << GA.x(v) << "\" "
		                            << "y=\"" << GA.y(v) << "\" "
		                            << "z=\"" << z << "\" "
		                            << "/>\n";

		// TODO: size is a scale here, so we have to know average size first.
		// const double size = std::max(GA.width(v), GA.height(v));
		// GraphIO::indent(out, depth) << "<viz:size "
		//                             << "value=\"" << size << "\" "
		//                             << "/>\n";

		const Shape shape = GA.shape(v);
		GraphIO::indent(out, depth) << "<viz:shape "
		                            << "value=\"" << toString(shape) << "\" "
		                            << "/>\n";
	}

	if(attrs & GraphAttributes::nodeStyle) {
		const Color &color = GA.fillColor(v);

		const int red = color.red();
		const int green = color.green();
		const int blue = color.blue();
		const int alpha = color.alpha();

		GraphIO::indent(out, depth) << "<viz:color "
		                            << "red=\"" << red << "\" "
		                            << "green=\"" << green << "\" "
		                            << "blue=\"" << blue << "\" "
		                            << "alpha=\"" << alpha << "\" "
		                            << "/>\n";

	}

	/*
	 * Node type, template and weight are not supported by VIZ module. So, they
	 * need to be written using <attvalues> tag (for estetic reasons, we write
	 * them only if either of them is present). For convenience reasons, we use
	 * the same names and values as in GraphML format.
	 */
	if(!(attrs & (GraphAttributes::nodeType |
	              GraphAttributes::nodeTemplate |
	              GraphAttributes::nodeWeight))) {
		return;
	}

	GraphIO::indent(out, depth) << "<attvalues>\n";

	if(attrs & GraphAttributes::nodeType) {
		writeAttValue(
			out, depth + 1,
			graphml::a_nodeType, graphml::toString(GA.type(v)));
	}

	if(attrs & GraphAttributes::nodeTemplate) {
		writeAttValue(out, depth + 1, graphml::a_template, GA.templateNode(v));
	}

	if(attrs & GraphAttributes::nodeWeight) {
		writeAttValue(out, depth + 1, graphml::a_nodeWeight, GA.weight(v));
	}

	GraphIO::indent(out, depth) << "</attvalues>\n";
}