尝试将背景图像添加到D3圈子

时间:2017-10-22 13:49:56

标签: javascript d3.js

我尝试使用每个气泡的水果图像创建以下气泡图。我没有在控制台中收到错误,控制台正确打印水果名称,但水果图像没有显示。我错过了什么我认为这可能是我在for循环中添加fill属性的说法,但是我已经玩了订单而没有成功。

var diameter = 500, //max size of the bubbles
    color    = d3.scale.category20b(); //color category

var bubble = d3.layout.pack()
    .sort(null)
    .size([diameter, diameter])
    .padding(1.5);

var svg = d3.select("body")
    .append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
    .attr("class", "bubble");

d3.csv("fruit.csv", function(error, data){

    //convert numerical values from strings to numbers
    data = data.map(function(d){ d.value = +d["Amount"]; return d; });


    //bubbles needs very specific format, convert data to this.
    var nodes = bubble.nodes({children:data}).filter(function(d) { return !d.children; });

    //setup the chart
    var bubbles = svg.append("g")
        .attr("transform", "translate(0,0)")
        .selectAll(".bubble")
        .data(nodes)
        .enter();

    //create the bubbles
    bubbles.append("circle")
        .attr("id", function(d) { return d.Fruit; })
        .attr("r", function(d){ return d.r; })
        .attr("cx", function(d){ return d.x; })
        .attr("cy", function(d){ return d.y; })
        .style("fill", function(d) { return color(d.value); });

    //format the text for each bubble
    bubbles.append("text")
        .attr("x", function(d){ return d.x; })
        .attr("y", function(d){ return d.y + 5; })
        .attr("text-anchor", "middle")
        .text(function(d){ return d["Fruit"]; })
        .style({
            "fill":"white", 
            "font-family":"Helvetica Neue, Helvetica, Arial, san-serif",
            "font-size": "12px"
        });

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

    var circles = document.getElementsByTagName("circle");

    for (var i = 0; i < circles.length; i++) {

        var fruit = circles[i].id;

        defs.append("pattern")
            .attr("height","100%")
            .attr("width", "100%")
            .attr("patternContentUnits", "objectBoundingBox")
            .append("image")
            .attr("height",1)
            .attr("width",1)
            .attr("preserveAspectRatio","none")
            .attr("xlink:href", fruit+".jpg"); 

        d3.select("#"+fruit)
            .attr("fill", "url(#" + fruit + ")");

        console.log(circles[i].id);

    }

})

1 个答案:

答案 0 :(得分:2)

您的代码现在的问题是您没有为<patterns>设置任何ID。

除此之外,您尝试使用fill覆盖以前设置的style() ...

.style("fill", function(d) { return color(d.value); });

...使用attr()方法:

.attr("fill", "url(#" + fruit + ")");

最后,摆脱for循环。作为一般规则,在使用D3附加/创建元素时避免循环。

因此,总结一个解决方案,您可以使用简单的“输入”选项来附加模式,使用d.Fruits设置其ID并根据模式ID设置圆圈fill:< / p>

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

defs.selectAll(null)
    .data(nodes)
    .enter()
    .append("pattern")
    .attr("id", function(d){
        return d.Fruit
    })//set the id here
    .attr("height", "100%")
    .attr("width", "100%")
    .attr("patternContentUnits", "objectBoundingBox")
    .append("image")
    .attr("height", 1)
    .attr("width", 1)
    .attr("preserveAspectRatio", "none")
    .attr("xlink:href", function(d) {
        return d.Fruit + ".jpg"
    });

bubbles.append("circle")
    .attr("id", function(d) {
        return d.Fruit;
    })
    .attr("r", function(d) {
        return d.r;
    })
    .attr("cx", function(d) {
        return d.x;
    })
    .attr("cy", function(d) {
        return d.y;
    })
    .style("fill", function(d) {
        return "url(#" + d.Fruit + ")";
    });//fill the circles according to the pattern's id