How to make dynamic spacing base on the no. of returned data? I want that if only one data is returned, it is positioned in middle. If two data returned it will adjust, and so on.
var prev = {
"Prev": [{
"type": "Prev1",
},
{
"type": "Prev2",
},
{
"type": "Prev3",
},
]
};
var draw = document.getElementById('drawing');
prev.Prev.forEach((p, i, arr) => {
let x = 55;
let y = 250/arr.length*i+50;
draw.innerHTML += `<g transform="translate(${x} ${y})">
<rect x="-50" y="-20" width="100" height="40" rx="10" />
<text dominant-baseline="middle" text-anchor="middle" width="100">${p.type}</text>
<line x1="50" y1="0" x2="100" y2="${250/arr.length-y+50}" />
</g>`;
});
draw.innerHTML += `<g>
<rect x="150" y="110" width="100" height="40" rx="10" />
<text x="200" y="130" dominant-baseline="middle" text-anchor="middle" width="100">BASE</text>
</g>`;
line, rect {stroke-width: 1; stroke: navy; fill: none;}
text {fill: navy;}
<svg id="drawing" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
</svg>
It's pretty simple. You just have to calculate the top of the first rect and then add on i
times the distance from the top of one item to the top of the next.
var prev = {
"Prev": [{
"type": "Prev1",
},
{
"type": "Prev2",
},
{
"type": "Prev3",
}
]
};
var draw = document.getElementById('drawing');
var RECT_HEIGHT = 40;
var RECT_SPACING = 50;
var SVG_HEIGHT = 300;
prev.Prev.forEach((p, i, arr) => {
// number of rects/graph items
let num = arr.length;
// total height of all <num>
let totalHeight = num * RECT_HEIGHT + (num - 1) * RECT_SPACING;
let x = 55;
// final position = position of first rect + i * distance_between_rects
let y = (SVG_HEIGHT - totalHeight) / 2 // top of first rect
+ i * (RECT_HEIGHT + RECT_SPACING); // i * distance_between_rects
draw.innerHTML += `<g transform="translate(${x} ${y})">
<rect x="-50" y="0" width="100" height="40" rx="10" />
<text y="20" dominant-baseline="middle" text-anchor="middle"
width="100">${p.type}</text>
<line x1="50" y1="20" x2="100" y2="${SVG_HEIGHT / 2 - y}" />
</g>`;
});
/*
draw.innerHTML += `<g>
<rect x="150" y="110" width="100" height="40" rx="10" />
<text x="200" y="130" dominant-baseline="middle" text-anchor="middle" width="100">BASE</text>
</g>`;
*/
svg {
background: linen;
}
<svg id="drawing" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg">
<style>
line, rect {stroke-width: 1; stroke: navy; fill: none;}
text {fill: navy;}
</style>
</svg>