2016-02-05 99 views
1

我有一個與條形圖協調的畫筆。當畫筆移動並調整大小時,條形圖僅顯示過濾條。在同一頁面中,我有一個餅圖與條形圖和畫筆不協調,但我希望它能成爲。我也希望餅圖根據過濾的值更新其內容。我怎樣才能做到這一點?協調餅圖和條形圖在D3.js

這是我的代碼,隨後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

回答

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); 

});