Loading map...

const cloudflareLocations = [
  { city: "San Francisco", iata: "SFO", lat: 37.77, lon: -122.42 },
  { city: "London", iata: "LHR", lat: 51.51, lon: -0.13 },
  { city: "Singapore", iata: "SIN", lat: 1.35, lon: 103.82 },
  // ...more locations
];

<BubbleMap
  echarts={echarts}
  geoJson={geoJson}
  data={cloudflareLocations}
  lng="lon"
  lat="lat"
  name="city"
  value={() => 1}
  bubbleColor="#F6821F"
  minRadius={8}
  maxRadius={8}
  tooltipFormatter={(row) =>
    "<strong>" + row.city + "</strong> " + row.iata
  }
/>

Installation

BubbleMap and ChoroplethMap require echarts as a peer dependency. Consumers provide the GeoJSON feature collection; map components do not fetch map data or use map tiles. GlobeMap is SVG-only and does not require ECharts or WebGL.
npm install echarts

Barrel

import { BubbleMap, ChoroplethMap, GlobeMap } from "kumo-svelte";

Granular

import { BubbleMap, ChoroplethMap, GlobeMap } from "kumo-svelte/components/chart";

Usage

import { BubbleMap, ChoroplethMap, type MapGeoJson } from "kumo-svelte";
import * as echarts from "echarts/core";
import { MapChart, ScatterChart } from "echarts/charts";
import { TooltipComponent, VisualMapComponent } from "echarts/components";
import { CanvasRenderer } from "echarts/renderers";

echarts.use([
  MapChart,
  ScatterChart,
  TooltipComponent,
  VisualMapComponent,
  CanvasRenderer,
]);

// Load GeoJSON in your app and pass it to map components.
const geoJson = world as MapGeoJson;

const colos = [
  { iata: "SFO", city: "San Francisco", lat: 37.77, lon: -122.42, requests: 1200 },
  { iata: "LHR", city: "London", lat: 51.5, lon: -0.12, requests: 1500 },
];

const countries = [
  { country: "United States of America", requests: 4200 },
  { country: "Germany", requests: 3100 },
];

<BubbleMap
  echarts={echarts}
  geoJson={geoJson}
  data={colos}
  lng="lon"
  lat="lat"
  name="city"
  value="requests"
/>

<ChoroplethMap
  echarts={echarts}
  geoJson={geoJson}
  data={countries}
  name="country"
  value="requests"
/>

Examples

Bubble Map

Plot raw rows by longitude and latitude. The value accessor controls proportional bubble size.

Loading map...

<BubbleMap
  echarts={echarts}
  geoJson={geoJson}
  data={colos}
  lng="lon"
  lat="lat"
  name="city"
  value="requests"
  minRadius={8}
/>

Choropleth Map

Shade regions by value. Data rows are joined to GeoJSON features by name, matched against the feature's nameProperty, which defaults to "name".

Loading map...

<ChoroplethMap
  echarts={echarts}
  geoJson={geoJson}
  data={countries}
  name="country"
  value="requests"
/>

Custom Tooltips

Provide tooltipFormatter when the default name/value tooltip is not enough. The formatter returns HTML rendered by ECharts, so escape user-provided values.

<BubbleMap
  echarts={echarts}
  geoJson={geoJson}
  data={colos}
  lng="lon"
  lat="lat"
  name="city"
  value="requests"
  tooltipFormatter={(row) =>
    "<strong>" + row.city + "</strong><br />" + row.requests.toLocaleString()
  }
/>

Globe Map

Render a boundary-free orthographic globe with hatched land and geographic markers. Drag or use the arrow keys to rotate it; automatic rotation respects reduced-motion preferences and pauses during interaction.

Use the arrow keys to rotate the globe.
  • SFO: San Francisco
  • LAX: Los Angeles
  • SEA: Seattle
  • DFW: Dallas
  • ORD: Chicago
  • IAD: Ashburn
  • EWR: New York
  • GRU: São Paulo
  • EZE: Buenos Aires
  • LHR: London
  • AMS: Amsterdam
  • CDG: Paris
  • FRA: Frankfurt
  • DXB: Dubai
  • JNB: Johannesburg
  • BOM: Mumbai
  • SIN: Singapore
  • HKG: Hong Kong
  • NRT: Tokyo
  • SYD: Sydney
<GlobeMap
  markers={locations}
  landHatchSpacing={8}
  oceanColor="transparent"
  showGraticule
  markerColor="var(--color-kumo-brand)"
  markerRadius={8}
  autoRotate
  aria-label="Cloudflare availability locations"
/>

API Reference

BubbleMap

