Published
Edited
Feb 21, 2020
Insert cell
Insert cell
height = 500
Insert cell
margin = ({top: 30, right: 50, bottom: 30, left: 30})
Insert cell
Insert cell
data = d3.csvParse(dataset, d3.autoType)
Insert cell
weightedAverageData = data.map(({["weighted average"]: value, year}) => ({key: "weighted average", year: year, value: value}))
Insert cell
tokyoData = data.map(({["tokyo"]: value, year}) => ({key: "tokyo", year: year, value: value}))
Insert cell
series = [tokyoData, weightedAverageData]
Insert cell
color = d3.scaleOrdinal()
.domain(["tokyo", "weighted average"])
.range(["red", "green"]);
Insert cell
x = d3.scaleLinear()
.domain([data[0].year, data[data.length - 1].year]) //2002-2019
.range([margin.left, width - margin.right]);
Insert cell
y = d3.scaleLinear()
.domain([0, d3.max(series, s => d3.max(s, d => d.value))]).nice()
.range([height - margin.bottom, margin.top]);
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x)
.ticks(tokyoData.length) //weightedAverageDataでも同じ
.tickSizeOuter(0)
.tickFormat(d3.format(".4")));
Insert cell
yAxis = g => g
.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(y)
.tickSize(- width + margin.right + margin.left))
.call(g => g.select(".tick:last-of-type text").clone()
.attr("y", -10)
.attr("font-size", 11)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.text("¥"))
.call(g => g.select(".domain").remove())
.attr("color", "lightgray")
.attr("font-size", 8)
.attr("stroke-width", 0.8);
Insert cell
line = d3.line()
.x(d => x(d.year))
.y(d => y(d.value));
Insert cell
chart = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height]);
//軸の設定
svg.append("g")
.call(xAxis);
svg.append("g")
.call(yAxis);


//折れ線グラフの設定
const serie = svg.append("g")
.selectAll("g")
.data(series)
.join("g");

//線の描画
serie.append("path")
.attr("fill", "none")
.attr("stroke", d => color(d[0].key))
.attr("stroke-width", 2)
.attr("d", line);

//折れ線グラフにラベルを追加
serie.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 9)
.attr("text-anchor", "middle")
.selectAll("text")
.data(d => d)
.join("text")
.text(d => d.value)
.attr("dy", 3.5)
.attr("x", d => x(d.year))
.attr("y", d => y(d.value))
.clone(true).lower()
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-width", 3);

//"tokyo"と"weighted average"の文字の追加
serie.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 11)
.attr("text-anchor", "end")
.attr("font-weight", "bold")
.selectAll("text")
.data((d, i) => d.filter((d, i, data) => i === data.length - 1))
.join("text")
.text(d => d.key)
.attr("x", d => x(d.year))
.attr("y", d => y(d.value) - 10)
.clone(true).lower()
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-width", 3);
return svg.node();
}
Insert cell
d3 = require("d3@5")
Insert cell
Insert cell
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