在D3中排序条形图

Sorting bar charts in D3

本文关键字:条形图 排序 D3      更新时间:2023-09-26

我在D3中创建了一个条形图,我试图对条形图中的条形图按升序排序,然后在再次单击时下降。我在代码片段的末尾添加了必要的排序代码,但是单击时什么也没有发生(这些栏不排序)。不知道我在这里错过了什么,任何帮助都会很感激!

    <script>
    var margin = {top: 40, right: 20, bottom: 30, left: 40},
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;
    var formatPercent = d3.format(".0%");
    var x = d3.scale.ordinal()
        .rangeRoundBands([0, width], .1);
    var y = d3.scale.linear()
        .range([height, 0]);
    var xAxis = d3.svg.axis()
        .scale(x)
        .orient("bottom");
    var yAxis = d3.svg.axis()
        .scale(y)
        .orient("left")
        .tickFormat(formatPercent);
    var tip = d3.tip()
      .attr('class', 'd3-tip')
      .offset([-10, 0])
      .html(function(d) {
        return "<strong>Frequency:</strong> <span style='color:red'>" + d.frequency + "</span>";
      })
    var svg = d3.select("body").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
      .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    svg.call(tip);
    d3.tsv("data/bar-graph-tooltips.tsv", type, function(error, data) {
      x.domain(data.map(function(d) { return d.letter; }));
      y.domain([0, d3.max(data, function(d) { return d.frequency; })]);
      svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis);
      svg.append("g")
          .attr("class", "y axis")
          .call(yAxis)
        .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Frequency");
      svg.selectAll(".bar")
          .data(data)
        .enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) { return x(d.letter); })
          .attr("width", x.rangeBand())
          .attr("y", function(d) { return y(d.frequency); })
          .attr("height", function(d) { return height - y(d.frequency); })
          .on('mouseover', tip.show)
          .on('mouseout', tip.hide)
          .on("click", function() {sortBars();});
          //Define sort order flag
        var sortOrder = false;
        //Define sort function
        var sortBars = function() {
            //Flip value of sortOrder
            sortOrder = !sortOrder;
            svg.selectAll("rect")
               .sort(function(a, b) {
                    if (sortOrder) {
                        return d3.ascending(a, b);
                    } else {
                        return d3.descending(a, b);
                    }
                })
               .transition()
               .delay(function(d, i) {
                   return i * 50;
               })
               .duration(1000)
               .attr("x", function(d, i) {
                    return xScale(i);
               });
        };          
    });

    function type(d) {
      d.frequency = +d.frequency;
      return d;
    }
    </script>

您需要设置需要在a, b中排序的值,这里:

.sort(function(a, b) {
                if (sortOrder) {
                    return d3.ascending(a, b);
                } else {
                    return d3.descending(a, b);
                }

类似于:a.value, b.value,但这取决于您的tsv的结构