2017-03-06 31 views
1

我正在用Javascript D3做一个条形图。我想在复选框被选中时对数据进行排序,并且当复选框未选中时,可视化将返回到未排序状态。
现在“检查复选框时排序数据”效果很好,但取消选中复选框没有任何区别(这意味着数据仍然保持排序状态)。任何帮助表示赞赏。提前致谢!取消勾选复选框没有区别

代码片段:

<form> 
    <label><input type="checkbox" id="check" onchange="sortData(this);" value="sort">Sort Data</label> 
</form> 

<script> 
var data; 
function sortData(cb) { 
    if (cb.checked) { 
    // sort data 
    var checkedData = data; 
    checkedData.sort((a, b) => d3.descending(a[myCategory], b[myCategory])); 
    drawVis(checkedData); 
    } else { 
    // do not sort data 
    console.log("Unchecked!"); 
    drawVis(data); 
    } 
} 

function drawVis(data) { 
    svg.selectAll(".bar").remove(); 
    svg.selectAll("g").remove(); 
    ...... 
    svg.append("g") 
     .attr("class", "axis axis--x") 
     .attr("transform", "translate(0," + height + ")") 
     .call(d3.axisBottom(x)); 

    svg.append("g") 
     .attr("class", "axis axis--y") 
     .call(d3.axisLeft(y)); 

    svg.selectAll(".bar") 
    .data(data) 
    .enter().append("rect"); 
    ...... 
} 
</script> 
+0

你在哪里给'data'赋值? – Ayush

+0

@Ayush我有值分配给'数据',但我省略了这部分代码片段。当复选框被选中时,它会对条进行排序。我不确定,但我不认为问题在于'数据'变量。 – Emile

回答

1

这里的问题必须做的事实,你认为,你克隆data数组中此行:

var checkedData = data; 

但是,不是。所以,当后来你做:

drawVis(data); 

data数组是数组排序。

总之,checkedData只指向data,它不是一个不同的数组。因此,你在其中一个中所做的任何改变都会改变另一个。

让我们在一个正在运行的代码片段中展示它。我会按fakeCopy,但data也改变:

var data = [3, 5, 7, 6, 2, 9, 0, 1, 4, 8]; 
 
var fakeCopy = data; 
 
fakeCopy.sort(); 
 
console.log(data);

解决方案:要真正克隆你data数组,这样做:

var checkedData = JSON.parse(JSON.stringify(data)); 

这样一来,无论你用checkedData做,你保持data不变。

PS:如果您有日期,则使用JSON.parse(JSON.stringify(foo))克隆阵列的此解决方案不起作用。如果这是你的情况,只需搜索“JavaScript深层复制”,你会发现几种不同的方法。

+1

谢谢Gerardo!你的解决方案确实有很大帮助。我没有意识到Javascript也有这个深层复制问题!我是Javascript的新手,但是当我使用Java时,我学到了深度拷贝。 – Emile

相关问题