Chart.jsギャラリー
気象庁・e-Statの実データをChart.js(Canvas描画の定番ライブラリ)で可視化した6点。各カードの「コードを見る」で実装をそのまま確認できます。
東京の月別平均気温の変化
収録データの1991-2020年平均と2016-2025年平均の比較。夏を中心に近年が上回る(2014年の観測地点移転の影響を含む)
コードを見る
"use client";
import { Line } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { MONTH_LABELS } from "@/lib/format";
import { SERIES, withAlpha } from "@/lib/palette";
import type { TempLineData } from "@/lib/selectors";
export default function TokyoTempLine({ data }: { data: TempLineData }) {
const reducedMotion = useReducedMotion();
const base = baseOptions<"line">(reducedMotion);
return (
<div
className="h-80"
role="img"
aria-label="東京の月別平均気温を収録データの1991-2020年平均と直近10年平均で比較した折れ線グラフ。夏を中心に多くの月で直近10年が上回る"
>
<Line
data={{
labels: [...MONTH_LABELS],
datasets: [
{
label: data.recentLabel,
data: data.recent,
borderColor: SERIES[5],
backgroundColor: withAlpha(SERIES[5], 0.15),
borderWidth: 2,
pointRadius: 3,
fill: false,
tension: 0.2,
},
{
label: data.normalLabel,
data: data.normal,
borderColor: SERIES[0],
backgroundColor: withAlpha(SERIES[0], 0.15),
borderWidth: 2,
borderDash: [6, 3],
pointRadius: 3,
fill: false,
tension: 0.2,
},
],
}}
options={{
...base,
interaction: { mode: "index", intersect: false },
plugins: {
...base.plugins,
tooltip: {
callbacks: {
label: (ctx) => `${ctx.dataset.label}: ${ctx.parsed.y}度`,
},
},
},
scales: {
y: {
title: { display: true, text: "月平均気温(度)" },
ticks: { callback: (v) => `${v}度` },
},
},
}}
/>
</div>
);
}
東京の猛暑日・真夏日・冬日の日数
年別の階級日数。夏の高温日は積み上げ棒、冬日は折れ線で重ねる
コードを見る
"use client";
import { Chart } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { SERIES, withAlpha } from "@/lib/palette";
import type { ExtremeDaysData } from "@/lib/selectors";
export default function ExtremeDaysBar({ data }: { data: ExtremeDaysData }) {
const reducedMotion = useReducedMotion();
// 棒+折れ線の混合チャートのためユニオン型で解決する
const base = baseOptions<"bar" | "line">(reducedMotion);
return (
<div
className="h-80"
role="img"
aria-label="東京の年別の猛暑日・真夏日日数の積み上げ棒グラフと冬日日数の折れ線グラフ。猛暑日は増加、冬日は減少傾向"
>
<Chart<"bar" | "line">
type="bar"
data={{
labels: data.years,
datasets: [
{
type: "bar" as const,
label: "猛暑日(最高35度以上)",
data: data.mousho,
backgroundColor: SERIES[5],
stack: "summer",
borderRadius: 2,
},
{
type: "bar" as const,
label: "真夏日(最高30度以上35度未満)",
data: data.manatsuExcl,
backgroundColor: withAlpha(SERIES[7], 0.85),
stack: "summer",
borderRadius: 2,
},
{
type: "line" as const,
label: "冬日(最低0度未満)",
data: data.fuyubi,
borderColor: SERIES[0],
backgroundColor: SERIES[0],
borderWidth: 2,
pointRadius: 2,
tension: 0.2,
},
],
}}
options={{
...base,
interaction: { mode: "index", intersect: false },
plugins: {
...base.plugins,
tooltip: {
callbacks: {
label: (ctx) => `${ctx.dataset.label}: ${ctx.parsed.y}日`,
},
},
},
scales: {
x: { stacked: true, ticks: { maxTicksLimit: 12 } },
y: {
stacked: true,
title: { display: true, text: "日数(日)" },
},
},
}}
/>
</div>
);
}
4都市の月別降水量(平年値)
札幌・東京・大阪・那覇の降水パターンの違い
コードを見る
"use client";
import { Bar } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { MONTH_LABELS } from "@/lib/format";
import { CITY_COLORS } from "@/lib/palette";
import type { CityPrecipData } from "@/lib/selectors";
export default function CityPrecipBar({ data }: { data: CityPrecipData }) {
const reducedMotion = useReducedMotion();
const base = baseOptions<"bar">(reducedMotion);
return (
<div
className="h-80"
role="img"
aria-label="札幌・東京・大阪・那覇の月別降水量平年値のグループ棒グラフ。那覇は梅雨期と台風期に多く、太平洋側は夏に多い"
>
<Bar
data={{
labels: [...MONTH_LABELS],
datasets: data.cities.map((c) => ({
label: c.name,
data: c.precip,
backgroundColor: CITY_COLORS[c.name],
borderRadius: 2,
})),
}}
options={{
...base,
plugins: {
...base.plugins,
tooltip: {
callbacks: {
label: (ctx) => `${ctx.dataset.label}: ${ctx.parsed.y}mm`,
},
},
},
scales: {
y: {
title: { display: true, text: `月降水量(mm、${data.period})` },
},
},
}}
/>
</div>
);
}
4都市の気候レーダー
1991-2020年平年値の5指標を指標ごとに正規化して比較(ツールチップは実測値)
コードを見る
"use client";
import { Radar } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { CITY_COLORS, withAlpha } from "@/lib/palette";
import type { CityRadarData } from "@/lib/selectors";
const UNITS = ["度", "mm", "時間", "度", "度"];
export default function CityRadar({ data }: { data: CityRadarData }) {
const reducedMotion = useReducedMotion();
const base = baseOptions<"radar">(reducedMotion);
return (
<div
className="h-80"
role="img"
aria-label="札幌・東京・大阪・那覇の気候指標(年平均気温・年降水量・年日照時間・8月と1月の平均気温)を正規化して比較したレーダーチャート"
>
<Radar
data={{
labels: data.indicators,
datasets: data.cities.map((c) => ({
label: c.name,
data: c.values,
borderColor: CITY_COLORS[c.name],
backgroundColor: withAlpha(CITY_COLORS[c.name], 0.08),
borderWidth: 2,
pointRadius: 2,
})),
}}
options={{
...base,
plugins: {
...base.plugins,
tooltip: {
callbacks: {
// 正規化値ではなく実測の平年値を単位付きで表示する
label: (ctx) => {
const city = data.cities[ctx.datasetIndex];
const raw = city.raw[ctx.dataIndex];
return `${city.name}: ${raw}${UNITS[ctx.dataIndex]}`;
},
},
},
},
scales: {
r: {
min: 0,
max: 100,
ticks: { display: false },
pointLabels: { font: { size: 11 } },
},
},
}}
/>
</div>
);
}
都道府県別人口増減率(上位・下位)
2015年 -> 2020年(国勢調査)
コードを見る
"use client";
import { Bar } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { DIVERGING } from "@/lib/palette";
import type { PrefGrowthData } from "@/lib/selectors";
export default function PrefGrowthBar({ data }: { data: PrefGrowthData }) {
const reducedMotion = useReducedMotion();
const base = baseOptions<"bar">(reducedMotion);
return (
<div
className="h-96"
role="img"
aria-label="都道府県別の人口増減率の横棒グラフ(増加上位と減少下位)。東京圏と沖縄で増加、東北で減少が大きい"
>
<Bar
data={{
labels: data.items.map((i) => i.name),
datasets: [
{
label: `人口増減率 ${data.periodLabel}`,
data: data.items.map((i) => i.rate),
// 増加は赤系・減少は青系の発散配色
backgroundColor: data.items.map((i) =>
i.rate >= 0 ? DIVERGING.positive : DIVERGING.negative,
),
borderRadius: 2,
},
],
}}
options={{
...base,
indexAxis: "y" as const,
plugins: {
...base.plugins,
legend: { display: false },
tooltip: {
callbacks: {
label: (ctx) => {
const v = ctx.parsed.x ?? 0;
return `増減率: ${v >= 0 ? "+" : ""}${v}%`;
},
},
},
},
scales: {
x: {
title: { display: true, text: `増減率(%、${data.periodLabel})` },
ticks: { callback: (v) => `${v}%` },
},
y: { ticks: { autoSkip: false, font: { size: 11 } } },
},
}}
/>
</div>
);
}
東京の月平均気温と月降水量の関係
1991年以降の全月をプロット。夏期(6〜9月)に多雨月が集中する
コードを見る
"use client";
import { Scatter } from "react-chartjs-2";
import { baseOptions } from "./chartjsSetup";
import { useReducedMotion } from "@/lib/useReducedMotion";
import { SERIES, withAlpha } from "@/lib/palette";
import type { ScatterPoint } from "@/lib/selectors";
export default function TempPrecipScatter({ data }: { data: ScatterPoint[] }) {
const reducedMotion = useReducedMotion();
const base = baseOptions<"scatter">(reducedMotion);
// 夏(6-9月)とそれ以外で色分けし、梅雨・台風期の降水集中を見せる
const summer = data.filter((p) => p.month >= 6 && p.month <= 9);
const other = data.filter((p) => p.month < 6 || p.month > 9);
return (
<div
className="h-80"
role="img"
aria-label="東京の月平均気温と月降水量の散布図(1991年以降の全月)。夏期に降水量の多い月が集中する"
>
<Scatter
data={{
datasets: [
{
label: "6〜9月",
data: summer,
backgroundColor: withAlpha(SERIES[5], 0.55),
pointRadius: 3,
},
{
label: "その他の月",
data: other,
backgroundColor: withAlpha(SERIES[0], 0.45),
pointRadius: 3,
},
],
}}
options={{
...base,
plugins: {
...base.plugins,
tooltip: {
callbacks: {
label: (ctx) => {
const p = ctx.raw as ScatterPoint;
return `${p.year}年${p.month}月: ${p.x}度 / ${p.y}mm`;
},
},
},
},
scales: {
x: {
title: { display: true, text: "月平均気温(度)" },
ticks: { callback: (v) => `${v}度` },
},
y: {
title: { display: true, text: "月降水量(mm)" },
},
},
}}
/>
</div>
);
}