2016-02-26 45 views
0

我想使用D3创建增强的svg-pathes并填充它们。 增强的路径是路径,包含使用不同插值方法的多个部分。看看下面的例子(执行代码见SVG):正确填充由D3创建的增强的svg路径

p1 = [ 
 
    [10,10], 
 
    [10,190], 
 
    [190,190] 
 
]; 
 

 
p2 = [ 
 
    [190,190], 
 
    [50,50], 
 
    [190,20] 
 
]; 
 

 
p3 = [ 
 
    [190,20], 
 
    [190, 10] 
 
]; 
 

 
p4 = [ 
 
    [190,10], 
 
    [100,20], 
 
    [10,10] 
 
]; 
 

 
    var svg = d3.select('svg') 
 
       .attr("width", 200) 
 
       .attr("height", 200) 
 
       .attr("viewBox", "0 0 200 200"); 
 

 
    var line = d3.svg.line().interpolate("linear"); 
 
    var spline = d3.svg.line().interpolate("basis"); 
 
    
 
    svg.append("path") 
 
    .attr("d", function(){ 
 
     return line(p1) + spline(p2) + line(p3) + spline(p4) 
 
    }) 
 
    .attr("fill", "none") 
 
    .attr("stroke-width", 1) 
 
    .attr("stroke", "black");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<svg> 
 
</svg>
如果我现在充满了创建路径(从“无”转变填写为“紫色”为例),我得到的不希望的结果:

<svg viewBox="0 0 200 200" height="190" width="190"> 
 
<path stroke="black" stroke-width="1" fill="purple" d="M10,10L10,190L190,190M190,190L166.66666666666666,166.66666666666666C143.33333333333331,143.33333333333331,96.66666666666666,96.66666666666666,96.66666666666666,68.33333333333333C96.66666666666666,39.99999999999999,143.33333333333331,29.999999999999996,166.66666666666666,24.999999999999996L190,20M190,20L190,10M190,10L174.99999999999997,11.666666666666664C160,13.333333333333332,130,16.666666666666664,99.99999999999999,16.666666666666664C69.99999999999999,16.666666666666664,39.99999999999999,13.333333333333332,24.999999999999996,11.666666666666666L10,10"></path></svg>

形状不被识别为一个形状,因此不能正确地填充。 (顺便说一句:它仅在使用一个样条线和只有一个线性插值部分时才起作用。)解决该问题的一种可能性是删除由D3插入的不一致移动命令。然而,我不能相信,这是唯一的解决方案。必须有一个更简单,更清洁的解决方案。可能我误解了如何使用D3。任何人都可以给我一个线索吗?

编辑: 我希望填充形状看起来像什么:

<svg viewBox="0 0 200 200" height="190" width="190"> 
 
<path stroke="black" stroke-width="1" fill="purple" 
 
d="M10,10L10,190L190,190L166.66666666666666,166.66666666666666C143.33333333333331,143.33333333333331,96.66666666666666,96.66666666666666,96.66666666666666,68.33333333333333C96.66666666666666,39.99999999999999,143.33333333333331,29.999999999999996,166.66666666666666,24.999999999999996L190,20L190,10L174.99999999999997,11.666666666666664C160,13.333333333333332,130,16.666666666666664,99.99999999999999,16.666666666666664C69.99999999999999,16.666666666666664,39.99999999999999,13.333333333333332,24.999999999999996,11.666666666666666L10,10"></path></svg>

+0

你能解释一下正确的,预期的形状填充的意思吗? –

+0

@DamienFayol增加了预期的结果,感谢您的光临。 –

回答

1

你不能只是串联路径在一起。每个人都从一个move to命令(M10,10或类似的东西)开始。这将产生一个“开放”的路径,你不能正确填写。简单的办法,就是直接删除move to命令所有,但第一道:“形状不被识别为一个形状,因此不正确填写”

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <svg> 
 
    </svg> 
 
    <script> 
 
    p1 = [ 
 
     [10, 10], 
 
     [10, 190], 
 
     [190, 190] 
 
    ]; 
 

 
    p2 = [ 
 
     [190, 190], 
 
     [50, 50], 
 
     [190, 20] 
 
    ]; 
 

 
    p3 = [ 
 
     [190, 20], 
 
     [190, 10] 
 
    ]; 
 

 
    p4 = [ 
 
     [190, 10], 
 
     [100, 20], 
 
     [10, 10] 
 
    ]; 
 

 
    var svg = d3.select('svg') 
 
     .attr("width", 200) 
 
     .attr("height", 200) 
 
     .attr("viewBox", "0 0 200 200"); 
 

 
    var line = d3.svg.line().interpolate("linear"); 
 
    var spline = d3.svg.line().interpolate("basis"); 
 

 
    svg.append("path") 
 
     .attr("d", function() { 
 

 
     var s1 = line(p1), 
 
      s2 = spline(p2), 
 
      s3 = line(p3), 
 
      s4 = spline(p4); 
 
      
 
     s2 = s2.substring(s2.indexOf("L"), s2.length); 
 
     s3 = s3.substring(s3.indexOf("L"), s3.length); 
 
     s4 = s4.substring(s4.indexOf("L"), s4.length); 
 

 
     return s1 + s2 + s3 + s4; 
 
     }) 
 
     .attr("fill", "purple") 
 
     .attr("stroke-width", 1) 
 
     .attr("stroke", "black") 
 
    </script> 
 
</body> 
 

 
</html>

+0

嗨马克,感谢您的解决方案,但正如我所说,我已经意识到这一点,并希望找到一个更好的解决方案(不需要修改D3.js返回的结果)。这就是为什么我只会给你一个upvote。我想可能没有解决我的问题(除了为D3写一个补丁;)。 –

+0

@LordBo,opps,我应该仔细阅读。在我用'd3'的经验中,我认为你不会找到一个更优雅的方式来做到这一点。 – Mark