chart = {
let svg = d3.select(DOM.svg(width + margin.left + margin.top, height + margin.top + margin.bottom))
let barCenter = horzScale.bandwidth() / 2;
let chart = svg.append("g").classed("chart", true).attr("transform", `translate(${margin.left}, ${margin.top})`)
chart.selectAll("rect.bar")
.data(dataset)
.join("rect")
.classed("bar", true)
.attr("x", (d)=>horzScale(d[0]))
.attr("y", (d)=>{
let {Online, Offline} = d[1],
max = Math.max(Online, Offline);
return vertScale(max);
})
.attr("width", horzScale.bandwidth())
.attr("height", (d)=>{
let {Online, Offline} = d[1]
return (height - vertScale(Math.abs(Online - Offline)))
})
.attr("fill", "gray")
var popup = null;
chart.selectAll("circle.online")
.data(dataset)
.join("circle")
.classed("online", true)
.attr("cx", (d)=>(horzScale(d[0])+barCenter))
.attr("cy", (d)=>(vertScale(d[1].Online)))
.attr("r", 7)
.attr("fill", "steelblue")
.style("cursor", "pointer")
.on("mouseover", function(event, d){
let x = horzScale(d[0]) + barCenter,
y = vertScale(d[1].Online)
popup.attr("transform", `translate(${x}, ${y}) rotate(-10)`)
callout(popup, [`${d[0]}(Online)`, revenueFormat(d[1].Online)])
})
.on("mouseout", function(){
popup.style("display", "none")
})
chart.selectAll("circle.offline")
.data(dataset)
.join("circle")
.classed("offline", true)
.attr("cx", (d)=>(horzScale(d[0])+barCenter))
.attr("cy", (d)=>(vertScale(d[1].Offline)))
.attr("r", 7)
.attr("fill", "red")
.style("cursor", "pointer")
.on("mouseover", function(event, d){
let x = horzScale(d[0]) + barCenter,
y = vertScale(d[1].Offline)
popup.attr("transform", `translate(${x}, ${y}) rotate(-10)`)
callout(popup, [`${d[0]}(Offline)`, revenueFormat(d[1].Offline)])
})
.on("mouseout", function(){
popup.style("display", "none")
})
chart.call(horzAxis)
chart.call(vertAxisLeft)
chart.call(vertAxisRight)
popup = chart.append("g").classed("popup", true);
return svg.node();
}