CrossingsMatrix::CrossingsMatrix(const HierarchyLevels &levels) { int max_len = 0; for (int i = 0; i < levels.size(); i++) { int len = levels[i].size(); if (len > max_len) max_len = len; } map.init(max_len); matrix.init(0, max_len - 1, 0, max_len - 1); m_bigM = 10000; }
void FastSimpleHierarchyLayout::doCall(const HierarchyLevels &levels, GraphCopyAttributes &AGC) { const Hierarchy &H = levels.hierarchy(); const GraphCopy &GC = H; node v; NodeArray<node> align(GC); NodeArray<node> root(GC); #ifdef DEBUG_OUTPUT for(int i = 0; i <= levels.high(); ++i) { cout << "level " << i << ": "; const Level &L = levels[i]; for(int j = 0; j <= L.high(); ++j) cout << L[j] << " "; cout << endl; } #endif if (m_balanced) { // the x positions; x = -infinity <=> x is undefined NodeArray<double> x[4]; NodeArray<double> blockWidth[4]; NodeArray<node> root[4]; double width[4]; double min[4]; double max[4]; int minWidthLayout = 0; // initializing for (int i = 0; i < 4; i++) { min[i] = numeric_limits<double>::max(); max[i] = -numeric_limits<double>::max(); } // calc the layout for down/up and leftToRight/rightToLeft for (int downward = 0; downward <= 1; downward++) { NodeArray<NodeArray<bool> > type1Conflicts(GC); markType1Conflicts(levels, downward == 0, type1Conflicts); for (int leftToRight = 0; leftToRight <= 1; leftToRight++) { int k = 2 * downward + leftToRight; root[k].init(GC); verticalAlignment(levels, root[k], align, type1Conflicts, downward == 0, leftToRight == 0); computeBlockWidths(GC, AGC, root[k], blockWidth[k]); horizontalCompactation(align, levels, root[k], blockWidth[k], x[k], leftToRight == 0, downward == 0); } } /* * - calc min/max x coordinate for each layout * - calc x-width for each layout * - find the layout with the minimal width */ for (int i = 0; i < 4; i++) { forall_nodes(v, GC) { double bw = 0.5 * blockWidth[i][root[i][v]]; double xp = x[i][v] - bw; if (min[i] > xp) { min[i] = xp; } xp = x[i][v] + bw; if (max[i] < xp) { max[i] = xp; } } width[i] = max[i] - min[i]; if (width[minWidthLayout] > width[i]) { minWidthLayout = i; } } /* * shift the layout so that they align with the minimum width layout * - leftToRight: align minimum coordinate * - rightToLeft: align maximum coordinate */ double shift[4]; for (int i = 0; i < 4; i++) { if (i % 2 == 0) { // for leftToRight layouts shift[i] = min[minWidthLayout] - min[i]; } else { // for rightToLeft layouts shift[i] = max[minWidthLayout] - max[i]; } } /* * shift the layouts and use the * median average coordinate for each node */ Array<double> sorting(4); forall_nodes(v, GC) { for (int i = 0; i < 4; i++) { sorting[i] = x[i][v] + shift[i]; } sorting.quicksort(); AGC.x(v) = 0.5 * (sorting[1] + sorting[2]); } } else {
void GreedyInsertHeuristic::init(const HierarchyLevels &levels) { m_weight.init(levels.hierarchy()); m_crossingMatrix = new CrossingsMatrix(levels); }