Published
Edited
Jan 27, 2021
Importers
Insert cell
Insert cell
Insert cell
Insert cell
cases.get('Osaka').slice(-10)
Insert cell
getCases({ prefName: 'Hokkaido', maxAge: 80 })
Insert cell
getCases({ prefName: 'Osaka', maxAge: 80 }).slice(-10)
Insert cell
getCases({ prefName: 'Miyazaki', maxAge: 80 }).slice(0, 10)
Insert cell
getCases = ({ prefName, maxAge = 200 } = {}) => {
return clipAgeCases(cases.get(prefName) ?? [], maxAge);
}
Insert cell
cases.get('Osaka').slice(-10)
Insert cell
tokyoCases.slice(-10)
Insert cell
osakaCases.slice(-10)
Insert cell
aichiCases.slice(-10)
Insert cell
miyazakiCases.slice(0, 10)
Insert cell
allCases = new Map([
['Hokkaido', hokkaidoCases],
// ['Aomori', aomoriCases],
// ['Saitama', saitamaCases],
['Chiba', chibaCases],
['Tokyo', tokyoCases],
['Kanagawa', kanagawaCases],
['Aichi', aichiCases],
['Osaka', osakaCases],
// ['Nara', naraCases],
['Hyogo', hyogoCases],
['Hiroshima', hiroshimaCases],
['Fukuoka', fukuokaCases],
['Saga', sagaCases],
['Nagasaki', nagasakiCases],
['Kumamoto', kumamotoCases],
['Oita', oitaCases],
['Miyazaki', miyazakiCases],
['Kagoshima', kagoshimaCases],
['Okinawa', okinawaCases]
])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
hokkaidoCases = {
const csvString = await getSourceStr({ prefName: 'Hokkaido' });
return d3.csvParse(csvString, d3.autoType).map(d => {
// fix typo
if (d.居住地 === '胆振振興局管内') {
d.居住地 = '胆振総合振興局管内';
}
if (d.居住地 === '宗谷総合誌振興局管内') {
d.居住地 = '宗谷総合振興局管内';
}
if (d.居住地 === 'オホーツク振興局管内') {
d.居住地 = 'オホーツク総合振興局管内';
}
if (d.居住地 === 'オホーツク総合振興局管内') {
d.居住地 = 'オホーツク総合振興局管内';
}
return {
date: d.リリース日,
age: d.年代 === '非公表' ? NaN : d.年代 === '10歳未満' ? 0 : d.age_group, //+d.年代.replace(/(\d+).+/, '$1'),
...d
};
});
}
Insert cell
Insert cell
aomoriCases = d3
.csvParse(await getSourceStr({ prefName: 'Aomori' }), d3.autoType)
.filter(d => d.年代)
.map(d => {
//fix typo
if (d.年代 === "10代") {
d.年代 = "10代";
}
return {
date: new Date(d.公表_年月日),
age: d.年代 === '10歳未満' ? 0 : +d.年代.replace(/(\d+).+/, '$1'),
...d
};
})
Insert cell
Insert cell
saitamaCases.slice(-10)
Insert cell
_saitamaCases = jagCases.get('埼玉県')
Insert cell
d3.group(saitamaCases, d => d.age)
Insert cell
d3.group(saitamaCases, d => (d.年代 ? d.年代 : 'NA'))
Insert cell
saitamaCases = {
const arrayData = new Uint8Array(await d3.buffer(proxiedURI(saitamaCSVURI)));
const csvString = iconv.decode(arrayData, 'Shift_JIS');

return d3
.csvParse(csvString, d3.autoType)
.filter(d => d.年代 && (d.年代 !== '-' && d.年代 !== '調査中'))
.map(d => ({
date: new Date(d.判明日),
age:
d.年代 > 0
? d.年代
: d.年代 === '未就学児' || d.年代 === '10歳未満'
? 0
: d.年代 === '未成年'
? 10
: +d.年代.replace(/(\d+).+/, '$1'),
...d
}));
}
Insert cell
saitamaCSVURI = {
const html = await d3.html(getSource({ prefName: 'SaitamaOpenData' }));
const d3html = d3.select(html);
const latestPath = d3html
.select('li.resource-item:last-child > a:nth-child(1)')
.attr('href');

const latestHtml = await d3.html(
proxiedURI('https://opendata.pref.saitama.lg.jp' + latestPath)
);
const latestCsvPath = d3
.select(latestHtml)
.select('.muted > a:nth-child(1)')
.attr('href');
return latestCsvPath;
}
Insert cell
Insert cell
chibaCases = jagCases.get('千葉県')
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
new Date(aichiCases[0].発表日)
Insert cell
d3.group(aichiCases, d => d.age)
Insert cell
aichiCases.slice(-10)
Insert cell
aichiCases = {
const json = aichiData.map(({ date, ...d }) => ({
date: new Date(date),
...d
}));

let result = [];

for (let d of json) {
for (let i = 0; i < d.cases; i++) {
result.push(d);
}
}
return result;
}
Insert cell
aichiData = {
const dailyData = (await d3.json(
getSource({ prefName: 'Aichi', useProxy: false }),
d3.autoType
)).patients_summary.data.map(d => ({
...d,
date: new Date(d.日付),
patients: new Map(
Object.entries(d.年代).map(([key, value]) => [
key,
d3.sum(Object.values(value))
])
)
}));

const result = [];
dailyData.forEach(d => {
if ([...d.patients.entries()].length > 0) {
const ageData = [...d.patients.entries()].map(([key, value]) => ({
date: d.date,
age:
key === '10歳未満'
? 0
: key === '90代' || key === '100代'
? 80
: +key.replace(/(\d+).+/, '$1'),
cases: value
}));
result.push(ageData);
}
});
return result.flat();
}
Insert cell
_aichiCases = (await d3.json(
getSource({ prefName: 'Aichi', useProxy: false }),
d3.autoType
)).patients.data
.map(d => ({
...d,
date: new Date(d.発表日),
年代: d['年代・性別'].replace(/(.+)(男性|女性)/, '$1'),
性別: d['年代・性別'].replace(/(.+)(男性|女性)/, '$2')
}))
.map(d => ({
age:
d.年代 === '10歳未満'
? 0
: d.年代 === '高齢者'
? 80
: +d.年代.replace(/(\d+).+/, '$1'),
...d
}))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
naraCases = {
const array = await getXlsxArray({ prefName: 'Nara' });
const wb = xlsx.read(array, { type: 'array', cellDates: true });
const ws = wb.Sheets[wb.SheetNames[0]];
function ec(r, c) {
return xlsx.utils.encode_cell({ r: r, c: c });
}
const delete_row = (ws, row_index) => {
var variable = xlsx.utils.decode_range(ws["!ref"]);
for (var R = row_index; R < variable.e.r; ++R) {
for (var C = variable.s.c; C <= variable.e.c; ++C) {
ws[ec(R, C)] = ws[ec(R + 1, C)];
}
}
variable.e.r--;
ws['!ref'] = xlsx.utils.encode_range(variable.s, variable.e);
};

delete_row(ws, 0);
return xlsx.utils.sheet_to_json(ws).map(d => ({
...d,
date: d.公表_年月日,
age: d.患者_年代 === '10歳未満' ? 0 : +d.患者_年代?.replace(/(\d+).+/, '$1')
}))
}
Insert cell
Insert cell
hyogoCases = (await d3.json(getSource({ prefName: 'Hyogo', useProxy: false })))
.data.map(d => ({
...d,
date: new Date(d.リリース日),
age: d.年代 === '10歳未満' ? 0 : +d.年代?.replace(/(\d+).+/, '$1'),
}))
Insert cell
Insert cell
import { hiroshimaCases } from "@sugi2000/covid-19-data-in-hiroshima"
Insert cell
Insert cell
d3.group(fukuokaCases, d => d.age)
Insert cell
fukuokaCases = {
return (await d3.csv(getSource({ prefName: 'Fukuoka' }), d3.autoType)).map(
d => ({
date: new Date(d.公表_年月日),
age: d.年代 === '1歳未満' || d.年代 === '10歳未満' ? 0 : +d.年代?.replace(/(\d+).+/, '$1'),
...d
})
);
}
Insert cell
Insert cell
d3.group(sagaCases, d => d.年代)
Insert cell
sagaCases = (await d3.json(
getSource({ prefName: 'Saga', useProxy: false }),
d3.autoType
)).patients.data.map(d => ({
...d,
date: new Date(d.リリース日),
age:
d.年代 === '10代未満' || d.年代 === '10歳未満'
? 0
: +d.年代.replace(/(\d+).+/, '$1')
}))
Insert cell
Insert cell
d3.group(nagasakiCases, d => d.age)
Insert cell
d3.group(nagasakiCases, d => d.年代)
Insert cell
nagasakiCases = (await d3.csv(getSource({ prefName: 'Nagasaki' }), d3.autoType))
.filter(({ 年代 }) => 年代) // exclude null age group
.map(d => ({
...d,
date: new Date(d.公表_年月日),
age:
d.年代 === '10代未満' || d.年代 === '10歳未満'
? 0
: +d.年代.replace(/(\d+).+/, '$1')
}))
Insert cell
Insert cell
kumamotoSource = {
const html = await d3.html(getSource({ prefName: 'KumamotoOpenData' }));
const d3html = d3.select(html);
return (
'https://www.pref.kumamoto.jp/' +
d3html
.select('table tbody:nth-child(2) > tr:nth-child(2) > td:last-child > a')
.attr('href')
);
}
Insert cell
d3.group(kumamotoCases, d => d.患者_年代)
Insert cell
(await d3.csv(proxiedURI(kumamotoSource), d3.autoType)).slice(0, 10)
Insert cell
// kumamotoCases = (await d3.csv(getSource({ prefName: 'Kumamoto' }), d3.autoType))
kumamotoCases = (await d3.csv(proxiedURI(kumamotoSource), d3.autoType))
.filter(({ 公表_年月日, 患者_年代 }) => 公表_年月日 && 患者_年代) // exclude null data
.map(d => ({
...d,
date: new Date(d.公表_年月日),
age:
d['患者_年代'] === '10歳未満'
? 0
: +d['患者_年代'].trim().replace(/(\d+).+/, '$1')
}))
Insert cell
Insert cell
d3.group(oitaCases, d => d.年代)
Insert cell
oitaCases = (await d3.csv(getSource({ prefName: 'Oita' }), d3.autoType)).map(
d => ({
...d,
date: new Date(d.公表_年月日),
age: d.年代 === '10歳未満' ? 0 : +d.年代.replace(/(\d+).+/, '$1')
})
)
Insert cell
Insert cell
d3.group(miyazakiCases, d => d.age)
Insert cell
d3.group(miyazakiCases, d => d.年代)
Insert cell
miyazakiCases = {
return miyazakiData.concat(miyazakiOldData);
}
Insert cell
miyazakiData = getMiyazakiData(getSource({ prefName: 'Miyazaki' }))
Insert cell
miyazakiOldData = getMiyazakiData(
proxiedURI(
'https://www.pref.miyazaki.lg.jp/kansensho-taisaku/covid-19/hassei_list_01.html'
)
)
Insert cell
getMiyazakiData(proxiedURI(miyazakiOldDataURIs[9]))
Insert cell
miyazakiOldDataURIs = d3
.range(202003, 202013)
.concat(d3.range(202101, 202102))
.map(
d =>
`https://www.pref.miyazaki.lg.jp/kansensho-taisaku/covid-19/hassei_list_${d}.html`
)
Insert cell
new Date('1月23日'.replace(/(\d+)月(\d+)日/, `2020-$1-$2`))
Insert cell
getMiyazakiData = async uri => {
let result = '';
const html = d3.select((await d3.html(uri)).body);

// get columns
const ths = html.select('table.datatable').selectAll('tbody > tr > th');
const columns = [];
ths.each(function() {
columns.push(
d3
.select(this)
.text()
.trim()
.split('\n')
.map(d => d.trim())
.join('')
);
});
const isInMiyazakiCityColumn = columns[1] === '宮崎市No';
const dateColumnIndex = columns.findIndex(d => d === '判明日');
// return isInMiyazakiCityColumn;

let prevDateStr = '';
// const tr = html.selectAll('table.datatable tbody tr:not(:first-child)');
const tr = html.selectAll('table.datatable tbody tr');
tr.each((d, i, nodes) => {
const tds = d3.select(nodes[i]).selectAll('td');

const tdTexts = [];
tds.each((e, j, tds) =>
tdTexts.push(
d3
.select(tds[j])
.text()
.trim()
.split('\n')[0]
)
);
if (/\d+月\d+日/.test(tdTexts[dateColumnIndex])) {
prevDateStr = tdTexts[dateColumnIndex];
} else {
tdTexts.splice(dateColumnIndex, 0, prevDateStr);
}
if (isInMiyazakiCityColumn) {
tdTexts.splice(1, 1);
}
result += tdTexts.join(',') + '\n';
});
if (isInMiyazakiCityColumn) {
columns.splice(1, 1);
}
result = columns.join(',') + result;
// return result;

return d3.csvParse(result, d3.autoType).map(d => ({
...d,
date: getMiyazakiDate(d.判明日),
age: d.年代 === '10歳未満' ? 0 : +d.年代.replace(/(\d+).+/, '$1')
}));
}
Insert cell
getMiyazakiDate('1月23日')
Insert cell
getMiyazakiDate = dateStr => {
let year = '2020';
const month = dateStr.replace(/(\d+)月(\d+)日/, '$1');
const date = dateStr.replace(/(\d+)月(\d+)日/, '$2');
if (month === '1') {
year = '2021';
}
return new Date(`${year}-${month}-${date}`);
}
Insert cell
Insert cell
d3.group(kagoshimaCases, d => d.年代)
Insert cell
kagoshimaCases = (await d3.json(
getSource({ prefName: 'Kagoshima', useProxy: false }),
d3.autoType
)).patients.data
.map(d => {
if (d.年代 === '30代') {
d.年代 = '30代';
}
return d;
})
.map(d => ({
...d,
date: new Date(d.リリース日),
age: d.年代 === '10歳未満' ? 0 : +d.年代.replace(/(\d+).+/, '$1')
}))
Insert cell
Insert cell
d3.group(okinawaCases, d => d.age)
Insert cell
new Date(okinawaCases[0].確定日)
Insert cell
okinawaCases = (await d3.json(
getSource({ prefName: 'Okinawa', useProxy: false }),
d3.autoType
)).patients.data.map(d => ({
...d,
age: d.年代 === '10歳未満' ? 0 : +d.年代.replace(/(\d+).+/, '$1'),
date: new Date(d.確定日)
}))
Insert cell
getSource({ prefName: 'Tokyo' })
Insert cell
getXlsxArray = async ({ prefName, useProxy = true } = {}) => {
const source = getSource({ prefName, useProxy });
const arrayData = new Uint8Array(await d3.buffer(source));
return arrayData;
}
Insert cell
getSourceStr = async ({ prefName, useProxy = true } = {}) => {
const source = getSource({ prefName, useProxy });
const arrayData = new Uint8Array(await d3.buffer(source));
const csvString = iconv.decode(arrayData, 'Shift_JIS');
return csvString;
}
Insert cell
getSource = ({ prefName, useProxy = true } = {}) =>
useProxy ? proxiedURI(sources.get(prefName)) : sources.get(prefName)
Insert cell
Insert cell
sourcesStr = `
Hokkaido,https://www.harp.lg.jp/opendata/dataset/1369/resource/2828/patients.csv
Aomori,https://opendata.pref.aomori.lg.jp/dataset/1531/resource/12431/02_20201127_%E9%99%BD%E6%80%A7%E6%82%A3%E8%80%85%E9%96%A2%E4%BF%82.csv
SaitamaOpenData,https://opendata.pref.saitama.lg.jp/data/dataset/covid19-jokyo
Saitama,https://opendata.pref.saitama.lg.jp/data/dataset/c3a8db28-b943-4fcc-82ec-b7febd460bec/resource/d0d9284c-7388-4ff7-a75b-b8b1ac0460c5/download/jokyo20201118.csv
Chiba,
Tokyo,https://raw.githubusercontent.com/tokyo-metropolitan-gov/covid19/development/static/data/130001_tokyo_covid19_patients.csv
TokyoSite,https://stopcovid19.metro.tokyo.lg.jp/data/130001_tokyo_covid19_patients.csv
Kanagawa,https://www.pref.kanagawa.jp/osirase/1369/data/csv/patient.csv
Aichi,https://raw.githubusercontent.com/code4nagoya/covid19/development/data/data.json
Osaka,https://covid19-osaka.info/data/patients.csv
OsakaNew,https://covid19-osaka.info/data/summary.csv
Hyogo,https://raw.githubusercontent.com/stop-covid19-hyogo/covid19/development/data/patients.json
Nara,http://www.pref.nara.jp/secure/227193/%E5%A5%88%E8%89%AF%E7%9C%8C_01%E6%96%B0%E5%9E%8B%E3%82%B3%E3%83%AD%E3%83%8A%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E6%84%9F%E6%9F%93%E8%80%85_%E6%82%A3%E8%80%85%E3%83%AA%E3%82%B9%E3%83%88.xlsx
Fukuoka,https://ckan.open-governmentdata.org/dataset/8a9688c2-7b9f-4347-ad6e-de3b339ef740/resource/e6c7a8d7-32e2-4dd9-8a3a-c71dec4ec87c/download/400009_pref_fukuoka_covid19_patients.csv
Saga,https://raw.githubusercontent.com/codeforsaga/covid19/development/data/data.json
Nagasaki,https://data.bodik.jp/dataset/09951e04-dc5d-42e9-9a49-37443be6787e/resource/de7ce61e-1849-47a1-b758-bca3f809cdf8/download/20201120_pref_nagasaki_covid_patients.csv
KumamotoOpenData,https://www.pref.kumamoto.jp/soshiki/211/82808.html
Kumamoto,https://www.pref.kumamoto.jp/common/UploadFileOutput.ashx?c_id=3&id=22038&sub_id=262&flid=259152
Oita,https://data.bodik.jp/dataset/f632f467-716c-46aa-8838-0d535f98b291/resource/3714d264-70f3-4518-a57a-8391e0851d7d/download/440001_oita_covid19_patients.csv
Miyazaki,https://www.pref.miyazaki.lg.jp/kansensho-taisaku/covid-19/hassei_list.html
Kagoshima,https://raw.githubusercontent.com/codeforkagoshima/covid19/development/data/data.json
Okinawa,https://raw.githubusercontent.com/Code-for-OKINAWA/covid19/development/data/data.json
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
prefNamesJ = {
const map = new Map();
let i = 0;
for (let nameE of prefectureNamesE) {
map.set(nameE, prefectureNamesJ[i]);
i++;
}
return map;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
jagCases = d3.group(
jagData.filter(d => /[都道府県]$/.test(d.居住都道府県)),
d => d.居住都道府県
)
Insert cell
jagData.slice(-2000)
Insert cell
jagData = (await d3.csv(
'https://dl.dropboxusercontent.com/s/6mztoeb6xf78g5w/COVID-19.csv',
d3.autoType
)).map(d => ({
age: d.年代 === '0-10' ? 0 : d.年代,
date: new Date(d.確定日),
...d
}))
Insert cell
Insert cell
Insert cell
xlsx = require('https://bundle.run/xlsx@0.14.1')
Insert cell
xlsx16 = require('xlsx')
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