GraphMLWriter.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. #include "GraphMLWriter.h"
  2. GraphMLWriter::GraphMLWriter()
  3. {
  4. }
  5. void GraphMLWriter::writeGraphml(SubGraph &gBoostGraph, QIODevice *outStreamFile)
  6. {
  7. try
  8. {
  9. m_boostGraphWrapper = new BoostGraphWrapper(gBoostGraph);
  10. //cout << "Graph at Writer: \n";
  11. //print_graph(gBoostGraph);
  12. //cout <<"vertex-coordX, coordY \n";
  13. // BGL_FORALL_VERTICES(v,gBoostGraph,SubGraph)
  14. // {
  15. // //print vertex, x, y
  16. // //cout << PGL_VERTEX_INDEX(v,gBoostGraph)
  17. // //<<" : " << m_boostGraphWrapper->getVertexCenterCoordX(v,gBoostGraph)
  18. // //<<" - " << m_boostGraphWrapper->getVertexCenterCoordY(v,gBoostGraph)
  19. // //<< endl;
  20. // }
  21. populateDataTagProperties();
  22. //Set outstream
  23. m_txtStreamOut.setDevice(outStreamFile);
  24. m_txtStreamOut.setCodec("UTF-8");
  25. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  26. ,LayoutException(__FUNCTION__
  27. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  28. , "File stream must be write enabled"
  29. ,"Text Stream"));
  30. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  31. ,LayoutException(__FUNCTION__
  32. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  33. , "File stream encoding must be UTF 8"
  34. , "Text Stream"));
  35. m_txtStreamOut << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  36. << "<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\">\n";
  37. //Generate <key> declarations in graphml and create a Map of it.
  38. //For example, Map("node","color") to "key0" key
  39. //Key Declaration Example:
  40. //<key id="key0" for="node" attr.name="color" attr.type="string">
  41. //cout << endl << "Writing graphml..." <<endl;
  42. generateKeyDeclaration();
  43. //iterate subgraph child subgraphs, direct nodes, edges
  44. generateGraphml(gBoostGraph);
  45. m_txtStreamOut << "</graphml>\n";
  46. m_txtStreamOut.flush();
  47. }
  48. catch(boost::exception &eBoostException)
  49. {
  50. throw *boost::get_error_info<errmsg_info>(eBoostException);
  51. }
  52. catch(LayoutException &eLayoutException)
  53. {
  54. throw eLayoutException;
  55. }
  56. // XXX obselete
  57. // catch(LayoutMemoryException &eMemoryException)
  58. // {
  59. // throw eMemoryException;
  60. // }
  61. catch(...)
  62. {
  63. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  64. }
  65. }
  66. void GraphMLWriter::generateGraphmlRecur(SubGraph &gSubGraph, SubGraph &gMainGraph, int iLevel)
  67. {
  68. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  69. ,LayoutException(__FUNCTION__
  70. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  71. , "File stream must be write enabled"
  72. ,"Text Stream"));
  73. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  74. ,LayoutException(__FUNCTION__
  75. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  76. , "File stream encoding must be UTF 8"
  77. , "Text Stream"));
  78. QString sGraphCounterVal = QString::number(m_iGraphCounter);
  79. QString sGraphId = m_boostGraphWrapper->getGraphId(gSubGraph);
  80. //Current graph
  81. m_txtStreamOut << indent(iLevel).toUtf8()
  82. <<"<graph " << GRAPH_ID << "=\""
  83. <<sGraphId << "\" "
  84. <<"edgedefault=\"" << DEFAULT_EDGE_TYPE <<"\""
  85. << ">\n";
  86. //Add current graph attributes
  87. addGraphDataAttribute(gSubGraph , iLevel+1 );
  88. //Subgraph
  89. VectorSubgraphRefs vecChildSubgraphRefs;
  90. m_boostGraphWrapper->getChildrenVector(gSubGraph , vecChildSubgraphRefs);
  91. for(VectorSubgraphRefs::iterator subgraphIter = vecChildSubgraphRefs.begin();
  92. subgraphIter != vecChildSubgraphRefs.end();
  93. subgraphIter++)
  94. {
  95. m_iGraphCounter++;
  96. sGraphCounterVal = QString::number(m_iGraphCounter);
  97. //add a new node for graph
  98. m_txtStreamOut << indent(iLevel + 1)
  99. << "<node " << NODE_ID <<"=\""
  100. << GRAPH_NODE_ID_PREFIX << sGraphId <<"\" "
  101. << ">\n";
  102. //add graph to newly added node
  103. generateGraphmlRecur(**subgraphIter , gMainGraph, iLevel + 2);
  104. //cout << "Recuring through writer graph: \n";
  105. //print_graph(**subgraphIter);
  106. m_txtStreamOut << indent(iLevel+1) << "</node>\n";
  107. }
  108. //Vertices
  109. VertexIterator vertexIter , vertexIterEnd;
  110. for(boost::tie(vertexIter , vertexIterEnd) = vertices(gSubGraph);
  111. vertexIter != vertexIterEnd;
  112. vertexIter++)
  113. {
  114. VertexDescriptor vVertex = *vertexIter;
  115. //Skip expandable and invisible vertices
  116. if(m_boostGraphWrapper->getVertexIsInvisible(vVertex, gSubGraph)
  117. || m_boostGraphWrapper->getVertexExpandable(vVertex , gSubGraph) )
  118. {
  119. continue;
  120. }
  121. //Write only Graph Nodes
  122. LayoutEnum::NodeType enVertexType = m_boostGraphWrapper->getVertexType(vVertex , gSubGraph);
  123. if(enVertexType == LayoutEnum::GraphNode)
  124. {
  125. //add vertex
  126. addNode( vVertex , gSubGraph, iLevel+1 , gMainGraph);
  127. }
  128. }
  129. //Edges
  130. EdgeIterator edgeIter , edgeIterEnd;
  131. for(boost::tie(edgeIter , edgeIterEnd) = edges(gSubGraph);
  132. edgeIter != edgeIterEnd;
  133. edgeIter++)
  134. {
  135. EdgeDescriptor eEdge = *edgeIter;
  136. //Skip invisible edges
  137. if(m_boostGraphWrapper->getEdgeIsInvisible(eEdge , gSubGraph))
  138. {
  139. continue;
  140. }
  141. //Skip long edge segments
  142. LayoutEnum::EdgeType enEdgeType = m_boostGraphWrapper->getEdgeType(eEdge , gSubGraph);
  143. if(enEdgeType == LayoutEnum::LongEdgeSegment)
  144. {
  145. continue;
  146. }
  147. if(enEdgeType == LayoutEnum::GraphEdge)
  148. {
  149. //add edge
  150. addEdge(eEdge , gSubGraph , iLevel+1 , gMainGraph);
  151. }
  152. }
  153. //Current graph end
  154. m_txtStreamOut << indent(iLevel).toUtf8() << "</graph>\n";
  155. }
  156. void GraphMLWriter::generateGraphml(SubGraph &gSubGraph)
  157. {
  158. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  159. ,LayoutException(__FUNCTION__
  160. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  161. , "File stream must be write enabled"
  162. ,"Text Stream"));
  163. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  164. ,LayoutException(__FUNCTION__
  165. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  166. , "File stream encoding must be UTF 8"
  167. , "Text Stream"));
  168. //reset graph counter
  169. m_iGraphCounter = 0;
  170. generateGraphmlRecur(gSubGraph ,gSubGraph, 0);
  171. }
  172. void GraphMLWriter::addGraphDataAttribute(SubGraph &gSubGraph, int iLevel)
  173. {
  174. //cout << "Graph while writing data props: \n";
  175. //print_graph(gSubGraph);
  176. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  177. ,LayoutException(__FUNCTION__
  178. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  179. , "File stream must be write enabled"
  180. ,"Text Stream"));
  181. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  182. ,LayoutException(__FUNCTION__
  183. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  184. , "File stream encoding must be UTF 8"
  185. , "Text Stream"));
  186. Q_UNUSED(gSubGraph);
  187. //graph coord_x
  188. int iGraphCoordX = m_boostGraphWrapper->getGraphLeftTopCoordX(gSubGraph);
  189. QString sGraphCoordX = QString::number(iGraphCoordX);
  190. QString sGraphCoordXKey = getKey("graph" , "coord_x");
  191. //cout << " iGraphCoordX: " << iGraphCoordX
  192. //<< " - " << sGraphCoordX.toStdString()
  193. //<< endl;
  194. addData(sGraphCoordXKey , sGraphCoordX , iLevel);
  195. //graph coord_y
  196. int iGraphCoordY = m_boostGraphWrapper->getGraphLeftTopCoordY(gSubGraph);
  197. QString sGraphCoordY = QString::number(iGraphCoordY);
  198. QString sGraphCoordYKey = getKey("graph" , "coord_y");
  199. addData(sGraphCoordYKey , sGraphCoordY , iLevel);
  200. //graph height
  201. int iGraphHeight = m_boostGraphWrapper->getGraphHeight(gSubGraph);
  202. QString sGraphHeight = QString::number(iGraphHeight);
  203. QString sGraphHeightKey = getKey("graph" , "height");
  204. addData(sGraphHeightKey , sGraphHeight , iLevel);
  205. //graph width
  206. int iGraphWidth = m_boostGraphWrapper->getGraphWidth(gSubGraph);
  207. QString sGraphWidth = QString::number(iGraphWidth);
  208. QString sGraphWidthKey = getKey("graph" , "width");
  209. addData(sGraphWidthKey , sGraphWidth , iLevel);
  210. }
  211. void GraphMLWriter::addNode(VertexDescriptor &vVertex, SubGraph &gSubGraph, int iLevel, SubGraph &gMainGraph)
  212. {
  213. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  214. ,LayoutException(__FUNCTION__
  215. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  216. , "File stream must be write enabled"
  217. ,"Text Stream"));
  218. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  219. ,LayoutException(__FUNCTION__
  220. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  221. , "File stream encoding must be UTF 8"
  222. , "Text Stream"));
  223. VertexDescriptor vGlobalVertex = gSubGraph.local_to_global(vVertex);
  224. int iGlobalVertexIndex = get(vertex_index , gMainGraph , vGlobalVertex);
  225. //visit each vertex only once
  226. if(isGlobalVertexVisited(iGlobalVertexIndex))
  227. {
  228. return;
  229. }
  230. //Get vertex property values
  231. //node id
  232. QString sNodeId = m_boostGraphWrapper->getVertexId(vVertex , gSubGraph);
  233. m_txtStreamOut << indent(iLevel)
  234. << "<node " << NODE_ID << "=\""
  235. << sNodeId.toUtf8() << "\""
  236. <<">\n";
  237. //node height
  238. int iNodeHeight = m_boostGraphWrapper->getVertexHeight(vGlobalVertex , gMainGraph);
  239. QString sNodeHeight;
  240. sNodeHeight =QString::number(iNodeHeight);
  241. QString sNodeHeightKey = getKey("node","height");
  242. addData( sNodeHeightKey , sNodeHeight , iLevel+1);
  243. //node width
  244. int iNodeWidth = m_boostGraphWrapper->getVertexWidth(vGlobalVertex , gMainGraph);
  245. QString sNodeWidth;
  246. sNodeWidth =QString::number(iNodeWidth);
  247. QString sNodeWidthKey = getKey("node" ,"width");
  248. addData( sNodeWidthKey , sNodeWidth , iLevel+1);
  249. //node coord_x --------- changing pritish
  250. int iNodeCoordX = m_boostGraphWrapper->getVertexLeftCoordX(vGlobalVertex , gMainGraph);
  251. QString sNodeCoordX =QString::number(iNodeCoordX);
  252. QString sNodeCoordXKey = getKey("node","coord_x");
  253. addData( sNodeCoordXKey , sNodeCoordX , iLevel+1);
  254. //node coord_y
  255. int iNodeCoordY = m_boostGraphWrapper->getVertexLeftCoordY(vGlobalVertex , gMainGraph);
  256. QString sNodeCoordY =QString::number(iNodeCoordY);
  257. QString sNodeCoordYKey = getKey("node","coord_y");
  258. addData( sNodeCoordYKey , sNodeCoordY , iLevel+1);
  259. m_txtStreamOut << indent(iLevel) << "</node>\n";
  260. markGlobalVertexVisited(iGlobalVertexIndex);
  261. }
  262. void GraphMLWriter::addEdge(EdgeDescriptor &eEdge, SubGraph &gSubGraph, int iLevel, SubGraph &gMainGraph)
  263. {
  264. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  265. ,LayoutException(__FUNCTION__
  266. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  267. , "File stream must be write enabled"
  268. ,"Text Stream"));
  269. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  270. ,LayoutException(__FUNCTION__
  271. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  272. , "File stream encoding must be UTF 8"
  273. , "Text Stream"));
  274. EdgeDescriptor eGlobalEdge = gSubGraph.local_to_global(eEdge);
  275. int iGlobalEdgeIndex = get(edge_index , gMainGraph , eGlobalEdge);
  276. //visit each edge only once
  277. if(isGlobalEdgeVisited(iGlobalEdgeIndex))
  278. {
  279. return;
  280. }
  281. //Get edge properties
  282. //edge id
  283. QString sEdgeId = m_boostGraphWrapper->getEdgeId(eGlobalEdge , gMainGraph);
  284. //edge source and target
  285. //Taking out source and target vertex from boost edge e
  286. VertexDescriptor vGlobalSourceVertex = gSubGraph.local_to_global(source(eEdge , gSubGraph));
  287. VertexDescriptor vGlobalTargetVertex = gSubGraph.local_to_global(target(eEdge , gSubGraph));
  288. QString sEdgeSource = m_boostGraphWrapper->getVertexId(vGlobalSourceVertex , gMainGraph);
  289. QString sEdgeTarget = m_boostGraphWrapper->getVertexId(vGlobalTargetVertex , gMainGraph);
  290. m_txtStreamOut << indent(iLevel)
  291. << "<edge "<<EDGE_ID<<"=\""
  292. << sEdgeId.toUtf8() << "\" "
  293. << "source=\"" << sEdgeSource << "\" "
  294. << "target=\"" << sEdgeTarget << "\">\n";
  295. //bidirectional - true or false
  296. bool bEdgeBidirectional = m_boostGraphWrapper->getEdgeBidirectional(eGlobalEdge , gMainGraph);
  297. QString sEdgeBidirectional;
  298. if(bEdgeBidirectional)
  299. {
  300. sEdgeBidirectional = "true";
  301. }
  302. else
  303. {
  304. sEdgeBidirectional = "false";
  305. }
  306. QString sBidirectionalKey = getKey("edge" , "bidirectional");
  307. addData(sBidirectionalKey , sEdgeBidirectional , iLevel+1 );
  308. // add bends HERE
  309. QString sBendDataKey = getKey("edge" , "bendpoints");
  310. addBendPointsData(sBendDataKey, iLevel + 1, eEdge, gSubGraph);
  311. m_txtStreamOut << indent(iLevel) << "</edge>\n";
  312. markGlobalEdgeVisited(iGlobalEdgeIndex);
  313. }
  314. void GraphMLWriter::populateDataTagProperties()
  315. {
  316. //add those attributes which should be represented in a <data> tag
  317. //node property list
  318. GraphElementProperties propListNode;
  319. propListNode.lstAttributeList.push_back(Attribute("height","integer",true,"40"));
  320. propListNode.lstAttributeList.push_back(Attribute("width","integer",true,"40"));
  321. propListNode.lstAttributeList.push_back(Attribute("coord_x","integer"));
  322. propListNode.lstAttributeList.push_back(Attribute("coord_y","integer"));
  323. //edge property list
  324. GraphElementProperties propListEdge;
  325. propListEdge.lstAttributeList.push_back(Attribute("bidirectional","boolean",true,"false"));
  326. propListEdge.lstAttributeList.push_back(Attribute("bendpoints", "interger"));
  327. //graph property list
  328. GraphElementProperties propListGraph;
  329. propListGraph.lstAttributeList.push_back(Attribute("coord_x" , "integer"));
  330. propListGraph.lstAttributeList.push_back(Attribute("coord_y" , "integer"));
  331. propListGraph.lstAttributeList.push_back(Attribute("height" , "integer"));
  332. propListGraph.lstAttributeList.push_back(Attribute("width" , "integer"));
  333. //Add element along with their atrribute list in map
  334. m_mapGraphElementToAttributeList.insert("node" , propListNode);
  335. m_mapGraphElementToAttributeList.insert("edge", propListEdge);
  336. m_mapGraphElementToAttributeList.insert("graph", propListGraph);
  337. }
  338. void GraphMLWriter::markGlobalVertexVisited(int iVertexId)
  339. {
  340. m_mapVisitedVertices.insert(iVertexId , true);
  341. }
  342. bool GraphMLWriter::isGlobalVertexVisited(int iVertexId)
  343. {
  344. return m_mapVisitedVertices.value(iVertexId);
  345. }
  346. void GraphMLWriter::markGlobalEdgeVisited(int iEdgeId)
  347. {
  348. m_mapVisitedEdges.insert(iEdgeId , true);
  349. }
  350. bool GraphMLWriter::isGlobalEdgeVisited(int iEdgeId)
  351. {
  352. return m_mapVisitedEdges.value(iEdgeId);
  353. }
  354. void GraphMLWriter::generateKeyDeclaration()
  355. {
  356. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  357. ,LayoutException(__FUNCTION__
  358. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  359. , "File stream must be write enabled"
  360. ,"Text Stream"));
  361. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  362. ,LayoutException(__FUNCTION__
  363. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  364. , "File stream encoding must be UTF 8"
  365. , "Text Stream"));
  366. LAYOUT_ASSERT(m_mapGraphElementToAttributeList.empty() == false
  367. ,LayoutException(__FUNCTION__
  368. , LayoutExceptionEnum::EMPTY_CONTAINER
  369. , ""
  370. , "MapGraphElementToAttributeList"));
  371. //Example: <key id="d0" for="node" attr.name="color" attr.type="string">
  372. int iKeyCounter;
  373. QString sElementName;
  374. QString sAttributeName;
  375. QString sAttributeType;
  376. QString sKeyId;
  377. iKeyCounter = 0;
  378. QMapIterator<QString , GraphElementProperties > elementIter(m_mapGraphElementToAttributeList);
  379. while(elementIter.hasNext())
  380. {
  381. elementIter.next();
  382. sElementName = elementIter.key(); // "node", "graph" or "edge"...
  383. QListIterator<Attribute> iterAttributeList = ((GraphElementProperties)(elementIter.value())).iterator();
  384. while(iterAttributeList.hasNext())
  385. {
  386. Attribute attribute = iterAttributeList.next();
  387. // create key id
  388. sKeyId = KEY_ID_PREFIX + QString::number(iKeyCounter++);
  389. //Attribute name
  390. sAttributeName = attribute.sName;
  391. //Attribute Type
  392. sAttributeType = attribute.sType;
  393. //set <<ElementName,ElementAttribute>,Key> map
  394. //Example: << "node", "coord" > "key0" >
  395. ElementNamePropertyNamePair elementNamePropertyPair
  396. = ElementNamePropertyNamePair( sElementName
  397. , sAttributeName );
  398. m_mapElementNameAndPropertyToKey.insert(elementNamePropertyPair
  399. , sKeyId);
  400. //Add Key Declaration to graphml file
  401. m_txtStreamOut <<"<key id = \"" << sKeyId.toUtf8() <<"\" "
  402. <<"for = \"" << sElementName.toUtf8() << "\" "
  403. <<"attr.name = \"" << sAttributeName.toUtf8() <<"\" "
  404. <<"attr.type = \"" << sAttributeType.toUtf8() <<"\"";
  405. //Default value
  406. if(attribute.bHasDefaultValue)
  407. {
  408. m_txtStreamOut << ">\n";
  409. //add default value tag
  410. m_txtStreamOut << indent(1)
  411. <<"<default>"<<attribute.sDefaultValue.toUtf8()
  412. <<"</default>\n";
  413. m_txtStreamOut << "</key>\n";
  414. }
  415. else
  416. {
  417. m_txtStreamOut << "/>\n";
  418. }
  419. }
  420. }
  421. }
  422. void GraphMLWriter::printAttributeTable()
  423. {
  424. QMapIterator<QString , GraphElementProperties > iter(m_mapGraphElementToAttributeList);
  425. while (iter.hasNext()) {
  426. iter.next();
  427. //cout << (iter.key()).toStdString() << endl;
  428. ((GraphElementProperties)(iter.value())).print();
  429. }
  430. }
  431. QString GraphMLWriter::indent(int iLevel)
  432. {
  433. QString sIndent = "";
  434. int iIndentSize = 4 * iLevel;
  435. for(int indentSizeCounter = 0;
  436. indentSizeCounter < iIndentSize;
  437. indentSizeCounter++)
  438. {
  439. sIndent += " ";
  440. }
  441. return sIndent;
  442. }
  443. QString GraphMLWriter::getKey(QString sElementName , QString sAttributeName)
  444. {
  445. QString sKey;
  446. try{
  447. sKey = m_mapElementNameAndPropertyToKey
  448. .value(ElementNamePropertyNamePair(sElementName,sAttributeName));
  449. }
  450. catch(...)
  451. {
  452. throw LayoutException(__FUNCTION__ , LayoutExceptionEnum::UNKNOWNLAYOUTEXCEPTION);
  453. }
  454. if(sKey == "")
  455. {
  456. throw LayoutException(__FUNCTION__
  457. , LayoutExceptionEnum::EMPTY_CONTAINER
  458. , ""
  459. ,"Key");
  460. }
  461. return sKey;
  462. }
  463. void GraphMLWriter::addData(QString sKey , QString sValue, int iLevel)
  464. {
  465. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  466. ,LayoutException(__FUNCTION__
  467. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  468. , "File stream must be write enabled"
  469. ,"Text Stream"));
  470. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  471. ,LayoutException(__FUNCTION__
  472. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  473. , "File stream encoding must be UTF 8"
  474. , "Text Stream"));
  475. LAYOUT_ASSERT(sKey.length() > 0
  476. ,LayoutException(__FUNCTION__
  477. , LayoutExceptionEnum::INVALID_PARAMETER
  478. , sKey
  479. ,"Key"));
  480. LAYOUT_ASSERT(iLevel >= 0
  481. ,LayoutException(__FUNCTION__
  482. , LayoutExceptionEnum::INVALID_PARAMETER
  483. , QString::number(iLevel)
  484. ,"Level"));
  485. m_txtStreamOut << indent(iLevel)
  486. << "<data key=\"" << sKey << "\">"
  487. <<sValue<<"</data>\n";
  488. }
  489. void GraphMLWriter::addBendPointsData(QString sKey, int iLevel, EdgeDescriptor& eEdge, SubGraph& gSubgraph)
  490. {
  491. LAYOUT_ASSERT(m_txtStreamOut.device()->isWritable() == true
  492. ,LayoutException(__FUNCTION__
  493. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  494. , "File stream must be write enabled"
  495. ,"Text Stream"));
  496. LAYOUT_ASSERT(strcmp((const char*)m_txtStreamOut.codec(),"UTF-8")
  497. ,LayoutException(__FUNCTION__
  498. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  499. , "File stream encoding must be UTF 8"
  500. , "Text Stream"));
  501. LAYOUT_ASSERT(sKey.length() > 0
  502. ,LayoutException(__FUNCTION__
  503. , LayoutExceptionEnum::REQUIRED_PARAMETER_NOT_SET
  504. , "string sKey"
  505. , ""));
  506. LAYOUT_ASSERT(iLevel >= 0
  507. ,LayoutException(__FUNCTION__
  508. , LayoutExceptionEnum::INVALID_PARAMETER
  509. , "it must be positive"
  510. , "iLevel"));
  511. /**
  512. Encorporate Bend Points in the following format:-
  513. <edge target="s13" id="s12_R_15_s13" source="s12">
  514. <data key="key_8">
  515. <bend X="10" Y "30" />
  516. </data>
  517. </edge>
  518. */
  519. // start of the data tag inside a edge tag for encorporating the bends.
  520. m_txtStreamOut << indent(iLevel)
  521. << "<data key=\"" <<sKey << "\">"
  522. << "\n";
  523. // get the number of BendPoints objects in the list of bendpoints.
  524. // get the x and y coordinates from the vector which has list of edge's bend points.
  525. // create equal number of bend tags in that edge.
  526. // end of data tag inside a edge tag for bends.
  527. IteratorQVectorBendPoints iterBendPoints, iterBendPointsEnd;
  528. BoostGraphWrapper boostGraphWrapper;
  529. for(boost::tie(iterBendPoints, iterBendPointsEnd) = boostGraphWrapper.edgeBendPointsIter(eEdge, gSubgraph);
  530. iterBendPoints != iterBendPointsEnd;
  531. iterBendPoints++)
  532. {
  533. BendPoints structBendPoints = **iterBendPoints;
  534. QString sEdgeId = boostGraphWrapper.getEdgeId(eEdge,gSubgraph);
  535. //cout<<"Bend Points for Edge : "<<sEdgeId.toStdString()<<" "
  536. //<<structBendPoints.iCoordinateX<<" "<<structBendPoints.iCoordinateY<<endl;
  537. m_txtStreamOut << indent(iLevel+1)
  538. << "<bend X = \"" <<structBendPoints.iCoordinateX
  539. <<"\" Y = \"" << structBendPoints.iCoordinateY << "\">"
  540. << "\n";
  541. m_txtStreamOut << indent(iLevel+1)
  542. << "</bend>\n";
  543. }
  544. m_txtStreamOut << indent(iLevel)
  545. << "</data>\n";
  546. }