Interactive data visualization application that displays statistical information overlaid on Swedish provinces and municipalities. Transform complex statistical data into intuitive visual representations for government analysis, research, business intelligence, and education.
Built with React, TypeScript, and custom Mercator projection without external mapping libraries.
- 🗺️ Interactive Map: Pan, zoom, and click to select Swedish provinces
- 📊 Statistical Data Visualization: Heat maps and choropleth maps for data overlay
- 🏛️ SCB API Integration: Direct integration with Statistics Sweden API
- 🏙️ City Markers: Population-based city visualization with hover tooltips
- 🌐 Internationalization: Automatic language detection (Swedish/English) with fallback
- ♿ Accessibility: Full keyboard navigation and screen reader support
- 🎨 Custom Styling: Centralized color system and responsive design
- ☁️ Animated Clouds: Dynamic cloud effects with province-responsive behavior
- Node.js (v16 or higher)
- npm
# Clone the repository
git clone <repository-url>
cd kartapp
# Install dependencies
npm install
# Start development server
npm run devThe application will be available at http://localhost:3001
# Build for production
npm run build
# Start production server (localhost:10000)
npm startnpm run dev- Start development server on http://localhost:3001npm run build- Build for productionnpm start- Start production server on http://localhost:10000npm test- Run all Cypress testsnpm run test:open- Open Cypress test runner GUInpm run test:controls- Run map controls tests onlynpm run test:provinces- Run province interaction tests onlynpm run test:cities- Run city marker tests onlynpm run test:clouds- Run cloud animation tests onlynpm run test:accessibility- Run accessibility tests only
src/
├── components/ # React components
│ ├── CustomMap.tsx # Main map component
│ ├── MapControls.tsx # Control panel
│ ├── MapGrid.tsx # Map grid rendering
│ ├── MapProvinces.tsx # Province polygons
│ ├── CityMarkers.tsx # City markers
│ └── MovingClouds.tsx # Animated clouds
├── hooks/ # Custom React hooks
│ ├── useMapState.ts # Map state management
│ ├── useMapInteractions.ts # Mouse/wheel events
│ ├── useMapKeyboard.ts # Keyboard events
│ └── useTranslations.ts # Internationalization
├── services/ # API services
│ └── scbApi.ts # SCB API integration
├── utils/ # Utility functions
│ ├── mapProjection.ts # Geographic calculations
│ ├── mapInteractions.ts # Interaction utilities
│ ├── mapCalculations.ts # Calculation hooks
│ ├── cityDataProcessing.ts # City data utilities
│ ├── scbDataProcessing.ts # SCB data processing
│ └── i18n.ts # Translation utilities
├── types/ # TypeScript types
│ ├── geographic.ts # Geographic data types
│ └── scb.ts # SCB API types
├── content/ # Text content
│ └── translations.ts # All translations
├── styles/ # Styling
│ └── _colors.scss # Color variables
└── data/ # Static data
├── sweden_provinces.ts # Province GeoJSON
└── swedish-cities.json # City data
- Frontend: React 19 + TypeScript
- Build: Webpack 5 + SASS
- Mapping: Custom SVG rendering with Mercator projection
- Testing: Cypress for E2E testing
- Production: Express.js static file server
- APIs: SCB (Statistics Sweden) API integration
- No external mapping libraries
- Custom Mercator projection for accurate Swedish geography
- Pan and zoom functionality with mouse and keyboard
- Province selection with visual feedback
- Responsive design for all screen sizes
- Population-based sizing (30k+ inhabitants)
- Appear only when provinces are selected
- Instant hover tooltips with city names
- Accessible with keyboard navigation
- Automatic browser language detection
- Swedish and English translations
- Fallback to English for missing translations
- Template string support for dynamic content
- Full keyboard navigation support
- Screen reader compatibility
- ARIA labels and descriptions
- High contrast mode support
- Reduced motion support
- Mouse: Click and drag to pan, scroll to zoom
- Keyboard: Tab to navigate provinces, Enter/Space to select
- Reset: Press Escape or click "Reset View" button
- Click any province to zoom in and show cities
- Cities appear as colored dots sized by population
- Hover over cities to see names
- Click "Show All" to return to full map view
The app automatically detects your browser language:
- Swedish users see Swedish interface
- All others see English interface
- All province and city names are localized
- TypeScript with strict mode
- Component-based architecture
- Custom hooks for logic separation
- Centralized color and content management
- WCAG 2.1 compliant
- Keyboard-only navigation support
- Screen reader optimization
- Color contrast compliance
- Memoized calculations with useMemo/useCallback
- Pre-calculated SVG paths
- Optimized rendering with React best practices
- Follow conventional commit format (
feat:,fix:,refactor:) - Keep components under 150 lines
- Extract logic into custom hooks
- Store utilities in
src/utils/ - Add text content to
src/content/ - Use centralized colors from
src/styles/_colors.scss
- Components: Rendering and basic prop management only
- Hooks: State management and complex logic
- Utils: Pure functions and calculations
- Content: All text content and translations
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
[Add your license information here]
- Built with Claude Code
- Geographic data from Swedish authorities
- City population data from public sources