API Bản đồ ký hiệu
Một bản đồ ký hiệu/bong bóng khử chồng lấn bằng mô phỏng lực: bạn cung cấp lng/lat cho mỗi mục, một mô phỏng một lần đẩy các vòng tròn chồng lấn ra xa nhau - xem demo Bản đồ ký hiệu.
Nhập
import "@michi-vz/wc/symbol-map-chart";
// <michi-vz-symbol-map-chart> is now definedimport { mountSymbolMapChart } from "@michi-vz/core";
const chart = mountSymbolMapChart(el, props);Thuộc tính
| Prop | Type | Default | Description |
|---|---|---|---|
timeline | boolean | TimelinePeriodConfig | - | Opt-in "play through years": snapshots one period at a time over the distinct per-row `date` values, with a headless controller (`chart.timeline()`) plus an optional built-in play button + scrubber. Off by default; requires rows with `date`. Values tween between periods unless `interpolate: false`. |
dataSet* | SymbolMapDataItem[] | - | Array of symbols; each supplies its own lng/lat (core bundles no coordinate table). |
geography | GeoJSON.FeatureCollection | GeoFeatureItem[] | - | OPTIONAL muted backdrop landmass (new capability - the legacy chart never drew one). A full GeoJSON FeatureCollection or a pre-normalized `GeoFeatureItem[]`, same contract as `ChoroplethMapChartProps.geography`. Omit for the legacy chart's dot-only look (the default). |
title | string | - | Optional chart title rendered above the plot |
projection | GeoProjectionName | - | d3-geo / d3-geo-projection projection (default "geoMercator", matching the legacy chart). With no `geography`, the projection is used UNTUNED (bare `factory()`, no translate/scale/rotate/center) and the projected point extent is rescaled to fill the plot - see the chart's docs page. With `geography` supplied, the SAME tuned dispatch as ChoroplethMapChart is used instead, so the backdrop and the symbols share one consistent geographic framing. |
projectionConfig | GeoProjectionConfig | - | Fine-tunes the projection; only consulted when `geography` is supplied (see `projection`). |
radiusRange | [number, number] | DEFAULT_RADIUS_RANGE | [min, max] circle radius in px (default [3, 70], the legacy `circleRange`). Mapped from the value domain via `buildSymbolMapRadiusScale`, whose domain is the TRUE combined extent of every item's `value` and `valueSecond` - DELIBERATELY NOT legacy Chart.js's own domain formula, which was defective (`[min(primaryMin, secondaryMax), max(primaryMin, secondaryMax)]` silently drops the primary max and secondary min). Relative circle sizes will differ from the legacy chart whenever `value` and `valueSecond` ranges diverge - see `symbolMap/scales.ts`'s `buildSymbolMapRadiusScale` for the worked example and the pinned regression test. |
radiusVisibleMin | number | - | Hides items whose RAW `value` is <= this threshold (and, when `valueSecond` is set, whose `valueSecond` is also < this threshold) BEFORE the force layout runs - ported from the legacy chart's own filter, which compares the raw value/valueSecond, not the scaled radius. Omit to show every located item. |
positionMode | "force" | "precise" | "force" | How symbols are placed: "force" (default) runs a one-shot de-overlap simulation that pulls colliding circles apart, while "precise" keeps every symbol at its exact projected lng/lat (overlaps allowed). - "force": a one-shot de-overlap simulation pulls colliding circles apart - readable for dense data, but symbols DRIFT from their true lng/lat (on small plots the drift can be large). Avoid it when the audience will read exact geographic position off the chart: a symbol drawn over the wrong country is a cartographic-accuracy problem and can be politically sensitive. - "precise": every symbol stays at its exact projected lng/lat; overlapping circles are allowed. Prefer this whenever a `geography` backdrop is shown, since a visible landmass invites reading positions literally. |
geographyColor | string | DEFAULT_GEOGRAPHY_COLOR | Fill for the optional backdrop `geography` (default `#eef1f5`, a muted neutral). |
strokeColor | string | DEFAULT_STROKE_COLOR | Border colour for the optional backdrop `geography` (default `#d7dce3`). |
strokeWidth | number | 1 | Border width for the optional backdrop `geography`, in px (default 1). |
showLabels | boolean | true | Draw a fitted label inside each circle when it is large enough (default true). |
isLoading | boolean | - | Loading overlay (stale symbols hidden while true) |
isNodata | boolean | ((dataSet: SymbolMapDataItem[] | null | undefined) => boolean) | - | No-data predicate/flag; default = empty dataSet |
noDataLabel | string | - | Text for the built-in no-data overlay |
suppressDefaultOverlay | boolean | - | Set by a framework wrapper passing its own overlay node - suppresses the default overlay |
tooltipFormatter | (d: SymbolMapDataItem) => string | - | Formats the tooltip for a hovered symbol. |
onHighlightItem | (labels: string[]) => void | - | Called when the hovered/highlighted label(s) change |
Common props - shared by every chart (14)
| Prop | Type | Default | Description |
|---|---|---|---|
width | number | 900 | Chart width in pixels |
height | number | 520 | Chart height in pixels |
margin | Margin | { top: 40, right: 10, bottom: 10, left: 10 } | Inner margins (top/right/bottom/left, in px) reserved for axes, titles, and labels |
colors | string[] | - | Categorical palette for series/labels without an explicit colour or colorsMapping entry |
colorsMapping | Record<string, string> | - | Explicit label -> colour map; takes precedence over the palette and per-item colours |
highlightItems | string[] | - | Labels to emphasise; all other marks dim |
disabledItems | string[] | - | Labels to hide and exclude from scales/stacks |
renderer | "svg" | "canvas" | "webgpu" | "svg" | Render as inline SVG (default) or to a canvas (faster for large datasets); getContext() is identical either way |
locale | string | - | BCP-47 locale used for number and date formatting |
skipColorMappingDispatch | boolean | false | External-CSS mode: unmapped labels resolve to transparent and onColorMappingGenerated is not emitted, so mark colours come from your CSS via the data-label-safe contract |
enableTransitions | boolean | true | Animate updates with CSS transitions (default true) |
onColorMappingGenerated | (mapping: Record<string, string>) => void | - | Called with the resolved label -> colour map after the chart assigns colours |
onChartDataProcessed | (context: ChartContext) => void | - | Called with the renderer-agnostic ChartContext whenever the data is (re)processed |
onDataWarning | (warnings: DataWarning[]) => void | - | Called with any non-fatal data warnings (duplicate labels, non-finite values, non-monotonic dates, ...) |
Sự kiện
Web component phát ra (dispatch) các CustomEvent nổi bọt (bubbling) sau đây (engine cũng phơi bày các sự kiện tương tự thông qua các callback on* trong bảng ở trên):
| Sự kiện | Chi tiết | Kích hoạt khi |
|---|---|---|
michi-vz:highlight | string[] | trạng thái nổi bật lúc di chuột thay đổi |
michi-vz:colormapping | Record<string, string> | một ánh xạ màu được tạo ra |
michi-vz:dataprocessed | ChartContext | dữ liệu được xử lý (lại) |
michi-vz:datawarning | DataWarning[] | phát hiện cảnh báo (lng/lat thiếu hoặc không hợp lệ, giá trị âm, id trùng lặp) |
getContext()
mountSymbolMapChart(el, props).getContext() trả về SymbolMapChartContext độc lập với renderer: stats.locatedCount / visibleCount / hiddenCount (bị loại bởi radiusVisibleMin) / invalidCount (bị loại vì tọa độ không hợp lệ) / valueDomain / min / max, một mảng symbols[] (một hàng cho mỗi mục hiển thị: id, label, value, valueSecond, radius, radiusSecond, color), tên projection đã phân giải, một bản tóm tắt bằng ngôn ngữ tự nhiên có tính xác định, và một a11yTable. Xem ngữ cảnh LLM.
Nguồn
Các thuộc tính (props) được định kiểu là SymbolMapChartProps trong @michi-vz/core.
