我正在用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 :(得分: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深层复制”,您就会找到几种不同的方法。