D3.js中的协调饼图和条形图

时间:2016-02-05 15:43:01

标签: javascript d3.js charts

我有一个与条形图协调的画笔。移动画笔并调整其大小时,条形图仅显示已过滤的条形图。在同一页面中,我有一个饼图,它不与条形图和画笔协调,但我希望它是。我希望饼图也根据过滤后的值更新其内容。我怎么能这样做?

这是我的代码,然后是plnkr链接,你可以看到我到目前为止所做的事情:

<script type="text/javascript">
  var margin = {
      top: 20,
      right: 20,
      bottom: 70,
      left: 40,
      mid: 20
    },
    w = 750 - margin.left - margin.right,
    h = 300 - margin.top - margin.bottom;
  var barPadding = 1;
  var padding = 20;
  var miniHeight = 60;

  var selected;

  var svg = d3.select(".outer-wrapper .chart").append("svg")
    .attr("width", w + margin.left + margin.right)
    .attr("height", h + margin.top + margin.mid + miniHeight + margin.bottom)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var barsGroup = svg.append('g')
                    .attr("class","barsGroup");

  var miniGroup = svg.append('g')
                    .attr("class","miniGroup")
                    .attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");

  var brushGroup = svg.append('g')
                    .attr("class","brushGroup")
                    .attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");

    var w2 = 400;
    var h2 = 400;

    var outerRadius = w2 / 2;
    var innerRadius = w2 / 3;
    var arc = d3.svg.arc()
                    .innerRadius(innerRadius)
                    .outerRadius(outerRadius);

    var pie = d3.layout.pie()
        .sort(null)
      .value(function(d) { return d.values; });

    var color = d3.scale.category20c();

    var svg2 = d3.select("body")
                .append("svg")
                .attr("width", w2)
                .attr("height", h2);


  d3.csv("data.csv", function(data) {

    var dataset = d3.nest()
      .key(function(d) {
        return d.Year;
      })
      .sortKeys(d3.ascending)
      .rollup(function(values) {
        return values.length;
      })
      .entries(data)
      .filter(function(d) {
        return d.key != "UNK" && d.key != "VAR" && d.key != 199 && d.key != 211 && d.key != 2017;
      });

    //SCALES

    var xScale = d3.scale.ordinal()
      .domain(dataset.map(function(d) {
        return d.key
      }))
      .rangeRoundBands([0, w], 0.05);

    var xScaleBrush = d3.scale.ordinal()
      .domain(d3.range(dataset.length))
        .rangeRoundBands([0, w], 0.05);


    var yScale = d3.scale.linear()
      .domain([0, d3.max(dataset, function(d) {
        return d.values;
      })])
      .range([h, 0]);

    //AXIS

    var xAxis = d3.svg.axis()
      .scale(xScale)
      .orient("bottom")
      .tickValues([1900,1920,1930,1940,1950,1960,1970,1980,1990,2000, 2010]);

    var yAxis = d3.svg.axis()
        .scale(yScale)
        .ticks(6)
        .orient("left");

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0," + h + ")")
      .selectAll("text")
      .style("text-anchor", "end")
      .attr("dx", "-.8em")
      .attr("dy", "-.55em")
      .attr("transform", "rotate(-90)");

    svg.append("g")
        .attr("class","x2 axis")
        .attr("transform", "translate(" + 0 + "," + (margin.top + h + margin.mid + miniHeight) + ")" )
      .call(xAxis)
      .selectAll("text")
      .style("text-anchor", "end")
      .attr("dx", "-.8em")
      .attr("dy", "-.55em")
      .attr("transform", "rotate(-90)");

    svg.append("g")
        .attr("class", "y axis")
      .append("g")
        .attr("class", "axisLabel")
      .append("text")
        .attr("transform", "translate(" + -(margin.left * 0.8) + "," + (h/2) + "), rotate(-90)")
        .style("text-anchor", "middle")
        .text("Score");

    var brush = d3.svg.brush()
      .x(xScaleBrush)
      .extent([0, w])
      .on("brush", display);

    brushGroup.append("g")
      .attr("class", "brush")
      .call(brush)
      .selectAll("rect")
      .attr("opacity", 0.5)
      .attr("height", miniHeight);

    function display() {

        selected =  xScaleBrush.domain()
                                .filter(function(d){
                                    return (brush.extent()[0] <= xScaleBrush(d)) && (xScaleBrush(d) <= brush.extent()[1]);
                                });

        var start;
        var end;

      /* Keep a minimum amount of bars on there to avoid any jank */
      if (selected.length > 2) {
        start = selected[0];
        end = selected[selected.length - 1] + 1;
      } else {
        start = 0;
        end = dataset.length;
      }

      var updatedData = dataset.slice(start, end);

      updateBars(updatedData);

    }

    function update(grp, data, main) {

      grp.selectAll("rect").data(data, function(d) {
          return d.key;
        })
        .attr("x", function(d) {
          return xScale(d.key);
        })
        .attr("y", function(d) {
          return main ? yScale(d.values) : 0;
        })
        .attr("width", function (d) {
                return xScale.rangeBand();
            })
        .attr("height", function(d) {
          return main ? h - yScale(d.values) : miniHeight;
        });
    }

    function enter(grp, data, main) {

      grp.selectAll("rect").data(data, function(d) {
          return d.key;
        })
        .enter()
        .append("rect")
        .attr("x", function(d, i) {
          return xScale(d.key);
        })
        .attr("y", function(d) {
          return main ? yScale( d.values) : 0;
        })
        .attr("width", function(d) {
                return xScale.rangeBand();
            })
        .attr("height", function(d) {
          return main ? h - yScale(d.values) : miniHeight;
        })
        .attr("fill", function(d) {
          var color = d3.scale.linear()
            .domain([0, d3.max(dataset, function(d) {
              return d.values;
            })])
            .range([200, 244]);
            var deg = color(d.values);
                return "hsl(" + deg + ", 100%, 50%)";
        })
        .on("mouseover", function(d) {

          if(main){

          d3.select(this)
            .attr("fill", "orange");

          var xPosition = parseFloat(d3.select(this).attr("x"));
          var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + 100;

          d3.select("#tooltip")
            .style("left", xPosition + "px")
            .style("top", yPosition + "px")
            .style("z-index", "10")
            .select("#value")
            .text(d.values);

          d3.select("#tooltip")
            .select("#key")
            .text("Film del " + d.key + " rilasciati su DVD");

          d3.select("#tooltip").classed("hidden", false);

          }

        })
        .on("mouseout", function(d) {
          d3.select(this)
            .transition()
            .duration(250)
            .attr("fill", function(d) {
              var color = d3.scale.linear()
                .domain([0, d3.max(dataset, function(d) {
                  return d.values;
                })])
                .range([200, 244]);
                var deg = color(d.values);
                    return "hsl(" + deg + ", 100%, 50%)";
            });

          d3.select("#tooltip").classed("hidden", true);
        });

    }


    function exit(grp, data) {

      grp.selectAll("rect").data(data, function(d) {
          return d.key;
        }).exit()
        .remove();

    }

    function updateBars(data) {

      xScale.domain(data.map(function(d) {
        return d.key
      }));
      yScale.domain([0, d3.max(data, function(d) {
        return d.values;
      })]);

      /* Update */
      update(barsGroup, data, true);

      /* Enter… */
      enter(barsGroup, data, true);

      /* Exit */
      exit(barsGroup, data);


        svg.select(".outer-wrapper .chart .y")
            .transition()
            .duration(10)
            .call(yAxis);

        svg.select(".outer-wrapper .chart .x")
            .transition()
            .duration(50)
            .call(xAxis);
    }


    enter(miniGroup, dataset, false);
    updateBars(dataset);


  var dataset2 = d3.nest()
          .key(function(d) { return d.Genre; })
          .sortKeys(d3.ascending)
          .rollup(function(values) {  return values.length; })
          .entries(data);




  var text = svg2.append("text")
            .attr("dx", 200)
            .attr("dy", 200)
            .attr("font-size", 30)
            .style("text-anchor", "middle")
            .attr("fill", "#36454f");

  var text2 = svg2.append("text")
            .attr("dx", 200)
            .attr("dy", 230)
            .attr("font-size", 20)
            .style("text-anchor", "middle")
            .attr("fill", "#36454f");

  var text3 = svg2.append("text")
            .attr("dx", 200)
            .attr("dy", 260)
            .attr("font-size", 20)
            .style("text-anchor", "middle")
            .attr("fill", "#36454f");

    //Set up groups
    var arcs = svg2.selectAll("g.arc")
                  .data(pie(dataset2))
                  .enter()
                  .append("g")
                  .attr("class", "arc")
                  .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
                  .on("mouseover", function(d) {

                     var total = data.length;
             var percent = Math.round(1000 * d.value / total) / 10;

                   text.text(d.data.key).attr("class", "inner-circle");
                   text2.text(d.value + " DVD");
                   text3.text(percent +"%");

                })
                .on("mouseout", function(d) {

                  text.text(function(d) { return ""; });
                  text2.text(function(d) { return ""; });
                  text3.text(function(d) { return ""; });

                });

    //Draw arc paths
    arcs.append("path")
        .attr("fill", function(d, i) {
            return color(i);
        })
        .attr("d", arc);

  });
