Files
mapbox_gl_d3_playground/qwencoder.html
2025-08-27 02:00:32 -06:00

231 lines
8.0 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mapbox GL JS + D3.js Integration</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet">
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#info {
position: absolute;
top: 10px;
left: 10px;
background: white;
padding: 10px;
border-radius: 5px;
z-index: 1000;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
#chart {
position: absolute;
top: 10px;
right: 10px;
width: 300px;
height: 200px;
background: white;
padding: 10px;
border-radius: 5px;
z-index: 1000;
box-shadow: 0 0 10px rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<div id="map"></div>
<div id="info">
<h3>Mapbox + D3.js Demo</h3>
<p>Interactive map with D3 data visualization</p>
</div>
<div id="chart">
<h4>Population Distribution</h4>
<svg id="bar-chart" width="280" height="150"></svg>
</div>
<script>
// Initialize Mapbox GL JS
mapboxgl.accessToken = 'pk.eyJ1Ijoiam9yZGl0b3N0IiwiYSI6ImQtcVkyclEifQ.vwKrOGZoZSj3N-9MB6FF_A'; // Replace with your token
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v12',
center: [-100, 40],
zoom: 3
});
// Sample data - in real app this could come from an API or file
const sampleData = [
{ name: "New York", population: 8336817, coordinates: [-74.006, 40.7128] },
{ name: "Los Angeles", population: 3979576, coordinates: [-118.2437, 34.0522] },
{ name: "Chicago", population: 2746388, coordinates: [-87.6298, 41.8781] },
{ name: "Houston", population: 2320268, coordinates: [-95.3698, 29.7604] },
{ name: "Phoenix", population: 1680992, coordinates: [-112.0740, 33.4484] },
{ name: "Philadelphia", population: 1584064, coordinates: [-75.1652, 39.9526] }
];
// Use D3 to process and visualize data
const populationData = sampleData.map(d => d.population);
const maxPopulation = Math.max(...populationData);
// Create bar chart with D3
function createBarChart() {
const svg = d3.select("#bar-chart");
const width = +svg.attr("width");
const height = +svg.attr("height");
// Clear existing content
svg.selectAll("*").remove();
// Set up scales
const xScale = d3.scaleBand()
.domain(sampleData.map(d => d.name))
.range([0, width])
.padding(0.1);
const yScale = d3.scaleLinear()
.domain([0, maxPopulation])
.range([height, 0]);
// Create bars
svg.selectAll(".bar")
.data(sampleData)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => xScale(d.name))
.attr("width", xScale.bandwidth())
.attr("y", d => yScale(d.population))
.attr("height", d => height - yScale(d.population))
.attr("fill", "#3b82f6");
// Add value labels
svg.selectAll(".label")
.data(sampleData)
.enter()
.append("text")
.attr("class", "label")
.attr("x", d => xScale(d.name) + xScale.bandwidth() / 2)
.attr("y", d => yScale(d.population) - 5)
.attr("text-anchor", "middle")
.text(d => Math.round(d.population / 1000000) + "M");
}
// Create map markers with D3 processing
function createMarkers() {
const markers = [];
sampleData.forEach((city, index) => {
// Use D3 to process data for marker styling
const normalizedPopulation = city.population / maxPopulation;
// Create marker element
const el = document.createElement('div');
el.className = 'marker';
el.style.width = '20px';
el.style.height = '20px';
el.style.background = `rgba(59, 130, 246, ${normalizedPopulation})`;
el.style.borderRadius = '50%';
el.style.border = '2px solid white';
el.style.boxShadow = '0 0 5px rgba(0,0,0,0.5)';
// Add click interaction
el.addEventListener('click', () => {
alert(`${city.name}: ${city.population.toLocaleString()} people`);
});
// Create marker
const marker = new mapboxgl.Marker(el)
.setLngLat(city.coordinates)
.addTo(map);
markers.push(marker);
});
}
// Initialize everything when map is loaded
map.on('load', function () {
// Create D3 visualizations
createBarChart();
// Create map markers
createMarkers();
// Add a custom data layer using D3 processed data
const geojsonData = {
type: "FeatureCollection",
features: sampleData.map(city => ({
type: "Feature",
geometry: {
type: "Point",
coordinates: city.coordinates
},
properties: {
name: city.name,
population: city.population
}
}))
};
// Add source and layer for data visualization
map.addSource('cities', {
type: 'geojson',
data: geojsonData
});
map.addLayer({
id: 'cities-points',
type: 'circle',
source: 'cities',
paint: {
'circle-radius': [
'interpolate', ['linear'], ['get', 'population'],
1000000, 5,
8000000, 20
],
'circle-color': '#3b82f6',
'circle-stroke-width': 1,
'circle-stroke-color': '#ffffff'
}
});
// Add a simple legend using D3
const legendData = [
{ label: "Small", population: 1000000 },
{ label: "Medium", population: 4000000 },
{ label: "Large", population: 8000000 }
];
const legendSvg = d3.select("#info")
.append("div")
.attr("id", "legend")
.style("margin-top", "10px");
legendSvg.selectAll("circle")
.data(legendData)
.enter()
.append("circle")
.attr("r", d => Math.sqrt(d.population / 100000))
.attr("cx", (d, i) => i * 30 + 10)
.attr("cy", 20)
.attr("fill", "#3b82f6");
});
// Handle window resize
window.addEventListener('resize', function() {
map.resize();
});
</script>
</body>
</html>