我正在通过SVG制作一个Sankey图,但是突然在一些未知的条件下,其中一个路径显示了一个不应该有任何圆的圆。
我试图从我的SVG中尽可能多地删除,但进一步删除任何内容都会使其不再可复制。
这里你可以看到我的缩小的SVG图像。黑色的路径元素是一个有问题的。我手动标记路径笔划元素应该结束的地方,但不知何故,它显示了一个圆圈,似乎有相同的半径笔划宽度。
<div style="width: 100%; height: 100%;">
<svg width=100% height=500px>
<g class="sankey-layer">
<g class="link-group">
<path d="M107.61971830985915,30C107.61971830985915,74,107.61971830985915,74,107.61971830985915,118" fill="none" stroke="#000000" stroke-opacity="1" stroke-width="200"></path>
<path d="M251.11267605633802,30C251.11267605633802,192,328.943661971831,192,328.943661971831,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="71.74647887323944"></path>
<path d="M478.38028169014075,30C478.38028169014075,192,384.7464788732394,192,384.7464788732394,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="39.859154929577464"></path>
<path d="M542.1549295774647,30C542.1549295774647,192,572.1549295774648,192,572.1549295774648,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="87.69014084507042"></path>
<path d="M344.8169014084507,30C344.8169014084507,192,452.50704225352115,192,452.50704225352115,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="95.66197183098592"></path>
<path d="M143.49295774647888,148C143.49295774647888,251,153.49295774647888,251,153.49295774647888,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="79.71830985915493"></path>
<path d="M409.12773522289996,148C409.12773522289996,251,213.28169014084506,251,213.28169014084506,354" fill="none" stroke="#00bbff35" stroke-opacity="0.5" stroke-width="39.859154929577464"></path>
</g>
</g>
</svg>
</div>
有什么线索吗?这是从哪里来的?我能做什么来避免它?
澄清:
路径是由d3计算的。它不是一个手动创建的图形,我正在寻找一个通用的解决方案的问题,而不是一个解决方案的这个特殊的例子。
3条答案
按热度按时间cbjzeqam1#
我将第一个路径更改为
<path d="M107.62,30L107.62,118" fill="none" stroke="#000000" stroke-opacity="1" stroke-width="200"></path>
。我通过将其加载到Illustrator中来解决这个问题。我不能100%确定问题出在哪里,但也许比我聪明的人会发现。
chy5wohz2#
似乎有一个与浏览器相关的错误,您应该报告。
作为“后期处理”的解决方案,您可以使用我曾经创建的此辅助对象将平坦曲线转换为
L
命令。(基于path data polyfill by Jarek Foksa)已修复edge中的问题。
第一个
同时使用curveto命令
d="M107.6 30 C 107.6 74 107.6 118 107.6 118"
个[x2,y2] = [x3,y3]
d="M107.6 30 C 107.6 118 107.6 118 107.6 118"
[x1,y1] = [x2,y2] = [x3,y3]
nhn9ugyo3#
解决方法
我解决这个问题的第一个方法是为我的链接路径的预期边界(开始和结束)定义一个剪切路径。这样,工件就被简单地剪切了,没有任何问题可见:
这个变通办法实际上效果很好,但感觉太错了。我想要一个“合适”的解决方案。
@herrstrietzel(https://stackoverflow.com/a/72588392/2230045)提出的解决方案在技术上似乎是一个更正确的解决方案,但我不能摆脱它仍然感觉像一个黑客的解决方案。
解决方案
在寻找解决方案时,我偶然发现了这篇博客文章:https://observablehq.com/@enjalot/weird-sankey-links
如果节点之间的距离太近且宽度太大,则默认的d3.sankeyLinkHorizontal会出现故障
虽然博客文章关注的问题看起来略有不同,但我确信这是我正在经历的完全相同的问题。
从某种意义上说,我觉得这里的潜在问题是路径元素的误用。当线条比笔画宽度短时,将填充设置为
none
并增加笔画宽度来绘制线条似乎无法正常工作。这篇博文建议绘制自定义的贝塞尔曲线。这样就不需要stroke属性了,我们可以只使用normal fill。我觉得这是一个合适的解决方案。让我们来看看代码。
在这个问题之前,我并没有真正研究过Sankey图的图形方面。当我试图理解博客文章中提出的解决方案时(我需要将代码更改为垂直工作而不是水平工作),我努力完整地绘制出什么坐标指的是什么。d3文档在这方面并没有真正的帮助。这里是我为自己制作的信息图:
博客文章中的代码使用了一个稍微不同的坐标命名。我对此进行了修改,添加了一些注解,并试图简化它。
它所做的是,它画出了链接的轮廓路径。
它将我的代码简化为:
调整Sankey的垂直绘图
最后,我调整了代码,使其垂直工作,而不是水平工作:
这就产生了这个绝对完美的桑基图:
第一个
我获得了相当多的洞察力与svg和d3的工作与此。我希望该解决方案有助于其他人在未来。