Published
Edited
Jan 17, 2021
Insert cell
Insert cell
index = 9
Insert cell
chart(qMap)
Insert cell
chart = data => {
const arcs = pie(qMap);

const svg = d3
.create("svg")
.attr("viewBox", [-width / 2, -height / 2 - 20, width, height + 20]);

svg
.append('g')
.attr('transform', `translate(${-width / 2},${-height / 2})`)
.attr('font-family', 'sans-serif')
.attr('font-weight', 'bold')
.append('text')
.text(
'国際的な人の往来再開に向けた段階的措置等による入国者数 ' +
d3.timeFormat('%Y/%m/%d')(dates[0]) +
'–' +
d3.timeFormat('%Y/%m/%d')(dates[1])
);

svg
.append("g")
.attr("stroke", "white")
.selectAll("path")
.data(arcs)
.join("path")
.attr("fill", d => color(d.data[0]))
.attr("d", arc)
.append("title")
.text(d => `${d.data[0]}: ${d.data[1].toLocaleString()}`);

svg
.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.attr("text-anchor", "middle")
.selectAll("text")
.data(arcs)
.join("text")
.attr("transform", d => `translate(${arcLabel.centroid(d)})`)
.call(text =>
text
.filter(d => d.endAngle - d.startAngle > 0.25)
.append("tspan")
.attr("y", "-0.4em")
.attr("font-size", '2em')
.attr("font-weight", "bold")
.text(d => d.data[0])
)
.call(text =>
text
.filter(d => d.endAngle - d.startAngle > 0.25)
.append("tspan")
.attr("x", 0)
.attr("y", "0.7em")
.attr("font-size", '1.25em')
.attr("fill-opacity", 0.7)
.text(d => `${d.data[1].toLocaleString()}人`)
);

return svg.node();
}
Insert cell
color = d3
.scaleOrdinal()
.domain(Array.from(qMap.keys()))
.range(
d3.quantize(
// t => d3.interpolateSpectral(t * 0.8 + 0.1),
t => d3.interpolateSpectral(t * 0.7 + 0.3),
Array.from(qMap.keys()).length
)
// .reverse()
)
Insert cell
height = Math.min(width, 500)
Insert cell
arc = d3
.arc()
.innerRadius(0)
.outerRadius(Math.min(width, height) / 2 - 1)
Insert cell
arcLabel = {
const radius = (Math.min(width, height) / 2) * 0.8;
return d3
.arc()
.innerRadius(radius)
.outerRadius(radius);
}
Insert cell
pie = d3
.pie()
.sort(null)
.value(d => d[1])
Insert cell
qMap = new Map(
Array.from(
d3
.rollup(data, v => d3.sum(v, v => v.count), d => d.qualification)
.entries()
).sort((a, b) => b[1] - a[1])
)
Insert cell
qGroup = d3.group(data, d => d.qualification)
Insert cell
data = (data, dates) =>
data
.map(d => {
const counts = new Map();
for (let key in d) {
counts.set(key, d[key]);
}
counts.delete('国');
counts.delete('総計');

return qualifications.map(qualification => ({
country: d.,
startDate: dates[0],
endDate: dates[1],
qualification,
count: d[qualification]
}));
// for (let qualification of qualifications) {
// }
// return {
// country: d.国,
// counts: counts
// // qualification: Object.keys(d).slice(2, -1),
// // count: Object.values(d).slice(2, -1)
// };
})
.flat()
Insert cell
qData = {
const qualifications = new Map();
for (let key in csvData[0]) {
qualifications.set(key, {});
}
return qualifications;
}
Insert cell
qualifications = csvString
.split('\n')
.slice(2, 3)[0]
.split(',')
.slice(2, -1)
Insert cell
Insert cell
trimedCsvString = csvString => {
const array = csvString.split('\n');

const newArray = array.slice(2, 3).concat(array.slice(4, 15));

return '国' + newArray.join('\n');
}
Insert cell
getDates = string => {
const matched = string.match(
/令和(\d+)年(\d+)月(\d+)日(~令和\d+年|~)(\d+)月(\d+)日/
);
const year = +matched[1] + 2018;
const month = +matched[2];
const date = +matched[3];
const endYear = matched[4] === "~" ? year : year + 1;
const endMonth = +matched[5];
const endDate = +matched[6];

// return matched;
return [
new Date(year, month - 1, date),
new Date(endYear, endMonth - 1, endDate)
];
}
Insert cell
getDates(csvString)
Insert cell
csvString = loadExcelCSV('https://sugi2000cors.herokuapp.com/' + uris[9])
Insert cell
Promise.all(uris.map(uri => getData(uri)))
Insert cell
{
const result = [];
for (let i = 0; i < uris.length; i++) {
result.push(await getData(uris[i]));
}
return result;
}
Insert cell
getData = async uri => {
const csvString = await loadExcelCSV(
'https://sugi2000cors.herokuapp.com/' + uri
);
const trimedString = trimedCsvString(csvString);
const rawData = csvData(trimedString);
const dates = getDates(csvString);

return data(rawData, dates);
}
Insert cell
loadExcelCSVBuffer(await FileAttachment("001335357.xlsx").arrayBuffer())
Insert cell
uris.map(d => `curl -O ${d}`).join('\n')
Insert cell
uris = [
`http://www.moj.go.jp/isa/content/930006293.xlsx`,
`http://www.moj.go.jp/isa/content/001334305.xlsx`,
`http://www.moj.go.jp/isa/content/001334307.xlsx`,
`http://www.moj.go.jp/isa/content/001334830.xlsx`,
`http://www.moj.go.jp/isa/content/001334896.xlsx`,
`http://www.moj.go.jp/isa/content/001335357.xlsx`,
`http://www.moj.go.jp/isa/content/001336437.xlsx`,
`http://www.moj.go.jp/isa/content/001337765.xlsx`,
`http://www.moj.go.jp/isa/content/001337767.xlsx`,
`http://www.moj.go.jp/isa/content/001338546.xlsx`
]
Insert cell
Insert cell
d3 = require('d3@6')
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