static bool inline readAttribute( GraphAttributes &GA, node v, const NodeAttribute &attr, const std::string &value) { const long attrs = GA.attributes(); switch(attr) { case na_name: // Not really an attribute, handled elsewhere. break; case na_label: if(attrs & GraphAttributes::nodeLabel) { GA.label(v) = value; } break; case na_x: if(attrs & GraphAttributes::nodeGraphics) { std::istringstream is(value); is >> GA.x(v); } break; case na_y: if(attrs & GraphAttributes::nodeGraphics) { std::istringstream is(value); is >> GA.y(v); }
bool GraphMLParser::readData( GraphAttributes &GA, const node &v, const XmlTagObject &nodeData) { XmlAttributeObject *keyId; nodeData.findXmlAttributeObjectByName("key", keyId); if(keyId == NULL) { cerr << "ERROR: Node data does not have a key.\n"; return false; } const long attrs = GA.attributes(); std::stringstream value(nodeData.getValue()); switch (graphml::toAttribute(m_attrName[keyId->getValue()])) { case graphml::a_nodeLabel: if(attrs & GraphAttributes::nodeLabel) { value >> GA.label(v); } break; case graphml::a_x: if(attrs & GraphAttributes::nodeGraphics) { value >> GA.x(v); }
//************************************************************* //adds new GraphAttributes to m_G if maxSubgraph() < 32 // bool SimDraw::addGraphAttributes(const GraphAttributes & GA) { if(maxSubGraph() >= 31) return false; //if(compareBy() == label) OGDF_ASSERT((compareBy() != label) || (m_GA.attributes() & GraphAttributes::edgeLabel)); int max = numberOfBasicGraphs(); bool foundEdge = false; //node v; //edge e, f; Graph G = GA.constGraph(); for(edge e : G.edges) { for(edge f : m_G.edges) { if (compare(m_GA, f->source(), GA, e->source()) && compare(m_GA, f->target(), GA, e->target())) { foundEdge = true; m_GA.addSubGraph(f,max); } } if (!foundEdge) { node s, t; bool srcFound = false; bool tgtFound = false; for(node v : m_G.nodes) { if (compare(m_GA, v, GA, e->source())) { s = v; srcFound = true; } if (compare(m_GA, v, GA, e->target())) { t = v; tgtFound = true; } } if (!srcFound) s = m_G.newNode(e->source()->index()); if (!tgtFound) t = m_G.newNode(e->target()->index()); edge d = m_G.newEdge(s, t); if(compareBy() == label) m_GA.label(d) = GA.label(e); m_GA.addSubGraph(d, max); } } return true; }// end addGraphAttributes
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 << "]"; }
static inline void writeAttributes( std::ostream &out, const GraphAttributes &GA, const edge &e) { const long flags = GA.attributes(); out << "["; bool comma = false; // Whether to put comma before attribute. if(flags & GraphAttributes::edgeLabel) { writeAttribute(out, comma, "label", GA.label(e)); } if(flags & GraphAttributes::edgeDoubleWeight) { writeAttribute(out, comma, "weight", GA.doubleWeight(e)); } else if(flags & GraphAttributes::edgeIntWeight) { writeAttribute(out, comma, "weight", GA.intWeight(e)); } if(flags & GraphAttributes::edgeGraphics) { // This should be legal cubic B-Spline in the future. std::stringstream sstream; for(const DPoint &p : GA.bends(e)) { sstream << p.m_x << "," << p.m_y << " "; } writeAttribute(out, comma, "pos", sstream.str()); } if(flags & GraphAttributes::edgeArrow) { writeAttribute(out, comma, "dir", dot::toString(GA.arrowType(e))); } if(flags & GraphAttributes::edgeStyle) { writeAttribute(out, comma, "color", GA.strokeColor(e)); } if(flags & GraphAttributes::edgeType) { writeAttribute(out, comma, "arrowhead", GA.arrowType(e)); // Additionaly, according to IBM UML doc dependency is a dashed edge. if(GA.type(e) == Graph::dependency) { writeAttribute(out, comma, "style", "dashed"); } } // NOTE: Edge subgraphs are not supported. out << "]"; }
bool GraphMLParser::readData( GraphAttributes &GA, const edge &e, const pugi::xml_node edgeData) { pugi::xml_attribute keyId = edgeData.attribute("key"); if (!keyId) { GraphIO::logger.lout() << "Edge data does not have a key." << endl; return false; } const long attrs = GA.attributes(); pugi::xml_text text = edgeData.text(); switch(graphml::toAttribute(m_attrName[keyId.value()])) { case graphml::a_edgeLabel: if(attrs & GraphAttributes::edgeLabel) { GA.label(e) = text.get(); } break; case graphml::a_edgeWeight: if(attrs & GraphAttributes::edgeIntWeight) { GA.intWeight(e) = text.as_int(); } else if(attrs & GraphAttributes::edgeDoubleWeight) { GA.doubleWeight(e) = text.as_double(); } break; case graphml::a_edgeType: if(attrs & GraphAttributes::edgeType) { GA.type(e) = graphml::toEdgeType(text.get()); } break; case graphml::a_edgeArrow: if(attrs & GraphAttributes::edgeArrow) { GA.arrowType(e) = graphml::toArrow(text.get()); } break; case graphml::a_edgeStroke: if(attrs & GraphAttributes::edgeStyle) { GA.strokeColor(e) = text.get(); } break; default: GraphIO::logger.lout(Logger::LL_MINOR) << "Unknown edge attribute with \"" << keyId.value() << "\"." << endl; } return true; }
static void write_ogml_graph_edges(const GraphAttributes &A, ostream &os) { const Graph &G = A.constGraph(); for(edge e : G.edges) { GraphIO::indent(os,3) << "<edge id=\"e" << e->index() << "\">\n"; if (A.has(GraphAttributes::edgeLabel)) { GraphIO::indent(os,4) << "<label id=\"le" << e->index() << "\">\n"; GraphIO::indent(os,5) << "<content>" << formatLabel(A.label(e)) << "</content>\n"; GraphIO::indent(os,4) << "</label>\n"; } GraphIO::indent(os,4) << "<source idRef=\"n" << e->source()->index() << "\" />\n"; GraphIO::indent(os,4) << "<target idRef=\"n" << e->target()->index() << "\" />\n"; GraphIO::indent(os,3) << "</edge>\n"; } }
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 << "]"; }
// write graph structure with attributes static void write_ogml_graph(const GraphAttributes &A, ostream &os) { const Graph &G = A.constGraph(); GraphIO::indent(os,2) << "<structure>\n"; for(node v : G.nodes) { GraphIO::indent(os,3) << "<node id=\"n" << v->index() << "\">\n"; if (A.has(GraphAttributes::nodeLabel)) { GraphIO::indent(os,4) << "<label id=\"ln" << v->index() << "\">\n"; GraphIO::indent(os,5) << "<content>" << formatLabel(A.label(v)) << "</content>\n"; GraphIO::indent(os,4) << "</label>\n"; } GraphIO::indent(os,3) << "</node>\n"; } write_ogml_graph_edges(A, os); GraphIO::indent(os,2) << "</structure>\n"; }
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; }
void createGraphFromJson(Graph& G, GraphAttributes& GA, string file) { // Read JSON file ifstream i(file); json js; i >> js; // map to be able to find nodes with name map<string, node> nodes; map<string, node>::iterator map_it; //map<edge, string> relTypes; //map<edge, string>::iterator map_it2; // create all nodes for (size_t i = 0; i < js.size(); i++) { string name = js[i]["name"]; node n = G.newNode(); GA.label(n) = name; GA.fillColor(n) = Color::Name::Aquamarine; nodes.insert(pair<string, node>(name, n)); } // create all edges for (size_t i = 0; i < js.size(); i++) { // walk through node members for (size_t j = 0; j < js[i]["members"].size(); j++) { string type = js[i]["members"][j]["relation"]; // check if edge/relation is found if (type != "NONE") { // find source node string source = js[i]["name"]; map_it = nodes.find(source); // if source node is found, continue if (map_it != nodes.end()) { // get source node from map node s = map_it->second; // find target node string target = js[i]["members"][j]["type"]["name"]; map_it = nodes.find(target); // if target node is found, continue if (map_it != nodes.end()) { // get target node from map node t = map_it->second; /* edge ed = G.searchEdge(t, s); if (ed != 0) { map_it2 = relTypes.find(ed); cout << "edge: " << GA.label(s) << " -- " << GA.label(t) << " type: " << type << endl; cout << "edge: " << GA.label(t) << " -- " << GA.label(s) << " type: " << map_it2->second << endl << endl; } */ // check for double edges and self-loops if (G.searchEdge(t, s) == 0 && GA.label(s) != GA.label(t)) { // make new edge edge e = G.newEdge(s, t); //relTypes.insert(pair<edge, string>(e, type)); GA.strokeWidth(e) = 0.5; if (type == "UNI_TO_ONE") { GA.strokeType(e) = ogdf::StrokeType::Solid; GA.arrowType(e) = ogdf::EdgeArrow::None; GA.fillColor(s) = Color::Name::White; GA.fillColor(t) = Color::Name::White; } else if (type == "BI_MANY_TO_ONE") { GA.strokeType(e) = ogdf::StrokeType::Dash; GA.arrowType(e) = ogdf::EdgeArrow::First; } else if (type == "BI_ONE_TO_MANY") { GA.strokeType(e) = ogdf::StrokeType::Dash; GA.arrowType(e) = ogdf::EdgeArrow::Last; } else if (type == "BI_MANY_TO_MANY") { GA.strokeType(e) = ogdf::StrokeType::Dash; GA.arrowType(e) = ogdf::EdgeArrow::Both; } else if (type == "BI_ONE_TO_ONE") { GA.strokeType(e) = ogdf::StrokeType::Dash; GA.arrowType(e) = ogdf::EdgeArrow::None; GA.fillColor(s) = Color::Name::White; GA.fillColor(t) = Color::Name::White; } } } } } } } // check degree and delete non-connected nodes for (map_it = nodes.begin(); map_it != nodes.end(); map_it++) { node n = map_it->second; if (n->degree() == 0) { G.delNode(n); } } /* // List all nodes for (node n : G.nodes) { cout << "FINAL NODES: " << GA.label(n) << endl; } // List all edges cout << endl << endl; for (edge e : G.edges) { cout << "FINAL EDGES: " << GA.label(e->source()) << " -- " << GA.label(e->target()) << endl; } */ }
// create testGraph to test criteria imlementations void CreateGraphTwo(Graph& graph, GraphAttributes& GA) { // add nodes node Adresses = graph.newNode(); node Schools = graph.newNode(); node Subjects = graph.newNode(); node Parent_Adresses = graph.newNode(); node Student_Adresses = graph.newNode(); node Parents = graph.newNode(); node Student_Parents = graph.newNode(); node Teachers = graph.newNode(); node Classes = graph.newNode(); node Family_Members = graph.newNode(); node Students = graph.newNode(); node Student_Classes = graph.newNode(); node Families = graph.newNode(); node Homework = graph.newNode(); node Reports = graph.newNode(); GA.label(Adresses) = "Adresses"; GA.label(Schools) = "Schools"; GA.label(Subjects) = "Subjects"; GA.label(Parent_Adresses) = "Parent_Adresses"; GA.label(Student_Adresses) = "Student_Adresses"; GA.label(Parents) = "Parents"; GA.label(Student_Parents) = "Student_Parents"; GA.label(Teachers) = "Teachers"; GA.label(Classes) = "Classes"; GA.label(Family_Members) = "Family_Members"; GA.label(Students) = "Students"; GA.label(Student_Classes) = "Student_Classes"; GA.label(Families) = "Families"; GA.label(Homework) = "Homework"; GA.label(Reports) = "Reports"; // add edgraphes edge SchoolsToAdresses = graph.newEdge(Schools, Adresses); edge Parent_AdressesToAdresses = graph.newEdge(Parent_Adresses, Adresses); edge Parent_AdressesToParents = graph.newEdge(Parent_Adresses, Parents); edge Student_AdressesToAdresses = graph.newEdge(Student_Adresses, Adresses); edge Student_AdressesToStudents = graph.newEdge(Student_Adresses, Students); edge Student_ParentsToParents = graph.newEdge(Student_Parents, Parents); edge Student_ParentsToStudents = graph.newEdge(Student_Parents, Students); edge TeachersToSchools = graph.newEdge(Teachers, Schools); edge ClassesToSubjects = graph.newEdge(Classes, Subjects); edge ClassesToTeachers = graph.newEdge(Classes, Teachers); edge Family_MembersToParents = graph.newEdge(Family_Members, Parents); edge Family_MembersToFamilies = graph.newEdge(Family_Members, Families); edge Family_MembersToStudents = graph.newEdge(Family_Members, Students); edge Student_ClassesToStudents = graph.newEdge(Student_Classes, Students); edge Student_ClassesToClasses = graph.newEdge(Student_Classes, Classes); edge FamiliesToParents = graph.newEdge(Families, Parents); edge HomeworkToStudents = graph.newEdge(Homework, Students); edge ReportsToStudents = graph.newEdge(Reports, Students); for (edge e : graph.edges) {// set default edge color and type GA.arrowType(e) = ogdf::EdgeArrow::Last; GA.strokeType(e) = ogdf::StrokeType::Solid; GA.strokeColor(e) = Color("#bababa"); } }
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
//************************************************************* // 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
// debug consistency check bool BitonicOrdering::consistencyCheck(GraphAttributes& GA) { GA.init(m_graph, GraphAttributes::nodeLabel); bool allBitonic = true; for (node v = m_graph.firstNode(); v; v = v->succ()) { std::stringstream str; str << v<<"("<<m_orderIndex[v]<<")"; GA.label(v) = str.str(); if (m_orderIndex[v] < 0) std::cout << "Node not assigned"<< std::endl; } // for all nodes we check now for bitonic indices for (node v = m_graph.firstNode(); v; v = v->succ()) { bool isNodeBitonic = true; // we skip t and s though if (m_orderIndex[v] == 0) continue; // we skip t and s though if (m_orderIndex[v] == m_graph.numberOfNodes()-1) continue; adjEntry adj_first_succ = nullptr; adjEntry adj_last_succ = nullptr; for (adjEntry adj = v->firstAdj(); adj; adj = adj->succ()) { // and its cyclic succ node w_prev = adj->cyclicPred()->twinNode(); // the other node node w = adj->twinNode(); // and its cyclic succ node w_next = adj->cyclicSucc()->twinNode(); if ((m_orderIndex[v] > m_orderIndex[w_prev]) && (m_orderIndex[v] < m_orderIndex[w])) adj_first_succ = adj; if ((m_orderIndex[v] > m_orderIndex[w_next]) && (m_orderIndex[v] < m_orderIndex[w])) adj_last_succ = adj; } // we are going to look for bitonic succ lists for (adjEntry adj = v->firstAdj(); adj; adj = adj->succ()) { // and its cyclic succ node w_prev = adj->cyclicPred()->twinNode(); // the other node node w = adj->twinNode(); // and its cyclic succ node w_next = adj->cyclicSucc()->twinNode(); // not a succ if (m_orderIndex[v] > m_orderIndex[w_prev]) continue; // not a succ if (m_orderIndex[v] > m_orderIndex[w]) continue; // not a succ if (m_orderIndex[v] > m_orderIndex[w_next]) continue; // all succs, lets check for bitonic indices if ((m_orderIndex[w_prev] >= m_orderIndex[w]) && (m_orderIndex[w_next] >= m_orderIndex[w]) && (m_orderIndex[v] > 0)) { isNodeBitonic = false; std::cout << "[BitonicOrder:] " << "NOT BITONIC SUCC LIST " << v<< "(" << m_orderIndex[v] << ")" << std::endl; std::cout << "[BitonicOrder:] " << w_prev << "("<< m_orderIndex[w_prev] << ") " << w << "(" << m_orderIndex[w] << ") "<< w_next <<"("<<m_orderIndex[w_next] << ")"<<std::endl; std::cout << std::endl; }; } if (!isNodeBitonic) { for (adjEntry adj = adj_first_succ; adj != adj_last_succ->cyclicSucc(); adj = adj->cyclicSucc()) { std::cout << "("<< m_orderIndex[adj->twinNode()] << ") "; } } allBitonic = allBitonic && isNodeBitonic; } return allBitonic; }