// recursively write clusters and nodes static void write_ogml_graph(const ClusterGraphAttributes &A, cluster c, int level, ostream &os) { if(level > 0) { GraphIO::indent(os,2+level) << "<node id=\"c" << c->index() << "\">\n"; if (A.has(GraphAttributes::nodeLabel)) { GraphIO::indent(os,4) << "<label id=\"lc" << c->index() << "\">\n"; GraphIO::indent(os,5) << "<content>" << formatLabel(A.label(c)) << "</content>\n"; GraphIO::indent(os,4) << "</label>\n"; } } ListConstIterator<node> itn; for (itn = c->nBegin(); itn.valid(); ++itn) { node v = *itn; GraphIO::indent(os,3+level) << "<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+level) << "</node>\n"; } for (cluster child : c->children) { write_ogml_graph(child, level+1, os); } if(level > 0) { GraphIO::indent(os,2+level) << "</node>\n"; } }
static inline void writeAttributes( std::ostream &out, const int &depth, const ClusterGraphAttributes &CA, const cluster &c) { GraphIO::indent(out, depth) << "color=\"" << CA.strokeColor(c) << "\"\n"; GraphIO::indent(out, depth) << "bgcolor=\"" << CA.fillColor(c) << "\"\n"; GraphIO::indent(out, depth) << "label=\"" << CA.label(c) << "\"\n"; // There is no point in exporting rest of the cluster attributes, so to // maintain high readability they are omitted. }
bool GraphMLParser::readData( ClusterGraphAttributes &CA, const cluster &c, const pugi::xml_node clusterData) { auto keyId = clusterData.attribute("key"); if (!keyId) { GraphIO::logger.lout() << "Cluster data does not have a key." << endl; return false; } pugi::xml_text text = clusterData.text(); using namespace graphml; switch (toAttribute(m_attrName[keyId.value()])) { case a_nodeLabel: CA.label(c) = text.get(); break; case a_x: CA.x(c) = text.as_double(); break; case a_y: CA.y(c) = text.as_double(); break; case a_width: CA.width(c) = text.as_double(); break; case a_height: CA.height(c) = text.as_double(); break; case a_size: // We want to set a new size only if width and height was not set. if (CA.width(c) == CA.height(c)) { CA.width(c) = CA.height(c) = text.as_double(); } case a_r: if (!GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { CA.fillColor(c).red(val); })) { return false; } break; case a_g: if (!GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { CA.fillColor(c).green(val); })) { return false; } break; case a_b: if (!GraphIO::setColorValue(text.as_int(), [&](uint8_t val) { CA.fillColor(c).blue(val); })) { return false; } break; case a_clusterStroke: CA.strokeColor(c) = text.get(); break; default: GraphIO::logger.lout(Logger::LL_MINOR) << "Unknown cluster attribute with \"" << keyId.value() << "--enum: " << m_attrName[keyId.value()] << "--" << "\"." << endl; } return true; }
//recursively read cluster subtree information bool GmlParser::recursiveAttributedClusterRead(GmlObject* clusterObject, ClusterGraph& CG, ClusterGraphAttributes& ACG, cluster c) { //for direct root cluster sons, this is checked twice... if (clusterObject->m_valueType != gmlListBegin) return false; GmlObject *clusterSon = clusterObject->m_pFirstSon; for(; clusterSon; clusterSon = clusterSon->m_pBrother) { //we dont read the attributes, therefore look only for //id and sons switch(id(clusterSon)) { case clusterPredefKey: { if (clusterSon->m_valueType != gmlListBegin) return false; cluster cson = CG.newCluster(c); //recursively read child cluster recursiveAttributedClusterRead(clusterSon, CG, ACG, cson); } break; case labelPredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.label(c) = clusterSon->m_stringValue; } break; case templatePredefKey: { if (clusterSon->m_valueType != gmlStringValue) return false; ACG.templateCluster(c) = clusterSon->m_stringValue; break; } case graphicsPredefKey: //read the info for cluster c { if (clusterSon->m_valueType != gmlListBegin) return false; readClusterAttributes(clusterSon, c , ACG); }//graphics break; case vertexPredefKey: //direct cluster vertex entries { if (clusterSon->m_valueType != gmlStringValue) return false; string vIDString = clusterSon->m_stringValue; if ((vIDString[0] != 'v') && (!isdigit((int)vIDString[0])))return false; //do not allow labels //if old style entry "v"i if (!isdigit((int)vIDString[0])) //should check prefix? vIDString[0] = '0'; //leading zero to allow conversion int vID = stoi(vIDString); OGDF_ASSERT(m_mapToNode[vID] != 0) //we assume that no node is already assigned //changed: all nodes are already assigned to root CG.reassignNode(m_mapToNode[vID], c); }//case vertex }//switch }//for clustersons return true; }//recursiveAttributedClusterRead