Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/424.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在d3.js中,跳过空数据的append()_Javascript_D3.js - Fatal编程技术网

Javascript 在d3.js中,跳过空数据的append()

Javascript 在d3.js中,跳过空数据的append(),javascript,d3.js,Javascript,D3.js,我正在用小圆圈的子弹画一个线图。但是,数据中有漏洞,在我的数组中用null表示。当然,没有数据的地方不应该有圆圈。但是d3的append()方法还是添加了它们。我如何避免这种情况 这是一个复制我的问题 我感兴趣的是不要在我的图形的X轴上有一系列的圆,因为它们都是空的 来自JSFIDLE链接的相关代码: svg.selectAll('circle').data(values).enter() .append('circle')// <-- I don't want to do this

我正在用小圆圈的子弹画一个线图。但是,数据中有漏洞,在我的数组中用null表示。当然,没有数据的地方不应该有圆圈。但是d3的append()方法还是添加了它们。我如何避免这种情况

这是一个复制我的问题

我感兴趣的是不要在我的图形的X轴上有一系列的圆,因为它们都是空的

来自JSFIDLE链接的相关代码:

svg.selectAll('circle').data(values).enter()
  .append('circle')// <-- I don't want to do this for null's
  .attr('fill', '#c00')
  .attr('r', 3)
  .attr('cx', xi)
  .attr('cy', yFlipped)
svg.selectAll('circle')。数据(值)。输入()
.append('circle')/只需过滤它

values.filter(function(el){return el !== null;})

一种选择是以不同的方式表示数据,这样您就不必依赖索引来计算x坐标。例如,如果将每个基准表示为一个对象(例如,
{x:0,y:0.2840042}
),则可以将x坐标计算为
x(d.x)
,而不是
x(i)

另一个选项是,当值为null时,将半径设置为零,因此圆是隐藏的:
circle.attr(“r”,function(d){return d==null?0:3;})
。或者,您可以隐藏圆圈:
circle.style(“display”,function(d){returnd==null?“none”:null;})


您还可以在附加空元素之后删除它们:
circle.filter(函数(d){return d==null;})。remove()
。这对于最初的创建是可行的,但我不建议这样做,因为如果您以后重新选择元素,索引将发生更改。

试试这种模式,它可以删除或隐藏您的圆圈

// Step 1: hides all circles which are "null"
d3.selectAll(".yourItem")
.data(data)
.enter()
    .append("circle")
    .attr("visibility", function(d,i){
        if(yourFunction(d) == null) return "hidden";
})

// Step 2: optional, deletes all circles which are "hidden"
d3.selectAll("circle[visibility=hidden]").remove();

最简单的选择是从传递到
.data(…)
的数据中过滤空值,增加数据以维护索引:

