Javascript 删除条形图';s栏,单击

Javascript 删除条形图';s栏,单击,javascript,d3.js,Javascript,D3.js,我在d3.js中制作了一个条形图。我想要一种行为,点击任何一个条,该条就会被删除 我有一个函数,在给定索引的情况下,它删除数组元素并更新DOM 第一次点击效果很好,但在以后的点击中,我会得到不同的索引值,其他一些条会被删除。你知道为什么点击时索引值不正确吗 <script> var dataSet = [ {key:0, value: 10}, {key:1, value: 18}

我在d3.js中制作了一个条形图。我想要一种行为,点击任何一个条,该条就会被删除

我有一个函数,在给定索引的情况下,它删除数组元素并更新DOM

第一次点击效果很好,但在以后的点击中,我会得到不同的索引值,其他一些条会被删除。你知道为什么点击时索引值不正确吗

 <script>         

var dataSet = [ 
                    {key:0, value: 10},
                    {key:1, value: 18},
                    {key:2, value: 13},
                    {key:3, value: 19},
                    {key:4, value: 21},
                    {key:5, value: 25}                        
            ];

var canvasWidth = 500, canvasHeight = 500;

var svg = d3.select('body').append('svg').attr('width',canvasWidth).attr('height',canvasHeight);

svg.append('rect').attr('width', "100%").attr('height', '100%').attr('fill', 'lightgrey').classed('bg',true);    

// Bargraph

var barWidth = 20, padding = 1;
var barScale = d3.scale.linear()
                .domain([ d3.min(dataSet,function(data){return data.value}), d3.max(dataSet,function(data){return data.value}) ])
                .range ([ d3.min(dataSet,function(data){return data.value}), canvasHeight-padding])

// Create

var key = function(d) { return d.key; };

var barGraph = svg.selectAll('rect.bars').data(dataSet,key).enter().append('rect')
    .attr('x', function(data,index){return (padding+barWidth)*index})   
    .attr('y', function(data){ return canvasHeight-barScale(data.value); })        
    .attr('width', barWidth)
    .attr('height', function(data){ return barScale(data.value); })        
    .style('fill', 'teal')
    .classed('bars',true) 

    // ---------- Here is the problem --------------------

    .on('click',function(data,index){ console.log(index) ; removeElement(index) })
    .on('mouseover',function(data){ })

// Exit some

function removeElement(index) 
{
    dataSet.splice( index , 1)        
    var updated = svg.selectAll('rect.bars').data(dataSet,key)

    updated.exit()
    .transition()
    .duration(1000)
    .attr('width', 0) 
    .remove()
    .each('end',function()
    {
        svg.selectAll('rect.bars')
        .transition()
        .duration(1000)
        .attr('x', function(data,index){return (padding+barWidth)*index})   
    })
}

</script> 

变量数据集=[
{键:0,值:10},
{键:1,值:18},
{键:2,值:13},
{键:3,值:19},
{键:4,值:21},
{键:5,值:25}
];
var canvasWidth=500,canvasHeight=500;
var svg=d3.select('body')。append('svg')。attr('width',canvaswitdth)。attr('height',canvaswitch);
svg.append('rect').attr('width','100%').attr('height','100%').attr('fill','lightgrey').classed('bg','true));
//条形图
var barWidth=20,padding=1;
var barScale=d3.scale.linear()
.domain([d3.min(数据集,函数(数据){return data.value}),d3.max(数据集,函数(数据){return data.value})])
.range([d3.min(数据集,函数(数据){return data.value}),画布高度填充])
//创造
var key=函数(d){return d.key;};
var barGraph=svg.selectAll('rect.bar').data(数据集,键).enter().append('rect'))
.attr('x',函数(数据,索引){return(padding+barWidth)*index})
.attr('y',函数(数据){return canvasHeight barScale(data.value);})
.attr('width',barWidth)
.attr('height',function(data){返回barScale(data.value);})
.style('fill','teal')
.classed('bars',true)
//-------问题就在这里--------------------
.on('click',函数(数据,索引){console.log(索引);removelement(索引)})
.on('mouseover',函数(数据){})
//退出一些
函数removeElement(索引)
{
数据集拼接(索引,1)
var updated=svg.selectAll('rect.bar')。数据(数据集,键)
已更新。退出()
.transition()
.持续时间(1000)
.attr('width',0)
.删除()
.each('end',function()
{
svg.selectAll('rect.bar')
.transition()
.持续时间(1000)
.attr('x',函数(数据,索引){return(padding+barWidth)*index})
})
}