PropTypeDefaultDescription
echarts *any-The ECharts core instance imported by the consumer.
geoJson *MapGeoJson-GeoJSON FeatureCollection for the map base.
mapName string-Stable ECharts map registry name. Invalid characters are replaced with dashes.
data *T[]-Rows to plot as bubbles.
lng *MapAccessor<T, number>-Longitude accessor: a row key or function.
lat *MapAccessor<T, number>-Latitude accessor: a row key or function.
value *MapAccessor<T, number>-Numeric value accessor used to size bubbles.
name MapAccessor<T, string>-Optional label accessor used by the default tooltip.
minRadius number6Smallest bubble radius in pixels.
maxRadius number26Largest bubble radius in pixels.
bubbleSize (value: number) => number-Explicit bubble radius function. Overrides minRadius/maxRadius scaling.
bubbleColor MapStyle<T, string>-Bubble fill color as a constant or row function.
bubbleBorderColor MapStyle<T, string>"transparent"Bubble border color as a constant or row function.
bubbleBorderWidth MapStyle<T, number>0Bubble border width as a constant or row function.
center [number, number]-Map center as [longitude, latitude]. Defaults to auto-fit.
zoom number1.25Zoom level as a multiple of the auto-fit scale.
roam booleanfalseEnables drag-to-pan and scroll-to-zoom.
projection MapProjection | null-Geographic projection. Defaults to latitude-clamped Mercator; use null for raw coordinates.
aspectRatio number | string-Container aspect ratio. Defaults to the projected map window.
showTooltip booleantrueWhether to show the default map tooltip.
valueFormat (value: number) => string-Formats values in the default tooltip.
tooltipFormatter (row: T) => string-Custom HTML tooltip formatter. Escape user-provided strings before returning.
onBubbleHover (row: T | undefined) => void-Callback fired as the pointer enters or leaves a bubble.
onBubbleClick (row: T) => void-Callback fired when a bubble is clicked.
height number-Fixed chart height in pixels. Overrides aspectRatio.
isDarkMode boolean-When true, switches map and bubble palette choices for dark mode.

ChoroplethMap

PropTypeDefaultDescription
echarts *any-The ECharts core instance imported by the consumer.
geoJson *MapGeoJson-GeoJSON FeatureCollection whose regions are shaded by value.
mapName string-Stable ECharts map registry name. Invalid characters are replaced with dashes.
data *T[]-Rows joined to GeoJSON features.
name *MapAccessor<T, string>-Region key accessor used to join rows to GeoJSON features.
value *MapAccessor<T, number>-Numeric value accessor used for the region fill scale.
nameProperty string"name"GeoJSON feature property used for the data join.
colorRange string[]-Sequential color ramp from low to high values.
min number-Lower bound for the continuous scale.
max number-Upper bound for the continuous scale.
noDataColor string-Fill color for GeoJSON regions without a matching data row.
showLegend booleanfalseWhether to show the ECharts visualMap legend.
showTooltip booleantrueWhether to show the default map tooltip.
valueFormat (value: number) => string-Formats values in the default tooltip.
tooltipFormatter (row: T) => string-Custom HTML tooltip formatter. Escape user-provided strings before returning.
center [number, number]-Map center as [longitude, latitude]. Defaults to auto-fit.
zoom number1.25Zoom level as a multiple of the auto-fit scale.
roam booleanfalseEnables drag-to-pan and scroll-to-zoom.
projection MapProjection | null-Geographic projection. Defaults to latitude-clamped Mercator; use null for raw coordinates.
aspectRatio number | string-Container aspect ratio. Defaults to the projected map window.
height number-Fixed chart height in pixels. Overrides aspectRatio.
isDarkMode boolean-When true, switches map and region palette choices for dark mode.
chartRef EChartsType | null-Bindable chart instance reference.
onRegionHover (row: T | undefined) => void-Callback fired as the pointer enters or leaves a region with data.
onRegionClick (row: T) => void-Callback fired when a region with data is clicked.

GlobeMap

PropTypeDefaultDescription
landColor string-Stroke color for the hatched land.
landHatchSpacing number10Spacing between land hatch lines in view-box pixels.
oceanColor stringvar(--color-kumo-base)Fill behind the land and graticule.
markers GlobeMapMarker[][]Geographic points drawn above the land.
markerColor string-Default marker fill.
markerRadius number7Default marker radius in view-box pixels.
onMarkerClick (marker: GlobeMapMarker) => void-Called when a visible marker is clicked.
defaultRotation [number, number, number][-10, -20, 0]Initial longitude, latitude, and roll rotation.
draggable booleantrueAllows pointer and keyboard rotation.
autoRotate booleanfalseContinuously rotates the globe horizontally.
autoRotateSpeed number4Horizontal auto-rotation speed in degrees per second.
showGraticule booleanfalseDraws latitude and longitude guides.
showTooltip booleantrueShows the Kumo-styled marker tooltip.
onUserRotationChange (rotation: [number, number, number]) => void-Called after pointer or keyboard rotation.
aria-label stringInteractive globe mapAccessible label for the visualization.
height number-Fixed height in pixels; otherwise uses a square aspect ratio.
isDarkMode boolean-Overrides automatic theme detection.