条形图在数组中的三个变量之间切换

问题描述 投票:1回答:1

我有一个使用以下数据集表示三个维度的条形图:

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函数在两个变量之间切换,但是我不认为这是解决方案。预先感谢!

javascript d3.js
1个回答
0
投票

您的讲师想说的是,如果您设置一个计数器,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>
© www.soinside.com 2019 - 2024. All rights reserved.