Мне сложно понять, как размещать изображения внутри круга, используя ссылки в моем наборе данных. Я знаю, что для добавления изображений в узлы требуется шаблон - связанных SO вопросы по этой теме добавляют элементы def, pattern и image перед введением узлов и данных.

В моем случае я не мог найти выхода из добавления тегов внутри функции селектора, потому что данные добавляются динамически к каждому узлу. Вот код проекта, каждая черная точка должна содержать другое изображение насекомого (URL-адрес находится в файле tsv): https://plnkr.co/edit/Ydrxogbfm9JvqrgeQaQ6?p=preview

Я попытался изменить xlink:href в тегах тела с помощью приведенного ниже кода:

<body>
<svg width="1000" height="600">
    <defs id="mdef">
    <pattern id="image" x="0" y="0" height="40" width="40">
      <image x="0" y="0" width="40" height="40" ></image>
    </pattern>
  </defs>
</svg>

</body>

И этот фрагмент JS в блоке кода, добавляющем узлы. :

.attr('"xlink:href", function(d){return d[1];}) //d is an array and the d[1] is the link

Однако изображения не появились. Затем я попытался добавить шаблон с помощью js:

for (i=0;i<insects.length;i++){
  g.selectAll("circle")
      .data(insects[i],function(d) {console.log(d); return d }) //each insect
    .enter().append("circle")
      .attr('cx', function(d,index) {return x(insects[i].length)/insects[i].length*index; })
      .attr("r", 20)
      .attr("cy", function(d,index){return y.bandwidth()*i})
    .append('svg:defs') //adding pattern
    .append('svg:pattern')
      .attr('id','pattern')
        .attr("x",0)
        .attr("y",0)
        .attr("width",40)
        .attr("height",40)
      .append("svg:image")
        .attr("x",0)
        .attr("y",0)
        .attr("width",40)
        .attr("height",40)
        .attr("xlink:href", function(d){console.log(d[1]); return d[1];})
    .style("fill", "url(#pattern)");
  }
})

Но я получаю тот же результат. Был бы очень признателен за любые указатели, так как я новичок в d3. Счастливых праздников

1
I Like 25 Дек 2016 в 11:04

1 ответ

Лучший ответ

Вы не можете добавить к кругу символы <defs>, <pattern> и <image>. Это не сработает.

Вместо этого вам нужно создать <defs>, добавить узоры и изображения и заполнить круги в соответствии с их уникальными идентификаторами:

var defs = g.append("defs");

defs.selectAll(".patterns")
    .data(insects[i], function(d) {
        return d
    })
    .enter().append("pattern")
    .attr("id", function(d) {
        return "insect" + (d[0].split(" ").join(""))
    })
    .attr("width", 1)
    .attr("height", 1)
    .append("svg:image")
    .attr("xlink:href", function(d) {
        return d[1]
    })
    .attr("width", 40)
    .attr("height", 40);


g.selectAll("circle")
    .data(insects[i], function(d) {
        return d
    })
    .enter().append("circle")
    .attr('cx', function(d, index) {
        return x(insects[i].length) / insects[i].length * index;
    })
    .attr("r", 20)
    .attr("cy", function(d, index) {
        return y.bandwidth() * i
    })
    .style("fill", function(d) {
        return "url(#insect" + (d[0].split(" ").join("")) + ")"
    });
}

Вот ваш обновленный плункер: http://plnkr.co/edit/WLC2ihpzsjDUgcuu910O?p=preview

PS : ваш код работает, но я должен сказать, что ваш цикл for не нужен (и даже неудобен) в D3 dataviz. Это не способ D3 доступа к данным. Таким образом, я предлагаю вам полностью реорганизовать свой код в этом блоке.

2
Gerardo Furtado 25 Дек 2016 в 13:05
Я попытался избавиться от внешнего цикла for, добавив циклы .forEach в .data, но, к сожалению, мне не удалось заставить его работать.
 – 
I Like
26 Дек 2016 в 00:28