javascript - Coordinated pie chart and bar chart in D3.js -
i have brush coordinated bar chart. when brush moved , resized bar chart shows filtered bars. in same page have pie chart isn't coordinated bar chart , brush, want be. want pie chart updates content according filtered values. how can that?
this code, followed plnkr link can see i've done far:
<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 minimum amount of bars on there avoid 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 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>
you can transforming part build piechart function receives new data.
the adjustment first thing i'm doing removing previous pie chart, draw again new data:
function updatepie(data){ svg2.selectall("g.arc").remove();
here complete code:
<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 minimum amount of bars on there avoid 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); });
Comments
Post a Comment