// Constructor. LteRlcGraphDialog::LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool channelKnown) : WiresharkDialog(parent, cf), ui(new Ui::LteRlcGraphDialog), mouse_drags_(true), rubber_band_(NULL), base_graph_(NULL), reseg_graph_(NULL), acks_graph_(NULL), nacks_graph_(NULL), tracer_(NULL), packet_num_(0) { ui->setupUi(this); loadGeometry(parent.width() * 4 / 5, parent.height() * 3 / 4); QCustomPlot *rp = ui->rlcPlot; rp->xAxis->setLabel(tr("Time")); rp->yAxis->setLabel(tr("Sequence Number")); // TODO: couldn't work out how to tell rp->xAxis not to label fractions of a SN... ui->dragRadioButton->setChecked(mouse_drags_); ctx_menu_ = new QMenu(this); ctx_menu_->addAction(ui->actionZoomIn); ctx_menu_->addAction(ui->actionZoomInX); ctx_menu_->addAction(ui->actionZoomInY); ctx_menu_->addAction(ui->actionZoomOut); ctx_menu_->addAction(ui->actionZoomOutX); ctx_menu_->addAction(ui->actionZoomOutY); ctx_menu_->addAction(ui->actionReset); ctx_menu_->addSeparator(); ctx_menu_->addAction(ui->actionMoveRight10); ctx_menu_->addAction(ui->actionMoveLeft10); ctx_menu_->addAction(ui->actionMoveUp10); ctx_menu_->addAction(ui->actionMoveUp100); ctx_menu_->addAction(ui->actionMoveDown10); ctx_menu_->addAction(ui->actionMoveDown100); ctx_menu_->addAction(ui->actionMoveRight1); ctx_menu_->addAction(ui->actionMoveLeft1); ctx_menu_->addAction(ui->actionMoveUp1); ctx_menu_->addAction(ui->actionMoveDown1); ctx_menu_->addSeparator(); ctx_menu_->addAction(ui->actionGoToPacket); ctx_menu_->addSeparator(); ctx_menu_->addAction(ui->actionDragZoom); // ctx_menu_->addAction(ui->actionToggleTimeOrigin); ctx_menu_->addAction(ui->actionCrosshairs); ctx_menu_->addSeparator(); ctx_menu_->addAction(ui->actionSwitchDirection); // Zero out this struct. memset(&graph_, 0, sizeof(graph_)); // If channel is known, details will be supplied by setChannelInfo(). if (!channelKnown) { completeGraph(); } }
// Set the channel information that this graph should show. void LteRlcGraphDialog::setChannelInfo(guint16 ueid, guint8 rlcMode, guint16 channelType, guint16 channelId, guint8 direction) { graph_.ueid = ueid; graph_.rlcMode = rlcMode; graph_.channelType = channelType; graph_.channelId = channelId; graph_.channelSet = TRUE; graph_.direction = direction; completeGraph(); }
void planarTriconnectedGraph(Graph &G, int n, double p1, double p2) { if (n < 4) n = 4; // start with K_4 completeGraph(G,4); planarEmbedPlanarGraph(G); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; for(; i < n; ++i) { // pick a random node v = nodes[randomNumber(0,i-1)]; int m = v->degree(); int a1 = randomNumber(0,m-1); int a2 = randomNumber(0,m-2); int j; adjEntry adj1, adj2; for(adj1 = v->firstAdj(), j = 0; j < a1; adj1 = adj1->succ(), ++j) ; for(adj2 = adj1->cyclicSucc(), j = 0; j < a2; adj2 = adj2->cyclicSucc(), ++j) ; adjEntry adj_b1 = adj2->cyclicPred(); adjEntry adj_b2 = adj1->cyclicPred(); nodes[i] = G.splitNode(adj1, adj2); if(adj1 == adj_b1) G.newEdge(adj_b1, adj2->twin()); else if(adj2 == adj_b2) G.newEdge(adj2, adj_b1->twin(), ogdf::before); else { double r = randomDouble(0.0,1.0); if(r <= p1) { int s = randomNumber(0,1); if(s == 0) G.newEdge(adj_b1, adj2->twin()); else G.newEdge(adj2, adj_b1->twin(), ogdf::before); } } double r = randomDouble(0.0,1.0); if(r <= p2) { int s = randomNumber(0,1); if(s == 0) G.newEdge(adj1, adj_b2->twin(), ogdf::before); else G.newEdge(adj_b2, adj1->twin()); } } }
void planarTriconnectedGraph(Graph &G, int n, int m) { if (n < 4) n = 4; if(n % 2) ++n; // need an even number // start with K_4 completeGraph(G,4); planarEmbedPlanarGraph(G); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; // create planar triconnected 3-graph for(; i < n; ) { // pick a random node v = nodes[randomNumber(0,i-1)]; adjEntry adj2 = v->firstAdj(); int r = randomNumber(0,2); switch(r) { case 2: adj2 = adj2->succ(); // fall through to next case case 1: adj2 = adj2->succ(); } adjEntry adj1 = adj2->cyclicSucc(); nodes[i++] = G.splitNode(adj1,adj2); r = randomNumber(0,1); if(r == 0) { adjEntry adj = adj1->twin(); G.newEdge(adj2,adj); nodes[i++] = G.splitNode(adj,adj->cyclicSucc()->cyclicSucc()); } else { adjEntry adj = adj1->cyclicSucc()->twin(); G.newEdge(adj2,adj,ogdf::before); nodes[i++] = G.splitNode(adj->cyclicPred(),adj->cyclicSucc()); } } nodes.init(); Array<edge> edges(m); CombinatorialEmbedding E(G); Array<face> faces(2*n); i = 0; face f; forall_faces(f,E) { if(f->size() >= 4) faces[i++] = f; } while(G.numberOfEdges() < m && i > 0) { int r = randomNumber(0,i-1); f = faces[r]; faces[r] = faces[--i]; int p = randomNumber(0,f->size()-1); int j = 0; adjEntry adj, adj2; for(adj = f->firstAdj(); j < p; adj = adj->faceCycleSucc(), ++j) ; p = randomNumber(2, f->size()-2); for(j = 0, adj2 = adj; j < p; adj2 = adj2->faceCycleSucc(), ++j) ; edge e = E.splitFace(adj,adj2); f = E.rightFace(e->adjSource()); if(f->size() >= 4) faces[i++] = f; f = E.rightFace(e->adjTarget()); if(f->size() >= 4) faces[i++] = f; } }
void randomTriconnectedGraph(Graph &G, int n, double p1, double p2) { if(n < 4) n = 4; // start with K_4 completeGraph(G,4); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; // Will be used below as array of neighbors of v Array<edge> neighbors(n); // used to mark neighbors // 0 = not marked // 1 = marked left // 2 = marked right // 3 = marked both Array<int> mark(0,n-1,0); for(; i < n; ++i) { // pick a random node v = nodes[randomNumber(0,i-1)]; // create a new node w such that v is split into v and w node w = nodes[i] = G.newNode(); // build array of all neighbors int d = v->degree(); int j = 0; adjEntry adj; forall_adj(adj,v) neighbors[j++] = adj->theEdge(); // mark two distinct neighbors for left for(j = 2; j > 0; ) { int r = randomNumber(0,d-1); if((mark[r] & 1) == 0) { mark[r] |= 1; --j; } } // mark two distinct neighbors for right for(j = 2; j > 0; ) { int r = randomNumber(0,d-1); if((mark[r] & 2) == 0) { mark[r] |= 2; --j; } } for(j = 0; j < d; ++j) { int m = mark[j]; mark[j] = 0; // decide to with which node each neighbor is connected // (possible: v, w, or both) double x = randomDouble(0.0,1.0); switch(m) { case 0: if(x < p1) m = 1; else if(x < p1+p2) m = 2; else m = 3; break; case 1: case 2: if(x >= p1+p2) m = 3; break; } // move edge or create new one if necessary edge e = neighbors[j]; switch(m) { case 2: if(v == e->source()) G.moveSource(e,w); else G.moveTarget(e,w); break; case 3: G.newEdge(w,e->opposite(v)); break; } } G.newEdge(v,w); } }