AgentSkillsCN

maps

借助 TopoJSONMap 和 DottedMap,打造地图可视化效果。无论是地理数据、区域热力图,还是基于位置的可视化场景,此技能都能助您轻松实现。

SKILL.md
--- frontmatter
name: maps
description: Build map visualizations with TopoJSONMap and DottedMap. Use for geographical data, choropleth maps, and location-based visualizations.

Map Components

vue-chrts provides two map components:

  • TopoJSONMap: Full-featured geographic maps using TopoJSON data
  • DottedMap: Stylized dot-matrix world maps

TopoJSONMap

Renders geographic regions using TopoJSON data. Supports choropleth coloring, points, and links.

Mental Model

code
┌─────────────────────────────────────────────────────────────┐
│  TOPOJSONMAP LAYERS                                         │
│                                                             │
│  ┌───────────────────────────────────────────────────────┐ │
│  │  Areas (regions/countries from TopoJSON)              │ │
│  │  ┌─────────┐  ┌─────────┐  ┌─────────┐               │ │
│  │  │  Region │  │  Region │  │  Region │               │ │
│  │  │    A    │──│    B    │──│    C    │               │ │
│  │  └─────────┘  └─────────┘  └─────────┘               │ │
│  │                    ●  ●  ●  Points (cities, etc.)     │ │
│  │                    └──┴──┘  Links (connections)       │ │
│  └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

Complete Example

vue
<script setup lang="ts">
import { TopoJSONMap, LegendPosition } from 'vue-chrts'
import usaTopoJson from './data/usa.topo.json'

interface StateData {
  id: string
  name: string
  value: number
}

const stateData: StateData[] = [
  { id: 'CA', name: 'California', value: 39500000 },
  { id: 'TX', name: 'Texas', value: 29000000 },
  { id: 'FL', name: 'Florida', value: 21500000 },
  // ... more states
]

const categories = {
  low: { name: 'Low Population', color: '#bfdbfe' },
  medium: { name: 'Medium Population', color: '#3b82f6' },
  high: { name: 'High Population', color: '#1e3a8a' }
}

const getAreaColor = (feature: any) => {
  const state = stateData.find(s => s.id === feature.properties.id)
  if (!state) return '#e5e7eb'
  if (state.value > 20000000) return categories.high.color
  if (state.value > 10000000) return categories.medium.color
  return categories.low.color
}
</script>

<template>
  <TopoJSONMap
    :data="{
      mapFeatureKey: 'id',
      data: { areas: stateData },
      topoJson: usaTopoJson
    }"
    :height="500"
    :areaColor="getAreaColor"
    :categories="categories"
    :legendPosition="LegendPosition.BottomRight"
    :fitView="true"
    :zoomExtent="[1, 8]"
  />
</template>

TopoJSONMap Props

PropTypeDescription
data.topoJsonobjectTopoJSON data object
data.mapFeatureKeykeyof TKey to match features with data
data.dataMapDataAreas, points, links data
heightstring | numberMap height
widthstring | numberMap width
projectionGeoProjectionD3 geo projection
areaColorstring | (feature) => stringArea fill color
areaCursorstring | (feature) => stringArea cursor style
pointColorstring | (point) => stringPoint color
pointSizenumber | (point) => numberPoint radius
pointLabel(point) => stringPoint label accessor
linkColorstring | (link) => stringLink stroke color
linkWidthnumber | (link) => numberLink stroke width
fitViewbooleanAuto-fit map to container
fitViewPaddingnumberPadding when fitting
zoomFactornumberInitial zoom level
zoomExtent[number, number]Min/max zoom levels

DottedMap

Creates stylized dot-matrix world maps. Great for showing global presence, locations, or minimalist geographic visualizations.

Mental Model

code
┌─────────────────────────────────────────────────────────────┐
│  DOTTED MAP                                                 │
│                                                             │
│    ·  · ·  ·  · ·  ·  · ·  ·  · ·  ·  · ·  ·             │
│   · ·  ·  · ·  ·  · ·  ·  · ·  ·  · ·  ·  · ·            │
│    ·  · ●  ·  · ·  ·  ● ·  ·  · ·  ·  · ·  ·  ← Pins     │
│   · ·  ·  · ·  ·  · ·  ·  · ·  ●  · ·  ·  · ·            │
│    ·  · ·  ·  · ·  ·  · ·  ·  · ·  ·  · ·  ·             │
│                                                             │
│  Base dots = landmass                                       │
│  Pins = custom locations with lat/lng                       │
└─────────────────────────────────────────────────────────────┘

