Created
January 11, 2026 07:11
-
-
Save eyasuyuki/b2a372eda9a072f1cc91eb4784d0b63b to your computer and use it in GitHub Desktop.
実質賃金と消費税率のグラフ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="ja"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>実質賃金と消費税率の推移</title> | |
| <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script> | |
| <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> | |
| <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | |
| <script src="https://unpkg.com/recharts@2.5.0/dist/Recharts.js"></script> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| </head> | |
| <body> | |
| <div id="root"></div> | |
| <script type="text/babel"> | |
| const { ComposedChart, Line, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, ReferenceLine, Label } = Recharts; | |
| const WageAndTaxChart = () => { | |
| const allYears = []; | |
| for (let year = 1989; year <= 2024; year++) { | |
| allYears.push(year); | |
| } | |
| const originalData = [ | |
| { year: 1989, wage: 92.5, tax: 3, pm: '竹下〜海部', event: '消費税導入', taxLabel: '3%導入' }, | |
| { year: 1997, wage: 100.0, tax: 5, pm: '橋本', event: '5%増税', taxLabel: '5%増税' }, | |
| { year: 2000, wage: 98.2, tax: 5, pm: '森', event: '', taxLabel: '' }, | |
| { year: 2005, wage: 96.5, tax: 5, pm: '小泉', event: '', taxLabel: '' }, | |
| { year: 2007, wage: 95.0, tax: 5, pm: '安倍(1次)', event: '', taxLabel: '' }, | |
| { year: 2008, wage: 93.5, tax: 5, pm: '麻生', event: '', taxLabel: '' }, | |
| { year: 2009, wage: 92.1, tax: 5, pm: '鳩山', event: '政権交代(民主)', taxLabel: '' }, | |
| { year: 2010, wage: 91.8, tax: 5, pm: '菅直人', event: '', taxLabel: '' }, | |
| { year: 2012, wage: 91.5, tax: 5, pm: '野田', event: '', taxLabel: '' }, | |
| { year: 2014, wage: 88.5, tax: 8, pm: '安倍(2次)', event: '8%増税', taxLabel: '8%増税' }, | |
| { year: 2019, wage: 86.2, tax: 10, pm: '安倍(2次)', event: '10%増税', taxLabel: '10%増税' }, | |
| { year: 2021, wage: 84.8, tax: 10, pm: '菅義偉', event: '', taxLabel: '' }, | |
| { year: 2024, wage: 82.5, tax: 10, pm: '岸田〜石破', event: '', taxLabel: '' } | |
| ]; | |
| const data = allYears.map(year => { | |
| const original = originalData.find(d => d.year === year); | |
| if (original) { | |
| return original; | |
| } | |
| let tax = null; | |
| for (let i = originalData.length - 1; i >= 0; i--) { | |
| if (originalData[i].year < year) { | |
| tax = originalData[i].tax; | |
| break; | |
| } | |
| } | |
| return { year, wage: null, tax, pm: '', event: '', taxLabel: '' }; | |
| }); | |
| const CustomTooltip = ({ active, payload }) => { | |
| if (active && payload && payload.length) { | |
| const data = payload[0].payload; | |
| return ( | |
| <div className="bg-white p-3 border border-gray-300 rounded shadow-lg"> | |
| <p className="font-bold text-sm">{data.year}年</p> | |
| <p className="text-sm text-red-600">実質賃金: {data.wage}</p> | |
| <p className="text-sm text-sky-400">消費税率: {data.tax}%</p> | |
| <p className="text-sm text-gray-700">総理: {data.pm}</p> | |
| {data.event && <p className="text-sm text-red-600 font-semibold">{data.event}</p>} | |
| </div> | |
| ); | |
| } | |
| return null; | |
| }; | |
| return ( | |
| <div className="w-full h-screen bg-gradient-to-br from-blue-50 to-gray-100 p-4"> | |
| <div className="bg-white rounded-lg shadow-xl p-4 h-full flex flex-col"> | |
| <h1 className="text-2xl font-bold text-gray-800 mb-1 text-center"> | |
| 実質賃金と消費税率の推移 | |
| </h1> | |
| <p className="text-xs text-gray-600 mb-3 text-center"> | |
| 1989年〜2024年の実質賃金指数と消費税率の変化 | |
| </p> | |
| <div className="flex-1"> | |
| <ResponsiveContainer width="100%" height="100%"> | |
| <ComposedChart | |
| data={data} | |
| margin={{ top: 50, right: 70, bottom: 70, left: 50 }} | |
| > | |
| <CartesianGrid strokeDasharray="3 3" stroke="#e0e0e0" /> | |
| <XAxis | |
| dataKey="year" | |
| label={{ value: '年', position: 'insideBottom', offset: -10 }} | |
| tick={{ fontSize: 10 }} | |
| angle={-45} | |
| textAnchor="end" | |
| height={80} | |
| /> | |
| <YAxis | |
| yAxisId="left" | |
| domain={[75, 100]} | |
| label={{ value: '実質賃金指数', angle: -90, position: 'insideLeft', offset: 10 }} | |
| tick={{ fontSize: 12 }} | |
| /> | |
| <YAxis | |
| yAxisId="right" | |
| orientation="right" | |
| domain={[0, 15]} | |
| label={{ value: '消費税率 (%)', angle: 90, position: 'insideRight', offset: 10 }} | |
| tick={{ fontSize: 12 }} | |
| /> | |
| <Tooltip content={<CustomTooltip />} /> | |
| <Legend | |
| verticalAlign="top" | |
| height={36} | |
| wrapperStyle={{ paddingBottom: '20px' }} | |
| /> | |
| <defs> | |
| <linearGradient id="taxGradient" x1="0" y1="0" x2="0" y2="1"> | |
| <stop offset="0%" stopColor="#38bdf8" stopOpacity={0.6}/> | |
| <stop offset="100%" stopColor="#38bdf8" stopOpacity={0.2}/> | |
| </linearGradient> | |
| </defs> | |
| <defs> | |
| <clipPath id="taxClip"> | |
| <rect x="0" y="0" width="100%" height="100%" /> | |
| </clipPath> | |
| </defs> | |
| <Line | |
| yAxisId="right" | |
| type="stepAfter" | |
| dataKey="tax" | |
| stroke="none" | |
| fill="url(#taxGradient)" | |
| fillOpacity={1} | |
| connectNulls={true} | |
| /> | |
| <Line | |
| yAxisId="right" | |
| type="stepAfter" | |
| dataKey="tax" | |
| stroke="#38bdf8" | |
| strokeWidth={3} | |
| name="消費税率 (%)" | |
| fill="none" | |
| dot={(props) => { | |
| const { cx, cy, payload } = props; | |
| const taxChangeYears = [1989, 1997, 2014, 2019]; | |
| if (!taxChangeYears.includes(payload.year)) return null; | |
| return React.createElement('circle', { cx, cy, r: 5, fill: '#38bdf8' }); | |
| }} | |
| activeDot={{ r: 7 }} | |
| connectNulls={true} | |
| label={(props) => { | |
| const { x, y, value, index } = props; | |
| const currentYear = 1989 + index; | |
| const original = originalData.find(d => d.year === currentYear); | |
| const label = original?.taxLabel || ''; | |
| if (!label) return null; | |
| return React.createElement('text', { | |
| x, y: y - 10, fill: '#9333ea', textAnchor: 'middle', | |
| fontSize: 11, fontWeight: 'bold' | |
| }, label); | |
| }} | |
| /> | |
| <Line | |
| yAxisId="left" | |
| type="linear" | |
| dataKey="wage" | |
| stroke="#ef4444" | |
| strokeWidth={3} | |
| name="実質賃金指数" | |
| dot={(props) => { | |
| const { cx, cy, payload } = props; | |
| const isOriginal = originalData.some(d => d.year === payload.year); | |
| if (!isOriginal || payload.wage === null) return null; | |
| return React.createElement('circle', { cx, cy, r: 5, fill: '#ef4444' }); | |
| }} | |
| activeDot={{ r: 7 }} | |
| connectNulls={true} | |
| /> | |
| <ReferenceLine yAxisId="left" x={1989} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="竹下〜海部" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={1997} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="橋本" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2000} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="森" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2005} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="小泉" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2007} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="安倍(1次)" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2008} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="麻生" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2009} stroke="#8b5cf6" strokeDasharray="3 3"> | |
| <Label value="鳩山" position="top" fill="#8b5cf6" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2010} stroke="#8b5cf6" strokeDasharray="3 3"> | |
| <Label value="菅直人" position="top" fill="#8b5cf6" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2012} stroke="#8b5cf6" strokeDasharray="3 3"> | |
| <Label value="野田" position="top" fill="#8b5cf6" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2014} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="安倍(2次)" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2019} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="安倍(2次)" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2021} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="菅義偉" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| <ReferenceLine yAxisId="left" x={2024} stroke="#9333ea" strokeDasharray="3 3"> | |
| <Label value="岸田〜石破" position="top" fill="#9333ea" fontSize={11} offset={45} /> | |
| </ReferenceLine> | |
| </ComposedChart> | |
| </ResponsiveContainer> | |
| </div> | |
| <div className="mt-2 text-xs text-gray-600 text-center"> | |
| <p>※ 実質賃金指数は1997年を100とした指数</p> | |
| <p>※ 紫線: 総理大臣名を表示(増税時および政権交代時)</p> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| const root = ReactDOM.createRoot(document.getElementById('root')); | |
| root.render(<WageAndTaxChart />); | |
| </script> | |
| </body> | |
| </html> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
use Claude Code