我有一个使用以下数据集表示三个维度的条形图:
var dataset = [
[5, 23, 75],
[10, 14, 34],
[13, 67, 23],
[19, 10, 65],
[21, 42, 29],
[25, 25, 25],
[22, 90, 30],
[18, 57, 17],
[15, 25, 35],
[13, 26, 39],
[11, 17, 85],
[12, 36, 24],
[15, 60, 45],
[20, 41, 11],
[18, 77, 33],
[17, 85, 55],
[16, 23, 44],
[18, 35, 23],
[23, 55, 15],
[25, 45, 100]
];
具有由svg元素构成的条形图和对条形图进行重新排序的功能:
var sortBars = function() {
svg.selectAll("rect")
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a[0], b[0]);
}
})
.transition()
.duration(1000)
.attr("x", function(d, i) {
return xScale(i);
});
svg.selectAll("text")
.sort(function(a, b) {
if (sortOrder) {
return d3.ascending(a[0], b[0]);
}
})
.transition()
.duration(1000)
.attr("x", function(d, i) {
return xScale(i) + 2.5;
});
};
这将按数组中的第一个变量对条/文本进行重新排序,但是我希望用户看到其他两个变量(a [1],b [1]和a [2],b [2])当他们点击条形图时我正在为一个项目这样做,我的老师建议使用模数(%)运算符在这些变量之间切换,但是我什么也没想!我试着做一个if ... else函数在两个变量之间切换,但是我不认为这是解决方案。预先感谢!
您的讲师想说的是,如果您设置一个计数器,counter % 3
将返回除以3的余数,有效地循环通过0、1和2。在这里看看:
console.log(d3.range(50).map(d => d % 3).join())
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
因此,在您的情况下,我们可以设置一个计数器,并使用余数运算符对条形进行排序。为了避免创建全局计数器,我将在此处创建一个闭包:
bars.on("click", sortBars());
function sortBars() {
let counter = 0;
return function() {
++counter;
bars.sort(function(a, b) {
return d3.ascending(a[counter % 3], b[counter % 3]);
})
.transition()
.attr("x", (_, i) => i * 15)
}
};
这里是使用您的数据的演示:
var dataset = [
[5, 23, 75],
[10, 14, 34],
[13, 67, 23],
[19, 10, 65],
[21, 42, 29],
[25, 25, 25],
[22, 90, 30],
[18, 57, 17],
[15, 25, 35],
[13, 26, 39],
[11, 17, 85],
[12, 36, 24],
[15, 60, 45],
[20, 41, 11],
[18, 77, 33],
[17, 85, 55],
[16, 23, 44],
[18, 35, 23],
[23, 55, 15],
[25, 45, 100]
];
const svg = d3.select("svg");
const bars = svg.selectAll(null)
.data(dataset)
.enter()
.append("rect")
.attr("x", (_, i) => i * 15)
.attr("width", 12)
.attr("y", d => 150 - d[0] * 4)
.attr("height", d => d[0] * 4);
bars.on("click", sortBars());
function sortBars() {
let counter = 0;
return function() {
++counter;
bars.sort(function(a, b) {
return d3.ascending(a[counter % 3], b[counter % 3]);
})
.transition()
.attr("x", (_, i) => i * 15)
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>