newChart = {
var timePeriod = 0
const svg = d3.create('svg').attr('width', width).attr('height', height)
var gEntities = svg.append("g")
.attr("id", "Entities")
.selectAll("g")
.data(orderedEntities.filter(d=>d!=""))
.join("g")
.attr("id", d=>d)
.attr('transform',d=> `translate(${getEntityX(d)},${getEntityY(d)+entityHeight})`)
.call(xAxis)
.append("text")
.style("fill", "black")
.style("text-anchor", "middle")
.style("font-size", "12px")
.attr("x", d=> bsMg.left+ (entityWidth-bsMg.inner-bsMg.left)/2)
.attr("y", -entityHeight-10)
.html((d,i) => d)
var gBaseline = svg.append("g")
.attr("id", "Baseline")
.selectAll("g")
.data(orderedEntities)
.join("g")
.attr("id", d=>d)
.attr('transform',d=> `translate(${getEntityX(d)},${getEntityY(d)})`)
.call(g=>g
.append("rect")
.attr("x", d=> xScale(accountNames[0]))
.attr("y", d=> yScale(maxVal-(baselineBump+getBaselineAsset(d))))
.attr('height', d => yScale(baselineBump+getBaselineAsset(d)))
.attr('width', d=>xScale.bandwidth()*entities.includes(d))
.style('fill', baselineColor))
.style("stroke", "#FFF")
.style("stroke-width", 1)
.call(g=>g
.append("rect")
.attr("x", d=> xScale(accountNames[1]))
.attr("y", d=> yScale(maxVal-(baselineBump+getBaselineLiab(d))))
.attr('height', d => yScale(baselineBump+getBaselineLiab(d)))
.attr('width', d=>xScale.bandwidth()*entities.includes(d))
.style('fill', baselineColor)
.style("stroke", "#FFF")
.style("stroke-width", 1))
var gDataGaps = svg.append("g").attr("id", "DataGaps")
svg.select("g#DataGaps").append("g").attr("id", "AssetGaps")
svg.select("g#DataGaps").append("g").attr("id", "LiabGaps")
// ------------- BUTTONS -------------
var buttons = svg.append("g")
.attr("id", "Buttons")
.selectAll("rect")
.data(timePeriods)
.enter().append("rect");
var buttonLabels = svg.selectAll("g#Buttons")
.selectAll("text")
.data(timePeriods)
.enter().append("text");
buttons
.attr("x", (d, i) => (i%5)*2*28 + mg.left)
.attr("y", (d, i) => Math.floor(i/5)*30 )
.attr("rx", 3)
.attr("width", 50)
.attr("height", 25)
.style("fill", d => d === timePeriod ? "#212121" : "#999")
.on("mouseover", changeTime)
.on("mouseleave", mouseLeave);
buttonLabels
.style("fill", "#FFF")
.style("text-anchor", "middle")
.attr("pointer-events", "none")
.attr("x", (d, i) => (i%5)*2*28 + mg.left + 25)
.attr("y", (d, i) => Math.floor(i/5)*30 + 18)
.html((d,i) => i);
// ------------- TITLES -------------
const info = svg.append('foreignObject')
.attr('height', 50)
.attr('width', width)
.attr('x', mg.left)
.attr('y', mg.top)
.append('xhtml:div')
const infoTitle = info.append('h3')
function title() {
infoTitle.html(`${titles[timePeriod]}`)
}
// ------------- TRANSITIONS -------------
// time functions
function mouseEnter() {
d3.select(this)
.style("stroke", "#000")
.style("stroke-width", 1);
}
function mouseLeave() {
d3.select(this)
.style("stroke", "#FFF")
.style("stroke-width", 2);
}
function changeTime() {
timePeriod = d3.select(this).datum();
title();
drawCategories();
buttons.style("fill", d => d == timePeriod ? "#212121" : "#999");
}
// ------------- HOVER -------------
function hoverEntry() {
d3.select(this)
.style("stroke", "#000")
.style("stroke-width", 2);
}
function leaveEntry() {
d3.select(this)
.style("stroke", "#FFF")
.style("stroke-width", 2);
}
// ------------- CREATE GRAPH -------------
function drawCategories () {
const data = dataByTime(accumBS_data,timePeriod)
const bars = svg.select('g')
.selectAll("rect")
.data(data, d=>d.Test)
.join(
enter => enter.append('rect')
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.attr('x', d => xScale(accountNames[d.Account]))
.attr('y', d => yScale(maxVal-d.Value-baselineBump
-getCtgY(d.Entity,d.Category,d.Account,timePeriod)))
.attr('height', d => yScale(d.Value))
.attr('width', xScale.bandwidth())
.style('fill',"white")
.style("stroke", "#FFF")
.style("stroke-width", 1)
.transition().duration(1000)
.style('fill',d => getColor(d.Category))
.selection(),
update => update//.append('rect')
.transition().duration(500)
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.attr('x', d => xScale(accountNames[d.Account]))
.attr('y', d => yScale(maxVal-d.Value-baselineBump
-getCtgY(d.Entity,d.Category,d.Account,timePeriod)))
.attr('height', d => yScale(d.Value))
.attr('width', xScale.bandwidth())
.style('fill',d => getColor(d.Category))
.style("stroke", "#FFF")
.style("stroke-width", 1)
//.end()
.selection(),
exit => exit
.transition().duration(100)
.remove()
)
.on("mouseover", hoverEntry)
.on("mouseleave", leaveEntry);
//------------- IF ASSETS AND LIABILITIES ARE MISMATCHED
//CALLS FUNCTION: getGapY(time,entity,account)
const dataGaps = getBalanceSheetGaps(accumBS_data,timePeriod)
// ASSETS
const aGaps = svg.select('g#AssetGaps')
.selectAll("rect")
.data(dataGaps, d=>d.Entity)
.join(
enter => enter.append("rect").style('fill', "white")
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.transition().duration(500)
.attr("x", d=> xScale(accountNames[0]))
.attr("y", d=> yScale(maxVal-d.Assets-getGapY(timePeriod,d.Entity,0)))
.attr('height', d => yScale(d.Assets))
.attr('width', d=>xScale.bandwidth()*entities.includes(d.Entity))
.style('fill', "white")
.transition().duration(1000)
.style('stroke', gapColor)
.style("stroke-dasharray", ("3, 3"))
.selection(),
update => update.style('fill', "white")
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.transition().duration(500)
.attr("x", d=> xScale(accountNames[0]))
.attr("y", d=> yScale(maxVal-d.Assets-getGapY(timePeriod,d.Entity,0)))
.attr('height', d => yScale(d.Assets))
.attr('width', d=>xScale.bandwidth()*entities.includes(d.Entity))
.style('fill', "white")
.transition().duration(1000)
.style('stroke', gapColor)
.style("stroke-dasharray", ("3, 3"))
.selection(),
exit => exit.remove())
// LIAB
const lGaps = svg.select('g#LiabGaps')
.selectAll("rect")
.data(dataGaps, d=>d.Entity)
.join(
enter => enter.append("rect").style('fill', "white")
// .transition().duration(200)
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.transition().duration(500)
.attr("x", d=> xScale(accountNames[1]))
.attr("y", d=> yScale(maxVal-d.Liab-getGapY(timePeriod,d.Entity,1)))
.attr('height', d => yScale(d.Liab))
.attr('width', d=>xScale.bandwidth()*entities.includes(d.Entity))
.style('fill', "white")
.transition().duration(1000)
.style('stroke', gapColor)
.style("stroke-dasharray", ("3, 3"))
.selection(),
update => update.style('fill', "white")
// .transition().duration(200)
.attr('transform',d=> `translate(${getEntityX(d.Entity)},${getEntityY(d.Entity)})`)
.transition().duration(500)
.attr("x", d=> xScale(accountNames[1]))
.attr("y", d=> yScale(maxVal-d.Liab-getGapY(timePeriod,d.Entity,1)))
.attr('height', d => yScale(d.Liab))
.attr('width', d=>xScale.bandwidth()*entities.includes(d.Entity))
.style('fill', "white")
.transition().duration(1000)
.style('stroke', gapColor)
.style("stroke-dasharray", ("3, 3"))
.selection(),
exit => exit.remove())
}
title()
initialChart(svg)
return svg.node()
}