I am working to draw a flow chart with Cytoscape.js framework. I have n-number of nodes and edges. One node can have multiple children. The output should appear like a flow chart with connections.
Initially, I kept my container size as static. Based on node count increase, i am increasing the height of the container. And currently, few of my nodes are crossing the border of the container. So need a solution to avoid that problem. I am following breadthfirst layout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<title>Cytoscape - Sample Data</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.2.0/cytoscape.min.js"></script>
<style>
#cy {
width: 100%;
height: 600px;
/* position: absolute; */
border: 1px solid black;
}
</style>
</head>
<body>
<div id="cy">
</div>
<script>
var elements = [
{data:{id:"A", label:"A", shape: "diamond"}},
{data:{id:"B", label:"B", shape: "diamond"}},
{data:{id:"C", label:"C", shape: "diamond"}},
{data:{id:"D", label:"D", shape: "diamond"}},
{data:{id:"E", label:"E", shape: "diamond"}},
{data:{id:"F", label:"F", shape: "diamond"}},
{data:{id:"G", label:"G", shape: "diamond"}},
{data:{id:"H", label:"H", shape: "diamond"}},
{data:{id:"I", label:"I", shape: "diamond"}},
{data:{id:"J", label:"J", shape: "diamond"}},
{data:{id:"K", label:"K", shape: "diamond"}},
{data:{id:"L", label:"L", shape: "diamond"}},
{data: {source: "A", target: "B"}},
{data: {source: "B", target: "C"}},
{data: {source: "C", target: "D"}},
{data: {source: "D", target: "E"}},
{data: {source: "D", target: "F"}},
{data: {source: "D", target: "G"}},
{data: {source: "D", target: "H"}},
{data: {source: "D", target: "I"}},
{data: {source: "G", target: "J"}},
{data: {source: "J", target: "K"}},
{data: {source: "D", target: "L"}},
];
var cy = cytoscape(
{
container: document.getElementById("cy"),
elements: elements,
style: [
{
selector: "node",
style: {
"label": "data(label)",
"shape": "data(shape)",
'text-valign': 'center',
'text-halign': 'center',
"font-size": "25px",
"text-wrap": "wrap",
"color": "#000",
"width": "100px",
"height": "60px"
}
},
{
selector: "edge",
style: {
'width': "2px",
"height": "50px",
'line-color': '#000',
'target-arrow-shape': 'triangle-backcurve',
'target-arrow-color': '#000',
"curve-style": "bezier"
}
}
],
layout: {
name: 'breadthfirst',
directed: true,
padding: 10,
spacingFactor: 1.5,
fit: true,
avoidOverlap: true,
},
zoomingEnabled: false
});
function adjustContainerHeight(){
var maxY = 0;
var minY = Infinity;
cy.nodes().forEach(function(node) {
var nodePosition = node.position();
var nodeY = nodePosition.y;
maxY = Math.max(maxY, nodeY);
minY = Math.min(minY, nodeY);
});
var newHeight = maxY - minY + 35;
document.getElementById("cy").style.height = newHeight + "px";
};
adjustContainerHeight();
cy.layout({name: 'breadthfirst', directed: true, padding: 10, spacingFactor: 1.5, fit: true, avoidOverlap: true, orientation: "vertical"}).run();
cy.on("add", "node", function(){
cy.layout({name: 'breadthfirst', directed: true, padding: 10, spacingFactor: 1.5, fit: true, avoidOverlap: true, orientation: "vertical"}).run();
adjustContainerHeight();
});
</script>
</body>
</html>