|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Sales Territory Maps</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" /> |
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script> |
|
|
<style> |
|
|
.map-container { |
|
|
width: 100%; |
|
|
height: 80vh; |
|
|
position: relative; |
|
|
background-color: #f0f4f8; |
|
|
border: 2px solid #e2e8f0; |
|
|
} |
|
|
#map { |
|
|
height: 100%; |
|
|
width: 100%; |
|
|
} |
|
|
.legend { |
|
|
position: absolute; |
|
|
bottom: 20px; |
|
|
right: 20px; |
|
|
background: white; |
|
|
padding: 15px; |
|
|
border-radius: 5px; |
|
|
box-shadow: 0 0 15px rgba(0,0,0,0.2); |
|
|
z-index: 1000; |
|
|
max-height: 60vh; |
|
|
overflow-y: auto; |
|
|
width: 300px; |
|
|
} |
|
|
.hospital-marker { |
|
|
background: #3b82f6; |
|
|
color: white; |
|
|
border-radius: 50%; |
|
|
width: 24px; |
|
|
height: 24px; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
font-weight: bold; |
|
|
font-size: 12px; |
|
|
box-shadow: 0 0 5px rgba(0,0,0,0.3); |
|
|
} |
|
|
.airport-marker { |
|
|
background: #ef4444; |
|
|
color: white; |
|
|
border-radius: 50%; |
|
|
width: 20px; |
|
|
height: 20px; |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
font-weight: bold; |
|
|
font-size: 10px; |
|
|
box-shadow: 0 0 5px rgba(0,0,0,0.3); |
|
|
} |
|
|
.hospital-table { |
|
|
width: 100%; |
|
|
border-collapse: collapse; |
|
|
} |
|
|
.hospital-table th, .hospital-table td { |
|
|
border: 1px solid #e2e8f0; |
|
|
padding: 8px; |
|
|
text-align: left; |
|
|
font-size: 12px; |
|
|
} |
|
|
.hospital-table th { |
|
|
background-color: #3b82f6; |
|
|
color: white; |
|
|
} |
|
|
.hospital-table tr:nth-child(even) { |
|
|
background-color: #f8fafc; |
|
|
} |
|
|
.hospital-table tr:hover { |
|
|
background-color: #e2e8f0; |
|
|
} |
|
|
.state-title { |
|
|
position: absolute; |
|
|
top: 20px; |
|
|
left: 20px; |
|
|
background: rgba(255,255,255,0.9); |
|
|
padding: 10px 20px; |
|
|
border-radius: 5px; |
|
|
font-size: 24px; |
|
|
font-weight: bold; |
|
|
z-index: 1000; |
|
|
box-shadow: 0 0 10px rgba(0,0,0,0.1); |
|
|
} |
|
|
.print-controls { |
|
|
margin-bottom: 20px; |
|
|
display: flex; |
|
|
gap: 10px; |
|
|
} |
|
|
@media print { |
|
|
.no-print { |
|
|
display: none; |
|
|
} |
|
|
body { |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
} |
|
|
.map-container { |
|
|
height: 100vh; |
|
|
width: 100vw; |
|
|
} |
|
|
.legend { |
|
|
position: absolute; |
|
|
bottom: 20px; |
|
|
right: 20px; |
|
|
max-height: 80vh; |
|
|
} |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-100 p-4"> |
|
|
<div class="max-w-7xl mx-auto"> |
|
|
<h1 class="text-3xl font-bold text-gray-800 mb-6">Sales Territory Maps</h1> |
|
|
|
|
|
<div class="print-controls no-print"> |
|
|
<select id="state-selector" class="px-4 py-2 border rounded-lg"> |
|
|
<option value="california">California</option> |
|
|
<option value="texas">Texas</option> |
|
|
<option value="florida">Florida</option> |
|
|
<option value="new-york">New York</option> |
|
|
<option value="pennsylvania">Pennsylvania</option> |
|
|
<option value="illinois">Illinois</option> |
|
|
<option value="ohio">Ohio</option> |
|
|
<option value="georgia">Georgia</option> |
|
|
<option value="north-carolina">North Carolina</option> |
|
|
</select> |
|
|
<button onclick="window.print()" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">Print Map</button> |
|
|
</div> |
|
|
|
|
|
<div class="map-container"> |
|
|
<div id="map"></div> |
|
|
<div class="state-title" id="state-title">California</div> |
|
|
<div class="legend"> |
|
|
<h3 class="font-bold text-lg mb-2">Hospital Legend</h3> |
|
|
<div class="overflow-x-auto"> |
|
|
<table class="hospital-table"> |
|
|
<thead> |
|
|
<tr> |
|
|
<th>#</th> |
|
|
<th>Name</th> |
|
|
<th>Beds</th> |
|
|
<th>NPR</th> |
|
|
<th>Parent</th> |
|
|
<th>Airport</th> |
|
|
</tr> |
|
|
</thead> |
|
|
<tbody id="legend-table"> |
|
|
|
|
|
</tbody> |
|
|
</table> |
|
|
</div> |
|
|
<div class="mt-3 text-sm"> |
|
|
<div class="flex items-center mb-1"> |
|
|
<div class="hospital-marker mr-2">1</div> |
|
|
<span>Hospital</span> |
|
|
</div> |
|
|
<div class="flex items-center"> |
|
|
<div class="airport-marker mr-2">A</div> |
|
|
<span>Major Airport</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
const stateData = { |
|
|
'california': { |
|
|
name: 'California', |
|
|
center: [36.7783, -119.4179], |
|
|
zoom: 6, |
|
|
hospitals: [ |
|
|
{ id: 1, name: 'UCSF Medical Center', beds: 785, npr: 3200000000, parent: 'UCSF Health', lat: 37.7631, lng: -122.4581, airportTime: 25 }, |
|
|
{ id: 2, name: 'Cedars-Sinai Medical Center', beds: 886, npr: 3800000000, parent: 'Cedars-Sinai', lat: 34.0836, lng: -118.3836, airportTime: 20 }, |
|
|
{ id: 3, name: 'Stanford Hospital', beds: 613, npr: 2800000000, parent: 'Stanford Health Care', lat: 37.4349, lng: -122.1755, airportTime: 15 }, |
|
|
{ id: 4, name: 'UCLA Medical Center', beds: 520, npr: 2500000000, parent: 'UCLA Health', lat: 34.0669, lng: -118.4467, airportTime: 18 }, |
|
|
{ id: 5, name: 'Kaiser Permanente Oakland', beds: 349, npr: 1500000000, parent: 'Kaiser Permanente', lat: 37.8119, lng: -122.2696, airportTime: 22 } |
|
|
], |
|
|
airports: [ |
|
|
{ code: 'LAX', name: 'Los Angeles International', lat: 33.9416, lng: -118.4085 }, |
|
|
{ code: 'SFO', name: 'San Francisco International', lat: 37.6213, lng: -122.3790 }, |
|
|
{ code: 'SAN', name: 'San Diego International', lat: 32.7338, lng: -117.1933 }, |
|
|
{ code: 'SJC', name: 'San Jose International', lat: 37.3626, lng: -121.9290 } |
|
|
] |
|
|
}, |
|
|
'texas': { |
|
|
name: 'Texas', |
|
|
center: [31.9686, -99.9018], |
|
|
zoom: 6, |
|
|
hospitals: [ |
|
|
{ id: 1, name: 'Houston Methodist Hospital', beds: 948, npr: 4200000000, parent: 'Houston Methodist', lat: 29.7099, lng: -95.4019, airportTime: 18 }, |
|
|
{ id: 2, name: 'UT Southwestern Medical Center', beds: 460, npr: 2100000000, parent: 'UT Southwestern', lat: 32.8136, lng: -96.8386, airportTime: 15 }, |
|
|
{ id: 3, name: 'Baylor University Medical Center', beds: 1025, npr: 3800000000, parent: 'Baylor Scott & White', lat: 32.7996, lng: -96.8007, airportTime: 12 } |
|
|
], |
|
|
airports: [ |
|
|
{ code: 'DFW', name: 'Dallas/Fort Worth International', lat: 32.8968, lng: -97.0380 }, |
|
|
{ code: 'IAH', name: 'George Bush Intercontinental', lat: 29.9844, lng: -95.3414 }, |
|
|
{ code: 'AUS', name: 'Austin-Bergstrom International', lat: 30.1945, lng: -97.6699 } |
|
|
] |
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
let map; |
|
|
let currentState = 'california'; |
|
|
|
|
|
function initMap() { |
|
|
const state = stateData[currentState]; |
|
|
|
|
|
|
|
|
map = L.map('map').setView(state.center, state.zoom); |
|
|
|
|
|
|
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
|
|
}).addTo(map); |
|
|
|
|
|
|
|
|
document.getElementById('state-title').textContent = state.name; |
|
|
|
|
|
|
|
|
map.eachLayer(layer => { |
|
|
if (layer instanceof L.Marker) { |
|
|
map.removeLayer(layer); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
state.hospitals.forEach(hospital => { |
|
|
const marker = L.marker([hospital.lat, hospital.lng], { |
|
|
icon: L.divIcon({ |
|
|
className: 'hospital-icon', |
|
|
html: `<div class="hospital-marker">${hospital.id}</div>`, |
|
|
iconSize: [24, 24] |
|
|
}) |
|
|
}).addTo(map); |
|
|
|
|
|
|
|
|
marker.bindPopup(` |
|
|
<b>${hospital.name}</b><br> |
|
|
Beds: ${hospital.beds.toLocaleString()}<br> |
|
|
NPR: $${(hospital.npr / 1000000).toLocaleString()}M<br> |
|
|
Parent: ${hospital.parent}<br> |
|
|
Airport: ${hospital.airportTime} min |
|
|
`); |
|
|
}); |
|
|
|
|
|
|
|
|
state.airports.forEach(airport => { |
|
|
const marker = L.marker([airport.lat, airport.lng], { |
|
|
icon: L.divIcon({ |
|
|
className: 'airport-icon', |
|
|
html: `<div class="airport-marker">${airport.code}</div>`, |
|
|
iconSize: [20, 20] |
|
|
}) |
|
|
}).addTo(map); |
|
|
|
|
|
|
|
|
marker.bindPopup(` |
|
|
<b>${airport.name} (${airport.code})</b> |
|
|
`); |
|
|
}); |
|
|
|
|
|
|
|
|
const tableBody = document.getElementById('legend-table'); |
|
|
tableBody.innerHTML = ''; |
|
|
|
|
|
state.hospitals.forEach(hospital => { |
|
|
const row = document.createElement('tr'); |
|
|
row.innerHTML = ` |
|
|
<td>${hospital.id}</td> |
|
|
<td>${hospital.name}</td> |
|
|
<td>${hospital.beds.toLocaleString()}</td> |
|
|
<td>$${(hospital.npr / 1000000).toLocaleString()}M</td> |
|
|
<td>${hospital.parent}</td> |
|
|
<td>${hospital.airportTime} min</td> |
|
|
`; |
|
|
tableBody.appendChild(row); |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', () => { |
|
|
initMap(); |
|
|
|
|
|
|
|
|
document.getElementById('state-selector').addEventListener('change', (e) => { |
|
|
currentState = e.target.value; |
|
|
initMap(); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
</script> |
|
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=Mishak/gis-map" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body> |
|
|
</html> |