Published
Edited
Mar 6, 2022
1 fork
Insert cell
# 安政の大獄 事件時の関係者年齢
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);

// イベント発生ライン(重なり順考慮して上の方で描画)
svg.append("line")
.attr("stroke-width", 2)
.attr("stroke", "red")
.attr("x1", x(eventData.year) + margin.left)
.attr("x2", x(eventData.year) + margin.left)
.attr("y1", margin.top - 10)
.attr("y2", height - margin.bottom);
data.forEach(d => d.color = d3.color(color(d.category)));

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

const groups = g
.selectAll("g")
.data(data)
.join("g")
.attr("class", "person");

const line = svg.append("line")
.attr("y1", margin.top - 10)
.attr("y2", height - margin.bottom)
.attr("stroke", "rgba(0,0,0,0)")
.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")
.style("opacity", 0.8);
d3.select(this)
.select("text")
.style("font-weight", "bold");
})
.on("mouseleave", function(d) {
d3.select(this)
.select("rect")
.style("opacity", 1);

d3.select(this)
.select("text")
.style("font-weight", "normal");
});

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(event) {
let [x, y] = d3.pointer(event);
console.log(x);
line
.attr("stroke", "rgba(0,0,0,0.2)")
.attr("transform", `translate(${x} 0)`);
});
return svg.node();
}
Insert cell
Insert cell
data = csv.map(d => {
return {
...d,
start: +d.start,
end: +d.end
}
}).sort((a, b) => a.start - b.start);
Insert cell
eventData = ({
year: 1858,
name: "安政の大獄"
})
Insert cell
margin = ({top: 30, right: 50, bottom: 30, left: 150})
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.start), d3.max(data, d => d.end)])
.range([0, width - margin.left - margin.right])
Insert cell
height = 500
Insert cell
getRect = function(d) {
const el = d3.select(this);
const sx = x(d.start);
const w = x(d.end) - x(d.start);
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.name)
.attr("x", - margin.left)
.attr("y", 10)
.attr("fill", "black")
.style("text-anchor", "start")
.style("dominant-baseline", "hanging");

// 誕生年
el
.append("text")
.text(d.start)
.attr("x", sx - 48)
.attr("y", 12)
.attr("fill", d.color)
.style("font-family", "sans-serif")
.style("font-size", 15)
.style("text-anchor", "start")
.style("dominant-baseline", "hanging");

// 没年
el
.append("text")
.text(d.end)
.attr("x", sx + w + 10)
.attr("y", 12)
.attr("fill", d.color)
.style("font-family", "sans-serif")
.style("font-size", 15)
.style("text-anchor", "start")
.style("dominant-baseline", "hanging");

// イベント時の年齢
// 背景円
el
.append("circle")
.attr("r", y.bandwidth()/2)
.attr("fill", "white")
.attr("stroke", d.color)
.attr("stroke-width", 1)
.attr("cx", x(eventData.year))
.attr("cy", 17);
// 年齢
el
.append("text")
.attr("fill", d.color)
.text(eventData.year - d.start + 1) // 満年齢
.attr("x", x(eventData.year))
.attr("y", 22)
.style("text-anchor", "middle")
.attr("font-size", 14)
.attr("font-weight", 600)
.attr("font-family", "sans-serif");
}
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 < 0 ? `${-d} BC` : `${d} AD`
Insert cell
categories = [...d3.group(data, d => d.category).keys()]
Insert cell
color = d3.scaleOrdinal(d3.schemeCategory10).domain(categories)
Insert cell
color
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