关于 arcgis-widgets-ui
arcgis-widgets-ui 是一项使用 ArcGIS Map Components、Core API widgets 和 Calcite 构建地图界面的技能,适合开发地图应用界面的开发者。内容覆盖组件选择、布局定位、事件处理与常见配置问题。
主要功能
- 01使用地图与场景组件
- 02配置图层、搜索和图例控件
- 03通过插槽定位组件
- 04集成 Calcite 界面组件
- 05处理控件事件与样式
适用场景
- 01为地图应用添加搜索和图例
- 02构建可折叠的地图控件面板
- 03在地图界面展示时间滑块
- 04用 Calcite 组织应用布局
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-widgets-ui安装后在 Claude Code 中输入/arcgis-widgets-ui确认已加载。
附带文件AGENTS.md
详细介绍
ArcGIS 微件与 UI
使用微件、地图组件和 Calcite 构建用户界面时,请使用此技能。
最佳实践: 优先使用地图组件(如
arcgis-legend、arcgis-search等 Web 组件),而不是 Core API 微件。Esri 已转向以 Web 组件为主要方案。
导入模式
地图组件(ESM)
import "@arcgis/map-components/dist/components/arcgis-map";
import "@arcgis/map-components/dist/components/arcgis-legend";
import "@arcgis/map-components/dist/components/arcgis-search";
import "@arcgis/map-components/dist/components/arcgis-layer-list";
import "@arcgis/map-components/dist/components/arcgis-expand";
Core API 微件(ESM)
import Legend from "@arcgis/core/widgets/Legend.js";
import LayerList from "@arcgis/core/widgets/LayerList.js";
import Search from "@arcgis/core/widgets/Search.js";
import BasemapGallery from "@arcgis/core/widgets/BasemapGallery.js";
动态导入(CDN)
const Legend = await $arcgis.import("@arcgis/core/widgets/Legend.js");
const Search = await $arcgis.import("@arcgis/core/widgets/Search.js");
注意: 地图组件的 CSS 会通过 npm 自动加载。Core API 微件需要:
@import "@arcgis/core/assets/esri/themes/light/main.css";
地图组件概览
| 组件 | 用途 |
|---|---|
arcgis-map | 2D 地图容器 |
arcgis-scene | 3D 场景容器 |
arcgis-zoom | 缩放按钮 |
arcgis-compass | 方向指示器 |
arcgis-home | 返回初始范围 |
arcgis-locate | 查找用户位置 |
arcgis-track | 跟踪用户位置 |
arcgis-navigation-toggle | 平移/旋转模式(3D) |
arcgis-floor-filter | 按楼层筛选室内地图 |
arcgis-fullscreen | 切换全屏 |
arcgis-scale-bar | 显示地图比例尺 |
arcgis-legend | 图层符号图例 |
arcgis-layer-list | 图层可见性控制 |
arcgis-basemap-gallery | 切换底图 |
arcgis-basemap-layer-list | 底图图层列表 |
arcgis-basemap-toggle | 切换两种底图 |
arcgis-catalog-layer-list | 浏览 CatalogLayer 子图层 |
arcgis-search | 位置搜索 |
arcgis-placement | 控件位置控制 |
arcgis-popup | 要素弹出窗口 |
arcgis-editor | 要素编辑 |
arcgis-feature | 无弹出窗口显示要素信息 |
arcgis-feature-form | 基于表单的属性编辑 |
arcgis-features | 显示多个要素的信息 |
arcgis-sketch | 绘制几何图形 |
arcgis-feature-table | 表格数据视图 |
arcgis-time-slider | 时间导航 |
arcgis-expand | 可折叠容器 |
arcgis-print | 地图打印 |
arcgis-table-list | 列出并管理要素表 |
arcgis-bookmarks | 导航至书签 |
arcgis-directions | 逐向导航 |
arcgis-swipe | 比较图层 |
arcgis-coordinate-conversion | 坐标格式 |
arcgis-daylight | 3D 光照控制 |
arcgis-weather | 3D 天气效果 |
arcgis-distance-measurement-2d | 2D 距离测量 |
arcgis-area-measurement-2d | 2D 面积测量 |
arcgis-direct-line-measurement-3d | 3D 线测量 |
arcgis-area-measurement-3d | 3D 面积测量 |
arcgis-elevation-profile | 沿路径的高程剖面 |
arcgis-line-of-sight | 视线分析(3D) |
arcgis-slice | 对 3D 数据进行切片 |
arcgis-shadow-cast | 阴影投射分析(3D) |
arcgis-oriented-imagery-viewer | 查看定向影像 |
arcgis-video-player | 播放视频流 |
arcgis-link-chart | 关系图可视化 |
arcgis-utility-network-trace | 公用设施网络追踪 |
arcgis-version-management | 管理地理数据库版本 |
基于插槽的定位
<arcgis-map basemap="streets-vector">
<arcgis-zoom slot="top-left"></arcgis-zoom>
<arcgis-home slot="top-left"></arcgis-home>
<arcgis-compass slot="top-left"></arcgis-compass>
<arcgis-search slot="top-right"></arcgis-search>
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
<arcgis-legend slot="bottom-left"></arcgis-legend>
<arcgis-scale-bar slot="bottom-right"></arcgis-scale-bar>
<arcgis-popup slot="popup"></arcgis-popup>
</arcgis-map>
可用插槽:top-left、top-right、bottom-left、bottom-right、top-start、top-end、bottom-start、bottom-end、popup
同一插槽中的组件会按 DOM 顺序垂直堆叠。
Expand 组件
将组件包装在 arcgis-expand 中,以实现可折叠行为:
<arcgis-map basemap="streets-vector">
<arcgis-expand slot="top-right" expand-tooltip="Show Legend" mode="floating">
<arcgis-legend></arcgis-legend>
</arcgis-expand>
<arcgis-expand slot="top-left" expanded>
<arcgis-layer-list></arcgis-layer-list>
</arcgis-expand>
</arcgis-map>
引用元素(外部组件)
将组件放在地图外部并引用它们:
<calcite-shell>
<calcite-shell-panel slot="panel-start">
<arcgis-legend reference-element="arcgis-map"></arcgis-legend>
</calcite-shell-panel>
<arcgis-map id="arcgis-map" basemap="topo-vector">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>
</calcite-shell>
常用组件
Legend
<arcgis-legend slot="bottom-left"></arcgis-legend>
// Core API
import Legend from "@arcgis/core/widgets/Legend.js";
const legend = new Legend({
view: view,
layerInfos: [
{
layer: featureLayer,
title: "Custom Title",
},
],
});
view.ui.add(legend, "bottom-left");
LayerList
<arcgis-layer-list slot="top-right"></arcgis-layer-list>
// Core API with actions
import LayerList from "@arcgis/core/widgets/LayerList.js";
const layerList = new LayerList({
view: view,
listItemCreatedFunction: (event) => {
const item = event.item;
item.actionsSections = [
[
{
title: "Zoom to layer",
icon: "zoom-to-object",
id: "zoom-to",
},
],
];
},
});
layerList.on("trigger-action", (event) => {
if (event.action.id === "zoom-to") {
view.goTo(event.item.layer.fullExtent);
}
});
view.ui.add(layerList, "top-right");
BasemapGallery
<arcgis-basemap-gallery slot="top-right"></arcgis-basemap-gallery>
// Core API
import BasemapGallery from "@arcgis/core/widgets/BasemapGallery.js";
const basemapGallery = new BasemapGallery({ view: view });
view.ui.add(basemapGallery, "top-right");
Search
<arcgis-search slot="top-right"></arcgis-search>
// Core API with custom sources
import Search from "@arcgis/core/widgets/Search.js";
const search = new Search({
view: view,
sources: [
{
layer: featureLayer,
searchFields: ["name", "address"],
displayField: "name",
exactMatch: false,
outFields: ["*"],
name: "My Layer",
placeholder: "Search features",
},
],
});
view.ui.add(search, "top-right");
// Events
search.on("select-result", (event) => {
console.log("Selected:", event.result);
});
FeatureTable
<arcgis-feature-table reference-element="arcgis-map"></arcgis-feature-table>
// Core API
import FeatureTable from "@arcgis/core/widgets/FeatureTable.js";
const featureTable = new FeatureTable({
view: view,
layer: featureLayer,
container: "tableDiv",
visibleElements: {
header: true,
columnMenus: true,
selectionColumn: true,
},
tableTemplate: {
columnTemplates: [
{ fieldName: "name", label: "Name" },
{ fieldName: "population", label: "Population" },
],
},
});
// Watch selection via highlightIds
featureTable.highlightIds.on("change", (event) => {
console.log("Selected IDs:", featureTable.highlightIds.toArray());
});
TimeSlider
<arcgis-time-slider
slot="bottom-right"
layout="auto"
mode="time-window"
time-visible
loop
>
</arcgis-time-slider>
<script type="module">
const timeSlider = document.querySelector("arcgis-time-slider");
const mapEl = document.querySelector("arcgis-map");
await mapEl.viewOnReady();
await layer.load();
timeSlider.fullTimeExtent = layer.timeInfo.fullTimeExtent;
timeSlider.stops = { interval: layer.timeInfo.interval };
</script>
// Core API
import TimeSlider from "@arcgis/core/widgets/TimeSlider.js";
const timeSlider = new TimeSlider({
view: view,
mode: "time-window", // instant, time-window, cumulative-from-start, cumulative-from-end
fullTimeExtent: layer.timeInfo.fullTimeExtent,
stops: {
interval: { value: 1, unit: "hours" },
},
playRate: 1000,
loop: true,
});
view.ui.add(timeSlider, "bottom-right");
// Events
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
reactiveUtils.watch(
() => timeSlider.timeExtent,
(timeExtent) => {
console.log("Time changed:", timeExtent.start, timeExtent.end);
},
);
Core Widget 方法
将组件添加到 View
import Legend from "@arcgis/core/widgets/Legend.js";
const legend = new Legend({ view: view });
// Add to view UI
view.ui.add(legend, "bottom-left");
// Add multiple widgets
view.ui.add([
{ component: legend, position: "bottom-left" },
{ component: search, position: "top-right" },
]);
// Add at specific index (order in position)
view.ui.add(legend, { position: "bottom-left", index: 0 });
// Remove widget
view.ui.remove(legend);
自定义容器中的组件
<div id="legendDiv"></div>
<script type="module">
import Legend from "@arcgis/core/widgets/Legend.js";
const legend = new Legend({
view: view,
container: "legendDiv",
});
</script>
Calcite 设计系统集成
使用 Calcite 的基本布局
<!DOCTYPE html>
<html>
<head>
<link
rel="stylesheet"
href="https://js.arcgis.com/5.0/@arcgis/core/assets/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/5.0/"></script>
<script
type="module"
src="https://js.arcgis.com/map-components/5.0/arcgis-map-components.esm.js"
></script>
<style>
html,
body {
height: 100%;
margin: 0;
}
</style>
</head>
<body class="calcite-mode-light">
<calcite-shell>
<calcite-navigation slot="header">
<calcite-navigation-logo
slot="logo"
heading="My Map App"
></calcite-navigation-logo>
</calcite-navigation>
<calcite-shell-panel slot="panel-start">
<calcite-panel heading="Layers">
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
</calcite-panel>
</calcite-shell-panel>
<arcgis-map id="map" basemap="streets-vector">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-map>
<calcite-shell-panel slot="panel-end">
<calcite-panel heading="Legend">
<arcgis-legend reference-element="map"></arcgis-legend>
</calcite-panel>
</calcite-shell-panel>
</calcite-shell>
</body>
</html>
Calcite Action Bar
<calcite-shell>
<calcite-shell-panel slot="panel-start">
<calcite-action-bar slot="action-bar">
<calcite-action
icon="layers"
text="Layers"
data-panel="layers"
></calcite-action>
<calcite-action
icon="legend"
text="Legend"
data-panel="legend"
></calcite-action>
<calcite-action
icon="bookmark"
text="Bookmarks"
data-panel="bookmarks"
></calcite-action>
</calcite-action-bar>
<calcite-panel id="layers" heading="Layers">
<arcgis-layer-list reference-element="map"></arcgis-layer-list>
</calcite-panel>
<calcite-panel id="legend" heading="Legend" hidden>
<arcgis-legend reference-element="map"></arcgis-legend>
</calcite-panel>
</calcite-shell-panel>
<arcgis-map id="map" basemap="topo-vector"></arcgis-map>
</calcite-shell>
<script>
document.querySelectorAll("calcite-action").forEach((action) => {
action.addEventListener("click", () => {
const panelId = action.dataset.panel;
document.querySelectorAll("calcite-panel").forEach((panel) => {
panel.hidden = panel.id !== panelId;
});
});
});
</script>
常用 Calcite 组件
| 组件 | 用途 |
|---|---|
calcite-shell | 应用布局容器 |
calcite-shell-panel | 侧边面板 |
calcite-panel | 内容面板 |
calcite-navigation | 页眉/页脚 |
calcite-action-bar | 图标按钮栏 |
calcite-action | 图标按钮 |
calcite-button | 标准按钮 |
calcite-input | 文本输入 |
calcite-list | 列表容器 |
calcite-list-item | 列表项 |
calcite-card | 卡片容器 |
calcite-modal | 模态对话框 |
calcite-alert | 警告消息 |
calcite-loader | 加载指示器 |
主题设置
<body class="calcite-mode-light">
<body class="calcite-mode-dark">
<style>
:root {
--calcite-color-brand: #007ac2;
--calcite-color-brand-hover: #005a8e;
--calcite-color-text-1: #323232;
}
</style>
</body>
</body>
组件事件
// Search select
search.on("select-result", (event) => {
console.log(event.result);
});
// LayerList trigger action
layerList.on("trigger-action", (event) => {
console.log(event.action, event.item);
});
// FeatureTable selection
featureTable.highlightIds.on("change", (event) => {
console.log(event.added, event.removed);
});
参考示例
legend- 用于图层符号系统的 Legend 组件widgets-layerlist- 用于管理图层的 LayerList 组件widgets-search-multiplesource- 支持多个来源的 Search 组件widgets-featuretable- FeatureTable 组件集成basemap-gallery- 用于切换底图的 BasemapGallerywidgets-timeslider- 用于时态数据的 TimeSlider 组件
常见问题
-
缺少 reference-element:放置在
<arcgis-map>标签外部的组件,如果没有显式引用,就无法找到视图。<arcgis-map id="myMap" basemap="topo-vector"></arcgis-map> <arcgis-search></arcgis-search><arcgis-map id="myMap" basemap="topo-vector"></arcgis-map> <arcgis-search reference-element="myMap"></arcgis-search>影响: 组件无法发现关联的视图,因此无法渲染或会抛出错误。
-
插槽名称是固定的:使用准确的插槽名称(
top-left,而不是topleft)。 -
Calcite CSS 未加载:使用 Calcite 组件前,请确保已加载 Calcite 脚本。
-
组件容器冲突:不要将同一个组件同时添加到 DOM 容器和
view.ui中。// Anti-pattern: widget in both container and view.ui const legend = new Legend({ view: view, container: "legendDiv" }); view.ui.add(legend, "bottom-right"); // Conflicts// Correct: pick one placement strategy const legend = new Legend({ view: view }); view.ui.add(legend, "bottom-right");影响: 组件会重复渲染,或导致布局错乱。
-
深色/浅色模式不匹配:为 body 添加
calcite-mode-light或calcite-mode-dark类。 -
Core API 组件缺少 CSS:使用 Core API 组件(而非 Map Components)时,必须导入
@arcgis/core/assets/esri/themes/light/main.css。Map Components 会自动处理 CSS。
相关技能
- 专用组件(BuildingExplorer、FloorFilter、Track、Locate 等)请参阅
arcgis-widgets-advanced - 测量、打印、路线和卷帘工具请参阅
arcgis-map-tools - Editor 和 Sketch 组件请参阅
arcgis-editing - FeatureTable 和 FeatureForm 详情请参阅
arcgis-tables-forms