关于 syncfusion-javascript-maps
syncfusion-javascript-maps 是用于在 TypeScript 或 JavaScript 应用中实现 Syncfusion EJ2 Maps 的框架无关技能。它介绍地理图层、数据可视化、交互和导出,并涵盖模块化导入与全局 bundle 的设置。
主要功能
- 01渲染瓦片图层和 GeoJSON 图层
- 02用标记和气泡呈现地理位置
- 03添加多边形、路线、标签和注释
- 04配置图例、工具提示和选择
- 05支持缩放、平移和状态持久化
- 06打印地图并导出图像
适用场景
- 01显示办公室等基于坐标的位置
- 02使用 GeoJSON 和气泡映射区域数值
- 03展示路线或自定义地理区域
- 04导出渲染后的地图用于打印或图像
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ syncfusion/ javascript-ui-controls-skills --skill syncfusion-javascript-maps安装后在 Claude Code 中输入/syncfusion-javascript-maps确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-reference-guide.mdAPI-Refernce_JavaScript.mdAPI-Refernce_TypeScript.mdcustomization-and-persistence.mddata-and-layers.mdgetting-started.mdlegends-and-annotations.mdmap-providers-and-selection.mdmarkers-and-navigation.mdtroubleshooting.mdvisualization-features.md详细介绍
使用 TypeScript 和 JavaScript 实现 Syncfusion Maps
Syncfusion EJ2 Maps 组件可通过在线瓦片服务提供商、GeoJSON 形状图层、标记、气泡、自定义多边形、导航线、标签、图例、注释、工具提示、选择、缩放、平移、打印和导出功能来可视化地理信息。
本技能涵盖与框架无关的实现方式,适用于:
- 使用 npm 和模块导入的 TypeScript 应用。
- 使用带版本号的 EJ2 全局包的 JavaScript 应用。
- OpenStreetMap 和经过身份验证的地图服务提供商。
- GeoJSON 地理形状。
- 基于坐标的标记。
- 区域绑定气泡。
- 自定义多边形叠加层。
- 形状和气泡颜色映射。
- 导航线。
- 图例、注释和工具提示。
- 选择和突出显示。
- 内置持久化和应用自有持久化。
- 打印和图像导出。
- 无障碍访问、验证、性能和清理。
平台支持
TypeScript
在应用使用以下内容时,使用 TypeScript:
@syncfusion/ej2-mapsnpm 包。- TypeScript 编译。
- Webpack、Vite 或其他模块打包工具。
- 显式功能模块注入。
- 强类型数据和配置模型。
- 编译时验证和 IDE IntelliSense。
安装该包:
npm install @syncfusion/ej2-maps
基本导入:
import {
Maps
} from '@syncfusion/ej2-maps';
必须先导入并注入功能模块,然后才能构造 Maps。
import {
Maps,
Marker,
Zoom
} from '@syncfusion/ej2-maps';
Maps.Inject(
Zoom,
Marker
);
JavaScript
在应用使用以下内容时,使用全局 JavaScript:
- 带版本号的 EJ2 CDN 包。
- 本地托管的 EJ2 全局包。
- 传统 HTML 和 JavaScript 文件。
- 全局
ej.maps.Maps构造函数。 - 不使用 TypeScript 编译。
全局构造函数:
ej.maps.Maps
使用完整的带版本号 EJ2 全局包:
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js"></script>
不要将完整包与单独的 ej2-base、ej2-data、ej2-svg-base 和 ej2-maps 脚本混用。
使用完整包的全局 JavaScript 无需显式调用 Maps.Inject(...)。
JavaScript 兼容性
全局 JavaScript 示例会尽可能使用兼容 ES5 的语法:
var declarations
Traditional functions
No TypeScript annotations
No ECMAScript module imports
Global ej namespace
浏览器支持仍须符合所安装 EJ2 版本的受支持浏览器矩阵。
不要承诺完全兼容所有旧版浏览器。
何时使用此技能
在任务需要以下功能时,使用此技能:
- 渲染在线地图服务提供商。
- 使用 GeoJSON 渲染国家、州或自定义区域。
- 显示基于坐标的位置。
- 使用气泡可视化区域数值。
- 应用数据驱动的形状或气泡颜色。
- 绘制由坐标定义的自定义多边形区域。
- 使用导航线连接位置。
- 为地理形状添加数据标签。
- 显示图例和工具提示。
- 添加相对于地图定位的注释内容。
- 选择或突出显示形状、标记或气泡。
- 支持缩放和平移。
- 持久化支持的地图状态。
- 存储经过验证的应用偏好设置。
- 打印渲染后的地图。
- 将地图导出为 PNG、JPEG 或 SVG。
- 支持响应式布局。
- 优化大型地理数据集。
- 诊断设置、网络、数据绑定或渲染故障。
可视化选择指南
使用标记
对于由纬度和经度直接定义的位置,使用标记。
示例:
- 办事处。
- 商店。
- 机场。
- 仓库。
- 事件点。
- 路线航点。
使用气泡
对于与 GeoJSON 形状关联的数值,使用气泡。
示例:
- 各国人口。
- 各州收入。
- 各区域销售额。
- 各地区参与度。
气泡不能直接替代坐标标记。
使用 GeoJSON 形状
以下情况使用 shapeData:
- 国家。
- 州。
- 省。
- 区。
- 行政边界。
- 自定义地理要素集合。
使用自定义多边形
对于基于坐标点的应用自定义区域,使用 polygonSettings.polygons。
示例:
- 配送区域。
- 限制区域。
- 覆盖区域。
- 服务边界。
使用导航线
使用导航线来显示:
- 路线。
- 行程。
- 连接关系。
- 航线。
- 地理依赖关系。
功能模块参考
Zooming and panning -> Zoom
Markers -> Marker
Bubbles -> Bubble
Navigation lines -> NavigationLine
Tooltips -> MapsTooltip
Legends -> Legend
Annotations -> Annotations
Selection -> Selection
Data labels -> DataLabel
Custom polygons -> Polygon
Printing -> Print
Image export -> ImageExport
PDF export -> PdfExport
仅导入并注入示例中使用的模块。
示例:
import {
Maps,
MapsTooltip,
Marker,
Zoom
} from '@syncfusion/ej2-maps';
Maps.Inject(
Zoom,
Marker,
MapsTooltip
);
确保导入与注入保持同步。
错误示例:
import {
Maps
} from '@syncfusion/ej2-maps';
Maps.Inject(
Marker
);
正确示例:
import {
Maps,
Marker
} from '@syncfusion/ej2-maps';
Maps.Inject(
Marker
);
实现规则
显式挂载到 DOM
推荐的 TypeScript:
const map: Maps =
new Maps({
layers
});
map.appendTo(
'#maps-container'
);
推荐的 JavaScript:
var map =
new ej.maps.Maps({
layers: layers
});
map.appendTo(
'#maps-container'
);
验证宿主元素
const host:
HTMLElement | null =
document.getElementById(
'maps-container'
);
if (!host) {
throw new Error(
'The Maps host element "#maps-container" was not found.'
);
}
提供可测量的尺寸
#maps-container {
width: 100%;
min-height: 600px;
}
为地图设置确定的高度:
width:
'100%',
height:
'600px'
避免依赖:
height:
'100%'
除非每个相关祖先元素都有确定的计算高度。
使用 centerPosition
错误示例:
center: {
latitude: 37.7749,
longitude: -122.4194
}
正确示例:
centerPosition: {
latitude: 37.7749,
longitude: -122.4194
}
在正确的层级配置功能
Shape data -> Layer shapeData
Shape binding data -> Layer dataSource
Shape tooltip -> Layer tooltipSettings
Shape selection -> Layer selectionSettings
Markers -> Layer markerSettings array
Marker tooltip -> Marker entry tooltipSettings
Marker selection -> Marker entry selectionSettings
Bubbles -> Layer bubbleSettings array
Bubble tooltip -> Bubble entry tooltipSettings
Bubble selection -> Bubble entry selectionSettings
Navigation lines -> Layer navigationLineSettings array
Custom polygons -> Layer polygonSettings
Shape labels -> Layer dataLabelSettings
文档与导航指南
入门与设置
请阅读:
references/getting-started.md
此参考适用于:
- 软件包安装。
- TypeScript 导入。
- 模块注入。
- JavaScript CDN 设置。
- OpenStreetMap 初始化。
- 宿主尺寸。
- 获取世界地图数据。
- 首个 Maps 实现。
数据与图层
请阅读:
references/data-and-layers.md
此参考适用于:
- 在线瓦片图层。
- GeoJSON 形状图层。
- 主图层。
- 子图层。
baseLayerIndex。- 形状数据绑定。
- 标记和气泡数据定位。
- 图层可见性。
- 安全的运行时更新。
标记与导航
请阅读:
references/markers-and-navigation.md
此参考适用于:
- 基于坐标的标记。
- 标记外观。
- 标记模板。
- 标记图像。
- 标记工具提示。
- 标记选择。
- 标记事件。
- 标记聚类。
- 导航线。
- 动态更新标记和路线。
可视化功能
请阅读:
references/visualization-features.md
此参考适用于:
- 区域绑定气泡。
- GeoJSON 形状渲染。
- 自定义多边形叠加层。
- 形状颜色映射。
- 气泡颜色映射。
- 形状数据标签。
- 组合区域可视化。
图例与注释
请阅读:
references/legends-and-annotations.md
此参考适用于:
- 默认图例和交互式图例。
- 停靠式和浮动图例。
- 图层、标记和气泡图例。
- 图例切换行为。
- 相对于地图的注释。
- 形状、标记和气泡工具提示。
地图提供商与选择
请阅读:
references/map-providers-and-selection.md
此参考适用于:
- OpenStreetMap。
- Bing Maps。
- 自定义瓦片提供商。
- 提供商身份验证。
- 提供商安全性与署名。
- 形状选择。
- 标记选择。
- 气泡选择。
- 单选和多选。
- 经过验证的交互事件。
自定义与持久化
请阅读:
references/customization-and-persistence.md
此参考适用于:
- 内置主题。
- 公开的外观模型。
- 应用自有的包装器 CSS。
- 响应式布局。
- 内置持久化。
- 经过验证的浏览器存储偏好设置。
- 打印。
- PNG、JPEG 和 SVG 导出。
- 清理。
故障排除
请阅读:
references/troubleshooting.md
此参考适用于:
- 安装失败。
- Bundle 加载失败。
- 缺少模块注入。
- 宿主和尺寸问题。
- 瓦片提供商故障。
- GeoJSON 加载失败。
- 标记和气泡问题。
- 数据绑定问题。
- 颜色映射失败。
- 工具提示和选择问题。
- 性能和内存问题。
- TypeScript 和 JavaScript 诊断。
TypeScript 快速入门
此示例使用 OpenStreetMap 渲染地图,并支持标记、标记工具提示、缩放和平移。
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
>
<title>Syncfusion Maps</title>
./styles.css
</head>
<body>
<main class="page-container">
<section
class="maps-card"
aria-labelledby="maps-heading"
aria-describedby="maps-description"
>
<h1 id="maps-heading">
Office Location
</h1>
<p id="maps-description">
An interactive OpenStreetMap view showing the
San Francisco office location.
</p>
<div id="maps-container"></div>
<p class="map-attribution">
Map data © OpenStreetMap contributors
</p>
<p
id="maps-status"
aria-live="polite"
>
Loading the map.
</p>
</section>
</main>
<script scr="app.ts"></script>
</body>
</html>
styles.css
html,
body {
margin: 0;
min-height: 100%;
}
body {
color: #111827;
background: #f1f5f9;
font-family:
"Segoe UI",
Arial,
sans-serif;
}
.page-container {
width: 100%;
min-height: 100vh;
padding: 24px;
box-sizing: border-box;
}
.maps-card {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 16px;
box-sizing: border-box;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 8px;
}
.maps-card h1 {
margin: 0 0 8px;
font-size: 24px;
}
.maps-card > p {
color: #475569;
line-height: 1.5;
}
#maps-container {
width: 100%;
min-height: 600px;
}
.map-attribution {
margin: 8px 0 0;
font-size: 12px;
}
@media (max-width: 768px) {
.page-container {
padding: 12px;
}
.maps-card {
padding: 12px;
}
#maps-container {
min-height: 500px;
}
}
app.ts
import {
Maps,
MapsTooltip,
Marker,
Zoom
} from '@syncfusion/ej2-maps';
Maps.Inject(
Zoom,
Marker,
MapsTooltip
);
interface LocationData {
id: string;
name: string;
latitude: number;
longitude: number;
}
const locationData:
LocationData[] = [
{
id:
'san-francisco-office',
name:
'San Francisco Office',
latitude:
37.7749,
longitude:
-122.4194
}
];
const validateLocations = (
locations:
LocationData[]
): void => {
const ids:
Set<string> =
new Set<string>();
locations.forEach(
(
location:
LocationData
): void => {
if (
!location.id.trim()
) {
throw new Error(
'Every marker requires a nonempty ID.'
);
}
if (
ids.has(
location.id
)
) {
throw new Error(
'Duplicate marker ID: ' +
location.id
);
}
if (
!location.name.trim()
) {
throw new Error(
'Every marker requires a name.'
);
}
if (
!Number.isFinite(
location.latitude
) ||
location.latitude < -90 ||
location.latitude > 90
) {
throw new Error(
'Invalid marker latitude.'
);
}
if (
!Number.isFinite(
location.longitude
) ||
location.longitude < -180 ||
location.longitude > 180
) {
throw new Error(
'Invalid marker longitude.'
);
}
ids.add(
location.id
);
}
);
};
validateLocations(
locationData
);
const host:
HTMLElement | null =
document.getElementById(
'maps-container'
);
const statusElement:
HTMLElement | null =
document.getElementById(
'maps-status'
);
if (!host) {
throw new Error(
'The Maps host element "#maps-container" was not found.'
);
}
const map: Maps =
new Maps({
width: '100%',
height: '600px',
centerPosition: {
latitude: 37.7749,
longitude: -122.4194
},
zoomSettings: {
enable: true,
enablePanning: true,
mouseWheelZoom: true,
pinchZooming: true,
minZoom: 1,
maxZoom: 13,
zoomFactor: 5,
toolbarSettings: {
buttonSettings: {
toolbarItems: [
'Zoom',
'ZoomIn',
'ZoomOut',
'Pan',
'Reset'
]
}
}
},
layers: [
{
urlTemplate:
'https://tile.openstreetmap.org/level/tileX/tileY.png',
markerSettings: [
{
visible: true,
dataSource:
locationData,
latitudeValuePath:
'latitude',
longitudeValuePath:
'longitude',
width: 24,
height: 24,
shape: 'Circle',
fill: '#dc2626',
border: {
color: '#ffffff',
width: 2
},
tooltipSettings: {
visible: true,
valuePath:
'name'
}
}
]
}
],
loaded: (): void => {
if (
statusElement
) {
statusElement.textContent =
'The map loaded successfully.';
}
}
});
map.appendTo(
host
);
JavaScript 快速入门
此示例在一个独立的 HTML 文件中提供相同的行为。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
>
<title>Syncfusion Maps</title>
<style>
html,
body {
margin: 0;
min-height: 100%;
}
body {
color: #111827;
background: #f1f5f9;
font-family:
"Segoe UI",
Arial,
sans-serif;
}
.page-container {
width: 100%;
min-height: 100vh;
padding: 24px;
box-sizing: border-box;
}
.maps-card {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 16px;
box-sizing: border-box;
background: #ffffff;
border: 1px solid #cbd5e1;
border-radius: 8px;
}
#maps-container {
width: 100%;
min-height: 600px;
}
.map-attribution {
color: #475569;
font-size: 12px;
}
@media (max-width: 768px) {
.page-container {
padding: 12px;
}
#maps-container {
min-height: 500px;
}
}
</style>
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js"></script>
</head>
<body>
<main class="page-container">
<section
class="maps-card"
aria-labelledby="maps-heading"
aria-describedby="maps-description"
>
<h1 id="maps-heading">
Office Location
</h1>
<p id="maps-description">
An interactive OpenStreetMap view showing the
San Francisco office location.
</p>
<div id="maps-container"></div>
<p class="map-attribution">
Map data © OpenStreetMap contributors
</p>
<p
id="maps-status"
aria-live="polite"
>
Loading the map.
</p>
</section>
</main>
<script>
var locationData = [
{
id:
'san-francisco-office',
name:
'San Francisco Office',
latitude:
37.7749,
longitude:
-122.4194
}
];
function validateLocations(
locations
) {
var ids =
new Set();
locations.forEach(
function (location) {
if (
typeof location.id !==
'string' ||
location.id
.trim()
.length === 0
) {
throw new Error(
'Every marker requires a nonempty ID.'
);
}
if (
ids.has(
location.id
)
) {
throw new Error(
'Duplicate marker ID: ' +
location.id
);
}
if (
!Number.isFinite(
location.latitude
) ||
location.latitude < -90 ||
location.latitude > 90
) {
throw new Error(
'Invalid marker latitude.'
);
}
if (
!Number.isFinite(
location.longitude
) ||
location.longitude < -180 ||
location.longitude > 180
) {
throw new Error(
'Invalid marker longitude.'
);
}
ids.add(
location.id
);
}
);
}
validateLocations(
locationData
);
var host =
document.getElementById(
'maps-container'
);
var statusElement =
document.getElementById(
'maps-status'
);
if (!host) {
throw new Error(
'The Maps host element "#maps-container" was not found.'
);
}
if (
typeof window.ej ===
'undefined' ||
!window.ej.maps
) {
throw new Error(
'The EJ2 Maps global bundle was not loaded.'
);
}
var map =
new ej.maps.Maps({
width: '100%',
height: '600px',
centerPosition: {
latitude: 37.7749,
longitude: -122.4194
},
zoomSettings: {
enable: true,
enablePanning: true,
mouseWheelZoom: true,
pinchZooming: true,
minZoom: 1,
maxZoom: 13,
zoomFactor: 5,
toolbarSettings: {
buttonSettings: {
toolbarItems: [
'Zoom',
'ZoomIn',
'ZoomOut',
'Pan',
'Reset'
]
}
}
},
layers: [
{
urlTemplate:
'https://tile.openstreetmap.org/level/tileX/tileY.png',
markerSettings: [
{
visible: true,
dataSource:
locationData,
latitudeValuePath:
'latitude',
longitudeValuePath:
'longitude',
width: 24,
height: 24,
shape: 'Circle',
fill: '#dc2626',
border: {
color:
'#ffffff',
width: 2
},
tooltipSettings: {
visible: true,
valuePath:
'name'
}
}
]
}
],
loaded:
function () {
statusElement.textContent =
'The map loaded successfully.';
}
});
map.appendTo(
host
);
</script>
</body>
</html>
GeoJSON 世界地图设置
OpenStreetMap 不需要世界地图文件。
GeoJSON 形状、颜色映射、形状标签和气泡示例需要完整的 shapeData。
下载世界地图 GeoJSON 文件:
mkdir -p src/data
curl -L "https://datahub.io/core/geo-countries/_r/-/data/countries.geojson" -o "src/data/world-map.geojson"
手动下载:
https://datahub.io/core/geo-countries/_r/-/data/countries.geojson
验证文件:
import {
readFile
} from 'node:fs/promises';
const content =
await readFile(
'src/data/world-map.geojson',
'utf8'
);
const worldMap =
JSON.parse(
content
);
if (
worldMap.type !==
'FeatureCollection'
) {
throw new Error(
'The world-map file must be a GeoJSON FeatureCollection.'
);
}
if (
!Array.isArray(
worldMap.features
) ||
worldMap.features.length === 0
) {
throw new Error(
'The world-map file does not contain features.'
);
}
如需导入 TypeScript JSON,请启用:
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true
}
}
然后导入:
import worldMap
from './data/world-map.json';
常见模式
区域数据可视化
使用包含完整数据绑定的 GeoJSON 图层。
layers: [
{
shapeData:
worldMap,
dataSource:
regionData,
shapePropertyPath:
'name',
shapeDataPath:
'country',
shapeSettings: {
fill: '#e2e8f0',
colorValuePath:
'value',
colorMapping: [
{
from: 0,
to: 39,
color: '#dbeafe',
label: 'Low'
},
{
from: 40,
to: 69,
color: '#60a5fa',
label: 'Moderate'
},
{
from: 70,
to: 100,
color: '#1d4ed8',
label: 'High'
}
]
}
}
]
使用单数形式:
colorMapping
不要使用:
colorMappings
多图层地图
使用经过验证的主图层和 SubLayer 覆盖层。
layers: [
{
shapeData:
worldMap
},
{
type: 'SubLayer',
shapeData:
overlayGeoJson,
shapeSettings: {
fill:
'rgb(37 99 235 / 30%)'
}
}
]
不要仅为分隔标记和气泡配置而创建空图层。
交互体验
使用:
Zoom -> Zooming and panning
MapsTooltip -> Tooltips
Selection -> Visual selection
将点击事件与视觉选中状态分开处理。
如果信息很重要,请使用外部持久化详情。不要只依赖悬停提示。
导航和路线可视化
navigationLineSettings: [
{
latitude: [
37.7749,
34.0522
],
longitude: [
-122.4194,
-118.2437
],
color: '#2563eb',
width: 3,
opacity: 0.8,
dashArray: '8 4'
}
]
验证:
- 至少包含两组坐标。
- 纬度和经度数组的长度相同。
- 坐标值均为有限值。
- 纬度介于
-90和90之间。 - 经度介于
-180和180之间。 - 线宽为正值。
- 不透明度介于
0和1之间。
距离和时长是由应用管理的值。导航线不会自动计算路线距离、行程时长或道路方向。
主要功能一览
标记
用于根据纬度和经度表示地理位置点。
气泡
用于可视化与 GeoJSON 形状关联的数值大小。
GeoJSON 形状
用于通过 shapeData 提供的地理边界。
自定义多边形
用于通过 polygonSettings.polygons 提供的坐标定义覆盖层。
颜色映射
用于按范围、相同值或基于不透明度为形状和气泡着色。
图层
用于主图层和经过验证的 SubLayer 覆盖层。
导航线
用于通过坐标路径连接位置。
图例
用于说明图层、气泡或标记的颜色和符号。
注释
用于地图相对的 HTML 覆盖层,通过 x 和 y 定位。
注释不使用纬度和经度。地理位置点请使用标记。
工具提示
用于显示与形状、标记或气泡相关的上下文信息。
持久化
如果内置组件持久化功能满足应用需求,请使用 enablePersistence。
对于自定义偏好设置、架构版本控制、过期时间、图层可见性或用户专属设置,请使用经过验证的应用自有存储。
打印和导出
使用:
Print -> Print module and allowPrint
ImageExport -> ImageExport module and allowImageExport
PdfExport -> PdfExport module and allowPdfExport
运行时验证清单
✅ @syncfusion/ej2-maps is installed.
✅ Maps is imported.
✅ Every enabled TypeScript feature has its module imported.
✅ Every imported runtime module is injected before construction.
✅ Unused optional modules are not injected.
✅ Global JavaScript does not call Maps.Inject.
✅ The complete EJ2 bundle loads before application code.
✅ Combined and individual bundles are not mixed.
✅ Every CDN script URL ends in .min.js.
✅ The Maps host exists.
✅ The appendTo target matches the host ID.
✅ The host has measurable width and height.
✅ Maps width and height use valid CSS-size strings.
✅ centerPosition is used instead of center.
✅ Zoom is injected when zooming or panning is enabled.
✅ Tile URLs are plain strings.
✅ OpenStreetMap URLs contain level, tileX, and tileY.
✅ OpenStreetMap attribution is visible.
✅ Provider terms and network requirements are reviewed.
✅ Maps provider credentials are protected as far as the provider permits.
✅ The layer contains urlTemplate or shapeData.
✅ GeoJSON is a nonempty FeatureCollection.
✅ shapePropertyPath matches a GeoJSON feature property.
✅ shapeDataPath matches application data.
✅ markerSettings is an array.
✅ Every active marker entry uses visible: true.
✅ Marker coordinate paths match marker data.
✅ Marker IDs are nonempty and unique when required.
✅ Marker latitudes are finite and between -90 and 90.
✅ Marker longitudes are finite and between -180 and 180.
✅ bubbleSettings is an array.
✅ Every active bubble entry uses visible: true.
✅ Bubble data is associated with GeoJSON shapes.
✅ Bubble valuePath matches finite numeric values.
✅ colorMapping uses the singular property name.
✅ Color ranges are finite and nonoverlapping.
✅ Navigation-line coordinate arrays have matching lengths.
✅ Annotations use x and y rather than latitude and longitude.
✅ Layer indexes are validated before runtime updates.
✅ Storage preferences are validated before use.
✅ Print and export flags match injected modules.
✅ Runtime updates are batched.
✅ refresh is called once after complete updates.
✅ Important information is not communicated only by color, size, or hover.
✅ Application-owned listeners and timers are cleaned up.
✅ Pending requests are cancelled where appropriate.
✅ map.destroy() is called when a dynamic host is removed.
✅ No encoded HTML replaces executable markup.
✅ No rich-text anchors or editor-generated classes remain.
无障碍指导
- 提供语义化标题。
- 提供简洁的地图描述。
- 为标记和区域提供有意义的名称。
- 不要只依赖标记颜色。
- 不要只依赖气泡大小。
- 不要只依赖映射形状的颜色。
- 提供描述性图例标签。
- 提供持久显示的选中项详情。
- 保持焦点可见。
- 对打印、导出、重置和其他应用操作使用原生按钮。
- 为对决策至关重要的可视化数据提供语义化表格。
- 确保标记的触控目标便于触摸设备使用。
- 不要让工具提示内容成为关键信息的唯一来源。
- 避免过度使用实时区域播报。
- 包含所需的提供方署名。
- 测试键盘、触控、屏幕阅读器、浏览器缩放和重排行为。
- 不要声称整个应用会自动符合无障碍标准。
性能和清理
- 重用已解析的 GeoJSON。
- 避免重复获取未更改的形状数据。
- 只有在验证地理精度后,才简化几何图形。
- 在渲染前验证标记、气泡、形状和路线数据。
- 保持标记和工具提示模板简洁。
- 只有在完成性能分析后,才使用聚类。
- 批量处理运行时更改。
- 只调用一次
refresh()。 - 避免记录开销较大的渲染事件。
- 同一宿主中重新创建 Maps 前,请先进行清理。
- 移除应用自有的事件监听器。
- 清除待处理的计时器。
- 在适当情况下取消待处理的请求。
- 移除动态视图时,销毁 Maps。
map.destroy();
常见错误与后续参考
中心属性错误
错误:
center: {
latitude: 37.7749,
longitude: -122.4194
}
正确:
centerPosition: {
latitude: 37.7749,
longitude: -122.4194
}
缺少缩放注入
错误:
import {
Maps
} from '@syncfusion/ej2-maps';
const map: Maps =
new Maps({
zoomSettings: {
enable: true
}
});
正确:
import {
Maps,
Zoom
} from '@syncfusion/ej2-maps';
Maps.Inject(
Zoom
);
将标记设置写成对象
错误:
markerSettings: {
dataSource:
locationData
}
正确:
markerSettings: [
{
visible: true,
dataSource:
locationData
}
]
将 Bubble 设置为对象
错误:
bubbleSettings: {
dataSource:
bubbleData
}
正确:
bubbleSettings: [
{
visible: true,
dataSource:
bubbleData
}
]
缺少功能可见性
错误:
markerSettings: [
{
dataSource:
locationData
}
]
正确:
markerSettings: [
{
visible: true,
dataSource:
locationData
}
]
富文本 Tile URL
错误:
urlTemplate:
'https://tile.openstreetmap.org/......</a>'
正确:
urlTemplate:
'https://tile.openstreetmap.org/level/tileX/tileY.png'
不必要的 OSM 类型
避免:
type:
'OSM'
使用:
urlTemplate:
'https://tile.openstreetmap.org/level/tileX/tileY.png'
基于坐标的 Bubble 假设
错误:
Bubbles can always be positioned like markers by supplying
latitude and longitude on a basic tile layer.
正确:
Use markers for direct coordinates.
Use bubbles for values associated with GeoJSON shapes.
错误的颜色映射属性
错误:
colorMappings: []
正确:
colorMapping: []
错误的形状属性路径
错误:
shapePropertyPath:
'properties.name'
正确:
shapePropertyPath:
'name'
使用地理坐标的注释
错误:
annotations: [
{
latitude:
37.7749,
longitude:
-122.4194
}
]
地理坐标请使用标记。
注释请使用 x 和 y:
annotations: [
{
content:
'#annotation-template',
x:
'5%',
y:
'10%'
}
]
位于 Maps 根级别的导航线
错误:
map.navigationLineSettings =
routes;
正确:
map.layers[0]
.navigationLineSettings =
routes;
未定义的地理数据
避免:
shapeData:
worldMap
除非 worldMap 已导入、定义或成功获取。
未验证的事件名称
不要假设存在以下事件:
zoomEnd
panEnd
mouseMove
layerRender
请根据已安装的软件包验证事件及其类型。
格式错误的 CDN 标记
错误:
https://cdn.syncfusion.com/...
https://cdn.syncfusion.com/...
</a>
正确:
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js"></script>
混用合并包和单独的包
错误:
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js"></script>
<script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-base/dist/global/ej2-base.min.js"></script>
<script src="https://cdn.syncfusion.com/ej2/34.2.2/ej2-maps/dist/global/ej2-maps.min.js"></script>
正确:
<script src="https://cdn.syncfusion.com/ej2/34.2.2/dist/ej2.min.js"></script>
编码后的可执行 HTML
错误:
<div id="maps-container"></div>
正确:
<div id="maps-container"></div>
缺少清理操作
移除动态视图时:
button.removeEventListener(
'click',
handleClick
);
controller.abort();
map.destroy();
编辑器生成的标记
从可执行 HTML、TypeScript、JavaScript、CSS、导入语句、命令、模板和 URL 中移除以下内容:
<a>
<strong data-lexical-text="true">
<br>
data-lexical-text
Editor-generated class names
Encoded executable tags