d3绘图缺少数组中的第一项

时间:2016-10-14 12:55:07

标签: javascript arrays d3.js

我真的很挣扎。我正在使用d3库在javascript中创建一个点图。我想过滤实际绘制的点,以便稍后我可以将文本字段添加到数据集中名为'highlight'的列中指定的一些字段中。就像测试一样,我只是绘制标记为“是”但最终将绘制所有圆圈的圆圈。我只包含了实际的绘图代码,因为我非常确定数据结构是否正常。以下代码按照我的预期绘制了圆圈。

var category = plot.selectAll("."+media+"category")
        .data(plotData)
        .enter()
        .append("g")
        .attr("transform", function (d) {return "translate(0," + yScale(d.key) + ")"; })
        .attr("class", media+"category")
        .call(function(parent){
    parent.append('text')
        .attr("class", media+"Subtitle")
        .attr("x",margin.left)
        .attr("y",0)
        .text(function(d){return d.key})

    parent.selectAll('circles')
    .data(function(d){
        //console.log("object= ",d)
        let filtered=d.values.filter(function(d){
            return d.highlight=="yes"
        })
        //console.log("circles filtered ", filtered)
        return filtered
    })
    .enter()
    .append('circle')
    .attr("class",function(d,i){
        if(d.highlight=="yes"){
            return media+"highlight"
        }
        else {return media+"fill"}
    })
    .attr("id",function(d){return d.name +" "+d.value+ " "+d.size})
    .attr("cx",function(d){return xScale(d.value)})
    .attr("cy",yScale.rangeBand()*.4)
    .attr("r", function(d) {
        if (size) {return d.size*(yScale.rangeBand()*.003   )}
        else {return yOffset/2}
    })
    .attr("transform", function (d) {return "translate("+(margin.left)+","+(0)+")"})
    .style("fill",colours[0])

情节如下:

enter image description here

当我尝试添加文本时出现问题。我正在使用完全相同的过滤器来过滤数据,这些数据为.data要使用的数据创建。但是由于某种原因,尽管数组中的第一个对象IS没有绘制。我修改后的代码如下所示:

var category = plot.selectAll("."+media+"category")
        .data(plotData)
        .enter()
        .append("g")
        .attr("transform", function (d) {return "translate(0," + yScale(d.key) + ")"; })
        .attr("class", media+"category")
        .call(function(parent){

        parent.append('text')
            .attr("class", media+"Subtitle")
            .attr("x",margin.left)
            .attr("y",0)
            .text(function(d){return d.key})

        parent.selectAll('circles')
        .data(function(d){
            //console.log("object= ",d)
            let filtered=d.values.filter(function(d){
                return d.highlight=="yes"
            })
            //console.log("circles filtered ", filtered)
            return filtered
        })
        .enter()
        .append('circle')
        .attr("class",function(d,i){
            if(d.highlight=="yes"){
                return media+"highlight"
            }
            else {return media+"fill"}
        })
        .attr("id",function(d){return d.name +" "+d.value+ " "+d.size})
        .attr("cx",function(d){return xScale(d.value)})
        .attr("cy",yScale.rangeBand()*.4)
        .attr("r", function(d) {
            if (size) {return d.size*(yScale.rangeBand()*.003   )}
            else {return yOffset/2}
        })
        .attr("transform", function (d) {return "translate("+(margin.left)+","+(0)+")"})
        .style("fill",colours[0])

        parent.selectAll('text')
        .data(function(d){
            console.log("object= ",d)
            let filtered=d.values.filter(function(d){
                return d.highlight=="yes"
            })
            console.log("text filtered ", filtered)
            return filtered
        })
        .enter()
        .append('text')
        .attr("x",function(d){
                    return xScale(d.value)+(margin.left);
                    })
                    .attr("y",function(d){
                    return yScale.rangeBand()*.4;
                    })
                    .text(function(d){
                        return d.name+' '+d.size
                    })
                    .attr("class",media+"subtitle")

但情节如下:

enter image description here

无论我在数据集中定义了多少个圆圈为“是”以便绘制它们,第一个圆圈始终缺少其标签。我猜测数据在某处变异,但无法弄清楚在哪里。我也尝试先在圆圈之前绘制文本,但结果总是一样。

这是控制台的输出,显示.data araay中有第一项

[Object, Object, Object, Object]
dot-plot.js:104 object=  Object {key: "Endland", values: Array[22]}
dot-plot.js:108 text filtered  [Object, Object]0: Objectgroup: "Endland"highlight: "yes"name: "Manchester City"size: "95.65695168"value: "55097"__proto__: Object1: Objectgroup: "Endland"highlight: "yes"name: "Stoke"size: "9.13121722"value: "27743"__proto__: Objectlength: 2__proto__: Array[0]
dot-plot.js:104 object=  Object {key: "Spain", values: Array[44]}
dot-plot.js:108 text filtered  [Object, Object, Object]0: Objectgroup: "Spain"highlight: "yes"name: "Barcelona"size: "47.32724506"value: "100000"__proto__: Object1: Objectgroup: "Spain"highlight: "yes"name: "Deportivo de La Coru_a"size: "59.93202583"value: "34600"__proto__: Object2: Objectlength: 3__proto__: Array[0]
dot-plot.js:104 object=  Object {key: "Italy", values: Array[22]}
dot-plot.js:108 text filtered  [Object]
dot-plot.js:104 object=  Object {key: "Germany", values: Array[20]}
dot-plot.js:108 text filtered  [Object, Object]

我很欣赏任何人可能有的见解。真的很抱歉这么冗长,但我从来没有使用过js.fiddle或者我举了一个例子

由于

1 个答案:

答案 0 :(得分:1)

执行此操作时:

parent.append('text')
        .attr("class", media+"Subtitle")
        .attr("x",margin.left)
        .attr("y",0)
        .text(function(d){return d.key});

您正在SVG中创建text元素(在您的情况下,是副标题)。所以,当你稍后这样做时:

parent.selectAll('text')//here you select ALL text elements
    .data(function(d){
        console.log("object= ",d)
        let filtered=d.values.filter(function(d){
            return d.highlight=="yes"
        })
        console.log("text filtered ", filtered)
        return filtered
    })
    .enter()
    .append('text');

您正在选择之前的文字(副标题)。因此,您的输入选择少了一个元素。

解决方案:选择其他内容:

parent.selectAll('.somethingElse')//here you don't select existing elements
    .data(function(d){
        console.log("object= ",d)
        let filtered=d.values.filter(function(d){
            return d.highlight=="yes"
        })
        console.log("text filtered ", filtered)
        return filtered
    })
    .enter()
    .append('text')