void GridLayoutModule::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); // compute grid layout GridLayout gridLayout(G); doCall(G,gridLayout,m_gridBoundingBox); // transform grid layout to real layout mapGridLayout(G,gridLayout,AG); }
//************************************************************* //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
void StressMinimization::copyLayout( const GraphAttributes& GA, NodeArray<double>& newX, NodeArray<double>& newY) { // copy the layout for(node v : GA.constGraph().nodes) { newX[v] = GA.x(v); newY[v] = GA.y(v); } }
void PivotMDS::getPivotDistanceMatrix( const GraphAttributes& GA, Array<Array<double> >& pivDistMatrix) { const Graph& G = GA.constGraph(); const int n = G.numberOfNodes(); // lower the number of pivots if necessary int numberOfPivots = min(n, m_numberOfPivots); // number of pivots times n matrix used to store the graph distances pivDistMatrix.init(numberOfPivots); for (int i = 0; i < numberOfPivots; i++) { pivDistMatrix[i].init(n); } // edges costs array EdgeArray<double> edgeCosts; bool hasEdgeCosts = false; // already checked whether this attribute exists or not (see call method) if (m_hasEdgeCostsAttribute) { edgeCosts.init(G); for(edge e : G.edges) { edgeCosts[e] = GA.doubleWeight(e); } hasEdgeCosts = true; } // used for min-max strategy NodeArray<double> minDistances(G, std::numeric_limits<double>::infinity()); NodeArray<double> shortestPathSingleSource(G); // the current pivot node node pivNode = G.firstNode(); for (int i = 0; i < numberOfPivots; i++) { // get the shortest path from the currently processed pivot node to // all other nodes in the graph shortestPathSingleSource.fill(std::numeric_limits<double>::infinity()); if (hasEdgeCosts) { dijkstra_SPSS(pivNode, G, shortestPathSingleSource, edgeCosts); } else { bfs_SPSS(pivNode, G, shortestPathSingleSource, m_edgeCosts); } copySPSS(pivDistMatrix[i], shortestPathSingleSource); // update the pivot and the minDistances array ... to ensure the // correctness set minDistance of the pivot node to zero minDistances[pivNode] = 0; for(node v : G.nodes) { minDistances[v] = min(minDistances[v], shortestPathSingleSource[v]); if (minDistances[v] > minDistances[pivNode]) { pivNode = v; } } } }
int LayoutStatistics::numberOfBends( const GraphAttributes &ga, int *pMinBendsPerEdge, int *pMaxBendsPerEdge, double *pAvgBendsPerEdge, double *pStdDeviation, bool considerSelfLoops) { const Graph &G = ga.constGraph(); int m = G.numberOfEdges(); int totalBends = 0, minBends = numeric_limits<int>::max(), maxBends = 0; EdgeArray<int> bends(G); int nSelfLoops = 0; for(edge e : G.edges) { if(!considerSelfLoops && e->isSelfLoop()) { nSelfLoops++; continue; } const DPolyline &dpl = ga.bends(e); bends[e] = max(0, dpl.size() - 2); totalBends += bends[e]; minBends = min(minBends, bends[e]); maxBends = max(maxBends, bends[e]); } m -= nSelfLoops; double avgBends = double(totalBends) / m; if(pAvgBendsPerEdge) *pAvgBendsPerEdge = avgBends; if(pMinBendsPerEdge) *pMinBendsPerEdge = minBends; if(pMaxBendsPerEdge) *pMaxBendsPerEdge = maxBends; if(pStdDeviation) { double sum = 0; for(edge e : G.edges) { if(!considerSelfLoops && e->isSelfLoop()) continue; double d = bends[e] - avgBends; sum += d*d; } *pStdDeviation = sqrt(sum / m); } return totalBends; }
void ComponentSplitterLayout::call(GraphAttributes &GA) { // Only do preparations and call if layout is valid if (m_secondaryLayout.valid()) { //first we split the graph into its components const Graph& G = GA.constGraph(); NodeArray<int> componentNumber(G); m_numberOfComponents = connectedComponents(G, componentNumber); if (m_numberOfComponents == 0) { return; } //std::vector< std::vector<node> > componentArray; //componentArray.resize(numComponents); //Array<GraphAttributes *> components(numComponents); // // intialize the array of lists of nodes contained in a CC nodesInCC.init(m_numberOfComponents); node v; forall_nodes(v,G) nodesInCC[componentNumber[v]].pushBack(v); // Create copies of the connected components and corresponding // GraphAttributes GraphCopy GC; GC.createEmpty(G); EdgeArray<edge> auxCopy(G); for (int i = 0; i < m_numberOfComponents; i++) { GC.initByNodes(nodesInCC[i],auxCopy); GraphAttributes cGA(GC, GA.attributes()); //copy information into copy GA forall_nodes(v, GC) { cGA.width(v) = GA.width(GC.original(v)); cGA.height(v) = GA.height(GC.original(v)); cGA.x(v) = GA.x(GC.original(v)); cGA.y(v) = GA.y(GC.original(v)); } // copy information on edges if (GA.attributes() & GraphAttributes::edgeDoubleWeight) { edge e; forall_edges(e, GC) { cGA.doubleWeight(e) = GA.doubleWeight(GC.original(e)); } }
void PlanarGridLayoutModule::callFixEmbed(GraphAttributes &AG, adjEntry adjExternal) { const Graph &G = AG.constGraph(); // compute grid layout GridLayout gridLayout(G); if (!handleTrivial(G, gridLayout, m_gridBoundingBox)) { doCall(G, adjExternal, gridLayout, m_gridBoundingBox, true); } // transform grid layout to real layout mapGridLayout(G,gridLayout,AG); }
void FastMultipoleMultilevelEmbedder::call(GraphAttributes &GA) { EdgeArray<float> edgeLengthAuto(GA.constGraph()); computeAutoEdgeLength(GA, edgeLengthAuto); const Graph& t = GA.constGraph(); if (t.numberOfNodes() <= 25) { FastMultipoleEmbedder fme; fme.setNumberOfThreads(this->m_iMaxNumThreads); fme.setRandomize(true); fme.setNumIterations(500); fme.call(GA); return; } run(GA, edgeLengthAuto); for(edge e : GA.constGraph().edges) { GA.bends(e).clear(); } }
void PivotMDS::pivotMDSLayout(GraphAttributes& GA) { const Graph& G = GA.constGraph(); if (G.numberOfNodes() <= 1) { // make it exception save node v; forall_nodes(v,G) { GA.x(v) = 0.0; GA.y(v) = 0.0; if (DIMENSION_COUNT > 2) GA.z(v) = 0.0; }
void PivotMDS::call(GraphAttributes& GA) { if (!isConnected(GA.constGraph())) { OGDF_THROW_PARAM(PreconditionViolatedException,pvcConnected); return; } if (m_hasEdgeCostsAttribute && !GA.has(GraphAttributes::edgeDoubleWeight)) { OGDF_THROW(PreconditionViolatedException); return; } pivotMDSLayout(GA); }
//chooses the initial radius of the disk as half the maximum of width and height of //the initial layout or depending on the value of m_fineTune void DavidsonHarel::computeFirstRadius(const GraphAttributes &AG) { const Graph &G = AG.constGraph(); node v = G.firstNode(); double minX = AG.x(v); double minY = AG.y(v); double maxX = minX; double maxY = minY; forall_nodes(v,G) { minX = min(minX,AG.x(v)); maxX = max(maxX,AG.x(v)); minY = min(minY,AG.y(v)); maxY = max(maxY,AG.y(v)); }
void FastMultipoleMultilevelEmbedder::computeAutoEdgeLength(const GraphAttributes& GA, EdgeArray<float>& edgeLength, float factor) { for(edge e : GA.constGraph().edges) { node v = e->source(); node w = e->target(); float radius_v = (float)sqrt(GA.width(v)*GA.width(v) + GA.height(v)*GA.height(v)) * 0.5f; float radius_w = (float)sqrt(GA.width(w)*GA.width(w) + GA.height(w)*GA.height(w)) * 0.5f; float sum = radius_v + radius_w; if (OGDF_GEOM_ET.equal(sum, (float) 0)) sum = 1.0; edgeLength[e] = factor*(sum); } }
void FastMultipoleMultilevelEmbedder::initFinestLevel(GraphAttributes &GA, const EdgeArray<float>& edgeLength) { #if 0 NodeArray<float> perimeter(GA.constGraph(), 0.0); #endif for(node v : GA.constGraph().nodes) { GalaxyMultilevel::LevelNodeInfo& nodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[v]; nodeInfo.mass = 1.0; float r = (float)sqrt(GA.width(v)*GA.width(v) + GA.height(v)*GA.height(v)) * 0.5f; nodeInfo.radius = r; } for(edge e : GA.constGraph().edges) { GalaxyMultilevel::LevelEdgeInfo& edgeInfo = (*(m_pFinestLevel->m_pEdgeInfo))[e]; node v = e->source(); node w = e->target(); GalaxyMultilevel::LevelNodeInfo& vNodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[v]; GalaxyMultilevel::LevelNodeInfo& wNodeInfo = (*(m_pFinestLevel->m_pNodeInfo))[w]; edgeInfo.length = (vNodeInfo.radius + wNodeInfo.radius) + edgeLength[e]; } }
//the vertices with degree zero are placed below all other vertices on a horizontal // line centered with repect to the rest of the drawing void DavidsonHarel::placeIsolatedNodes(GraphAttributes &AG) const { double minX = 0.0; double minY = 0.0; double maxX = 0.0; if (!m_nonIsolatedNodes.empty()) { //compute a rectangle that includes all non-isolated vertices node vFirst = m_nonIsolatedNodes.front(); minX = AG.x(vFirst); minY = AG.y(vFirst); maxX = minX; double maxY = minY; for (node v : m_nonIsolatedNodes) { double xVal = AG.x(v); double yVal = AG.y(v); double halfHeight = AG.height(v) / 2.0; double halfWidth = AG.width(v) / 2.0; if (xVal - halfWidth < minX) minX = xVal - halfWidth; if (xVal + halfWidth > maxX) maxX = xVal + halfWidth; if (yVal - halfHeight < minY) minY = yVal - halfHeight; if (yVal + halfHeight > maxY) maxY = yVal + halfHeight; } } // compute the width and height of the largest isolated node List<node> isolated; const Graph &G = AG.constGraph(); double maxWidth = 0; double maxHeight = 0; for (node v : G.nodes) if (v->degree() == 0) { isolated.pushBack(v); if (AG.height(v) > maxHeight) maxHeight = AG.height(v); if (AG.width(v) > maxWidth) maxWidth = AG.width(v); } // The nodes are placed on a line in the middle under the non isolated vertices. // Each node gets a box sized 2 maxWidth. double boxWidth = 2.0*maxWidth; double commonYCoord = minY - (1.5*maxHeight); double XCenterOfDrawing = minX + ((maxX - minX) / 2.0); double startXCoord = XCenterOfDrawing - 0.5*(isolated.size()*boxWidth); double xcoord = startXCoord; for (node v : isolated) { AG.x(v) = xcoord; AG.y(v) = commonYCoord; xcoord += boxWidth; } }
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"; } }
void DominanceLayout::compact(const UpwardPlanRep &UPR, GraphAttributes &GA) { double maxNodeSize = 0; for(node v : GA.constGraph().nodes) { if (GA.width(v) > maxNodeSize || GA.height(v) > maxNodeSize) maxNodeSize = max(GA.width(v), GA.height(v)); } int gridDist = m_grid_dist; if (gridDist < maxNodeSize+1) gridDist = (int) maxNodeSize+1; xCoord.init(UPR); yCoord.init(UPR); //ASSIGN X COORDINATE OGDF_ASSERT(!xNodes.empty()); node v = xNodes.popFrontRet(); xCoord[v] = 0; while (!xNodes.empty()) { node u = xNodes.popFrontRet(); if ( (yPreCoord[v] > yPreCoord[u]) || (firstout[v] == lastout[v] && firstin[u] == lastin[u] && m_L <= m_R)) { xCoord[u] = xCoord[v] + gridDist; } else xCoord[u] = xCoord[v]; v = u; } //ASSIGN Y COORDINATE OGDF_ASSERT(!yNodes.empty()); v = yNodes.popFrontRet(); yCoord[v] = 0; while (!yNodes.empty()) { node u = yNodes.popFrontRet(); if ( (xPreCoord[v] > xPreCoord[u]) || (firstout[v] == lastout[v] && firstin[u] == lastin[u] && m_L > m_R)) { yCoord[u] = yCoord[v] + gridDist; } else yCoord[u] = yCoord[v]; v = u; } }
void RadialTreeLayout::ComputeCoordinates(GraphAttributes &AG) { const Graph &G = AG.constGraph(); //double mx = m_outerRadius + 0.5*m_connectedComponentDistance; //double my = mx; for(node v : G.nodes) { double r = m_radius[m_level[v]]; double alpha = m_angle[v]; AG.x(v) = r * cos(alpha); AG.y(v) = r * sin(alpha); } AG.clearAllBends(); }
void FastMultipoleMultilevelEmbedder::run(GraphAttributes& GA, const EdgeArray<float>& edgeLength) { // too lazy for new, delete NodeArray<float> nodeXPos1; NodeArray<float> nodeYPos1; NodeArray<float> nodeXPos2; NodeArray<float> nodeYPos2; EdgeArray<float> edgeLength1; NodeArray<float> nodeSize1; m_pCurrentNodeXPos = &nodeXPos1; m_pCurrentNodeYPos = &nodeYPos1; m_pLastNodeXPos = &nodeXPos2; m_pLastNodeYPos = &nodeYPos2; m_pCurrentEdgeLength= &edgeLength1; m_pCurrentNodeSize = &nodeSize1; Graph* pGraph = const_cast<Graph*>(&(GA.constGraph())); // create all multilevels this->createMultiLevelGraphs(pGraph, GA, edgeLength); // init the coarsest level initCurrentLevel(); // layout the current level layoutCurrentLevel(); //proceed with remaining levels while (m_iCurrentLevelNr > 0) { // move to finer level nextLevel(); // init the arrays for current level initCurrentLevel(); // assign positions from last to current assignPositionsFromPrevLevel(); // layout the current level layoutCurrentLevel(); } // the finest level is processed // assumes m_pCurrentGraph == GA.constGraph writeCurrentToGraphAttributes(GA); // clean up multilevels deleteMultiLevelGraphs(); }
void TutteLayout::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); List<node> fixedNodes; List<DPoint> positions; double diam = sqrt((m_bbox.width()) * (m_bbox.width()) + (m_bbox.height()) * (m_bbox.height())); // handle graphs with less than two nodes switch (G.numberOfNodes()) { case 0: return; case 1: node v = G.firstNode(); DPoint center(0.5 * m_bbox.width(),0.5 * m_bbox.height()); center = center + m_bbox.p1(); AG.x(v) = center.m_x; AG.y(v) = center.m_y; return; } // increase radius to have no overlap on the outer circle node v = G.firstNode(); double r = diam/2.8284271; int n = G.numberOfNodes(); double nodeDiam = 2.0*sqrt((AG.width(v)) * (AG.width(v)) + (AG.height(v)) * (AG.height(v))); if(r<nodeDiam/(2*sin(2*Math::pi/n))) { r=nodeDiam/(2*sin(2*Math::pi/n)); m_bbox = DRect (0.0, 0.0, 2*r, 2*r); } setFixedNodes(G,fixedNodes,positions,r); doCall(AG,fixedNodes,positions); }
void ArrayGraph::readFrom(const GraphAttributes& GA, const EdgeArray<float>& edgeLength, const NodeArray<float>& nodeSize) { const Graph& G = GA.constGraph(); NodeArray<__uint32> nodeIndex(G); node v; m_numNodes = 0; m_numEdges = 0; m_avgNodeSize = 0; m_desiredAvgEdgeLength = 0; forall_nodes(v, G) { m_nodeXPos[m_numNodes] = (float)GA.x(v); m_nodeYPos[m_numNodes] = (float)GA.y(v); m_nodeSize[m_numNodes] = nodeSize[v]; nodeIndex[v] = m_numNodes; m_avgNodeSize += nodeSize[v]; m_numNodes++; };
void FMMMLayout::call(GraphAttributes &GA, const EdgeArray<double> &edgeLength) { const Graph &G = GA.constGraph(); //tms t_total;//helping variable for time measure double t_total; NodeArray<NodeAttributes> A(G); //stores the attributes of the nodes (given by L) EdgeArray<EdgeAttributes> E(G); //stores the edge attributes of G Graph G_reduced; //stores a undirected simple and loopfree copy //of G EdgeArray<EdgeAttributes> E_reduced; //stores the edge attributes of G_reduced NodeArray<NodeAttributes> A_reduced; //stores the node attributes of G_reduced if(G.numberOfNodes() > 1) { GA.clearAllBends();//all are edges straight line if(useHighLevelOptions()) update_low_level_options_due_to_high_level_options_settings(); import_NodeAttributes(G,GA,A); import_EdgeAttributes(G,edgeLength,E); //times(&t_total); usedTime(t_total); max_integer_position = pow(2.0,maxIntPosExponent()); init_ind_ideal_edgelength(G,A,E); make_simple_loopfree(G,A,E,G_reduced,A_reduced,E_reduced); call_DIVIDE_ET_IMPERA_step(G_reduced,A_reduced,E_reduced); if(allowedPositions() != apAll) make_positions_integer(G_reduced,A_reduced); //time_total = get_time(t_total); time_total = usedTime(t_total); export_NodeAttributes(G_reduced,A_reduced,GA); } else //trivial cases { if(G.numberOfNodes() == 1 ) { node v = G.firstNode(); GA.x(v) = 0; GA.y(v) = 0; } } }
SpringEmbedderFRExact::ArrayGraph::ArrayGraph(GraphAttributes &ga) : m_ga(&ga), m_mapNode(ga.constGraph()) { const Graph &G = ga.constGraph(); m_numNodes = m_numEdges = 0; m_orig = nullptr; m_src = m_tgt = nullptr; m_x = m_y = nullptr; m_nodeWeight = nullptr; m_useNodeWeight = false; // compute connected components of G NodeArray<int> component(G); m_numCC = connectedComponents(G,component); m_nodesInCC.init(m_numCC); for(node v : G.nodes) m_nodesInCC[component[v]].pushBack(v); }
// 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"; }
void createDocument(GraphAttributes attr, pugi::xml_document &doc, GraphIO::SVGSettings *settings = nullptr, bool reassignPositions = true) { std::ostringstream write; if(reassignPositions) { int i = 0; for(node v : attr.constGraph().nodes) { attr.x(v) = attr.y(v) = i++ * 100; attr.width(v) = attr.height(v) = 10; } } if(settings == nullptr) { GraphIO::drawSVG(attr, write); } else { GraphIO::drawSVG(attr, write, *settings); } pugi::xml_parse_result result = doc.load_string(write.str().c_str()); AssertThat((bool) result, IsTrue()); }
static void compute_bounding_box(const GraphAttributes &A, double &xmin, double &ymin, double &xmax, double &ymax) { const Graph &G = A.constGraph(); if(G.numberOfNodes() == 0) { xmin = xmax = ymin = ymax = 0; return; } node v = G.firstNode(); xmin = xmax = A.x(v), ymin = ymax = A.y(v); forall_nodes(v, G) { double lw = (A.attributes() & GraphAttributes::nodeStyle) ? 0.5*A.strokeWidth(v) : 0.5; xmax = max(xmax, A.x(v) + A.width (v)/2 + lw); ymax = max(ymax, A.y(v) + A.height(v)/2 + lw); xmin = min(xmin, A.x(v) - A.width (v)/2 - lw); ymin = min(ymin, A.y(v) - A.height(v)/2 - lw); }
void BertaultLayout::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); if(G.numberOfNodes() == 0) return; if( (AG.attributes() & GraphAttributes::nodeGraphics) == 0 ) return; if( (AG.attributes() & GraphAttributes::edgeGraphics) != 0 ) AG.clearAllBends(); if(iter_no==0) iter_no=G.numberOfNodes()*10; if(req_length==0) { edge e; forall_edges(e,G) { node a=e->source(); node b=e->target(); req_length+=sqrt((AG.x(a)-AG.x(b))*(AG.x(a)-AG.x(b))+(AG.y(a)-AG.y(b))*(AG.y(a)-AG.y(b))); }
void StressMinimization::minimizeStress( GraphAttributes& GA, NodeArray<NodeArray<double> >& shortestPathMatrix, NodeArray<NodeArray<double> >& weightMatrix) { const Graph& G = GA.constGraph(); int numberOfPerformedIterations = 0; double prevStress = numeric_limits<double>::max(); double curStress = numeric_limits<double>::max(); if (m_terminationCriterion == STRESS) { curStress = calcStress(GA, shortestPathMatrix, weightMatrix); } NodeArray<double> newX; NodeArray<double> newY; NodeArray<double> newZ; if (m_terminationCriterion == POSITION_DIFFERENCE) { newX.init(G); newY.init(G); if (GA.has(GraphAttributes::threeD)) newZ.init(G); } do { if (m_terminationCriterion == POSITION_DIFFERENCE) { if (GA.has(GraphAttributes::threeD)) copyLayout(GA, newX, newY, newZ); else copyLayout(GA, newX, newY); } nextIteration(GA, shortestPathMatrix, weightMatrix); if (m_terminationCriterion == STRESS) { prevStress = curStress; curStress = calcStress(GA, shortestPathMatrix, weightMatrix); } } while (!finished(GA, ++numberOfPerformedIterations, newX, newY, prevStress, curStress)); Logger::slout() << "Iteration count:\t" << numberOfPerformedIterations << "\tStress:\t" << calcStress(GA, shortestPathMatrix, weightMatrix) << endl; }
MultilevelGraph::MultilevelGraph(GraphAttributes &GA) :m_createdGraph(false) { m_G = new Graph(); if(m_G == 0) { OGDF_THROW(InsufficientMemoryException); } else { m_createdGraph = true; } m_nodeAssociations.init(*m_G); m_edgeAssociations.init(*m_G); m_x.init(*m_G); m_y.init(*m_G); m_radius.init(*m_G); m_weight.init(*m_G); copyFromGraph(GA.constGraph(), m_nodeAssociations, m_edgeAssociations); prepareGraphAttributes(GA); importAttributes(GA); initReverseIndizes(); }
MultilevelGraph::MultilevelGraph(GraphAttributes &GA) :m_createdGraph(true) { m_G = new Graph(); if(m_G == 0) { OGDF_THROW(InsufficientMemoryException); } //replaces layout info stuff below initInternal(); m_nodeAssociations.init(*m_G); m_edgeAssociations.init(*m_G); m_radius.init(*m_G); m_weight.init(*m_G); copyFromGraph(GA.constGraph(), m_nodeAssociations, m_edgeAssociations); prepareGraphAttributes(GA); importAttributes(GA); initReverseIndizes(); }
void StressMinimization::call( GraphAttributes& GA, NodeArray<NodeArray<double> >& shortestPathMatrix, NodeArray<NodeArray<double> >& weightMatrix) { // compute the initial layout if necessary if (!m_hasInitialLayout) { computeInitialLayout(GA); } const Graph& G = GA.constGraph(); // replace infinity distances by sqrt(n) and compute weights. // Note isConnected is only true during calls triggered by the // ComponentSplitterLayout. if (!m_componentLayout && !isConnected(G)) { replaceInfinityDistances(shortestPathMatrix, m_avgEdgeCosts * sqrt((double)(G.numberOfNodes()))); } // calculate the weights calcWeights(G, G.numberOfNodes() - 1, shortestPathMatrix, weightMatrix); // minimize the stress minimizeStress(GA, shortestPathMatrix, weightMatrix); }