Skip to content

Commit

Permalink
Fix broken positionX shift with multiple classes
Browse files Browse the repository at this point in the history
  • Loading branch information
cpettitt committed Nov 2, 2014
1 parent 5ef0dcd commit ad2cf7a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/position/bk.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
// We use local variables for these parameters instead of manipulating the
// graph because it becomes more verbose to access them in a chained manner.
var shift = {},
shiftNeighbor = {},
sink = {},
xs = {},
pred = {},
Expand All @@ -223,7 +224,7 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {

_.each(g.nodes(), function(v) {
if (root[v] === v) {
placeBlock(g, layering, sepFn, root, align, shift, sink, pred, xs, v);
placeBlock(g, layering, sepFn, root, align, shift, shiftNeighbor, sink, pred, xs, v);
}
});

Expand All @@ -234,14 +235,20 @@ function horizontalCompaction(g, layering, root, align, reverseSep) {
// http://www.inf.uni-konstanz.de/~brandes/publications/ for details.
if (v === root[v] && shift[sink[root[v]]] < Number.POSITIVE_INFINITY) {
xs[v] += shift[sink[root[v]]];

// Cascade shifts as necessary
var w = shiftNeighbor[sink[root[v]]];
if (w && shift[w] !== Number.POSITIVE_INFINITY) {
xs[v] += shift[w];
}
}
});
});

return xs;
}

function placeBlock(g, layering, sepFn, root, align, shift, sink, pred, xs, v) {
function placeBlock(g, layering, sepFn, root, align, shift, shiftNeighbor, sink, pred, xs, v) {
if (_.has(xs, v)) return;
xs[v] = 0;

Expand All @@ -250,14 +257,15 @@ function placeBlock(g, layering, sepFn, root, align, shift, sink, pred, xs, v) {
do {
if (pred[w]) {
u = root[pred[w]];
placeBlock(g, layering, sepFn, root, align, shift, sink, pred, xs, u);
placeBlock(g, layering, sepFn, root, align, shift, shiftNeighbor, sink, pred, xs, u);
if (sink[v] === v) {
sink[v] = sink[u];
}

var delta = sepFn(g, w, pred[w]);
if (sink[v] !== sink[u]) {
shift[sink[u]] = Math.min(shift[sink[u]], xs[v] - xs[u] - delta);
shiftNeighbor[sink[u]] = sink[v];
} else {
xs[v] = Math.max(xs[v], xs[u] + delta);
}
Expand Down
23 changes: 23 additions & 0 deletions test/position/bk-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,29 @@ describe("position/bk", function() {
expect(xs.d).to.equal(60 / 2 + 75 + 150 / 2);
});

it("cascades class shift", function() {
var root = { a: "a", b: "b", c: "c", d: "d", e: "b", f: "f", g: "d" },
align = { a: "a", b: "e", c: "c", d: "g", e: "b", f: "f", g: "d" };
g.graph().nodesep = 75;
g.setNode("a", { rank: 0, order: 0, width: 50 });
g.setNode("b", { rank: 0, order: 1, width: 50 });
g.setNode("c", { rank: 1, order: 0, width: 50 });
g.setNode("d", { rank: 1, order: 1, width: 50 });
g.setNode("e", { rank: 1, order: 2, width: 50 });
g.setNode("f", { rank: 2, order: 0, width: 50 });
g.setNode("g", { rank: 2, order: 1, width: 50 });

var xs = horizontalCompaction(g, buildLayerMatrix(g), root, align);

// Use f as 0, everything is relative to it
expect(xs.a).to.equal(xs.b - 50 / 2 - 75 - 50 / 2);
expect(xs.b).to.equal(xs.e);
expect(xs.c).to.equal(xs.f);
expect(xs.d).to.equal(xs.c + 50 / 2 + 75 + 50 / 2);
expect(xs.e).to.equal(xs.d + 50 / 2 + 75 + 50 / 2);
expect(xs.g).to.equal(xs.f + 50 / 2 + 75 + 50 / 2);
});

it("handles labelpos = l", function() {
var root = { a: "a", b: "b", c: "c" },
align = { a: "a", b: "b", c: "c" };
Expand Down

0 comments on commit ad2cf7a

Please sign in to comment.