d2 icon indicating copy to clipboard operation
d2 copied to clipboard

dagre: container escape

Open ejulio-ts opened this issue 2 years ago • 4 comments

state machine: {
	0
	1: {
		red.shape:step
		blu.shape:step
	}
	2: {
		red.shape:step
		blu.shape:step
	}
	3: {
		red.shape:step
		blu.shape:step
	}
	4: {
		red.shape:step
		blu.shape:step
	}
	5: {
		red.shape:step
		blu.shape:step
	}
	6: {
		red.shape:step
		blu.shape:step
	}
	7: {
		red.shape:step
		blu.shape:step
	}
	8: {
		red.shape:step
		blu.shape:step
	}
	9: {
		red.shape:step
		blu.shape:step
	}
	10: {
		red.shape:step
		blu.shape:step
	}
	11: {
		red.shape:step
		blu.shape:step
	}
	12: {
		red.shape:step
		blu.shape:step
	}
	13

	1.red -> 5
	1.blu -> 0
	2.red -> 6
	2.blu -> 0
	3.red -> 7
	3.blu -> 0
	4.red -> 8
	4.blu -> 0
	5.red -> 9
	5.blu -> 2
	6.red -> 10
	6.blu -> 3
	7.red -> 11
	7.blu -> 4
	8.red -> 12
	8.blu -> 1
	9.red -> 13
	9.blu -> 6
	10.red -> 13
	10.blu -> 7
	11.red -> 13
	11.blu -> 8
	12.red -> 13
	12.blu -> 5
}

Result image

Note how 8.blu was rendered outside the container, between 10 and 7

ejulio-ts avatar Dec 15 '22 19:12 ejulio-ts

This appears to just be a rare bug with dagre's layout. Not sure how much we can do about this.

Without any of our code in the mix, running dagre.layout(g) with the following setup results in the eight_blue node with a n x value much further to the left despite its parent's dimensions and position.

