← Blog

michi-vz chart by chart: the maps

August 26, 20264 min read

This is part 8 of 9 in a series touring all 22 michi-vz chart types, family by family. The series starts in Introducing @michi-vz. Part 7 covered tornado and bar-bell.

Eighth stop: geography. Both maps share one principle, that the library bundles no topology, so the shapes on screen are always yours. Every michi-vz chart takes the same props in React, Vue, Svelte, Angular and plain HTML; the first chart below shows all four flavours, the rest show React to keep things short.

The choropleth map

Shade a world or region map by value. One design decision matters here: michi-vz bundles no topology data, so the geography is always a prop. You bring your own GeoJSON, which means your organization's cartographic choices stay yours. This demo fetches a simplified public-domain world file hosted on this site and joins the data by ISO-A3 code:

Live chart, rendered in your browser by @michi-vz/wc straight from the CDN. Hover it.

The data joins against the GeoJSON by feature id (ISO-A3 codes here); colorScale builds a d3 threshold scale from a domain and a colour range:

import world from "./world.json"; // your own GeoJSON FeatureCollection

const data = [
  { id: "BRA", label: "Brazil", value: 3400 },
  { id: "VNM", label: "Vietnam", value: 1900 },
  // ...joined to features via joinBy (default: "id")...
];
const colorScale = {
  domain: [200, 500, 1000, 2000],
  range: ["#e0f2fe", "#7dd3fc", "#38bdf8", "#0284c7", "#075985"],
};
import { ChoroplethMapChart } from "@michi-vz/react";

<ChoroplethMapChart
  geography={world}
  dataSet={data}
  colorScale={colorScale}
  width={640}
  height={380}
/>;
  • projection picks one of 13 d3-geo projections; the default is geoRobinson.
  • joinBy: "name" matches by display name when your data has no stable codes; ids are safer.
  • noDataColor fills countries with no matching row, and a per-row color supports categorical maps with no scale at all.

Full props on the choropleth map API page.

The symbol map

Choropleths distort the story when the interesting places are small: a city-state vanishes while an empty landmass shouts. The symbol map plots sized circles at real coordinates instead, and a one-shot force simulation pulls overlapping circles apart just enough to keep every one legible:

Live chart, rendered in your browser by @michi-vz/wc straight from the CDN. Hover it.

Each symbol supplies its own coordinates; the library bundles no coordinate table. The muted backdrop landmass is optional:

import world from "./world.json"; // optional muted backdrop

const data = [
  { id: "GVA", label: "Geneva", lng: 6.14, lat: 46.2, value: 95 },
  { id: "HAN", label: "Hanoi", lng: 105.85, lat: 21.03, value: 80 },
  // ...lng/lat per item, value drives the radius scale...
];
import { SymbolMapChart } from "@michi-vz/react";

<SymbolMapChart
  dataSet={data}
  geography={world}
  radiusRange={[4, 28]}
  width={640}
  height={380}
/>;
  • positionMode: "precise" keeps every circle at its exact projected location, overlaps and all, when accuracy beats legibility.
  • Omit geography entirely for the dot-only look; the backdrop is opt-in.
  • radiusVisibleMin hides items below a raw-value threshold before the layout runs.

Full props on the symbol map API page.

Next in the series: sankey and the fountain.