From e61e507bd690f4f1160d0e35635a112854025602 Mon Sep 17 00:00:00 2001 From: shenron Date: Sat, 14 Feb 2026 14:19:12 -0500 Subject: [PATCH] Phase F: Add SVG interactivity with event binding for country selection --- src/app/map-svg/map-svg.css | 22 ++++++++++++++++ src/app/map-svg/map-svg.html | 1 + src/app/map-svg/map-svg.ts | 51 ++++++++++++++++++++++++++++++++++++ src/app/map/map.html | 2 +- src/app/map/map.ts | 3 ++- 5 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/app/map-svg/map-svg.css create mode 100644 src/app/map-svg/map-svg.html create mode 100644 src/app/map-svg/map-svg.ts diff --git a/src/app/map-svg/map-svg.css b/src/app/map-svg/map-svg.css new file mode 100644 index 0000000..feba52d --- /dev/null +++ b/src/app/map-svg/map-svg.css @@ -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; +} diff --git a/src/app/map-svg/map-svg.html b/src/app/map-svg/map-svg.html new file mode 100644 index 0000000..4af6af0 --- /dev/null +++ b/src/app/map-svg/map-svg.html @@ -0,0 +1 @@ +
diff --git a/src/app/map-svg/map-svg.ts b/src/app/map-svg/map-svg.ts new file mode 100644 index 0000000..e6795f8 --- /dev/null +++ b/src/app/map-svg/map-svg.ts @@ -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(); + + 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()); + }); + } + }); + } +} diff --git a/src/app/map/map.html b/src/app/map/map.html index 515b37d..0bcaa72 100644 --- a/src/app/map/map.html +++ b/src/app/map/map.html @@ -2,7 +2,7 @@

Interactive World Map

- World Map +
diff --git a/src/app/map/map.ts b/src/app/map/map.ts index 16690de..62bef10 100644 --- a/src/app/map/map.ts +++ b/src/app/map/map.ts @@ -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' })