扩展SVG元素(如果与另一个元素重叠)

我有一个用D3创建的数据图,在其中为每个数据点画了一个圆。

当圆重叠时,我想将它们放大一些,以便在多个数据点堆积在同一位置时看到差异。

我发现我可以将feMorphology应用于dilate过滤器,但是我需要能够根据相同位置的圆数以某种方式缩放膨胀。

这是SVG演示:

<svg width="400" height="120" xmlns="http://www.w3.org/2000/svg">
 <filter id="dilateIfOverlapping">
  <feMorphology operator="dilate" radius="4">
 </filter>
 <g filter="url(#dilateIfOverlapping)">
   <circle cx="60" cy="60" r="30" fill="green" />
   <circle cx="60" cy="60" r="30" fill="green" />
   <circle cx="170" cy="60" r="30" fill="green" />
 </g>
</svg>

这将渲染两个相同大小的圆。我希望第一个更大,因为彼此之间有两个圆圈。

有没有办法在不通过编程方式设置不同的圆半径的情况下实现这一目标?

tftp156656 回答:扩展SVG元素(如果与另一个元素重叠)

您可以使用feComponentTransfer / feFuncA执行这种操作。但是它只能处理完全重叠的点与部分重叠的点。

它的工作方式是首先以低不透明度渲染圆形。因此,在同一点渲染的圆圈越多,其不透明度越高。然后,滤镜将图像切成具有不同不透明度范围的不同图层。然后,它将不同大小的模糊应用于每个图层,然后在模糊的圆圈上拨出不透明度,并添加一个带有附加模糊效果的假假抗锯齿。

这里的窍门是使圆的不透明度值恰好正确,因此它与feFuncA tableValues的不透明度范围对齐。您必须提前知道最大重叠点数,这样您才能正确地进行校准。 (例如,此tableValues="0 1 0 0 0"创建5个不透明度范围,分别为0-20%,20-40%,40-60%,60-80%和80-100%。)

<svg width="800px" height="600px">
  <defs>
  <filter id="embiggen" x="-50%" y="-50%" width="200%" height="200%">
    <feComponentTransfer in="SourceGraphic" result="layer1">
      <feFuncA type="discrete" tableValues="0 1 0 0 0" />
      </feComponentTransfer>
      
         <feComponentTransfer in="SourceGraphic" >
      <feFuncA type="discrete" tableValues="0 0 1 0 0"  />
      </feComponentTransfer>
    <feGaussianBlur stdDeviation= "2"/>
    <feComponentTransfer >
      <feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
      </feComponentTransfer>
      <feGaussianBlur stdDeviation= "0.5" result="layer2"/>
    
    <feComponentTransfer in="SourceGraphic" >
      <feFuncA type="discrete" tableValues="0 0 0 1 0" />
      </feComponentTransfer>
    <feGaussianBlur stdDeviation= "4"/>
    <feComponentTransfer>
    <feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"/>
      </feComponentTransfer>
          <feGaussianBlur stdDeviation= "0.5" result="layer3"/>
                  
    <feComponentTransfer in="SourceGraphic">
      <feFuncA type="discrete" tableValues="0 0 0 0 1" />
    </feComponentTransfer>
    <feGaussianBlur stdDeviation= "8"/>
    <feComponentTransfer >
     <feFuncA type="discrete" tableValues="0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1" />                   
    </feComponentTransfer>
     <feGaussianBlur stdDeviation= "0.5" result="layer4"/>
      
    <feMerge>
      <feMergeNode in="layer1"/>      
      <feMergeNode in="layer2"/>
      <feMergeNode in="layer3"/>
      <feMergeNode in="layer4"/>
    </feMerge>
    </defs>
  </filter>
  
  <g filter="url(#embiggen)" shape-rendering="crispEdges">

    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>  
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="50" cy="50" fill-opacity="0.21" r="10" fill="red"/>  
    
    <circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="120" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    
    <circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    <circle cx="180" cy="50" fill-opacity="0.21" r="10" fill="red"/>
    
    <circle cx="240" cy="50" fill-opacity="0.21" r="10" fill="red"/>

  </g>
  
</svg>

本文链接:https://www.f2er.com/2569086.html

大家都在问