可能是因为当您重新绑定数据(
var updated=…
)时,删除的条仍然是选择的一部分,这会影响索引

我认为最好的解决方案是使用
dataSet.indexOf(data)
dataSet
中查找
index
,而不是依赖传递到单击处理程序中的
索引

或者,如果在
处理程序中添加,则可以尝试查看以下任一项是否有效。每个('end',…)
处理程序:

  • 再次绑定数据
  • 在条形图上调用
    .order()
    ,如在
    svg中一样。selectAll('rect.bar')。order()
  • 重新订阅click事件,如svg中的
    selectAll('rect.bar')。打开('click',…)

  • 可能是因为当您重新绑定数据(
    var updated=…
    )时,删除的条仍然是选择的一部分,这会影响索引

    我认为最好的解决方案是使用
    dataSet.indexOf(data)
    dataSet
    中查找
    index
    ,而不是依赖传递到单击处理程序中的
    索引

    或者,如果在
    处理程序中添加,则可以尝试查看以下任一项是否有效。每个('end',…)
    处理程序:

  • 再次绑定数据
  • 在条形图上调用
    .order()
    ,如在
    svg中一样。selectAll('rect.bar')。order()
  • 重新订阅click事件,如svg中的
    selectAll('rect.bar')。打开('click',…)

  • 我认为这是依靠索引和就地数组拼接的组合,导致了数据绑定

    尝试:

    例如

    编辑

    让我澄清一下,这并不是拼接的位置造成的,而是索引移位的依赖性。不管删除元素,单击处理程序仍然认为数据是它的旧索引。您可以在
    控制台.log(index)
    中看到这一点。这就是我上面的代码工作的原因。您不再依赖于按索引删除,而是通过
    d.key
    这是起始索引(单击时记住的索引)

    解决此问题的另一种方法是在数据更新时重新绑定事件处理程序,这种方法确实适用于splice

    function removeElement(index) 
    {
        dataSet.splice(index, 1);
        var updated = svg.selectAll('rect.bars')
          .data(dataSet,key)
          .on('click',function(data,index){ console.log(index) ; removeElement(index) });
    
    updated.exit()....
    

    看到这一点。

    我认为是依赖索引和就地阵列拼接的组合导致了
    d3
    数据绑定

    尝试:

    例如

    编辑

    让我澄清一下,这并不是拼接的位置造成的,而是索引移位的依赖性。不管删除元素,单击处理程序仍然认为数据是它的旧索引。您可以在
    控制台.log(index)
    中看到这一点。这就是我上面的代码工作的原因。您不再依赖于按索引删除,而是通过
    d.key
    这是起始索引(单击时记住的索引)

    解决此问题的另一种方法是在数据更新时重新绑定事件处理程序,这种方法确实适用于splice

    function removeElement(index) 
    {
        dataSet.splice(index, 1);
        var updated = svg.selectAll('rect.bars')
          .data(dataSet,key)
          .on('click',function(data,index){ console.log(index) ; removeElement(index) });
    
    updated.exit()....
    

    看看这个。

    啊!谢谢知道为什么拼接阵列会导致D3出现问题吗?@AmitTomar,请参阅最新解释。我原来的回答不是很清楚。啊!谢谢知道为什么拼接阵列会导致D3出现问题吗?@AmitTomar,请参阅最新解释。我最初的回答不是很清楚。