2016-12-25 4 views
1

Мне сложно определить, как размещать изображения внутри круга, используя ссылки в моем наборе данных. Я знаю, что для добавления изображений в узлы требуется шаблон. related ВОПРОСЫ В этом разделе к теме добавляются элементы def, pattern и image перед введением узлов и данных.Как добавить изображение в круг динамически в D3js

В моем случае я не смог найти выход из добавления тегов внутри функции селектора, поскольку данные динамически добавляются к каждому узлу. Вот код проекта, каждая черная точка должна содержать другое изображение насекомого (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. С праздником

ответ

2

Вы не можете добавить <defs>, a <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("")) + ")" 
    }); 
} 

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

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

+0

Я попытался избавиться от внешнего цикла, добавив forfor каждый цикл в '.data', но, к сожалению, я не смог заставить его работать. – st4rgut