svg.selectAll('circle')
  .data(values
    .map(function(v, idx) { return v == null? null : { idx: idx, value: v })
    .filter(function(v) { return v != null })
  )
  .enter()
    .append('circle')
    .attr('fill', '#c00')
    .attr('r', 3)
    .attr('cx', function(d) { return d.idx * 10 }) // or whatever
    .attr('cy', function(d) { return d.value.y }) // or whatever
请注意,您也可以按照此模式创建单个子元素,即使它们不是列表。例如,考虑一种情况,您希望有条件地添加第二个循环:

var circles = [
    { color: 'red', cx: 30, cy: 30, subCircleColor: 'blue' },
    { color: 'blue', cx: 60, cy: 60, subCircleColor: 'green' },
    { color: 'green', cx: 90, cy: 90 },
];

// Create a group which will hold the circles, since the result will
// be:
//    <g class="circles">
//      <circle color="{{ color }}" ... />
//      <circle class="sub-circle" color="{{ subCircleColor }}" ... />
//    </g>
var circlesGroups = svg.selectAll("g.circles")
    .data(circles)
    .enter()
        .append("g").attr({"class": "circles"})

// Add the first circle to the group
circlesGroups
    .append("circle").attr({
        "fill": function(d) { return d.color },
        "r": 20,
        "cx": function(d) { return d.cx },
        "cy": function(d) { return d.cy },
    })

// If there is a subCircleColor, add the second circle to the group
circlesGroups.selectAll("circle.sub-circle")
    .data(function(d) {
        if (d.subCircleColor)
            return [d];
        return [];
    })
    .enter()
        .append("circle").attr({
            "class": "sub-circle",
            "fill": function(d) { return d.subCircleColor; },
            "r": 10,
            "cx": function(d) { return d.cx },
            "cy": function(d) { return d.cy },
        })
var圆=[
{颜色:'红色',cx:30,cy:30,亚圆形:'蓝色'},
{颜色:'蓝色',cx:60,cy:60,亚圆形:'绿色'},
{颜色:'绿色',cx:90,cy:90},
];
//创建一个包含圆圈的组,因为结果是
//是:
//    
//      
//      
//    
var circlesGroups=svg.selectAll(“g.circles”)
.数据(圆圈)
.输入()
.append(“g”).attr({“class”:“circles”})
//将第一个圆添加到组中
圈群
.append(“圆圈”).attr({
“fill”:函数(d){return d.color},
“r”:20,
“cx”:函数(d){返回d.cx},
“cy”:函数(d){返回d.cy},
})
//如果存在子圆颜色,请将第二个圆添加到组中
圆圈组。选择全部(“圆圈.子圆圈”)
.数据(功能(d){
if(d.亚圆形颜色)
返回[d];
返回[];
})
.输入()
.append(“圆圈”).attr({
“类”:“子圈”,
“fill”:函数(d){返回d.subCircleColor;},
“r”:10,
“cx”:函数(d){返回d.cx},
“cy”:函数(d){返回d.cy},
})

Fiddle:

如果你一开始就不想附加它,这里有一种方法。我在.each()中使用了if语句,然后使用d3.select(this)将其附加到当前项

var data = [9, 0, 7, 0, 5, 0, 3, 0, 1];

var svg = d3.select('#svg').append('svg').attr({'viewBox': '-10 -10 99 20'});

svg.selectAll('g').data(data).enter().append('g').each(function (d,i) {
 if(d){
  d3.select(this).append('circle').attr({r:5,cx:(i*9)});
 }else{
  d3.select(this).remove();
 }
});

这是一个bin

谢谢,但它只是从数组中删除了这些元素,这会影响传递到attr()设置函数的索引i。我需要指数保持不变,因为这是我用来计算x位置的东西。这实际上是我的问题,我觉得自己很傻,甚至连过滤都不考虑。我想我是被“d3是如何做到这一点的?”迷住了,以至于我没有想到:)撇开不谈,关于零半径方法——使用我的大而稀疏的数组,当我创建并使用一个新的过滤数组时,我获得了更好的性能。我意识到@meetamit希望保持原始指数,但我想指出可能存在不理想的性能影响。当我使用
circle.filter(函数(d){return d==null;})时,d3可能通过短路来解决这个问题。remove()
方法解决了我的问题,它工作得很好!虽然这跳过了附加
,但它仍然将
附加为容器-当
d
为0时,它将保留为空。如果您还想在
中附加其他元素,那么这可能是有利的,但它实际上并没有跳过附加
。另外,在
.selectAll('z')
中,它应该是
.selectAll('g')
,否则重复调用此代码(即使使用相同的
数据
)将每次附加
元素。感谢您的审阅。如果没有d,添加一个else来删除g怎么样?“else{d3.select(this).remove()}”Yes-调用
.remove()
的结果是
数据中的非零数量与
的数量相同。它还使
i
d
数据中的位置保持同步。但是,根据更大的背景,这可能会有问题。例如,如果要对此
.data()
联接的更新或退出结果调用附加函数(例如
.attr
.remove
),则可能会出现错误,因为某些元素已被删除。另外,如果您稍后重新选择
all()
这些
并用数据重新连接它们,
i
可能不再与
d
的数组位置同步。如果不进行测试,我不确定我指出的问题示例是否会如所述实际发生。我的主要假设是,如果您曾经
.remove()
d3选择中的一个成员没有使用现有的选择,那么您可能会遇到问题。自从我发布这个问题(5年前,geez)以来,我基本上采纳了mbostock的建议(在本页上),几乎从不依赖
I
来获取数据