带有可排序条形图的d3 v4单选按钮

时间:2017-08-04 23:35:23

标签: javascript d3.js bar-chart ternary-operator

尝试将单选按钮值传递给对条形图进行排序的函数change()。

jsfiddle is here

首先,我有一组单选按钮,

  <form id="form">
    <input type="radio" name="stack" value="val1">val1<br>
    <input type="radio" name="stack" value="val2">val2<br>
    <input type="radio" name="stack" value="val3">val3<br>
  </form>

我将选中的单选按钮中的值传递给名为change()的函数,

  d3.selectAll("input[name='stack']").on("change", change);

此更改函数应该对xAxis进行排序,

function change() {
  console.log(this.value); // outputs correctly

  var x0 = x.domain(data.sort(this.value = "val1" ?
        function(a, b) {
          return b.val1 - a.val1;
        } :
        function(a, b) {
          return d3.ascending(a.name, b.name);
        })
      .map(function(d) {
        return d.name;
      }))
    .copy();

  svg.selectAll(".bar")
    .sort(function(a, b) {
      return x0(a.name) - x0(b.name);
    });

  var transition = svg.transition().duration(750),
    delay = function(d, i) {
      return i * 50;
    };

  transition.selectAll(".bar")
    .delay(delay)
    .attr("x", function(d) {
      return x0(d.name);
    });

  transition.select(".x.axis")
    .call(xAxis)
    .selectAll("g")
    .delay(delay);
}

我收到错误,

Uncaught TypeError: t.apply is not a function

并参考该行

  .call(xAxis)

先前在代码中使用

创建了xAxis
var xAxis = svg.append("g")
  .attr("class", "axis")
  .attr("transform", "translate(0," + height + ")")
  .call(d3.axisBottom(x));

我可能在sort()中错误地使用了三元运算符。

由于

1 个答案:

答案 0 :(得分:0)

我想出了如何使用三个单选按钮对此条形图进行排序。我使用if else else格式的三元运算符。

此处它位于jsfiddleGithub以及gh-pages

<!DOCTYPE html>

<body>
  <div>
    <form id="form">
      <input type="radio" name="stack" value="val1">blue (val1)
      <br>
      <input type="radio" name="stack" value="val2">white (val2)
      <br>
      <input type="radio" name="stack" value="val3">green (val3)
      <br>
    </form>
  </div>
  <div id="bar_chart">
  </div>
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    var data = [{
      "name": "A",
      "val1": 10,
      "val2": 6,
      "val3": 1

    }, {
      "name": "B",
      "val1": 8,
      "val2": 7,
      "val3": 3
    }, {
      "name": "C",
      "val1": 9,
      "val2": 5,
      "val3": 4
    }]

    data.forEach(function(d) {
      d.value = +d.value;
    });

    var margin = {
        top: 50,
        right: 50,
        bottom: 100,
        left: 80
      },
      width = 1500 - margin.left - margin.right,
      height = 600 - margin.top - margin.bottom;

    var x = d3.scaleBand()
      .domain(data.map(function(d) {
        return d.name
      }))
      .range([0, width / 4]);

    var y1 = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.val1
      })])
      .range([height, 0]);

    var y2 = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.val2
      })])
      .range([height, 0]);

    var y3 = d3.scaleLinear()
      .domain([0, d3.max(data, function(d) {
        return d.val3
      })])
      .range([height, 0]);

    var svg = d3.select("#bar_chart")
      .data(data)
      .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 + ")");

    var xAxis = d3.axisBottom(x)
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis);

    // Add the Y Axis
    svg.append("g")
      .attr("class", "axis")
      .call(d3.axisLeft(y1)
        .ticks(7));

    var tooltip = d3.select("#info")
      .append("div")
      .style("position", "absolute")
      .style("z-index", "10")
      .style("visibility", "hidden");

    var rects = svg.selectAll('rect')
      .data(data);

    //********* Bar Chart 1 ****************
    var newRects1 = rects.enter();

    newRects1.append('rect')
      .attr('x', function(d, i) {
        return x(d.name);
      })
      .attr('y', function(d, i) {
        return y1(d.val1);
      })
      .attr('height', function(d, i) {
        return height - y1(d.val1)
      })
      .attr('opacity', 0.85)
      .attr("class", "bar")
      .attr('width', 40)
      .attr("transform", "translate(" + 27 + ",0)")
      .style('fill', 'blue')
      .style('stroke', 'gray')
      .attr('class', 'bar');

    //********* Bar Chart 2 ****************
    var newRects2 = rects.enter();

    newRects2.append('rect')
      .attr('x', function(d, i) {
        return x(d.name);
      })
      .attr('y', function(d, i) {
        return y1(d.val2);
      })
      .attr('height', function(d, i) {
        return height - y1(d.val2)
      })
      .attr('opacity', 0.85)
      .attr('width', 40)
      .attr("transform", "translate(" + 37 + ",0)")
      .style('fill', 'white')
      .style('stroke', 'gray')
      .attr('class', 'bar');

    //********* Bar Chart 3 ****************
    var newRects3 = rects.enter();

    newRects3.append('rect')
      .attr('x', function(d, i) {
        return x(d.name);
      })
      .attr('y', function(d, i) {
        return y1(d.val3);
      })
      .attr('height', function(d, i) {
        return height - y1(d.val3)
      })
      .attr('width', 40)
      .attr('opacity', 0.95)
      .attr("transform", "translate(" + 47 + ",0)")
      .style('fill', 'green')
      .style('stroke', 'gray')
      .attr('class', 'bar');

    d3.selectAll("input[name='stack']").on("change", change);

    function change() {

      var x0 = x.domain(data.sort(this.value == "val1" ?
          (function(a, b) {
            return b.val1 - a.val1;
          }) : ((this.value == "val2") ?
            (function(a, b) {
              return b.val2 - a.val2;
            }) : (function(a, b) {
              return b.val3 - a.val3;
            }))).map(function(d) {
          return d.name;
        }))
        .copy();

      svg.selectAll(".bar")
        .sort(function(a, b) {
          return x0(a.name) - x0(b.name);
        });

      var transition = svg.transition().duration(750),
        delay = function(d, i) {
          return i * 50;
        };

      transition.selectAll(".bar")
        .delay(delay)
        .attr("x", function(d) {
          return x0(d.name);
        });

      transition.select(".x.axis")
        .call(xAxis)
        .selectAll("g")
        .delay(delay);
    }
  </script>