【问题标题】:SVG thick curved paths not behaving as expectedSVG 粗曲线路径未按预期运行
【发布时间】:2016-03-20 04:17:59
【问题描述】:

我正在 D3 中创建一个桑基图,使用路径作为粗壮的连接器来指示流程。然而,我发现那些比它们更长的路径开始表现得很奇怪。你可以在这里看到一个例子,我将路径分成几个部分:

蓝色和橙色重叠,因为蓝色(以及它后面的灰色)的弯曲方式与较细的路径不同,它们有一种“扭结”。

所有的线曲线都很好,除了这些大的。我用 SVG 做了一个简单的例子:

<SVG height=800 width=800>
<g transform="translate(40,400)">
    <Path class="link1" d="M29,-129C104.5,-129 104.5,-202.125 180,-202.125" />
    <Path class="link2" d="M29,-129C104.5,-129 104.5,-202.125 180,-202.125" />
    <Path class="link3" d="M29,-129C104.5,-129 104.5,-202.125 180,-202.125" />
    <Path class="normal" d="M29,-129 L104.5,-129" />
    <Path class="normal" d="M104.5,-202 L180,-202.125" />
</g>

你可以在这里看到它:

https://jsfiddle.net/hanvyj/t91pbp4w/

我在谷歌上找不到任何东西,我希望有人会遇到这个问题并知道解决方法,或者有更多的 SVG 经验并且知道不会这样做的 'SVG:Path' 的好替代品?

【问题讨论】:

  • 再看看你的小提琴,它需要内容。
  • 糟糕,没有保存。现在更新了。谢谢。
  • 而不是制作不同的路径笔画;可以使用填充属性制作一条路径吗?
  • 这是一个与stroke-linecap 相关的问题,您必须重新绘制曲线才能修复它
  • 这与linecap无关。这只是简单的几何图形。

标签: d3.js svg sankey-diagram


【解决方案1】:

SVG 笔画宽度表现不同

问题示例:

<svg width="800px" height="600px" viewBox="0 0 100 100">
  <path stroke-width="15" stroke="rgba(0,0,0,0.5)" fill="none" d="m0,40 c 20,0 20,-10 40,-10" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,24 c 5,0 5,-5 10,-5" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,27 c 5,0 5,-2 10,-2" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,30 10,0" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,33 c 5,0 5,2 10,2" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,36 c 5,0 5,5 10,5" />

  <path stroke-width="3" stroke="rgba(255, 200, 50, 0.7)" fill="none" d="m0,46 c 20,0 20,-10 40,-10" />
</svg>

解决方案:

<svg width="800px" height="600px" viewBox="0 0 100 100">
  <path stroke-width="15" stroke="rgba(0,0,0,0.5)" fill="none" d="m0,40 c 20,0 20,-10 40,-10" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,24 c 5,0 5,-5 10,-5" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,27 c 5,0 5,-2 10,-2" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,30 10,0" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,33 c 5,0 5,2 10,2" />
  <path stroke-width="3" stroke="rgba(0,0,0,0.5)" fill="none" D="m40,36 c 5,0 5,5 10,5" />

  <path stroke-width="3" stroke="rgba(255, 200, 50, 0.7)" fill="none" d="m0,46 c 22,0 22,-10 40,-10" />
</svg>

等等你对路径做了什么?

让我们看看那些橙色路径上的 d 属性。
问题路径:m0,46 c 20,0 20,-10 40,-10
解决路径:m0,46 c 22,0 22,-10 40,-10

我只是将C curve command 调整了 2 个单位。

我想要差异的图片...哦,好吧:

【讨论】:

    【解决方案2】:

    虽然 Persijn 的解决方案很好,但它并不十分完美 - 它使“覆盖”较细线的曲线与下面的扭结线相匹配。理想情况下,我想完全消除扭结。

    正如 maioman 所建议的,对于这种形状,最好我定义完整路径并使用填充,而不是描边宽度。这给了我更多的控制权。笔划宽度在整个线条长度上保持厚度不变,这不是我真正想要的,正如人们指出的那样,当宽度大于长度时,这是不可能的。

    我希望 x 轴的高度沿其长度保持不变。我创建了一个函数来生成我真正想要的形状,以防万一有人遇到这种情况:

    var linkPath = function(sourceTop,sourceBottom,
                    targetTop,targetBottom) {
        //middle
        var MiddleDelta =(targetTop.x - sourceTop.x)/2;
        console.log(MiddleDelta);
        //start in the top left
        var d = "M";
        //top left corner
        d += sourceTop.x + ", " + sourceTop.y + " ";
        d += "C" + (sourceTop.x+MiddleDelta) + "," + sourceTop.y + " ";
        d += (targetTop.x - MiddleDelta) + "," + targetTop.y + " ";
        //top right corner
        d += "" + targetTop.x + "," + targetTop.y + " ";
        //bottom right corner
        d += "L" + targetBottom.x + "," + targetBottom.y + " ";
        d += "C" + (targetBottom.x-MiddleDelta) + "," + targetBottom.y + " ";
        d += (sourceBottom.x + MiddleDelta) + "," + sourceBottom.y + " ";
        //bottom left corner
        d += "" + sourceBottom.x + "," + sourceBottom.y + " ";
        return d;
    };
    

    它产生这个:

    与此相反:

    【讨论】:

      【解决方案3】:

      你的线太粗了,当它沿着贝塞尔曲线时,它超出了线另一端的起点。

      几乎所有非直线贝塞尔曲线都会在开始自相交之前的粗度受到限制。你刚刚超出了这个限制。如果起点和终点相距较远,您将能够变得更厚。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-10
        • 1970-01-01
        • 2021-07-21
        • 1970-01-01
        • 1970-01-01
        • 2011-09-17
        • 1970-01-01
        • 2017-04-10
        相关资源
        最近更新 更多