Изображение размытое при использовании шаблона заполнения URL для круга SVG

Я пытаюсь использовать пример упаковки кругов d3.js, чтобы заполнить кучу svg-кругов изображениями, используя шаблон SVG. Мои исходные изображения 800x600, но круги будут разных размеров. Я настроил это следующим образом:

  var patterns = defs.selectAll("pattern")
      .data(nodes.filter(function(d){ return !d.children }))
      .enter()
      .append('pattern')
      .attr('id',function(d){
        return 'id'+d.id
      })
      .attr('x','0')
      .attr('y','0')
      .attr('height',function(d){ return d.r*2})
      .attr('width',function(d){ return d.r*2*1.333333})
      .append('image')
      .attr('x','0')
      .attr('y','0')
      .attr('height',function(d){ return d.r*2})
      .attr('width',function(d){ return d.r*2*1.333333})
      .attr('xlink:href',function(d){
        return 'img/img' + d.image;
      })

  var circle = svg.selectAll("circle")
      .data(nodes)
    .enter().append("circle")
      .attr("class", function(d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; })
      .style("fill", function(d) {
        if (!d.children){
          return 'url(#id' + d.id + ')';
        } else {
          return d.children ? color(d.depth) : null;
        }

      })

так что мой DOM рендерит так:

<defs id="cdef">
    <pattern id="id65" x="0" y="0" height="326.8534904318234" width="435.8045449579344">
        <image x="0" y="0" height="326.8534904318234" width="435.8045449579344" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="img/img65.png"></image>
    </pattern>
    ...
</defs>

Но когда я делаю это, изображения в круге становятся очень раздувными (см. Прикрепленное изображение). Есть идеи, что происходит? введите описание изображения здесь

1 ответ

Я понял это.

Высота и ширина элемента шаблона, кажется, функционируют как масштаб / процент. Таким образом, ширина "1" означает, что он заполнит весь установленный элемент. Ширина ".25" означает 25% этого элемента. Затем в пределах <pattern> Вы бы указали высоту и ширину изображения как фактическое значение в пикселях высоты и ширины круга, который они заполняют, поэтому в этом случае мой код был изменен на:

  var patterns = defs.selectAll("pattern")
      .data(nodes.filter(function(d){ return !d.children }))
      .enter()
      .append('pattern')
      .attr('id',function(d){
        return 'id'+d.id
      })
      .attr('x','0')
      .attr('y','0')
      .attr('height','1')
      .attr('width','1')
      .append('image')
      .attr('height',function(d){ return d.r*2})
      .attr('width',function(d){ return d.r*2*1.333333})
      .attr('xlink:href',function(d){
        return 'img/img' + d.image;
      })

и затем, поскольку макет пакета кругов увеличивается, я должен был убедиться, что изменил также и изображения, так:

function zoomTo(v) {
    var k = diameter / v[2]; view = v;
    defs.selectAll('image').attr('width',function(d){
      return d.r*2*1.333333*k
    }).attr('height',function(d){
      return d.r*2*k
    });
    node.attr("transform", function(d) { return "translate(" + (d.x - v[0]) * k + "," + (d.y - v[1]) * k + ")"; });
    circle.attr("r", function(d) { return d.r * k; });


  }

необходим, если вы изменяете пример bl.ocks.org, упомянутый выше.

Другие вопросы по тегам