Published
Edited
Aug 11, 2020
1 star
Insert cell
Insert cell
Insert cell
chart = {

let filteredData;
if(sorting !== "time") {
filteredData = [].concat.apply([], dataByRegion.map(d=>d.values));
} else {
filteredData = data.sort((a,b)=> a.min-b.min);
}

filteredData.forEach(d=> d.color = d3.color(color(d.region)))


let parent = this;
if (!parent) {
parent = document.createElement("div");
const svg = d3.select(DOM.svg(width, height));


const g = svg.append("g").attr("transform", (d,i)=>`translate(${margin.left} ${margin.top})`);

const groups = g
.selectAll("g")
.data(filteredData)
.enter()
.append("g")
.attr("class", "civ")


const tooltip = d3.select(document.createElement("div")).call(createTooltip);

const line = svg.append("line").attr("y1", margin.top-10).attr("y2", height-margin.bottom).attr("stroke", "rgba(0,0,0,0.2)").style("pointer-events","none");

groups.attr("transform", (d,i)=>`translate(0 ${y(i)})`)

groups
.each(getRect)
.on("mouseover", function(d) {
d3.select(this).select("rect").attr("fill", d.color.darker())

tooltip
.style("opacity", 1)
.html(getTooltipContent(d))
})
.on("mouseleave", function(d) {
d3.select(this).select("rect").attr("fill", d.color)
tooltip.style("opacity", 0)
})


svg
.append("g")
.attr("transform", (d,i)=>`translate(${margin.left} ${margin.top-10})`)
.call(axisTop)

svg
.append("g")
.attr("transform", (d,i)=>`translate(${margin.left} ${height-margin.bottom})`)
.call(axisBottom)



svg.on("mousemove", function(d) {

let [x,y] = d3.mouse(this);
line.attr("transform", `translate(${x} 0)`);
y +=20;
if(x>width/2) x-= 100;

tooltip
.style("left", x + "px")
.style("top", y + "px")
})

parent.appendChild(svg.node());
parent.appendChild(tooltip.node());
parent.groups = groups;

} else {


const civs = d3.selectAll(".civ")

civs.data(filteredData, d=>d.country)
.transition()
// .delay((d,i)=>i*10)
.ease(d3.easeCubic)
.attr("transform", (d,i)=>`translate(0 ${y(i)})`)


}
return parent

}
Insert cell
getTooltipContent = function(d) {
return `<b>${d.country}</b>
<br/>
<b style="color:${d.color.darker()}">${d.region}</b>
<br/>
${formatDate(d.min)} - ${formatDate(d.max)}
`
}
Insert cell
height = 1000
Insert cell

y= d3.scaleBand()
.domain(d3.range(data.length))
.range([0,height - margin.bottom - margin.top])
.padding(0.2)

Insert cell
x = d3.scaleLinear()
.domain([d3.min(data, d => d.min), d3.max(data, d => d.max)])
.range([0, width - margin.left - margin.right])

Insert cell
margin = ({top: 30, right: 30, bottom: 30, left: 30})
Insert cell
createTooltip = function(el) {
el
.style("position", "absolute")
.style("pointer-events", "none")
.style("top", 0)
.style("opacity", 0)
.style("background", "white")
.style("border-radius", "5px")
.style("box-shadow", "0 0 10px rgba(0,0,0,.25)")
.style("padding", "10px")
.style("line-height", "1.3")
.style("font", "11px sans-serif")
}
Insert cell
getRect = function(d){
const el = d3.select(this);
const sx = x(d.min);
const w = x(d.max) - x(d.min);
const isLabelRight =(sx > width/2 ? sx+w < width : sx-w>0);

el.style("cursor", "pointer")

el
.append("rect")
.attr("x", sx)
.attr("height", y.bandwidth())
.attr("width", w)
.attr("fill", d.color);

el
.append("text")
.text(d.country)
.attr("x",isLabelRight ? sx-5 : sx+w+5)
.attr("y", 2.5)
.attr("fill", "black")
.style("text-anchor", isLabelRight ? "end" : "start")
.style("dominant-baseline", "hanging");
}
Insert cell
dataByTimeline = d3.nest().key(d=>d.timeline).entries(data);
Insert cell
dataByRegion = d3.nest().key(d=>d.region).entries(data);
Insert cell
axisBottom = d3.axisBottom(x)
.tickPadding(2)
.tickFormat(formatDate)
Insert cell
axisTop = d3.axisTop(x)
.tickPadding(2)
.tickFormat(formatDate)
Insert cell
formatDate = d=> d
Insert cell
Insert cell
csv = d3.csv("https://raw.githubusercontent.com/belamadrid/balbudgregion/master/balbudget_spellsregion.csv")
Insert cell
data = csv.map(d=>{
return {
...d,
start: +d.min,
end: +d.max
}
}).sort((a,b)=> a.min-b.min);
Insert cell
regions = d3.nest().key(d=>d.region).entries(data).map(d=>d.key)
Insert cell
timelines = dataByTimeline.map(d=>d.key)
Insert cell
color = d3.scaleOrdinal(d3.schemeSet2).domain(regions)
Insert cell
Insert cell
Insert cell
md ` Note: I would like if this chart had each country's spells on the same line. `
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more