chart = {
var background_color = "#f2f3f4"
var unicef_color = "green"
var wfp_color = "blue"
var highlight_color = "#D79922"
var outline_color = "#4056A1"
var center_circle_color = "#C5CBE3"
var federal_color = "#f13C20"
var font_color = '#303C6C'
var fontsize = d3.scaleSqrt()
.domain([0, 250])
.range([6, 16])
.clamp(true)
const svg = d3.create("svg")
.attr("viewBox", `-${width / 2} -${height /(2)} ${width} ${height}`)
.style("display", "block")
.style("background",background_color)
.style("cursor", "pointer")
const toolTip = d3.select("body")
.append("div")
.attr("class", "toolTip")
.style("position", "absolute")
.style("display", "none")
.style("border-radius", "5px")
.style("height", "auto")
.style("background", "white")
.style("padding", "9px")
.style("border", "1px solid #DDD")
.style("font-size", "0.8rem")
.style("text-align", "left")
//https://stackoverflow.com/questions/149055/how-to-format-numbers-as-currency-strings
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
// These options are needed to round to whole numbers if that's what you want.
//minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
// maximumFractionDigits: 0, // (causes 2500.99 to be printed as $2,501)
});
// apple mouseovers
function leafMouseOver(event, d){
d3.select(event.target).attr("stroke-width", 4)
d3.select(event.target).attr("stroke", highlight_color)
var formattedString = String(d.data.award_description.join("<br/>"))
var formattedString = String(d.data.award_description.join("<br/>"))
var formated_money =parseFloat(d.data.outlay)*parseFloat(dd3)/8992408699023
formated_money = formatter.format(formated_money)
toolTip.style("left", event.pageX + 18 + "px")
.style("top", event.pageY + 18 + "px")
.style("display", "block")
.html(`
<b>Award Recipiant</b> : ${d.data.name} <br>
<b>Your taxes provide</b> : ${formated_money} <br>
<b> First Sentence in Wikipedia</b> : ${formattedString}<br>`);
}
function leafMouseOut(event, d){
d3.select(event.target).attr("stroke", d => d.data.column_name == "federal_account_name" ? federal_color: (d.data.name == "International Affairs" || d.data.name == "Agency For International Development") ? highlight_color : outline_color)
d3.select(event.target).attr("stroke-width",d =>(d.data.name == "International Affairs" || d.data.name == "Agency for International Development") ? 5 : d => d.data.un_money == "no"? 5: 1)
toolTip.style("display", "none");
}
function setYear(level) {
function zoomTo(v) {
toolTip.style("display", "none");
k = width *.9 / v[2];
view = v;
node
.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`)
.attr("r", d => d.r * k);
label.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`)
.attr("font-size", d => fontsize(d.r * k))
.style("fill-opacity", function(d) { if (fontsize(d.r * k) > 6 && d.parent == focus) {return 1} else {return 0} })
.text(function (d) {
return d.data.name.substring(0, 20) + "...";
})
}
function zoom(d) {
const focus0 = focus;
if (d.height ==0)
{
focus = d.parent}
else {focus = d}
const transition = svg.transition()
.duration(1500)
.tween("zoom", d => {
const i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2]);
return t => zoomTo(i(t));
});
}
var variable = {"data": account_recipients, "opacity_true": true, "opacity_name": "Agency for International Development", "zoom_in": false, "zoom_name": "Agency for International Development", "text_title1": "The agencies (biggest circle) decide how to allocate funds to recipients", "text_title2": "These Federal Accounts (orange circles) are a small faction of the total Federal Accounts", "text_title3": "Double click the smallest circle to see recipients. WFP is in blue, UNICEF is green", "text_title1_color": true, "text_title2_color": false, "text_title3_color": false, "head_title": "Federal Funds Provided to Recipients in 2020", "starting_opacity": 0}
console.log(variable)
const root = pack(variable.data)
var opacity_true = variable.opacity_true
var opacity_name = variable.opacity_name
var zoom_in = variable.zoom_in
var zoom_name = variable.zoom_name
var starting_opacity = variable.starting_opacity
var head_title = variable.head_title
var text_title1 = variable.text_title1
var text_title2 = variable.text_title2
var text_title3 = variable.text_title3
var text_title1_color = variable.text_title1_color
var text_title2_color = variable.text_title2_color
var text_title3_color = variable.text_title3_color
var v = [root.x, root.y, root.r * 2]
var view = v
let focus = root;
let format = d3.format(",d")
let current_circle = undefined;
var k = 1
var node = svg.append("g")
.selectAll("circle")
.data(root.descendants().slice(1), d => d.data.key)
var label = svg.append("g")
.selectAll("text")
.data(root.descendants().slice(1), d => d.data.key)
const t = svg.transition()
.duration(1500);
svg
.on("dblclick", (event) => zoom( root));
node = node
.join(
enter => enter.append('circle')
.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`)
.attr("r", d => d.r * k)
//if there are still children, color by how far in you are
.attr("stroke", d => d.data.column_name == "federal_account_name" ? highlight_color: (d.data.name == "International Affairs" || d.data.name == "Agency For International Development" ) ? highlight_color : outline_color)
.attr("stroke-width", d => (d.data.name == "International Affairs" || d.data.name == "Agency For International Development") ? 5 : 2)
.attr("fill", d => d.children ? background_color: d.data.name =="World Food Program" ? wfp_color: d.data.name =="Unicef" ? unicef_color: center_circle_color)
.attr("opacity", starting_opacity)
.attr("class", d=> d.data.name == zoom_name ? "pick_me": "never_mind")
.on("dblclick", (event, d) => focus !== d && (zoom(d), event.stopPropagation()))
.on("mouseover", (event, d) => leafMouseOver(event, d))
.on("mouseout", (event, d) => leafMouseOut(event, d)),
)
node
.transition()
.duration(2000)
.attr('opacity', d => opacity_true ? .6 : (d.data.un_money == "yes" ) ? .2 : .6)
label = label
.join(
enter => enter.append('text')
.attr("pointer-events", "none")
.attr("text-anchor", "middle")
.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`)
.attr("opacity", starting_opacity)
//label resized using new radius
.attr("font-size", d => fontsize(d.r * k))
.style("fill", font_color)
.style("fill-opacity", function(d) { if (fontsize(d.r * k) > 6 && d.depth == 1) {return 1} else {return 1} })
.text(function (d) {
var formated_money =parseFloat(d.data.outlay)*parseFloat(dd3)/8992408699023
formated_money = formatter.format(formated_money)
return d.data.name + ": " + formated_money ;
})
)
label
.transition()
.attr('opacity', d => opacity_true ? 1 : (d.data.un_money == "yes" ) ? 1 : 0)
d3.selectAll('circle.pick_me').attr("stroke", highlight_color)
d3.selectAll('circle.pick_me').filter(function(d, i) { return i == 0 }).select(function(d) {zoom_in ? zoom(d): console.log("nope")})
// tooltip + styling
var second_title = svg.append("text")
.attr("x", 0)
.attr("y", -height/2 + 30)
.attr("text-anchor", "middle")
.style("font-size", "16px")
second_title.text(head_title)
}
return Object.assign(svg.node(), { setYear });
}