Complete Example

vue
<script setup lang="ts">
import { DottedMap, getMap, getPin } from 'vue-chrts'

const pins = [
  getPin({ lat: 40.7128, lng: -74.0060, color: '#ef4444', radius: 3 }), // New York
  getPin({ lat: 51.5074, lng: -0.1278, color: '#3b82f6', radius: 3 }),  // London
  getPin({ lat: 35.6762, lng: 139.6503, color: '#10b981', radius: 3 }), // Tokyo
  getPin({ lat: -33.8688, lng: 151.2093, color: '#f59e0b', radius: 3 }) // Sydney
]
</script>

<template>
  <DottedMap
    :mapHeight="50"
    :pins="pins"
    color="#4b5563"
    :dotSize="0.4"
    backgroundColor="#1f2937"
    shape="circle"
  />
</template>

DottedMap Props

PropTypeDefaultDescription
mapHeightnumber-Height in dots (auto-calculates width)
mapWidthnumber-Width in dots (auto-calculates height)
countriesstring[]allISO 3166-1 alpha-3 country codes to include
regionMapRegion-Specific lat/lng bounds to display
grid'vertical' | 'diagonal''vertical'Dot alignment pattern
pinsMapPin[]-Location markers
precomputedMapstring | object-Pre-generated map data
colorstring'#ffffff'Default dot color
dotSizenumber0.5Dot radius
strokeColorstring-Dot stroke color
strokeWidthnumber-Dot stroke width
shape'circle' | 'hexagon''circle'Dot shape
countryColorsRecord<string, string>-Per-country colors
backgroundColorstring-Container background
avoidOuterPinsbooleanfalseHide pins outside region

Pin Helper Function

typescript
import { getPin } from 'vue-chrts'

const pin = getPin({
  lat: 40.7128,
  lng: -74.0060,
  color: '#ef4444',
  radius: 5,
  strokeColor: '#ffffff',
  strokeWidth: 1
})

MapPin Structure

typescript
interface MapPin {
  lat: number
  lng: number
  svgOptions?: {
    color?: string
    radius?: number
    strokeColor?: string
    strokeWidth?: number
    strokeOpacity?: number
  }
  data?: Record<string, unknown>
}

Common Patterns

Highlight Specific Countries

vue
<DottedMap
  :mapHeight="40"
  :countries="['USA', 'GBR', 'DEU', 'JPN', 'AUS']"
  :countryColors="{
    'USA': '#3b82f6',
    'GBR': '#ef4444',
    'DEU': '#f59e0b',
    'JPN': '#10b981',
    'AUS': '#8b5cf6'
  }"
  color="#374151"
/>

Regional Focus

vue
<DottedMap
  :mapHeight="60"
  :region="{
    lat: { min: 35, max: 72 },
    lng: { min: -25, max: 45 }
  }"
  color="#6b7280"
  :dotSize="0.6"
/>

Office Locations

vue
<script setup>
import { getPin } from 'vue-chrts'

const offices = [
  { city: 'HQ', lat: 37.7749, lng: -122.4194 },
  { city: 'NYC', lat: 40.7128, lng: -74.0060 },
  { city: 'London', lat: 51.5074, lng: -0.1278 },
]

const pins = offices.map(office => getPin({
  lat: office.lat,
  lng: office.lng,
  color: '#10b981',
  radius: 4
}))
</script>

<template>
  <DottedMap
    :mapHeight="50"
    :pins="pins"
    color="#4b5563"
    backgroundColor="transparent"
  />
</template>

Gotchas

  1. TopoJSON required for TopoJSONMap: You need valid TopoJSON data for regions
  2. Country codes are ISO 3166-1 alpha-3: Use 'USA' not 'US', 'GBR' not 'UK'
  3. Lat/Lng order matters: Latitude first, then longitude
  4. DottedMap dimensions: Specify either mapHeight OR mapWidth, not both
  5. Large maps are slow: DottedMap with many dots can be performance-heavy