本文整理汇总了C++中GridLayout::x方法的典型用法代码示例。如果您正苦于以下问题:C++ GridLayout::x方法的具体用法?C++ GridLayout::x怎么用?C++ GridLayout::x使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GridLayout
的用法示例。
在下文中一共展示了GridLayout::x方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: doCall
void MixedModelLayout::doCall(
PlanRep &PG,
adjEntry adjExternal,
GridLayout &gridLayout,
IPoint &boundingBox,
bool fixEmbedding)
{
// handle graphs with less than 3 nodes
node v1, v2;
switch (PG.numberOfNodes()) {
case 0:
boundingBox = IPoint(0,0);
return;
case 1:
v1 = PG.firstNode();
gridLayout.x(v1) = gridLayout.y(v1) = 0;
boundingBox = IPoint(0,0);
return;
case 2:
v1 = PG.firstNode();
v2 = v1->succ();
gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
gridLayout.x(v2) = 1;
boundingBox = IPoint(1,0);
return;
}
MixedModelBase mm(PG,gridLayout);
if(fixEmbedding) {
OGDF_ASSERT(PG.representsCombEmbedding());
PlanarAugmentationFix fixAugmenter;
mm.computeOrder(fixAugmenter, 0, adjExternal, m_compOrder.get());
} else
mm.computeOrder(m_augmenter.get(),&m_embedder.get(),0,m_compOrder.get());
mm.assignIopCoords();
mm.placeNodes();
mm.postprocessing1();
mm.setBends();
mm.postprocessing2();
m_crossingsBeautifier.get().call(PG,gridLayout);
int xmin, ymin;
gridLayout.computeBoundingBox(xmin,boundingBox.m_x,ymin,boundingBox.m_y);
}
示例2: doCall
void SchnyderLayout::doCall(
const Graph &G,
adjEntry adjExternal,
GridLayout &gridLayout,
IPoint &boundingBox,
bool fixEmbedding)
{
// check for double edges & self loops
OGDF_ASSERT(isSimple(G));
// handle special case of graphs with less than 3 nodes
if (G.numberOfNodes() < 3) {
node v1, v2;
switch (G.numberOfNodes()) {
case 0:
boundingBox = IPoint(0, 0);
return;
case 1:
v1 = G.firstNode();
gridLayout.x(v1) = gridLayout.y(v1) = 0;
boundingBox = IPoint(0, 0);
return;
case 2:
v1 = G.firstNode();
v2 = G.lastNode();
gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
gridLayout.x(v2) = 1;
boundingBox = IPoint(1, 0);
return;
}
}
// make a copy for triangulation
GraphCopy GC(G);
// embed
if (!fixEmbedding) {
if (planarEmbed(GC) == false) {
OGDF_THROW_PARAM(PreconditionViolatedException, pvcPlanar);
}
}
triangulate(GC);
schnyderEmbedding(GC, gridLayout, adjExternal);
}
示例3: mapGridLayout
void GridLayoutModule::mapGridLayout(const Graph &G,
GridLayout &gridLayout,
GraphAttributes &AG)
{
// maximum width of columns and rows
double maxWidth = 0;
double yMax = 0;
for(node v : G.nodes) {
Math::updateMax<double>(maxWidth, AG.width(v));
Math::updateMax<double>(maxWidth, AG.height(v));
Math::updateMax<double>(yMax, gridLayout.y(v));
}
maxWidth += m_separation;
// set position of nodes
for(node v : G.nodes) {
AG.x(v) = gridLayout.x(v) * maxWidth;
AG.y(v) = (yMax - gridLayout.y(v)) * maxWidth;
}
// transform bend points of edges
for(edge e : G.edges) {
IPolyline ipl = gridLayout.polyline(e);
// Remove superfluous bendpoints
node v = e->source();
while(!ipl.empty() && ipl.front() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
ipl.popFront();
}
v = e->target();
while(!ipl.empty() && ipl.back() == IPoint(gridLayout.x(v), gridLayout.y(v))) {
ipl.popBack();
}
DPolyline &dpl = AG.bends(e);
dpl.clear();
for (const IPoint &ip : ipl) {
dpl.pushBack(DPoint(ip.m_x*maxWidth, (yMax-ip.m_y)*maxWidth));
}
dpl.normalize();
}
}
示例4: collapseVertices
void PlanRep::collapseVertices(const OrthoRep &OR, GridLayout &drawing)
{
for (node v : nodes) {
const OrthoRep::VertexInfoUML *vi = OR.cageInfo(v);
if(vi == nullptr ||
(typeOf(v) != Graph::highDegreeExpander &&
typeOf(v) != Graph::lowDegreeExpander))
continue;
node vOrig = original(v);
OGDF_ASSERT(vOrig != 0);
node vCenter = newNode();
m_vOrig[vCenter] = vOrig;
m_vCopy[vOrig] = vCenter;
m_vOrig[v] = nullptr;
node lowerLeft = vi->m_corner[odNorth]->theNode();
node lowerRight = vi->m_corner[odWest ]->theNode();
node upperLeft = vi->m_corner[odEast ]->theNode();
drawing.x(vCenter) = (drawing.x(lowerLeft)+drawing.x(lowerRight)) >> 1;
drawing.y(vCenter) = (drawing.y(lowerLeft)+drawing.y(upperLeft )) >> 1;
edge eOrig;
forall_adj_edges(eOrig,vOrig) {
if(eOrig->target() == vOrig) {
node connect = m_eCopy[eOrig].back()->target();
edge eNew = newEdge(connect,vCenter);
m_eOrig[eNew] = eOrig;
m_eIterator[eNew] = m_eCopy[eOrig].pushBack(eNew);
} else {
node connect = m_eCopy[eOrig].front()->source();
edge eNew = newEdge(vCenter,connect);
m_eOrig[eNew] = eOrig;
m_eIterator[eNew] = m_eCopy[eOrig].pushFront(eNew);
}
}
}
}
示例5: handleTrivial
bool PlanarGridLayoutModule::handleTrivial(const Graph &G, GridLayout &gridLayout, IPoint &boundingBox)
{
// handle special case of graphs with less than 3 nodes
node v1, v2;
switch (G.numberOfNodes()) {
case 0:
boundingBox = IPoint(0, 0);
return true;
case 1:
v1 = G.firstNode();
gridLayout.x(v1) = gridLayout.y(v1) = 0;
boundingBox = IPoint(0, 0);
return true;
case 2:
v1 = G.firstNode();
v2 = G.lastNode();
gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
gridLayout.x(v2) = 1;
boundingBox = IPoint(1, 0);
return true;
}
return false;
}
示例6: computeCoordinates
void FPPLayout::computeCoordinates(const GraphCopy &G, IPoint &boundingBox, GridLayout &gridLayout, NodeArray<int> &num,
NodeArray<adjEntry> &e_wp, NodeArray<adjEntry> &e_wq) {
NodeArray<int> &x = gridLayout.x();
NodeArray<int> &y = gridLayout.y();
const int n = G.numberOfNodes();
NodeArray<int> x_rel(G);
NodeArray<node> upper(G);
NodeArray<node> next(G);
Array<node, int> v(1, n);
node w, vk, wp, wq;
int k, xq, dx;
forall_nodes(w, G) {
v[num[w]] = (node) w;
}
示例7: mapGridLayout
void GridLayoutModule::mapGridLayout(const Graph &G,
GridLayout &gridLayout,
GraphAttributes &AG)
{
double maxWidth = 0; // maximum width of columns and rows;
double yMax = 0;
node v;
forall_nodes(v,G) {
if (AG.width (v) > maxWidth) maxWidth = AG.width (v);
if (AG.height(v) > maxWidth) maxWidth = AG.height(v);
if (gridLayout.y(v) > yMax) yMax = gridLayout.y(v);
}
maxWidth += m_separation;
// set position of nodes
forall_nodes(v,G) {
AG.x(v) = gridLayout.x(v) * maxWidth;
AG.y(v) = (yMax - gridLayout.y(v)) * maxWidth;
}
示例8: doCall
void GridLayoutPlanRepModule::doCall(
const Graph &G,
adjEntry adjExternal,
GridLayout &gridLayout,
IPoint &boundingBox,
bool fixEmbedding)
{
// create temporary graph copy and grid layout
PlanRep PG(G);
PG.initCC(0); // currently only for a single component!
GridLayout glPG(PG);
// determine adjacency entry on external face of PG (if required)
if(adjExternal != nullptr) {
edge eG = adjExternal->theEdge();
edge ePG = PG.copy(eG);
adjExternal = (adjExternal == eG->adjSource()) ? ePG->adjSource() : ePG->adjTarget();
}
// call algorithm for copy
doCall(PG,adjExternal,glPG,boundingBox,fixEmbedding);
// extract layout for original graph
for(node v : G.nodes) {
node vPG = PG.copy(v);
gridLayout.x(v) = glPG.x(vPG);
gridLayout.y(v) = glPG.y(vPG);
}
for(edge e : G.edges) {
IPolyline &ipl = gridLayout.bends(e);
ipl.clear();
for(edge ec : PG.chain(e))
ipl.conc(glPG.bends(ec));
}
}
示例9: doCall
void PlanarizationGridLayout::doCall(
const Graph &G,
GridLayout &gridLayout,
IPoint &bb)
{
m_nCrossings = 0;
if(G.empty()) return;
PlanRep pr(G);
const int numCC = pr.numberOfCCs();
// (width,height) of the layout of each connected component
Array<IPoint> boundingBox(numCC);
for(int cc = 0; cc < numCC; ++cc)
{
//--------------------------------------
// 1. crossing minimization
//--------------------------------------
int cr;
m_crossMin.get().call(pr, cc, cr);
m_nCrossings += cr;
OGDF_ASSERT(isPlanar(pr));
GridLayout gridLayoutPG(pr);
m_planarLayouter.get().callGrid(pr,gridLayoutPG);
// copy grid layout of PG into grid layout of G
for(int j = pr.startNode(); j < pr.stopNode(); ++j)
{
node vG = pr.v(j);
gridLayout.x(vG) = gridLayoutPG.x(pr.copy(vG));
gridLayout.y(vG) = gridLayoutPG.y(pr.copy(vG));
adjEntry adj;
forall_adj(adj,vG) {
if ((adj->index() & 1) == 0) continue;
edge eG = adj->theEdge();
IPolyline &ipl = gridLayout.bends(eG);
ipl.clear();
bool firstTime = true;
ListConstIterator<edge> itE;
for(itE = pr.chain(eG).begin(); itE.valid(); ++itE) {
if(!firstTime) {
node v = (*itE)->source();
ipl.pushBack(IPoint(gridLayoutPG.x(v),gridLayoutPG.y(v)));
} else
firstTime = false;
ipl.conc(gridLayoutPG.bends(*itE));
}
}
}
boundingBox[cc] = m_planarLayouter.get().gridBoundingBox();
boundingBox[cc].m_x += 1; // one row/column space between components
boundingBox[cc].m_y += 1;
}
Array<IPoint> offset(numCC);
m_packer.get().call(boundingBox,offset,m_pageRatio);
bb.m_x = bb.m_y = 0;
for(int cc = 0; cc < numCC; ++cc)
{
const int dx = offset[cc].m_x;
const int dy = offset[cc].m_y;
if(boundingBox[cc].m_x + dx > bb.m_x)
bb.m_x = boundingBox[cc].m_x + dx;
if(boundingBox[cc].m_y + dy > bb.m_y)
bb.m_y = boundingBox[cc].m_y + dy;
// iterate over all nodes in i-th cc
for(int j = pr.startNode(cc); j < pr.stopNode(cc); ++j)
{
node vG = pr.v(j);
gridLayout.x(vG) += dx;
gridLayout.y(vG) += dy;
adjEntry adj;
forall_adj(adj,vG) {
if ((adj->index() & 1) == 0) continue;
edge eG = adj->theEdge();
ListIterator<IPoint> it;
for(it = gridLayout.bends(eG).begin(); it.valid(); ++it) {
(*it).m_x += dx;
(*it).m_y += dy;
}
}
}
}
bb.m_x -= 1; // remove margin of topmost/rightmost box
bb.m_y -= 1;
}
示例10: doCall
void PlanarizationGridLayout::doCall(
const Graph &G,
GridLayout &gridLayout,
IPoint &bb)
{
m_nCrossings = 0;
if(G.empty()) return;
PlanRep PG(G);
const int numCC = PG.numberOfCCs();
// (width,height) of the layout of each connected component
Array<IPoint> boundingBox(numCC);
int i;
for(i = 0; i < numCC; ++i)
{
PG.initCC(i);
const int nOrigVerticesPG = PG.numberOfNodes();
List<edge> deletedEdges;
m_subgraph.get().callAndDelete(PG, deletedEdges);
m_inserter.get().call(PG,deletedEdges);
m_nCrossings += PG.numberOfNodes() - nOrigVerticesPG;
GridLayout gridLayoutPG(PG);
m_planarLayouter.get().callGrid(PG,gridLayoutPG);
// copy grid layout of PG into grid layout of G
ListConstIterator<node> itV;
for(itV = PG.nodesInCC(i).begin(); itV.valid(); ++itV)
{
node vG = *itV;
gridLayout.x(vG) = gridLayoutPG.x(PG.copy(vG));
gridLayout.y(vG) = gridLayoutPG.y(PG.copy(vG));
adjEntry adj;
forall_adj(adj,vG) {
if ((adj->index() & 1) == 0) continue;
edge eG = adj->theEdge();
IPolyline &ipl = gridLayout.bends(eG);
ipl.clear();
bool firstTime = true;
ListConstIterator<edge> itE;
for(itE = PG.chain(eG).begin(); itE.valid(); ++itE) {
if(!firstTime) {
node v = (*itE)->source();
ipl.pushBack(IPoint(gridLayoutPG.x(v),gridLayoutPG.y(v)));
} else
firstTime = false;
ipl.conc(gridLayoutPG.bends(*itE));
}
}
}
boundingBox[i] = m_planarLayouter.get().gridBoundingBox();
boundingBox[i].m_x += 1; // one row/column space between components
boundingBox[i].m_y += 1;
}
Array<IPoint> offset(numCC);
m_packer.get().call(boundingBox,offset,m_pageRatio);
bb.m_x = bb.m_y = 0;
for(i = 0; i < numCC; ++i)
{
const List<node> &nodes = PG.nodesInCC(i);
const int dx = offset[i].m_x;
const int dy = offset[i].m_y;
if(boundingBox[i].m_x + dx > bb.m_x)
bb.m_x = boundingBox[i].m_x + dx;
if(boundingBox[i].m_y + dy > bb.m_y)
bb.m_y = boundingBox[i].m_y + dy;
// iterate over all nodes in i-th cc
ListConstIterator<node> it;
for(it = nodes.begin(); it.valid(); ++it)
{
node vG = *it;
gridLayout.x(vG) += dx;
gridLayout.y(vG) += dy;
adjEntry adj;
forall_adj(adj,vG) {
if ((adj->index() & 1) == 0) continue;
edge eG = adj->theEdge();
ListIterator<IPoint> it;
for(it = gridLayout.bends(eG).begin(); it.valid(); ++it) {
(*it).m_x += dx;
(*it).m_y += dy;
}
}
//.........这里部分代码省略.........
示例11: doCall
void PlanarStraightLayout::doCall(
const Graph &G,
adjEntry adjExternal,
GridLayout &gridLayout,
IPoint &boundingBox,
bool fixEmbedding)
{
// require to have a planar graph without multi-edges and self-loops;
// planarity is checked below
OGDF_ASSERT(isSimple(G) && isLoopFree(G));
// handle special case of graphs with less than 3 nodes
if(G.numberOfNodes() < 3)
{
node v1, v2;
switch(G.numberOfNodes())
{
case 0:
boundingBox = IPoint(0,0);
return;
case 1:
v1 = G.firstNode();
gridLayout.x(v1) = gridLayout.y(v1) = 0;
boundingBox = IPoint(0,0);
return;
case 2:
v1 = G.firstNode();
v2 = G.lastNode ();
gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
gridLayout.x(v2) = 1;
boundingBox = IPoint(1,0);
return;
}
}
// we make a copy of G since we use planar biconnected augmentation
GraphCopySimple GC(G);
if(fixEmbedding) {
// determine adjacency entry on external face of GC (if required)
if(adjExternal != 0) {
edge eG = adjExternal->theEdge();
edge eGC = GC.copy(eG);
adjExternal = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget();
}
PlanarAugmentationFix augmenter;
augmenter.call(GC);
} else {
adjExternal = 0;
// augment graph planar biconnected
m_augmenter.get().call(GC);
// embed augmented graph
m_embedder.get().call(GC,adjExternal);
}
// compute shelling order with shelling order module
m_computeOrder.get().baseRatio(m_baseRatio);
ShellingOrder order;
m_computeOrder.get().callLeftmost(GC,order,adjExternal);
// compute grid coordinates for GC
NodeArray<int> x(GC), y(GC);
computeCoordinates(GC,order,x,y);
boundingBox.m_x = x[order(1,order.len(1))];
boundingBox.m_y = 0;
node v;
forall_nodes(v,GC)
if(y[v] > boundingBox.m_y) boundingBox.m_y = y[v];
// copy coordinates from GC to G
forall_nodes(v,G) {
node vCopy = GC.copy(v);
gridLayout.x(v) = x[vCopy];
gridLayout.y(v) = y[vCopy];
}
示例12: schnyderEmbedding
void SchnyderLayout::schnyderEmbedding(
GraphCopy& GC,
GridLayout &gridLayout,
adjEntry adjExternal)
{
NodeArray<int> &xcoord = gridLayout.x();
NodeArray<int> &ycoord = gridLayout.y();
node v;
List<node> L; // (un)contraction order
GraphCopy T = GraphCopy(GC); // the realizer tree (reverse direction of edges!!!)
EdgeArray<int> rValues(T); // the realizer values
// choose outer face a,b,c
adjEntry adja;
if (adjExternal != 0) {
edge eG = adjExternal->theEdge();
edge eGC = GC.copy(eG);
adja = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget();
}
else {
adja = GC.firstEdge()->adjSource();
}
adjEntry adjb = adja->faceCyclePred();
adjEntry adjc = adjb->faceCyclePred();
node a = adja->theNode();
node b = adjb->theNode();
node c = adjc->theNode();
node a_in_T = T.copy(GC.original(a));
node b_in_T = T.copy(GC.original(b));
node c_in_T = T.copy(GC.original(c));
contract(GC, a, b, c, L);
realizer(GC, L, a, b, c, rValues, T);
NodeArray<int> t1(T);
NodeArray<int> t2(T);
NodeArray<int> val(T, 1);
NodeArray<int> P1(T);
NodeArray<int> P3(T);
NodeArray<int> v1(T);
NodeArray<int> v2(T);
subtreeSizes(rValues, 1, a_in_T, t1);
subtreeSizes(rValues, 2, b_in_T, t2);
prefixSum(rValues, 1, a_in_T, val, P1);
prefixSum(rValues, 3, c_in_T, val, P3);
// now Pi = depth of all nodes in Tree T(i) (depth[root] = 1)
prefixSum(rValues, 2, b_in_T, t1, v1);
// special treatment for a
v1[a_in_T] = t1[a_in_T];
/*
* v1[v] now is the sum of the
* "count of nodes in t1" minus the "subtree size for node x"
* for every node x on a path from b to v in t2
*/
prefixSum(rValues, 3, c_in_T, t1, val);
// special treatment for a
val[a_in_T] = t1[a_in_T];
/*
* val[v] now is the sum of the
* "count of nodes in t1" minus the "subtree size for node x"
* for every node x on a path from c to v in t3
*/
// r1[v]=v1[v]+val[v]-t1[v] is the number of nodes in region 1 from v
forall_nodes(v, T) {
// calc v1'
v1[v] += val[v] - t1[v] - P3[v];
}
示例13: doCall
void FPPLayout::doCall(
const Graph &G,
adjEntry adjExternal,
GridLayout &gridLayout,
IPoint &boundingBox,
bool fixEmbedding)
{
// check for double edges & self loops
OGDF_ASSERT(isSimple(G));
// handle special case of graphs with less than 3 nodes
if (G.numberOfNodes() < 3) {
node v1, v2;
switch (G.numberOfNodes()) {
case 0:
boundingBox = IPoint(0, 0);
return;
case 1:
v1 = G.firstNode();
gridLayout.x(v1) = gridLayout.y(v1) = 0;
boundingBox = IPoint(0, 0);
return;
case 2:
v1 = G.firstNode();
v2 = G.lastNode();
gridLayout.x(v1) = gridLayout.y(v1) = gridLayout.y(v2) = 0;
gridLayout.x(v2) = 1;
boundingBox = IPoint(1, 0);
return;
}
}
// make a copy for triangulation
GraphCopy GC(G);
// embed
if (!fixEmbedding) {
if (planarEmbed(GC) == false) {
OGDF_THROW_PARAM(PreconditionViolatedException, pvcPlanar);
}
}
triangulate(GC);
// get edges for outer face (triangle)
adjEntry e_12;
if (adjExternal != 0) {
edge eG = adjExternal->theEdge();
edge eGC = GC.copy(eG);
e_12 = (adjExternal == eG->adjSource()) ? eGC->adjSource() : eGC->adjTarget();
}
else {
e_12 = GC.firstEdge()->adjSource();
}
adjEntry e_2n = e_12->faceCycleSucc();
NodeArray<int> num(GC);
NodeArray<adjEntry> e_wp(GC); // List of predecessors on circle C_k
NodeArray<adjEntry> e_wq(GC); // List of successors on circle C_k
computeOrder(GC, num , e_wp, e_wq, e_12, e_2n, e_2n->faceCycleSucc());
computeCoordinates(GC, boundingBox, gridLayout, num, e_wp, e_wq);
}
示例14: writeGML
void PlanRep::writeGML(ostream &os, const OrthoRep &OR, const GridLayout &drawing)
{
const Graph &G = *this;
NodeArray<int> id(*this);
int nextId = 0;
os.setf(ios::showpoint);
os.precision(10);
os << "Creator \"ogdf::GraphAttributes::writeGML\"\n";
os << "graph [\n";
os << " directed 1\n";
for(node v : G.nodes) {
os << " node [\n";
os << " id " << (id[v] = nextId++) << "\n";
os << " label \"" << v->index() << "\"\n";
os << " graphics [\n";
os << " x " << ((double) drawing.x(v)) << "\n";
os << " y " << ((double) drawing.y(v)) << "\n";
os << " w " << 3.0 << "\n";
os << " h " << 3.0 << "\n";
os << " type \"rectangle\"\n";
os << " width 1.0\n";
if (typeOf(v) == Graph::generalizationMerger) {
os << " type \"oval\"\n";
os << " fill \"#0000A0\"\n";
}
else if (typeOf(v) == Graph::generalizationExpander) {
os << " type \"oval\"\n";
os << " fill \"#00FF00\"\n";
}
else if (typeOf(v) == Graph::highDegreeExpander ||
typeOf(v) == Graph::lowDegreeExpander)
os << " fill \"#FFFF00\"\n";
else if (typeOf(v) == Graph::dummy)
os << " type \"oval\"\n";
else if (v->degree() > 4)
os << " fill \"#FFFF00\"\n";
else
os << " fill \"#000000\"\n";
os << " ]\n"; // graphics
os << " ]\n"; // node
}
for (node v : nodes)
{
if (expandAdj(v) != nullptr && (typeOf(v) == Graph::highDegreeExpander ||
typeOf(v) == Graph::lowDegreeExpander))
{
node vOrig = original(v);
const OrthoRep::VertexInfoUML &vi = *OR.cageInfo(v);
node ll = vi.m_corner[odNorth]->theNode();
node ur = vi.m_corner[odSouth]->theNode();
os << " node [\n";
os << " id " << nextId++ << "\n";
if (m_pGraphAttributes->attributes() & GraphAttributes::nodeLabel) {
os << " label \"" << m_pGraphAttributes->label(vOrig) << "\"\n";
}
os << " graphics [\n";
os << " x " << 0.5 * (drawing.x(ur) + drawing.x(ll)) << "\n";
os << " y " << 0.5 * (drawing.y(ur) + drawing.y(ll)) << "\n";
os << " w " << widthOrig(vOrig) << "\n";
os << " h " << heightOrig(vOrig) << "\n";
os << " type \"rectangle\"\n";
os << " width 1.0\n";
os << " fill \"#FFFF00\"\n";
os << " ]\n"; // graphics
os << " ]\n"; // node
}
}
for(edge e : G.edges)
{
os << " edge [\n";
os << " source " << id[e->source()] << "\n";
os << " target " << id[e->target()] << "\n";
os << " generalization " << typeOf(e) << "\n";
os << " graphics [\n";
os << " type \"line\"\n";
if (typeOf(e) == Graph::generalization)
{
//.........这里部分代码省略.........