<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>地震情報 - 完全版</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: var(--bg-color, #ffffff);
color: var(--text-color, #000000);
transition: background-color 0.3s, color 0.3s;
}
.container {
max-width: 1200px;
margin: 20px auto;
padding: 20px;
background: var(--card-bg, #ffffff);
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
}
#map {
height: 400px;
margin-top: 20px;
}
.toggle-dark-mode {
position: fixed;
top: 10px;
right: 10px;
padding: 10px;
background: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
@media (max-width: 768px) {
.container {
padding: 10px;
}
}
</style>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<button class="toggle-dark-mode" onclick="toggleDarkMode()">ダークモード切り替え</button>
<div class="container">
<h1>地震情報</h1>
<div id="quakeStats">
<canvas id="intensityChart" width="400" height="200"></canvas>
</div>
<div id="map"></div>
<div id="regionData"></div>
</div>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<script>
const rssUrl = 'https://www.jma.go.jp/bosai/quake/data/list.xml';
let quakeData = [];
const regions = {};
const map = L.map('map').setView([35.6895, 139.6917], 5);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
async function fetchEarthquakeData() {
try {
const response = await fetch(`https://api.allorigins.win/get?url=${encodeURIComponent(rssUrl)}`);
const data = await response.json();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(data.contents, "text/xml");
const items = xmlDoc.getElementsByTagName('item');
quakeData = [];
for (let i = 0; i < items.length; i++) {
const title = items[i].getElementsByTagName('title')[0].textContent;
const description = items[i].getElementsByTagName('description')[0].textContent;
const pubDate = items[i].getElementsByTagName('pubDate')[0].textContent;
const match = description.match(/震源地:(.+?)、緯度:(.+?)、経度:(.+?)、震度:(.+?)、/);
if (match) {
const location = match[1];
const lat = parseFloat(match[2]);
const lng = parseFloat(match[3]);
const intensity = parseFloat(match[4]);
quakeData.push({ title, location, lat, lng, intensity, pubDate });
if (!regions[location]) {
regions[location] = [];
}
regions[location].push({ intensity, pubDate });
}
}
displayQuakeData();
updateChart();
} catch (error) {
console.error('地震情報の取得に失敗しました:', error);
}
}
function displayQuakeData() {
map.eachLayer(layer => {
if (layer.options && layer.options.pane === "markerPane") {
map.removeLayer(layer);
}
});
quakeData.forEach(quake => {
L.circle([quake.lat, quake.lng], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: quake.intensity * 10000
}).addTo(map)
.bindPopup(`<strong>${quake.title}</strong><br>震源地: ${quake.location}<br>震度: ${quake.intensity}`);
});
}
function updateChart() {
const ctx = document.getElementById('intensityChart').getContext('2d');
const labels = quakeData.map(q => q.pubDate);
const intensities = quakeData.map(q => q.intensity);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: '震度',
data: intensities,
borderColor: 'rgba(255, 99, 132, 1)',
borderWidth: 2,
fill: false
}]
}
});
}
function toggleDarkMode() {
const isDarkMode = document.body.style.getPropertyValue('--bg-color') === '#ffffff';
document.body.style.setProperty('--bg-color', isDarkMode ? '#333333' : '#ffffff');
document.body.style.setProperty('--text-color', isDarkMode ? '#ffffff' : '#000000');
document.body.style.setProperty('--card-bg', isDarkMode ? '#444444' : '#ffffff');
}
fetchEarthquakeData();
setInterval(fetchEarthquakeData, 60000); // 1分ごとに更新
</script>
</body>
</html>