Skip to content

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

ts
import "@michi-vz/wc/symbol-map-chart";
// <michi-vz-symbol-map-chart> is now defined
ts
import { mountSymbolMapChart } from "@michi-vz/core";

const chart = mountSymbolMapChart(el, props);

Thuộc tính

PropTypeDefaultDescription
timelineboolean | 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).
geographyGeoJSON.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).
titlestring-Optional chart title rendered above the plot
projectionGeoProjectionName-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.
projectionConfigGeoProjectionConfig-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.
radiusVisibleMinnumber-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.
geographyColorstringDEFAULT_GEOGRAPHY_COLORFill for the optional backdrop `geography` (default `#eef1f5`, a muted neutral).
strokeColorstringDEFAULT_STROKE_COLORBorder colour for the optional backdrop `geography` (default `#d7dce3`).
strokeWidthnumber1Border width for the optional backdrop `geography`, in px (default 1).
showLabelsbooleantrueDraw a fitted label inside each circle when it is large enough (default true).
isLoadingboolean-Loading overlay (stale symbols hidden while true)
isNodataboolean | ((dataSet: SymbolMapDataItem[] | null | undefined) => boolean)-No-data predicate/flag; default = empty dataSet
noDataLabelstring-Text for the built-in no-data overlay
suppressDefaultOverlayboolean-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)
PropTypeDefaultDescription
widthnumber900Chart width in pixels
heightnumber520Chart height in pixels
marginMargin{ top: 40, right: 10, bottom: 10, left: 10 }Inner margins (top/right/bottom/left, in px) reserved for axes, titles, and labels
colorsstring[]-Categorical palette for series/labels without an explicit colour or colorsMapping entry
colorsMappingRecord<string, string>-Explicit label -> colour map; takes precedence over the palette and per-item colours
highlightItemsstring[]-Labels to emphasise; all other marks dim
disabledItemsstring[]-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
localestring-BCP-47 locale used for number and date formatting
skipColorMappingDispatchbooleanfalseExternal-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
enableTransitionsbooleantrueAnimate 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ệnChi tiếtKích hoạt khi
michi-vz:highlightstring[]trạng thái nổi bật lúc di chuột thay đổi
michi-vz:colormappingRecord<string, string>một ánh xạ màu được tạo ra
michi-vz:dataprocessedChartContextdữ liệu được xử lý (lại)
michi-vz:datawarningDataWarning[]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.