D3 添加饼图防止条形图的可排序性

D3 adding pie chart prevents sortability of bar chart

我已经成功创建了一个排序条形图。但是当我向页面添加饼图时,我发现条形图不再排序。

每个都使用单独的数据,分别称为 'data' 和 'data1',并且它们分别是单独的 svg 附加到单独的 div 中,id 分别为 'bar_chart' 和 'pie。

当我注释掉饼图时,条形图再次正确排序。

jsFiddle-Complete and here is the same code only without the pie chart jsFiddle-no-pie-chart

工作的 jsFiddle 有完整的代码。

    <!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>
      <div id="pie">
      </div>
      <script src="https://d3js.org/d3.v4.min.js"></script>
      <script>
        var data = [.........]

        var data2 = [........]

        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('opacity', 0.85)
          .attr('width', 40)
          .attr("transform", "translate(" + 27 + ",0)")
          .style('fill', 'blue')
          .style('stroke', 'gray')
          .attr('class', 'bar')
          .attr('y', function(d, i) {
            return y1(d.val1);
          })
          .attr('height', function(d, i) {
            return height - y1(d.val1)
          });

        //********* Bar Chart 2 ****************
      .........
      .........

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) {
          // console.log("transition name001")
          return x0(a.name) - x0(b.name);
        });

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

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

      transition.select(".x.axis")
        .call(xAxis)
        .selectAll("g")
        .delay(delay);
    }
        //******** PIE CHART **********

        var width = 300,
          height = 300,
          radius = Math.min(width, height) / 2;

        var color = ["#2C93E8", "#838690", "#F56C4E", "#A60F2B", "#648C85", "#B3F2C9", "#528C18", "#C3F25C"];

        // Generate an array object on categories as a category
        var category_count = d3.nest()
          .key(function(d) {
            return d.category;
          })
          .rollup(function(leaves) {
            return leaves.length;
          })
          .entries(data2);

        var category_arcs = d3.pie()
          .value(function(d) {
            return d.value;
          })
          (category_count);

        var pie = d3.pie()
          .value(function(d) {
            return d.category;
          })(category_arcs);

        var arc = d3.arc()
          .outerRadius(radius - 10)
          .innerRadius(0);

        var labelArc = d3.arc()
          .outerRadius(radius - 10)
          .innerRadius(radius - 150);

        var svg = d3.select("#pie")
          .append("svg")
          .attr("width", width)
          .attr("height", height)
          .append("g")
          .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // Moving the center point. 1/2 the width and 1/2 the height

        var g = svg.selectAll("arc")
          .data(category_arcs)
          .enter().append("g")
          .attr("class", "arc");

        g.append("path")
          .attr("d", arc)
          .style("fill", function(d, i) {
            return color[i];
          });

        g.append("text")
          .attr("transform", function(d) {
            return "translate(" + labelArc.centroid(d) + ")";
          })
          .text(function(d) {
            return d.data.key + " = " + d.value;
          })
          .style("fill", "black");

        g.append("text")
          .attr("transform", "translate(" + (0 - (radius / 2)) + "," + (0 - radius + 10) + ")")
          .text("Count occurences of each category")
          .style("fill", "black");

      </script>

在饼图的第 305 行:

var svg = d3.select("#pie")

这会覆盖您在 change() 函数中使用的 svg。您需要将其更改为 pie_svg 或其他唯一名称。