var g = new dagre.graphlib.Graph({ compound: true, multigraph: true });
g.setDefaultNodeLabel(function () {
 return {};
});
g.setDefaultEdgeLabel(function () {
 return {};
});
g.setGraph({
 ranksep: 100,
 edgesep: 40,
 nodesep: 60,
 rankdir: "TB",
});
g.setNode(`container`, { id: `container` });
g.setNode(`zero`, { id: `zero` });
g.setParent(`zero`, `container`);
g.setNode(`one`, { id: `one` });
g.setParent(`one`, `container`);
g.setNode(`one_red`, { id: `one_red` });
g.setParent(`one_red`, `one`);
g.setNode(`one_blue`, { id: `one_blue` });
g.setParent(`one_blue`, `one`);
g.setNode(`two`, { id: `two` });
g.setParent(`two`, `container`);
g.setNode(`two_red`, { id: `two_red` });
g.setParent(`two_red`, `two`);
g.setNode(`two_blue`, { id: `two_blue` });
g.setParent(`two_blue`, `two`);
g.setNode(`three`, { id: `three` });
g.setParent(`three`, `container`);
g.setNode(`three_red`, { id: `three_red` });
g.setParent(`three_red`, `three`);
g.setNode(`three_blue`, { id: `three_blue` });
g.setParent(`three_blue`, `three`);
g.setNode(`four`, { id: `four` });
g.setParent(`four`, `container`);
g.setNode(`four_red`, { id: `four_red` });
g.setParent(`four_red`, `four`);
g.setNode(`four_blue`, { id: `four_blue` });
g.setParent(`four_blue`, `four`);
g.setNode(`five`, { id: `five` });
g.setParent(`five`, `container`);
g.setNode(`five_red`, { id: `five_red` });
g.setParent(`five_red`, `five`);
g.setNode(`five_blue`, { id: `five_blue` });
g.setParent(`five_blue`, `five`);
g.setNode(`six`, { id: `six` });
g.setParent(`six`, `container`);
g.setNode(`six_red`, { id: `six_red` });
g.setParent(`six_red`, `six`);
g.setNode(`six_blue`, { id: `six_blue` });
g.setParent(`six_blue`, `six`);
g.setNode(`seven`, { id: `seven` });
g.setParent(`seven`, `container`);
g.setNode(`seven_red`, { id: `seven_red` });
g.setParent(`seven_red`, `seven`);
g.setNode(`seven_blue`, { id: `seven_blue` });
g.setParent(`seven_blue`, `seven`);
g.setNode(`eight`, { id: `eight` });
g.setParent(`eight`, `container`);
g.setNode(`eight_red`, { id: `eight_red` });
g.setParent(`eight_red`, `eight`);
g.setNode(`eight_blue`, { id: `eight_blue` });
g.setParent(`eight_blue`, `eight`);
g.setNode(`nine`, { id: `nine` });
g.setParent(`nine`, `container`);
g.setNode(`nine_red`, { id: `nine_red` });
g.setParent(`nine_red`, `nine`);
g.setNode(`nine_blue`, { id: `nine_blue` });
g.setParent(`nine_blue`, `nine`);
g.setNode(`ten`, { id: `ten` });
g.setParent(`ten`, `container`);
g.setNode(`ten_red`, { id: `ten_red` });
g.setParent(`ten_red`, `ten`);
g.setNode(`ten_blue`, { id: `ten_blue` });
g.setParent(`ten_blue`, `ten`);
g.setNode(`eleven`, { id: `eleven` });
g.setParent(`eleven`, `container`);
g.setNode(`eleven_red`, { id: `eleven_red` });
g.setParent(`eleven_red`, `eleven`);
g.setNode(`eleven_blue`, { id: `eleven_blue` });
g.setParent(`eleven_blue`, `eleven`);
g.setNode(`twelve`, { id: `twelve` });
g.setParent(`twelve`, `container`);
g.setNode(`twelve_red`, { id: `twelve_red` });
g.setParent(`twelve_red`, `twelve`);
g.setNode(`twelve_blue`, { id: `twelve_blue` });
g.setParent(`twelve_blue`, `twelve`);
g.setNode(`thirteen`, { id: `thirteen` });
g.setParent(`thirteen`, `container`);
g.setEdge({v:`one_red`, w:`five_red` });
g.setEdge({v:`one_blue`, w:`zero` });
g.setEdge({v:`two_red`, w:`six_red` });
g.setEdge({v:`two_blue`, w:`zero` });
g.setEdge({v:`three_red`, w:`seven_red` });
g.setEdge({v:`three_blue`, w:`zero` });
g.setEdge({v:`four_red`, w:`eight_red` });
g.setEdge({v:`four_blue`, w:`zero` });
g.setEdge({v:`five_red`, w:`nine_red` });
g.setEdge({v:`five_blue`, w:`two_red` });
g.setEdge({v:`six_red`, w:`ten_red` });
g.setEdge({v:`six_blue`, w:`three_red` });
g.setEdge({v:`seven_red`, w:`eleven_red` });
g.setEdge({v:`seven_blue`, w:`four_red` });
g.setEdge({v:`eight_red`, w:`twelve_red` });
g.setEdge({v:`eight_blue`, w:`one_red` });
g.setEdge({v:`nine_red`, w:`thirteen` });
g.setEdge({v:`nine_blue`, w:`six_red` });
g.setEdge({v:`ten_red`, w:`thirteen` });
g.setEdge({v:`ten_blue`, w:`seven_red` });
g.setEdge({v:`eleven_red`, w:`thirteen` });
g.setEdge({v:`eleven_blue`, w:`eight_red` });
g.setEdge({v:`twelve_red`, w:`thirteen` });
g.setEdge({v:`twelve_blue`, w:`five_red` });

Result g._nodes:

