void QGVScene::loadLayout(const QString &text) { _graph->setGraph(QGVCore::agmemread2(text.toLocal8Bit().constData())); if(gvLayout(_context->context(), _graph->graph(), "dot") != 0) { qCritical()<<"Layout render error"<<agerrors()<<QString::fromLocal8Bit(aglasterr()); return; } //Debug output //gvRenderFilename(_context->context(), _graph->graph(), "png", "debug.png"); //Read nodes and edges for (Agnode_t* node = agfstnode(_graph->graph()); node != NULL; node = agnxtnode(_graph->graph(), node)) { QGVNode *inode = new QGVNode(new QGVNodePrivate(node), this); inode->updateLayout(); addItem(inode); _nodes.append (inode); for (Agedge_t* edge = agfstout(_graph->graph(), node); edge != NULL; edge = agnxtout(_graph->graph(), edge)) { QGVEdge *iedge = new QGVEdge(new QGVEdgePrivate(edge), this); iedge->updateLayout(); addItem(iedge); _edges.append (iedge); } } update(); }
QGVNode *QGVScene::addNode(const QString &label) { Agnode_t *node = agnode(_graph->graph(), NULL, TRUE); if(node == NULL) { qWarning()<<"Invalid node :"<<label; return 0; } QGVNode *item = new QGVNode(new QGVNodePrivate(node), this); item->setLabel(label); addItem(item); _nodes.append(item); return item; }
QGVNode *QGVSubGraph::addNode(const QString &label) { Agnode_t *node = agnode(_sgraph->graph(), NULL, TRUE); if (node == NULL) { qWarning() << "Invalid sub node :" << label; return 0; } agsubnode(_sgraph->graph(), node, TRUE); QGVNode *item = new QGVNode(new QGVNodePrivate(node), _scene); item->setLabel(label); _scene->addItem(item); _scene->_nodes.append(item); _nodes.append(item); return item; }
void MainWindow::drawGraph(Graph &graph) { initScene(); if(graph.nodesCount() == 0) return; layoutSubgraph = ui->actionSubgraph->isChecked(); //Configure scene attributes //scene->setGraphAttribute("label", "yarp-viz"); scene->setGraphAttribute("splines", layoutStyle.c_str()); //curved, polyline, line. ortho scene->setGraphAttribute("rankdir", "LR"); scene->setGraphAttribute("bgcolor", "#2e3e56"); //scene->setGraphAttribute("concentrate", "true"); //Error ! scene->setGraphAttribute("nodesep", "0.4"); scene->setGraphAttribute("ranksep", "0.5"); //scene->setNodeAttribute("shape", "box"); scene->setNodeAttribute("style", "filled"); scene->setNodeAttribute("fillcolor", "gray"); scene->setNodeAttribute("height", "1.0"); scene->setEdgeAttribute("minlen", "2.0"); //scene->setEdgeAttribute("dir", "both"); // drawing nodes // create a map between graph nodes and their visualization //std::map<const Vertex*, QGVNode*> nodeSet; //adding all machine subgraphs pvertex_const_iterator itr; const pvertex_set& vertices = graph.vertices(); int countChild =0; for(itr = vertices.begin(); itr!=vertices.end(); itr++) { dynamic_cast<GraphicVertex*>(*itr)->setGraphicItem(nullptr); const Property& prop = (*itr)->property; QGVSubGraph *sgraph; if(dynamic_cast<MachineVertex*>(*itr)) { string hostname = prop.find("hostname").asString(); if(layoutSubgraph) { std::stringstream key; key<<hostname; if(sceneSubGraphMap[key.str()] == nullptr) { sgraph = scene->addSubGraph(prop.toString().c_str()); sceneSubGraphMap[key.str()] = sgraph; dynamic_cast<GraphicVertex*>(*itr)->setGraphicItem(sgraph); sgraph->setVertex(*itr); //sgraph->setAttribute("label", prop.find("name").asString().c_str()); sgraph->setAttribute("color", "#FFFFFF"); sgraph->setAttribute("label", prop.find("hostname").toString().c_str()); string host = prop.find("os").asString(); if(host == "Linux") sgraph->setIcon(QImage(":/icons/resources/Linux-icon.png")); else if(host == "Windows") sgraph->setIcon(QImage(":/icons/resources/Windows-icon.png")); else if(host == "Mac") sgraph->setIcon(QImage(":/icons/resources/Mac-icon.png")); else sgraph->setIcon(QImage(":/icons/resources/Gnome-System-Run-64.png")); std::string endNodeName = key.str() + ".end"; QGVNode * node = sgraph->addNode(endNodeName.c_str()); node->setAttribute("shape", "circle"); node->setAttribute("height", "0.0000000000001"); //a subgraph cannot be empty, adding fake hidden node node->setAttribute("fixedsize", "true"); node->setAttribute("label", ""); node->setAttribute("fillcolor", "#2e3e56"); node->setAttribute("color", "#2e3e56"); node->setAttribute("node_type", "end"); node->setAttribute("rawname", endNodeName.c_str()); sceneNodeMap[endNodeName] = node; } } } } // adding all process subgraphs for(itr = vertices.begin(); itr!=vertices.end(); itr++) { dynamic_cast<GraphicVertex*>(*itr)->setGraphicItem(nullptr); const Property& prop = (*itr)->property; QGVSubGraph *sgraph; if(dynamic_cast<ProcessVertex*>(*itr) && !prop.find("hidden").asBool()) { int randNum = rand()%(16777214 - 0 + 1) + 0; stringstream hexStream; hexStream<<std::hex<< randNum; string hexRandNum ="#" + hexStream.str(); string name = std::string(prop.find("name").asString().c_str()) + std::to_string(countChild); if(layoutSubgraph) { std::stringstream key; key<<prop.find("hostname").asString(); QGVSubGraph *sgraphParent = sceneSubGraphMap[key.str()]; if(sgraphParent == nullptr || (!ui->actionDebugMode->isChecked() && name.find("yarplogger") != string::npos)) { continue; } sgraph = sgraphParent->addSubGraph(name.c_str()); countChild++; } else { continue; } std::stringstream label; label << " " << prop.find("name").asString().c_str() << " (" << prop.find("pid").asInt32() << ") "; sgraph->setAttribute("shape", "box"); sgraph->setAttribute("label", label.str().c_str()); if(prop.check("color")) { sgraph->setAttribute("fillcolor", prop.find("color").asString().c_str()); sgraph->setAttribute("color", prop.find("color").asString().c_str()); }else { sgraph->setAttribute("fillcolor", "#a5cf80"); sgraph->setAttribute("color", "#a5cf80"); } sgraph->setAttribute("colorOfTheProcess", hexRandNum.c_str()); //nodeSet[*itr] = node; dynamic_cast<GraphicVertex*>(*itr)->setGraphicItem(sgraph); sgraph->setVertex(*itr); std::stringstream keyProcess; keyProcess<<prop.find("hostname").asString()<<prop.find("pid").asInt32(); std::string endNodeName = keyProcess.str() + ".end"; QGVNode * node = sgraph->addNode(endNodeName.c_str()); node->setAttribute("shape", "circle"); node->setAttribute("height", "0.0000000000001"); //a subgraph cannot be empty, adding fake hidden node node->setAttribute("fixedsize", "true"); node->setAttribute("label", ""); node->setAttribute("fillcolor", "#2e3e56"); node->setAttribute("color", "#2e3e56"); node->setAttribute("node_type", "end"); node->setAttribute("rawname", endNodeName.c_str()); sceneNodeMap[endNodeName] = node; sceneSubGraphMap[keyProcess.str()]= sgraph; } } // adding port nodes //pvertex_const_iterator itr; //const pvertex_set& vertices = graph.vertices(); int portCounts = 0; for(itr = vertices.begin(); itr!=vertices.end(); itr++) { const Property& prop = (*itr)->property; string portName = prop.find("name").asString(); if(dynamic_cast<PortVertex*>(*itr)) { PortVertex* pv = dynamic_cast<PortVertex*>(*itr); ProcessVertex* v = (ProcessVertex*) pv->getOwner(); if(ui->actionHideDisconnectedPorts->isChecked() && pv->property.find("orphan").asBool()) continue; if(!ui->actionDebugMode->isChecked() && (portName.find("/log") != string::npos || portName.find("/yarplogger") != string::npos )) continue; std::stringstream key; if(v->property.find("hidden").asBool()) { pv->property.put("hidden",true); updateNodeWidgetItems(); continue; } else if(prop.find("hidden").asBool()) continue; QGVNode *node; QString colorProcess; if(layoutSubgraph) { key<<v->property.find("hostname").asString()<<v->property.find("pid").asInt32(); QGVSubGraph *sgraph = sceneSubGraphMap[key.str()]; if(sgraph) { node = sgraph->addNode(portName.c_str()); if(ui->actionColorMode->isChecked()) { QColor color(sgraph->getAttribute("colorOfTheProcess")); if(color.lightness()<100) node->setAttribute("labelfontcolor","#ffffff"); colorProcess = sgraph->getAttribute("colorOfTheProcess"); } } else node = scene->addNode(portName.c_str()); } else node = scene->addNode(portName.c_str()); node->setAttribute("shape", "ellipse"); if(prop.check("color")) { node->setAttribute("fillcolor", prop.find("color").asString().c_str()); node->setAttribute("color", prop.find("color").asString().c_str()); } else if(!colorProcess.isEmpty()) { node->setAttribute("fillcolor", colorProcess); node->setAttribute("color", colorProcess); } else { node->setAttribute("fillcolor", "#edad56"); node->setAttribute("color", "#edad56"); } //nodeSet[*itr] = node; dynamic_cast<GraphicVertex*>(*itr)->setGraphicItem(node); node->setVertex(*itr); portCounts++; } } // arrange the nodes deifferently if they are not port nodes if(portCounts == 0) { scene->setGraphAttribute("nodesep", "0.5"); scene->setGraphAttribute("ranksep", "1.5"); } for(itr = vertices.begin(); itr!=vertices.end(); itr++) { const Vertex &v1 = (**itr); for(size_t i=0; i<v1.outEdges().size(); i++) { const Edge& edge = v1.outEdges()[i]; const Vertex &v2 = edge.second(); string targetName = v2.property.find("name").asString(); if(!ui->actionDebugMode->isChecked() && targetName.find("/yarplogger") != string::npos) continue; //yInfo()<<"Drawing:"<<v1.property.find("name").asString()<<" -> "<<v2.property.find("name").asString(); // add ownership edges if(!v1.property.find("hidden").asBool() && !v2.property.find("hidden").asBool()) { if(edge.property.find("type").asString() == "ownership" && edge.property.find("dir").asString() != "unknown") { continue; } if(edge.property.find("type").asString() == "connection") { //QGVEdge* gve = scene->addEdge(nodeSet[&v1], nodeSet[&v2], // edge.property.find("carrier").asString().c_str()); string lable=""; if(!ui->actionHideConnectionsLable->isChecked()) lable = edge.property.find("carrier").asString(); QGVEdge* gve = scene->addEdge((QGVNode*)((GraphicVertex*)&v1)->getGraphicItem(), (QGVNode*)((GraphicVertex*)&v2)->getGraphicItem(), lable.c_str()); QosStyle::PacketPriorityLevel level= (QosStyle::PacketPriorityLevel)edge.property.find("FromPacketPriority").asInt32(); switch (level) { case QosStyle::PacketPriorityNormal: gve->setAttribute("color", "white"); break; case QosStyle::PacketPriorityHigh: gve->setAttribute("color", "orange"); break; case QosStyle::PacketPriorityCritical: gve->setAttribute("color", "red"); break; case QosStyle::PacketPriorityLow: gve->setAttribute("color", "yellow"); break; default: gve->setAttribute("color", "white"); break; } //gve->setToolTip("hello!"); gve->setEdge(&edge); } } } } //Layout scene scene->applyLayout(); //Fit in view ui->graphicsView->fitInView(scene->sceneRect(), Qt::KeepAspectRatio); //QGVSubGraph *ssgraph = sgraph->addSubGraph("SUB2"); //ssgraph->setAttribute("label", "DESK"); //scene->addEdge(snode1, ssgraph->addNode("PC0155"), "S10"); }