Redraw d3 pie chart on click
I have two d3 chart one pie and one bar. I would like to redraw the pie chart when the bar is clicked. The pie chart should take the key of te bar chart element selected.
I succeed to create a new pie chart each time a click append but I do not understand how I am suppose to implement to the onclick function to redraw the pie instead of creates a new one.
main.js
/*
MAIN CONTROLLER
- Instantiates data manager, and makes it load data
- Gives dashboard DOM structure
- Generates bar charts in dashboard
- Feeds data from data manager into bar charts
- Provides bar charts click interaction
Author: Pierre Le Bras
Date Created: 31/10/17
*/
var dataManager = {};
function startApplication(){
dataManager = dataManager();
dataManager.loadCsv("csvFiles/REF2014_Results.csv",
function(error){ // to call in case of error
console.log("Error");
console.log(error);
},
function(){ // to call if everything ok
makePage();
});
}
function makePage(){
var dash = d3.select('div#dashboard');
// EDIT PAGE STRUCTURE
dash.append('div')
.attr('id', 'bar1') // for renderer generation
.classed("barchart", true) // for styling
.append("h3").text("Number of submission per Univsersity");
// APPEND VISUALISATION
var bar1 = barchart("div#bar1")
.setHeight(200)
.setWidth(800)
.setColor("#2b38c5")
.setTooltipText(function(d, i){
return "<b>"+d.key+"</b>: "+(d.value);
})
.loadAndRender(dataManager.getByName());
bar1.setMouseclickCallback(function (d,i) {
redraw();
})
// Piechart
dash.append('div').attr('id','pie1').classed('piechart',true).append("h3").text("Number of submission by categories");
var t = ["Anglia Ruskin University"];
var s = ["Aston University"];
var pie1 = piechart("div#pie1")
.setHeight(960)
.setWidth(500)
.setRadius(960, 500)
.setTooltipText(function (d, i) {
return "<b>" + d.data.key + "</b>: " + (d.value);
})
.loadAndRender(dataManager.getArea(t))
function redraw(){
// just feed data to bars, dataManager will handle filters
bar1.loadAndRender(dataManager.getByName());
pie1.loadAndRender(dataManager.getArea());
}
}
pie.js
function piechart(DOMElement){
var pieObj = {}; // main object
// ---- PUBLIC API
// Sizing variables setters
// parameters:
// - value
// returns:
// - pieObj for chaining
pieObj.setWidth = function(w){
width = w;
render();
return pieObj;
}
pieObj.setHeight = function(h){
height = h;
render();
return pieObj;
}
pieObj.setRadius = function(h,w){
radius = Math.min(w,h)/2 ;
render();
return pieObj;
}
pieObj.setTooltipText = function(f){
tooltipText = f;
updateInteractions();
return pieObj;
}
pieObj.setMouseoverCallback = function(f){
mouseoverCallback = f;
updateInteractions();
return pieObj;
}
pieObj.setMouseoutCallback = function(f){
mouseoutCallback = f;
updateInteractions();
return pieObj;
}
pieObj.setMouseclickCallback = function(f){
mouseclickCallback = f;
updateInteractions();
return pieObj;
}
pieObj.loadAndRender = function(data,to_array){
if (to_array = true) {
var arr = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
arr.push({
key: key,
value: data[key]
});
}
}
dataset = arr;
}
console.log('lol',dataset);
render();
return pieObj;
}
// ---- PRIVATE VARIABLES
// dom elements
var svg = d3.select(DOMElement).append("svg")
.attr("width", width)
.attr("height", height)
.append("pies")
.attr("transform", "translate(" + radius + "," + radius + ")");
var tooltip = d3.select(DOMElement).append("div")
.classed("tooltip", true);
// scales
var xScale = d3.scaleBand(),
yScale = d3.scaleLinear();
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal()
.range(["#2b1dc5", "#3f1da6", "#531988"]);
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var labelArc = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
var pie = d3.pie()
.sort(null)
.value(function(d) { return d.value; });
var svg = d3.select(DOMElement).append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// data
var dataset =[];
// interaction settings
var tooltipText = function(d, i){return "tooltip over element "+i;}
var mouseoverCallback = function(d, i){ };
var mouseoutCallback = function(d, i){ };
var mouseclickCallback = function(d, i){ console.log(d, i) };
var keySelected = null;
// ---- PRIVATE FUNCTIONS
function render(){
GUP_pies();
updateStyles();
updateInteractions();
}
function GUP_pies(){
var increments = 300;
var t1 = d3.transition().duration(increments),
t2 = d3.transition().delay(increments).duration(increments),
t3 = d3.transition().delay(increments*2).duration(increments),
t4 = d3.transition().delay(increments*3).duration(increments);
var g = svg.selectAll(".arc")
.data(pie(dataset))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.transition(t4)
.style("fill", function(d) { return color(d.value); });
g.append("text")
.attr("transform", function(d) { return "translate(" + labelArc.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.value; });
g.transition(t2)
.attr("class",arc);
}
function updateStyles(){
// separate function for styles,
// this way there is no need to do GUP when just changing colour
svg.selectAll(".arc")
.style("fill", color)
.style("stroke", "#424242")
.style("opacity", 1.0)
}
function updateInteractions(){
// separate function for interactions,
// this way there is no need to do GUP when just changing callbacks
svg.selectAll(".arc")
.on("mouseover", function(d, i){
d3.select(this).style("opacity", 0.7);
tooltip.html(tooltipText(d,i))
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("opacity", 0.9);
mouseoverCallback(d, i);
})
.on("mouseout", function(d, i){
d3.select(this).style("opacity", 1.0);
tooltip.style("opacity", 0);
mouseoutCallback(d, i);
})
}
return pieObj; // returning the main object
}
bar.js
function barchart(DOMElement){
var barObj = {}; // main object
// ---- PUBLIC API
// Sizing variables setters
// parameters:
// - value
// returns:
// - barObj for chaining
barObj.setWidth = function(w){
svgWidth = w;
render();
return barObj;
}
barObj.setHeight = function(h){
svgHeight = h;
render();
return barObj;
}
barObj.setPadding = function(p){
svgPadding = p;
render();
return barObj;
}
// Styling variables setters
// parameters:
// - value
// returns:
// - barObj for chaining
barObj.setColor = function(c){
barColor = c;
updateStyles();
return barObj;
}
// Callbacks setters
// parameters:
// - callback
// returns:
// - barObj for chaining
barObj.setTooltipText = function(f){
tooltipText = f;
updateInteractions();
return barObj;
}
barObj.setMouseoverCallback = function(f){
mouseoverCallback = f;
updateInteractions();
return barObj;
}
barObj.setMouseoutCallback = function(f){
mouseoutCallback = f;
updateInteractions();
return barObj;
}
barObj.setMouseclickCallback = function(f){
mouseclickCallback = f;
updateInteractions();
return barObj;
}
// function loading data and rendering it in bar chart
// parameters:
// - dataset in following format:
// [{"key": year, "value": money}, {...}, ...]
// returns:
// - barObj for chaining
barObj.loadAndRender = function(data){
dataset = data;
render();
return barObj;
}
// ---- PRIVATE VARIABLES
// sizing vars
var svgWidth = 800,
svgHeight = 600,
svgPadding = 20;
// styling vars
var barColor = "#009688";
// dom elements
var svg = d3.select(DOMElement).append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight);
var tooltip = d3.select(DOMElement).append("div")
.classed("tooltip", true);
// scales
var xScale = d3.scaleBand(),
yScale = d3.scaleLinear();
// data
var dataset = [];
// interaction settings
var tooltipText = function(d, i){return "tooltip over element "+i;}
var mouseoverCallback = function(d, i){ };
var mouseoutCallback = function(d, i){ };
var mouseclickCallback = function(d, i){ console.log(d,i)};
var keySelected = null;
// ---- PRIVATE FUNCTIONS
function render(){
svg.attr("width", svgWidth)
.attr("height", svgHeight);
updateScales();
GUP_bars();
updateInteractions();
updateStyles();
}
function updateScales(){
xScale.domain(dataset.map(function(d){return d.key;}))
.paddingInner(0.1)
.range([svgPadding, svgWidth-svgPadding]);
yScale.domain([0, d3.max(dataset, function(d){return d.value;})])
.range([0, svgHeight-svgPadding*2]);
}
function GUP_bars(){
// transitions
var increments = 300;
var t1 = d3.transition().duration(increments),
t2 = d3.transition().delay(increments).duration(increments),
t3 = d3.transition().delay(increments*2).duration(increments),
t4 = d3.transition().delay(increments*3).duration(increments);
// GUP
var bars = svg.selectAll("rect.bar") // Selection
.data(dataset, d=>d.key) // Bind
// exit
bars.exit().transition(t1)
.attr("y", svgHeight-svgPadding)
.attr("height", 0)
.remove();
// enter
bars.enter().append("rect")
.classed("bar", true)
.attr("x", d=>xScale(d.key))
.attr("width", xScale.bandwidth())
.attr("height", 0)
.attr("y", svgHeight-svgPadding)
.transition(t4)
.attr("y", d=>svgHeight-svgPadding-yScale(d.value))
.attr("height", d=>yScale(d.value));
// update
bars.transition(t2)
.attr("y", d=>svgHeight-svgPadding-yScale(d.value))
.attr("height", d=>yScale(d.value))
.transition(t3)
.attr("x", d=>xScale(d.key))
.attr("width", xScale.bandwidth());
}
function updateStyles(){
// separate function for styles,
// this way there is no need to do GUP when just changing colour
svg.selectAll("rect.bar")
.style("fill", barColor)
.style("stroke", "#424242")
.style("stroke-width", d=>keySelected == d.key ? "5px": "0px")
.style("opacity", 0.7)
}
function updateInteractions(){
// separate function for interactions,
// this way there is no need to do GUP when just changing callbacks
svg.selectAll("rect.bar")
.on("mouseover", function(d, i){
d3.select(this).style("opacity", 1);
tooltip.html(tooltipText(d,i))
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px")
.style("opacity", 0.9);
mouseoverCallback(d, i);
})
.on("mouseout", function(d, i){
d3.select(this).style("opacity", 0.7);
tooltip.style("opacity", 0);
mouseoutCallback(d, i);
})
.on("click", function(d, i) {
var color = ["#009688","#968118","#009688",];
var p = d3.select("#pie1").selectAll(".arc");
console.log(p);
p
.data(p.pie(dataManager.getArea(d.key)))
.enter().append("p")
.attr("class","arc")
render();
console.log(p);
})
}
return barObj; // returning the main object
}
链接地址: http://www.djcxy.com/p/84206.html
上一篇: 有没有办法限制Firebase中的注册
下一篇: 单击重绘d3饼图