Spaces:
Sleeping
Sleeping
File size: 10,344 Bytes
32c2587 bcd0e3c f039650 bcd0e3c 32c2587 bcd0e3c d7ed39d bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 d7ed39d bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c f8842a2 766b697 f8842a2 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c 766b697 bcd0e3c d7ed39d bcd0e3c f8842a2 bcd0e3c d7ed39d bcd0e3c 766b697 bcd0e3c a2875f8 bcd0e3c 2ba8eb9 bcd0e3c 766b697 bcd0e3c b0bc07c bcd0e3c d7ed39d bcd0e3c f8842a2 61186ad bcd0e3c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 |
import gradio as gr
import json
import random
# Sample country data with random progress percentages
COUNTRY_DATA = {
"MX": {"name": "Mexico", "percent": random.randint(10, 90)},
"AR": {"name": "Argentina", "percent": random.randint(10, 90)},
"CO": {"name": "Colombia", "percent": random.randint(10, 90)},
"CL": {"name": "Chile", "percent": random.randint(10, 90)},
"PE": {"name": "Peru", "percent": random.randint(10, 90)},
"ES": {"name": "Spain", "percent": random.randint(10, 90)},
"BR": {"name": "Brazil", "percent": random.randint(10, 90)},
"VE": {"name": "Venezuela", "percent": random.randint(10, 90)},
"EC": {"name": "Ecuador", "percent": random.randint(10, 90)},
"BO": {"name": "Bolivia", "percent": random.randint(10, 90)},
"PY": {"name": "Paraguay", "percent": random.randint(10, 90)},
"UY": {"name": "Uruguay", "percent": random.randint(10, 90)},
"CR": {"name": "Costa Rica", "percent": random.randint(10, 90)},
"PA": {"name": "Panama", "percent": random.randint(10, 90)}
}
# Create the basic HTML container for the map
def create_map_container():
return """
<div id="map-container" style="width:100%; height:600px; position:relative; background-color:#111;">
<div style="display:flex; justify-content:center; align-items:center; height:100%; color:white; font-family:sans-serif;">
Loading map visualization...
</div>
</div>
<div id="tooltip" style="position:absolute; background-color:rgba(0,0,0,0.8); border-radius:5px; padding:8px; color:white; font-size:12px; pointer-events:none; opacity:0; transition:opacity 0.3s;"></div>
"""
# Create a script tag with the D3 code
def create_map_script():
# Convert country data to JSON for JavaScript
country_data_json = json.dumps(COUNTRY_DATA)
return f"""
<script>
// Function to load D3.js and create the map
async function createMap() {{
// Load D3.js dynamically
await new Promise((resolve) => {{
const script = document.createElement('script');
script.src = 'https://d3js.org/d3.v7.min.js';
script.onload = resolve;
document.head.appendChild(script);
}});
console.log('D3 loaded successfully');
// Country data from Python
const countryData = {country_data_json};
// Get container dimensions
const container = document.getElementById('map-container');
const width = container.clientWidth;
const height = container.clientHeight;
// Clear loading message
container.innerHTML = '';
// Create SVG
const svg = d3.select('#map-container')
.append('svg')
.attr('width', width)
.attr('height', height)
.attr('viewBox', `0 0 ${{width}} ${{height}}`);
// Create color scale
const colorScale = d3.scaleLinear()
.domain([0, 100])
.range(['#4a1942', '#f32b7b']);
// Set up projection focused on Latin America
const projection = d3.geoMercator()
.center([-60, 0])
.scale(width / 5)
.translate([width / 2, height / 2]);
const path = d3.geoPath().projection(projection);
// Tooltip setup
const tooltip = d3.select('#tooltip');
// Load GeoJSON data
try {{
const response = await fetch('https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson');
const data = await response.json();
// Draw countries
svg.selectAll('path')
.data(data.features)
.enter()
.append('path')
.attr('d', path)
.attr('stroke', '#f32b7b')
.attr('stroke-width', 1)
.attr('fill', d => {{
// Get the ISO code from the properties
const iso = d.properties.iso_a2;
if (countryData[iso]) {{
return colorScale(countryData[iso].percent);
}}
return '#2d3748'; // Default gray for other countries
}})
.on('mouseover', function(event, d) {{
const iso = d.properties.iso_a2;
d3.select(this)
.attr('stroke', '#4a1942')
.attr('stroke-width', 2);
if (countryData[iso]) {{
tooltip.style('opacity', 1)
.style('left', (event.pageX + 15) + 'px')
.style('top', (event.pageY + 15) + 'px')
.html(`
<strong>${{countryData[iso].name}}</strong><br/>
Progress: ${{countryData[iso].percent}}%
`);
}}
}})
.on('mousemove', function(event) {{
tooltip.style('left', (event.pageX + 15) + 'px')
.style('top', (event.pageY + 15) + 'px');
}})
.on('mouseout', function() {{
d3.select(this)
.attr('stroke', '#f32b7b')
.attr('stroke-width', 1);
tooltip.style('opacity', 0);
}});
// Add a legend
const legendWidth = Math.min(width - 40, 200);
const legendHeight = 15;
const legendX = width - legendWidth - 20;
const legend = svg.append('g')
.attr('transform', `translate(${{legendX}}, 30)`);
// Create gradient for legend
const defs = svg.append('defs');
const gradient = defs.append('linearGradient')
.attr('id', 'dataGradient')
.attr('x1', '0%')
.attr('y1', '0%')
.attr('x2', '100%')
.attr('y2', '0%');
gradient.append('stop')
.attr('offset', '0%')
.attr('stop-color', '#4a1942');
gradient.append('stop')
.attr('offset', '100%')
.attr('stop-color', '#f32b7b');
// Add legend title
legend.append('text')
.attr('x', legendWidth / 2)
.attr('y', -10)
.attr('text-anchor', 'middle')
.attr('font-size', '12px')
.attr('fill', '#f1f5f9')
.text('Progress');
// Add legend rectangle
legend.append('rect')
.attr('width', legendWidth)
.attr('height', legendHeight)
.attr('rx', 2)
.attr('ry', 2)
.style('fill', 'url(#dataGradient)');
// Add legend labels
legend.append('text')
.attr('x', 0)
.attr('y', legendHeight + 15)
.attr('text-anchor', 'start')
.attr('font-size', '10px')
.attr('fill', '#94a3b8')
.text('0%');
legend.append('text')
.attr('x', legendWidth / 2)
.attr('y', legendHeight + 15)
.attr('text-anchor', 'middle')
.attr('font-size', '10px')
.attr('fill', '#94a3b8')
.text('50%');
legend.append('text')
.attr('x', legendWidth)
.attr('y', legendHeight + 15)
.attr('text-anchor', 'end')
.attr('font-size', '10px')
.attr('fill', '#94a3b8')
.text('100%');
// Handle window resize
window.addEventListener('resize', () => {{
const width = container.clientWidth;
// Update SVG dimensions
svg.attr('width', width)
.attr('viewBox', `0 0 ${{width}} ${{height}}`);
// Update projection
projection.scale(width / 5)
.translate([width / 2, height / 2]);
// Update paths
svg.selectAll('path').attr('d', path);
// Update legend position
const legendWidth = Math.min(width - 40, 200);
const legendX = width - legendWidth - 20;
legend.attr('transform', `translate(${{legendX}}, 30)`);
}});
}} catch (error) {{
console.error('Error loading or rendering the map:', error);
container.innerHTML = `<div style="color: white; text-align: center;">Error loading map: ${{error.message}}</div>`;
}}
}}
// Call the function when the DOM is ready
document.addEventListener('DOMContentLoaded', createMap);
</script>
"""
# Create a simple Gradio interface
with gr.Blocks(theme=gr.themes.Soft(primary_hue="pink", secondary_hue="purple")) as demo:
gr.Markdown("# Latin America & Spain Map")
# Create a container for the map
map_container = gr.HTML(create_map_container())
# Create a container for the script
script_container = gr.HTML(create_map_script(), visible=False)
# Button to generate new random data
def update_data():
# Declare the variable as global first
global COUNTRY_DATA
# Create new random percentages
new_data = {
code: {"name": data["name"], "percent": random.randint(10, 90)}
for code, data in COUNTRY_DATA.items()
}
# Update the global variable
COUNTRY_DATA = new_data
# Return the updated script
return create_map_script()
gr.Button("Generate New Random Data").click(fn=update_data, outputs=script_container)
if __name__ == "__main__":
demo.launch() |