【问题标题】:Formula for <rect>dynamic spacing in svgsvg中<rect>动态间距的公式
【发布时间】:2026-02-01 08:25:01
【问题描述】:

如何根据编号制作动态间距。返回的数据?我希望如果只返回一个数据,它位于中间。如果返回两个数据,它将调整,依此类推。

   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>

 

【问题讨论】:

  • y2="${y}" 不工作?
  • @dalelandry 不工作。如果只返回一个数据,它位于左上角,而不是中间。
  • 你可以看看这个答案:*.com/questions/68781957/…

标签: javascript svg formula


【解决方案1】:

这很简单。您只需计算第一个矩形的顶部,然后将 i 乘以从一个项目的顶部到下一个项目的顶部的距离。

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>

【讨论】:

  • 这是一个附加问题。如何动态地将文本放在行的中间?
  • 你能解释一下“动态”是什么意思吗?您的意思是在创建 SVG 之后?
  • 是的,我也会在每行的中心显示文本。可以是任何一种方式,在创建 svg 之后或在创建 svg 期间,只要文本显示。我发现制定正确的公式有点困难。
  • 对于水平居中,text-anchor="middle" 是正确的方法。对于垂直居中alignment-baseline="middle" 有效。但是,根据您的文字,它可能看起来很有趣。例如,如果你的下一个不包含下降器,它可能看起来不对,就像这里。另一种方法是使用带有em 值的dy 将文本向下轻推一点。例如。 dy="0.35em"。您可能会发现您更喜欢这种方法。
  • 要在创建文本后更改文本,首先以某种方式选择您的&lt;text&gt; 元素。例如。通过 ID:var elem = getElementById("myTextId")。然后您可以使用elem.textContent = "New text content";更改显示的文本。