{
    "container": {
        "id": "container",
        "x": 1295,
        "y": 375,
        "width": 2590,
        "height": 750
    },
    "zero": {
        "id": "zero",
        "x": 180,
        "y": 400
    },
    "one": {
        "id": "one",
        "x": 135,
        "y": 250,
        "width": 190,
        "height": 100
    },
    "one_red": {
        "id": "one_red",
        "x": 180,
        "y": 250
    },
    "one_blue": {
        "id": "one_blue",
        "x": 120,
        "y": 250
    },
    "two": {
        "id": "two",
        "x": 545,
        "y": 250,
        "width": 190,
        "height": 100
    },
    "two_red": {
        "id": "two_red",
        "x": 590,
        "y": 250
    },
    "two_blue": {
        "id": "two_blue",
        "x": 530,
        "y": 250
    },
    "three": {
        "id": "three",
        "x": 945,
        "y": 250,
        "width": 190,
        "height": 100
    },
    "three_red": {
        "id": "three_red",
        "x": 990,
        "y": 250
    },
    "three_blue": {
        "id": "three_blue",
        "x": 930,
        "y": 250
    },
    "four": {
        "id": "four",
        "x": 1345,
        "y": 250,
        "width": 190,
        "height": 100
    },
    "four_red": {
        "id": "four_red",
        "x": 1390,
        "y": 250
    },
    "four_blue": {
        "id": "four_blue",
        "x": 1330,
        "y": 250
    },
    "five": {
        "id": "five",
        "x": 345,
        "y": 250,
        "width": 130,
        "height": 400
    },
    "five_red": {
        "id": "five_red",
        "x": 360,
        "y": 400
    },
    "five_blue": {
        "id": "five_blue",
        "x": 345,
        "y": 100
    },
    "six": {
        "id": "six",
        "x": 1145,
        "y": 250,
        "width": 130,
        "height": 400
    },
    "six_red": {
        "id": "six_red",
        "x": 1160,
        "y": 400
    },
    "six_blue": {
        "id": "six_blue",
        "x": 1145,
        "y": 100
    },
    "seven": {
        "id": "seven",
        "x": 1975,
        "y": 250,
        "width": 130,
        "height": 400
    },
    "seven_red": {
        "id": "seven_red",
        "x": 1990,
        "y": 400
    },
    "seven_blue": {
        "id": "seven_blue",
        "x": 1960,
        "y": 100
    },
    "eight": {
        "id": "eight",
        "x": 2315,
        "y": 250,
        "width": 130,
        "height": 400
    },
    "eight_red": {
        "id": "eight_red",
        "x": 2330,
        "y": 400
    },
    "eight_blue": {
        "id": "eight_blue",
        "x": 1820,
        "y": 100
    },
    "nine": {
        "id": "nine",
        "x": 745,
        "y": 400,
        "width": 130,
        "height": 400
    },
    "nine_red": {
        "id": "nine_red",
        "x": 760,
        "y": 550
    },
    "nine_blue": {
        "id": "nine_blue",
        "x": 745,
        "y": 250
    },
    "ten": {
        "id": "ten",
        "x": 1545,
        "y": 400,
        "width": 130,
        "height": 400
    },
    "ten_red": {
        "id": "ten_red",
        "x": 1560,
        "y": 550
    },
    "ten_blue": {
        "id": "ten_blue",
        "x": 1545,
        "y": 250
    },
    "eleven": {
        "id": "eleven",
        "x": 2145,
        "y": 400,
        "width": 130,
        "height": 400
    },
    "eleven_red": {
        "id": "eleven_red",
        "x": 2160,
        "y": 550
    },
    "eleven_blue": {
        "id": "eleven_blue",
        "x": 2145,
        "y": 250
    },
    "twelve": {
        "id": "twelve",
        "x": 2485,
        "y": 400,
        "width": 130,
        "height": 400
    },
    "twelve_red": {
        "id": "twelve_red",
        "x": 2500,
        "y": 550
    },
    "twelve_blue": {
        "id": "twelve_blue",
        "x": 2485,
        "y": 250
    },
    "thirteen": {
        "id": "thirteen",
        "x": 1860,
        "y": 700
    }
}

gavin-ts avatar Dec 17 '22 04:12 gavin-ts

good sleuthing, thx @gavin-ts . do you see any pattern for when this arises? wondering if this is something we can catch at the compilation step that dagre can't handle

alixander avatar Dec 17 '22 07:12 alixander

I don't think the compiler should've these layout engine specific checks. Otherwise, dare can get an update and we might still generate the error while it would work as expected

ejulio-ts avatar Dec 17 '22 12:12 ejulio-ts

dagre's not getting an update (hasn't been maintained in years). we inherit our dependencies issues and ppl will think it's our bug.

alixander avatar Dec 17 '22 15:12 alixander