</script>

http://plnkr.co/edit/cwNl6zUSOM4yPmUtSRr4?p=preview

1 个答案:

答案 0 :(得分:0)

您可以通过将构建pieChart的部分转换为接收新数据的函数来实现。

唯一的调整是,我正在做的第一件事是删除上一个饼图,再次使用新数据绘制它:

function updatePie(data){    
    svg2.selectAll("g.arc").remove();

以下是完整的代码:

<script type="text/javascript">
var margin = {
    top: 20,
    right: 20,
    bottom: 70,
    left: 40,
    mid: 20
  },
  w = 750 - margin.left - margin.right,
  h = 300 - margin.top - margin.bottom;
var barPadding = 1;
var padding = 20;
var miniHeight = 60;

var selected;

var svg = d3.select(".outer-wrapper .chart").append("svg")
  .attr("width", w + margin.left + margin.right)
  .attr("height", h + margin.top + margin.mid + miniHeight + margin.bottom)
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

var barsGroup = svg.append('g')
                    .attr("class","barsGroup");

var miniGroup = svg.append('g')
                    .attr("class","miniGroup")
                    .attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");

var brushGroup = svg.append('g')
                    .attr("class","brushGroup")
                    .attr("transform","translate(" + 0 + "," + (margin.top + h + margin.mid) + ")");

    var w2 = 400;
    var h2 = 400;

    var outerRadius = w2 / 2;
    var innerRadius = w2 / 3;
    var arc = d3.svg.arc()
                    .innerRadius(innerRadius)
                    .outerRadius(outerRadius);

    var pie = d3.layout.pie()
        .sort(null)
    .value(function(d) { return d.values; });

    var color = d3.scale.category20c();

    var svg2 = d3.select("body")
                .append("svg")
                .attr("width", w2)
                .attr("height", h2);


d3.csv("data.csv", function(data) {

  var dataset = d3.nest()
    .key(function(d) {
      return d.Year;
    })
    .sortKeys(d3.ascending)
    .rollup(function(values) {
      return values.length;
    })
    .entries(data)
    .filter(function(d) {
      return d.key != "UNK" && d.key != "VAR" && d.key != 199 && d.key != 211 && d.key != 2017;
    });

  //SCALES

  var xScale = d3.scale.ordinal()
    .domain(dataset.map(function(d) {
      return d.key
    }))
    .rangeRoundBands([0, w], 0.05);

  var xScaleBrush = d3.scale.ordinal()
    .domain(d3.range(dataset.length))
    .rangeRoundBands([0, w], 0.05);


  var yScale = d3.scale.linear()
    .domain([0, d3.max(dataset, function(d) {
      return d.values;
    })])
    .range([h, 0]);

  //AXIS

  var xAxis = d3.svg.axis()
    .scale(xScale)
    .orient("bottom")
    .tickValues([1900,1920,1930,1940,1950,1960,1970,1980,1990,2000, 2010,2020,2030,2040,2050,2060]);

  var yAxis = d3.svg.axis()
    .scale(yScale)
    .ticks(6)
    .orient("left");

  //Appendi asse x
  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + h + ")")
    .selectAll("text")
    .style("text-anchor", "end")
    .attr("dx", "-.8em")
    .attr("dy", "-.55em")
    .attr("transform", "rotate(-90)");

  //Asse x per brush
  svg.append("g")
    .attr("class","x2 axis")
    .attr("transform", "translate(" + 0 + "," + (margin.top + h + margin.mid + miniHeight) + ")" )
    .call(xAxis)
    .selectAll("text")
    .style("text-anchor", "end")
    .attr("dx", "-.8em")
    .attr("dy", "-.55em")
    .attr("transform", "rotate(-90)");

  svg.append("g")
    .attr("class", "y axis")
    .append("g")
    .attr("class", "axisLabel")
    .append("text")
    .attr("transform", "translate(" + -(margin.left * 0.8) + "," + (h/2) + "), rotate(-90)")
    .style("text-anchor", "middle")
    .text("Score");

  var brush = d3.svg.brush()
    .x(xScaleBrush)
    .extent([0, w])
    .on("brush", display);

  brushGroup.append("g")
    .attr("class", "brush")
    .call(brush)
    .selectAll("rect")
    .attr("opacity", 0.5)
    .attr("height", miniHeight);

  function display() {

    selected =  xScaleBrush.domain()
                            .filter(function(d){
                                return (brush.extent()[0] <= xScaleBrush(d)) && (xScaleBrush(d) <= brush.extent()[1]);
                            });

    var start;
    var end;

    /* Keep a minimum amount of bars on there to avoid any jank */
    if (selected.length > 2) {
      start = selected[0];
      end = selected[selected.length - 1] + 1;
    } else {
      start = 0;
      end = dataset.length;
    }

    var updatedData = dataset.slice(start, end);

    updateBars(updatedData);
    updatePie(updatedData);

  }

  function update(grp, data, main) {

    grp.selectAll("rect").data(data, function(d) {
        return d.key;
      })
      .attr("x", function(d) {
        return xScale(d.key);
      })
      .attr("y", function(d) {
        return main ? yScale(d.values) : 0;
      })
      .attr("width", function (d) {
            return xScale.rangeBand();
        })
      .attr("height", function(d) {
        return main ? h - yScale(d.values) : miniHeight;
      });
  }

  function enter(grp, data, main) {

    grp.selectAll("rect").data(data, function(d) {
        return d.key;
      })
      .enter()
      .append("rect")
      .attr("x", function(d, i) {
        return xScale(d.key);
      })
      .attr("y", function(d) {
        return main ? yScale( d.values) : 0;
      })
      .attr("width", function(d) {
            return xScale.rangeBand();
        })
      .attr("height", function(d) {
        return main ? h - yScale(d.values) : miniHeight;
      })
      .attr("fill", function(d) {
        var color = d3.scale.linear()
          .domain([0, d3.max(dataset, function(d) {
            return d.values;
          })])
          .range([200, 244]);
          var deg = color(d.values);
                return "hsl(" + deg + ", 100%, 50%)";
      })
      .on("mouseover", function(d) {

        if(main){

        d3.select(this)
          .attr("fill", "orange");

        var xPosition = parseFloat(d3.select(this).attr("x"));
        var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + 100;

        d3.select("#tooltip")
          .style("left", xPosition + "px")
          .style("top", yPosition + "px")
          .style("z-index", "10")
          .select("#value")
          .text(d.values);

        d3.select("#tooltip")
          .select("#key")
          .text("Film del " + d.key + " rilasciati su DVD");

        d3.select("#tooltip").classed("hidden", false);

        }

      })
      .on("mouseout", function(d) {
        d3.select(this)
          .transition()
          .duration(250)
          .attr("fill", function(d) {
            var color = d3.scale.linear()
              .domain([0, d3.max(dataset, function(d) {
                return d.values;
              })])
              .range([200, 244]);
              var deg = color(d.values);
                    return "hsl(" + deg + ", 100%, 50%)";
          });

        d3.select("#tooltip").classed("hidden", true);
      });

  }


  function exit(grp, data) {

    grp.selectAll("rect").data(data, function(d) {
        return d.key;
      }).exit()
      .remove();

  }

  function updateBars(data) {

    xScale.domain(data.map(function(d) {
      return d.key
    }));
    yScale.domain([0, d3.max(data, function(d) {
      return d.values;
    })]);

    /* Update */
    update(barsGroup, data, true);

    /* Enter… */
    enter(barsGroup, data, true);

    /* Exit */
    exit(barsGroup, data);


    svg.select(".outer-wrapper .chart .y")
        .transition()
        .duration(10)
        .call(yAxis);

        svg.select(".outer-wrapper .chart .x")
        .transition()
        .duration(50)
        .call(xAxis);
  }


  enter(miniGroup, dataset, false);
  updateBars(dataset);

var dataset2 = d3.nest()
        .key(function(d) { return d.Genre; })
        .sortKeys(d3.ascending)
        .rollup(function(values) {  return values.length; })
        .entries(data);


var text = svg2.append("text")
          .attr("dx", 200)
          .attr("dy", 200)
          .attr("font-size", 30)
          .style("text-anchor", "middle")
          .attr("fill", "#36454f");

var text2 = svg2.append("text")
          .attr("dx", 200)
          .attr("dy", 230)
          .attr("font-size", 20)
          .style("text-anchor", "middle")
          .attr("fill", "#36454f");

var text3 = svg2.append("text")
          .attr("dx", 200)
          .attr("dy", 260)
          .attr("font-size", 20)
          .style("text-anchor", "middle")
          .attr("fill", "#36454f");

function updatePie(data){
  svg2.selectAll("g.arc").remove();
  var arcs = svg2.selectAll("g.arc")
        .data(pie(data))
        .enter()
        .append("g")
        .attr("class", "arc")
        .attr("transform", "translate(" + outerRadius + "," + outerRadius + ")")
        .on("mouseover", function(d) {

           var total = data.length;
           var percent = Math.round(1000 * d.value / total) / 10;

           text.text(d.data.key).attr("class", "inner-circle");
           text2.text(d.value + " DVD");
           text3.text(percent +"%");

        })
        .on("mouseout", function(d) {

          text.text(function(d) { return ""; });
          text2.text(function(d) { return ""; });
          text3.text(function(d) { return ""; });

        });
  arcs.append("path")
    .attr("fill", function(d, i) {
      return color(i);
    })
    .attr("d", arc);

}
updatePie(dataset2);

});