Phase F: Add SVG interactivity with event binding for country selection

This commit is contained in:
2026-02-14 14:19:12 -05:00
parent d5728a0dbe
commit e61e507bd6
5 changed files with 77 additions and 2 deletions

View File

@@ -0,0 +1,22 @@
.svg-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
:host ::ng-deep svg {
max-width: 100%;
height: auto;
}
:host ::ng-deep .country-path {
cursor: pointer;
transition: fill 0.2s ease;
}
:host ::ng-deep .country-path:hover {
fill: #3498db !important;
opacity: 0.8;
}

View File

@@ -0,0 +1 @@
<div class="svg-container"></div>

View File

@@ -0,0 +1,51 @@
import { Component, Output, EventEmitter, AfterViewInit, ElementRef } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-map-svg',
imports: [],
templateUrl: './map-svg.html',
styleUrl: './map-svg.css'
})
export class MapSvgComponent implements AfterViewInit {
@Output() countryClick = new EventEmitter<string>();
constructor(private http: HttpClient, private elementRef: ElementRef) {}
ngAfterViewInit(): void {
// Load SVG file and inject it into the component
this.http.get('assets/map-image.svg', { responseType: 'text' }).subscribe({
next: (svgContent) => {
const container = this.elementRef.nativeElement.querySelector('.svg-container');
if (container) {
container.innerHTML = svgContent;
this.attachClickHandlers();
}
},
error: (err) => {
console.error('Failed to load SVG:', err);
}
});
}
private attachClickHandlers(): void {
const svgElement = this.elementRef.nativeElement.querySelector('svg');
if (!svgElement) return;
// Find all path elements with id attributes (country codes)
const paths = svgElement.querySelectorAll('path[id]');
paths.forEach((path: Element) => {
const countryCode = path.getAttribute('id');
if (countryCode) {
// Add hover effect
path.setAttribute('class', 'country-path');
// Add click handler
path.addEventListener('click', () => {
this.countryClick.emit(countryCode.toUpperCase());
});
}
});
}
}

View File

@@ -2,7 +2,7 @@
<div class="map-column">
<h2>Interactive World Map</h2>
<div class="map-container">
<img src="assets/map-image.svg" alt="World Map" class="world-map" />
<app-map-svg (countryClick)="onCountrySelected($event)"></app-map-svg>
</div>
</div>

View File

@@ -1,10 +1,11 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { WorldBankService, CountryData } from '../services/world-bank';
import { MapSvgComponent } from '../map-svg/map-svg';
@Component({
selector: 'app-map',
imports: [CommonModule],
imports: [CommonModule, MapSvgComponent],
templateUrl: './map.html',
styleUrl: './map.css'
})