chart = {
var background_color = "#f2f3f4"
var highlight_color = "#D79922"
var outline_color = "#4056A1"
var center_circle_color = "#C5CBE3"
var font_color = '#303C6C'
var fontsize = d3.scaleSqrt()
.domain([0, 150])
.range([5, 20])
.clamp(true)
const root = packWithMapChildren(data_total);
let focus = root;
console.log(root)
let view;
var current_title = "Click to Zoom"
const svg = d3.create("svg")
.attr("viewBox", `-${width / 2} -${height /(2)} ${width} ${height}`)
.style("display", "block")
.style("margin", "0 0px")
.style("background", background_color)
.on("mouseover", (event) => (svgMouseOut(event, root)))
const toolTip = d3.select("body")
.append("div")
.attr("class", "toolTip")
.style("position", "absolute")
.style("display", "none")
.style("border-radius", "1px")
.style("width", width/3)
.style("height", "auto")
.style("background", background_color)
.style("padding", "0px")
.style("border", "1px solid #DDD")
.style("font-size", "1.1rem")
.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',
notation: 'compact',
// 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)
});
var startTime;
var endTime;
const node = svg.append("g")
.selectAll("circle")
//.data(root)
.data(root.descendants().slice(1))
.join("circle")
.attr("fill", d => d.children ? background_color : toTitleCase(String(d.data[0])) == toTitleCase(String(recipientdrop)) ? highlight_color : center_circle_color)
.attr("stroke", d=> d.children ? highlight_color : toTitleCase(String(d.data[0])) == toTitleCase(String(recipientdrop)) ? highlight_color : outline_color)
.attr("stroke-width", 1)
// .on('touchdown', function() { startTime = new Date(); })
// .on('touchup',function(event, d) {
// endTime = new Date();
// (((endTime - startTime) > 1000) && focus !== d) ? (zoom(d), event.stopPropagation()) : console.log(d)})
//event.stopPropagation stops the mouseover
//being used to trigger a background event
.on("mouseover", (event, d) => (leafMouseOver(event, d), event.stopPropagation()))
.on("mouseout", (event, d) => (leafMouseOut(event, d), event.stopPropagation()))
.on("click", (event, d) => focus !== d ? (zoom(d)) : console.log(d))
.on("touchstart", (event, d) => focus !== d ? (leafMouseOver(event, d)) : console.log(d))
.on("touchend", (event, d) => focus !== d ? (leafMouseOut(event, d), zoom(d)) : console.log(d))
// show tooltip on mousehover
function leafMouseOver(event, d){
d3.selectAll('.toolTip').style("display", "none" )
d3.select(event.target).attr("stroke-width", 10)
d3.select(event.target).attr("stroke", highlight_color)
var formated_money =parseFloat(d.value)*parseFloat(dd3)/root.value
var formated_money = formatter.format(formated_money)
var raw_money = formatter.format(parseFloat(d.value))
var descendents = d.ancestors().map(d => (d.data[0])).join(' -> ')
toolTip
.style("left", (width - d3.select(event.target).attr("cx")) < width/3 ? event.pageX - width/3 + "px": event.pageX + "px")
.style("top", event.pageY + 10 + "px")
.style("display", "block")
.html(`
<b>${toTitleCase(String(d.data[0]))}</b> <br>
Your taxes provide : <strong> ${formated_money} </strong><br>
Total money : <strong> ${raw_money} </strong><br>
Click to zoom in`)
}
function svgMouseOut(event, d){
d3.selectAll('.toolTip').style("display", "none" )
d3.selectAll('.title_desc').style("display", "none" )
}
function leafMouseOut(event, d){
d3.select(event.target).attr("stroke", d=> d.children ? highlight_color : d.data[0] == recipientdrop ? highlight_color : outline_color)
d3.select(event.target).attr("stroke-width", d=> d.data[0] == recipientdrop ? 3 : 1)
//toolTip.style("display", "none" );
}
const label = svg.append("g")
.style("font", "10px sans-serif")
.attr("text-anchor", "middle")
.selectAll("text")
.data(root.descendants())
.join("text")
.style("fill-opacity", d => d.parent === root ? 1 : 0)
.style("display", d => d.parent === root ? "inline" : "none")
.text(d => toTitleCase(String(d.data[0])).substring(0, 30) + "...")
// .on('touchdown', function() { startTime = new Date(); })
// .on('touchup',function(event, d) {
// endTime = new Date();
// (((endTime - startTime) > 1000) && focus !== d) ? (zoom(d), event.stopPropagation()) : console.log(d)})
// .on("click", (event, d) => focus !== d ? (zoom(d), event.stopPropagation()) : console.log(d))
const node_international_affairs = node
//.attr("test", d => console.log(d.descendants().map(d => (d.data[0]))))
.filter(function(d, i) { return d.data[0] == "International Affairs: Budget Function" })
.filter(function(d, i) { return i == 0 })
console.log(node_international_affairs )
if (first_item === recipientdrop) {
zoom(root);
}
else {
node_international_affairs
.each(function(d) {
zoom(d); // d is datum
temp_highlight()
})
}
function temp_highlight(){
node_international_affairs
.each(function(d) {
zoom(d) // d is datum
})
console.log(recipientdrop)
const node_selected = node
//.attr("test", d => console.log(d.descendants().map(d => (d.data[0]))))
.filter(function(d, i) { return d.data[0] == recipientdrop })
console.log(node_selected)
node_selected
.attr("stroke-width", 20)
.attr('stroke-opacity', .8)
}
function zoomTo(v) {
console.log(v)
const k = width / v[2];
view = v;
label.attr("transform", d => d == focus ? `translate(-${0}, -${height * .9 /(2)})` : `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`)
.attr("font-size", d => fontsize(d.r * k))
.style("fill-opacity", d =>d.parent == focus ? 1 : d == focus && d != root ? .9 : 0)
.style("display", d => fontsize(d.r * k) < 10 ? "none": (d.parent == focus | d == focus) ? "inline" : "none")
node.attr("transform", d => `translate(${(d.x - v[0]) * k},${(d.y - v[1]) * k})`);
node.attr("r", d => d.r * k)
}
function zoom(d) {
console.log("zoom")
console.log(d)
const focus0 = focus;
if (d != focus && d.height == 0){
d = d.parent.parent
}
if (d != focus && d.height == 1){
d = d.parent
}
// if (d != focus && d.depth != 1) {
// if (d.parent){
// if (d.parent.children.length == 1){
// d = d.parent
// if (d.parent){
// if (d.parent.children.length == 1){
// d = d.parent
// if (d.parent){
// if (d.parent.children.length == 1){
// d = d.parent
// }
// }
// }
// }
// }
// }}
focus = d;
console.log(focus)
current_title = focus.data[0]
console.log(current_title)
if (focus0 !=focus | focus == root){
zoomTo([focus.x, focus.y, focus.r * 2])}
}
var title1 = svg.append("text")
.attr("x", width / 2 - 100)//`-${width / 2} - 200`)
.attr("y", -height /2 + 100 )//`-${height / 2} - 200`)
.attr("text-anchor", "middle")
.style("cursor", "pointer")
.style("font-size", "18px")
// .on("click", (event, d) => (temp_highlight(), event.stopPropagation()) )
.attr('font-weight', 500)
.style("display", d => recipientdrop != first_item ? "inline" : "none")
.text("Highlight Selected")
.on("mouseover", (event, d) => (d3.select(event.target).style("font-weight", "bold"), temp_highlight(), event.stopPropagation()) )
.on("mouseout", (event, d) => d3.select(event.target).style("font-weight", "normal"))
var title2 = svg.append("text")
.attr("x", width / 2 - 100)//`-${width / 2} - 200`)
.attr("y", -height /2 + 50 )//`-${height / 2} - 200`)
.attr("text-anchor", "middle")
.style("cursor", "pointer")
.style("font-size", "18px")
// .on("click", (event, d) => (zoom(root), event.stopPropagation()) )
.attr('font-weight', 600)
.text("Zoom Out")
.on("mouseover", (event, d) => (d3.select(event.target).style("font-weight", 900), zoom(root), event.stopPropagation()))
.on("mouseout", (event, d) => d3.select(event.target).style("font-weight", 600))
return svg.node();
}