Web コンポーネントでマッピング アプリを構築
出典:Calcite Design System - Construct a mapping app with web components
Calcite コンポーネントと ArcGIS Maps SDK for JavaScript の Map コンポーネントを使用して、Web コンポーネントでマッピング アプリケーションの UI を構築する方法をご紹介します。
Calcite コンポーネントを使用して、マッピング アプリケーションのユーザー エクスペリエンスを向上させ、インタラクションを促進します。このチュートリアルでは、アプリの作成を効率化するためのユーザー インタフェースとマップ コンポーネントに焦点を当て、ArcGIS Maps SDK for JavaScript の予備知識は必要ありません。ArcGIS Maps SDK for JavaScript を初めてお使いになる場合は、このアプリケーションで使用されている同様のマッピングをコンセプトに扱った素晴らしいチュートリアルをご覧ください。
前提条件
ステップ
新しいペンの作成
- CodePen に移動し、マッピングアプリケーション用の新しいペンを作成します。
HTML の追加
CodePen > HTML で、地図を表示する
arcgis-mapコンポーネントを含むページを作成するための HTML と CSS を追加してください。arcgis-mapコンポーネントにidを追加して、アプリ開発全体で参照できるようにし、CSS を使って幅と高さをブラウザーのウィンドウに合わせて設定し、さらにアプリのスタイリングを補うために Flexbox を使用してください。
CodePen では、<!DOCTYPE html> タグは必須ではありません。別のエディターを使用している場合や、ローカル サーバーでページを運営している場合は、必ずこのタグを HTML ページの先頭に追加してください。
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Calcite Components: Construct a mapping app with web components</title>
</head>
<style>
html,
body,
#mapEl {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
display: flex;
}
</style>
<body>
<arcgis-map id="mapEl"></arcgis-map>
</body>
<script type="module">
</script>
</html><head>要素に、Calcite コンポーネントと ArcGIS Maps SDK for JavaScript への参照を追加します。
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Calcite Components: Create a mapping app with web components</title>
<!-- 追加開始 -->
<script src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js" type="module"></script>
<script src="https://js.arcgis.com/4.33/"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />
<!-- 追加終了 -->
</head>- 次に、ArcGIS Maps SDK for JavaScript のマップ コンポーネントへの参照を追加します。
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>Calcite Components: Create a mapping app with web components</title>
<script src="https://js.arcgis.com/calcite-components/3.2.1/calcite.esm.js" type="module"></script>
<script src="https://js.arcgis.com/4.33/"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.33/esri/themes/light/main.css" />
<!-- 追加開始 -->
<script type="module" src="https://js.arcgis.com/4.33/map-components"></script>
<!-- 追加終了 -->
</head>API キーの使用
開発者アカウントを使用している場合、ArcGIS サービスにアクセスするには API キーが必要です。ArcGIS Online の組織に関連付けられているアカウントがある場合は、この手順を省略できます。
- セキュアなリソースにアクセスできるアプリを作るには、セキュリティと認証を始めるをご覧ください。
- CodePen >
<script>に戻り、esriConfigクラスをインポートします。 apiKeyプロパティを設定します。
<script type="module">
// 追加開始
const [esriConfig] = await $arcgis.import([
"@arcgis/core/config.js"
]);
esriConfig.apiKey = "YOUR_API_KEY";
// 追加終了
</script>マップの表示
マップはこのアプリケーションの中心です。HTML の追加で追加したCSSは、マップをウィンドウの幅と高さいっぱいに表示します。また、マップと連動する ArcGIS Maps SDK for JavaScript のマップ コンポーネントも追加します。
<body>内で、item-id属性を使ってarcgis-mapコンポーネントを初期化します。この属性は Web マップのアイテム ID を指定します。
<body>
<!-- 更新開始 -->
<arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
</arcgis-map>
<!-- 更新終了 -->
</body>- 次に、
arcgis-zoomコンポーネントを追加し、arcgis-mapコンポーネントに対する位置を設定します。
<body>
<arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
<!-- 追加開始 -->
<arcgis-zoom position="top-left"></arcgis-zoom>
<!-- 追加終了 -->
</arcgis-map>
</body>この時点でアプリケーションはマップを表示します。 次に、Calcite コンポーネントを使ってアプリのユーザー インターフェイスを構築します。
レイアウトの作成
レイアウトを作るために、スロットを使ってページ上の他のコンポーネントを整理する calcite-shell を使います。スロットは Web コンポーネントの概念であり、コア コンセプトのセクションに簡単な説明があります。Calcite コンポーネントにスロットがある場合は、その一覧がリファレンス ページに記載されています。たとえば、こちらが シェルのスロットです。
- calcite-shell コンポーネントを追加し、content-behind 属性を設定して、ユーザーがシェルの背後にある地図と操作できるようにします。
<body>
<!-- 追加開始 -->
<calcite-shell content-behind>
<!-- 追加終了 -->
<arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
<arcgis-zoom position="top-left"></arcgis-zoom>
</arcgis-map>
<!-- 追加開始 -->
</calcite-shell>
<!-- 追加終了 -->
</body>次に、
calcite-shell-panelコンポーネントを追加し、それをシェルの"panel-end"スロットに配置します。次に、シェル パネルの
displayMode属性を"float"に設定して、コンテンツが地図の上に浮かんで表示されるようにします。
<calcite-shell content-behind>
<!-- 追加開始 -->
<calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">
</calcite-shell-panel>
<!-- 追加終了 -->
<arcgis-map id="mapEl" item-id="03d584a7c9874b44821c6a766c3bbc11">
<arcgis-zoom position="top-left"></arcgis-zoom>
</arcgis-map>
</calcite-shell>calcite-panelコンポーネントを追加します。headingに Web マップのタイトルを動的に入力するためにidを指定し、初期化時にコンポーネントを隠すためにhidden属性を追加します。次に、
calcite-iconをパネルの"header-actions-start"スロットに挿入します。次に、
calcite-action-barをパネルの"action-bar"スロットに挿入します。ここにcalcite-actionを追加して、マップ コンポーネントを表示できるようにします。各アクションに、一意の
data-action-idの値を追加する。
<calcite-shell content-behind>
<calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">
<!-- 追加開始-->
<calcite-panel id="app-heading" hidden>
<calcite-icon id="logo-icon" slot="header-actions-start" icon="explore" text-label="explore"></calcite-icon>
<calcite-action-bar id="map-actions" slot="action-bar" layout="horizontal" expand-disabled>
<calcite-action icon="layers" text="Layers" data-action-id="layers"></calcite-action>
<calcite-action icon="basemap" text="Basemaps" data-action-id="basemaps"></calcite-action>
<calcite-action icon="legend" text="Legend" data-action-id="legend"></calcite-action>
<calcite-action icon="bookmark" text="Bookmarks" data-action-id="bookmarks"></calcite-action>
<calcite-action icon="print" text="Print" data-action-id="print"></calcite-action>
<calcite-action icon="information" text="About" data-action-id="information"></calcite-action>
</calcite-action-bar>
</calcite-panel>
<!-- 追加開始-->
</calcite-shell-panel>マップ コンポーネントの追加
レイアウトをさらに構築するために、ユーザーが calcite-action に操作したときに表示されるマップ コンポーネントを追加します。
はじめに calcite-block コンポーネントを追加する。
- コンテンツを表示するために
expanded属性を追加します。 - ユニークな
headingを付けます。 - 対応する
data-action-idの値を、ブロックのdata-block-id属性に指定します。 - アプリの初期化時にコンポーネントとそのコンテンツが表示されないように、
hidden属性を追加します。
- コンテンツを表示するために
calcite-blockに、arcgis-layer-listマップ コンポーネントをスロットに挿入します。reference-elementにマップ コンポーネントのidに設定します。
<calcite-shell-panel id="shell-panel-nav" slot="panel-end" display-mode="float" height="l">
<calcite-panel id="app-heading" hidden>
<calcite-icon id="logo-icon" slot="header-actions-start" icon="explore" text-label="explore"></calcite-icon>
<calcite-action-bar id="map-actions" slot="action-bar" layout="horizontal" expand-disabled>
<calcite-action icon="layers" text="Layers" data-action-id="layers"></calcite-action>
<calcite-action icon="basemap" text="Basemaps" data-action-id="basemaps"></calcite-action>
<calcite-action icon="legend" text="Legend" data-action-id="legend"></calcite-action>
<calcite-action icon="bookmark" text="Bookmarks" data-action-id="bookmarks"></calcite-action>
<calcite-action icon="print" text="Print" data-action-id="print"></calcite-action>
<calcite-action icon="information" text="About" data-action-id="information"></calcite-action>
</calcite-action-bar>
</calcite-panel>
<!-- 追加開始 -->
<!-- ArcGIS Maps SDK for JavaScript コンポーネントを含むマップ固有のブロック -->
<calcite-block expanded heading="Layers" data-block-id="layers" hidden>
<arcgis-layer-list drag-enabled reference-element="mapEl" visibility-appearance="checkbox"></arcgis-layer-list>
</calcite-block>
<!-- 追加終了 -->
</calcite-shell-panel>- ステップ 1 と 2 を繰り返して、
calcite-blockコンポーネントを追加し、arcgis-basemap-gallery、arcgis-legend、arcgis-bookmarks、およびarcgis-printコンポーネントをそれぞれ含めます。
<!-- ArcGIS Maps SDK for JavaScript コンポーネントを含むマップ固有のブロック -->
<calcite-block expanded heading="Layers" data-block-id="layers" hidden>
<arcgis-layer-list drag-enabled reference-element="mapEl" visibility-appearance="checkbox"></arcgis-layer-list>
</calcite-block>
<!-- 追加開始 -->
<calcite-block expanded heading="Basemaps" data-block-id="basemaps" hidden>
<arcgis-basemap-gallery reference-element="mapEl"></arcgis-basemap-gallery>
</calcite-block>
<calcite-block expanded heading="Legend" data-block-id="legend" hidden>
<arcgis-legend legend-style="classic" reference-element="mapEl"></arcgis-legend>
</calcite-block>
<calcite-block expanded heading="Bookmarks" data-block-id="bookmarks" hidden>
<arcgis-bookmarks editing-enabled="false" reference-element="mapEl"></arcgis-bookmarks>
</calcite-block>
<calcite-block expanded heading="Print" data-block-id="print" hidden>
<arcgis-print allowed-formats="all" allowed-layouts="all" include-default-templates="false"
reference-element="mapEl"></arcgis-print>
</calcite-block>
<!-- 追加終了 -->インフォメーション カードの作成
インフォメーション カードは、アプリのデータに関する情報をユーザーに提供できます。calcite-card を使用して Web マップの情報を表示します。このカードには、タイトル、サムネイル画像、説明、最終更新日、タグが動的に入力・整理されます。
他の地図コンポーネントと同様に、
calcite-blockコンポーネントを追加します。- コンテンツを表示するために
expanded属性を追加します。 - ユニークな
headingを付けます。 - 対応する
data-action-idの値を、ブロックのdata-block-id属性に指定します。 closed属性を追加し、アプリの初期化時にコンポーネントとそのコンテンツが表示されないようにします。
- コンテンツを表示するために
calcite-cardコンポーネントを追加します。カードに以下の子要素を、固有の ID を付けて追加します。
- カードの thumbnail スロットに img 要素を定義します。
- 3 つの div 要素を追加してください。1 つは heading スロットに、もう 1 つは description スロットに、最後の 1 つは footer-end スロットに配置します。
<calcite-block expanded heading="Print" data-block-id="print" hidden>
<arcgis-print allowed-formats="all" allowed-layouts="all" include-default-templates="false"
reference-element="mapEl"></arcgis-print>
</calcite-block>
<!-- 追加開始 -->
<!-- Info block (populates with info from the web map) -->
<calcite-block expanded heading="About the data" data-block-id="information" hidden>
<calcite-card id="card-content">
<img id="card-thumbnail" alt="Webmap thumbnail" slot="thumbnail" />
<div id="card-heading" slot="heading">
<!-- Dynamically populated -->
</div>
<div id="card-description" slot="description">
<!-- Dynamically populated -->
</div>
<div id="card-tags" slot="footer-end">
<!-- Dynamically populated -->
</div>
</calcite-card>
</calcite-block>
<!-- 追加終了 -->
</calcite-shell-panel>コンテンツの設定
アプリケーションにコンポーネントの追加が終わりました。パネルの見出しとインフォメーション カードに Web マップの内容を入力します。
<script>タグでarcgis-mapコンポーネントを宣言します。
<script type="module">
// 追加開始
const mapEl = document.getElementById("mapEl");
// 追加終了
</script>マップの
arcgisViewReadyChangeイベントで、Web マップのコンテンツを取得するために、次のportalItemの定数を宣言してください。:title、thumbnailUrl、snippet、modified、およびtags次に、UI に値を追加します。
titleは、パネルの見出しおよびカードの"heading"スロットに使用されます。thumbnailUrlは、カードの画像(img)のsrcプロパティとして"thumbnail"スロットに追加されます。snippetとmodifiedは、カードの"description"スロットを補足します。tagsは、それぞれのタグを繰り返し処理して、カードの"footer-end"スロットに個別のcalcite-chipコンポーネントを作成します。
<script type="module">
const mapEl = document.getElementById("mapEl");
// 追加開始
mapEl.addEventListener("arcgisViewReadyChange", () => {
const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
document.getElementById("app-heading").heading = `${title} Explorer`;
document.getElementById("card-heading").innerHTML = title;
document.getElementById("card-thumbnail").src = thumbnailUrl;
document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
tags.forEach(tag => {
document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
});
});
// 追加終了
</script>コンポーネントをインタラクティブにする
次のステップは、対応する calcite-action コンポーネントをクリックしたときに、マップ コンポーネントを含む calcite-block コンポーネントを表示します。
- 各
calcite-actionがクリックされたときに実行される関数を作成します。この関数は、現在表示されているcalcite-blockを非表示にし、クリックされたアクションに対応するブロックを表示します。ユーザーが現在アクティブなアクションをクリックした場合、対応するブロックは閉じられ、展開されたブロックは存在しなくなります。
このステップでは、上で追加したデータ属性を使って、アクション要素とブロック要素にアクセスするために属性セレクターを使用します。データ属性の値は、対応するマップコンポーネントの名前です。
mapEl.addEventListener("arcgisViewReadyChange", () => {
const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
document.getElementById("app-heading").heading = `${title} Explorer`;
document.getElementById("card-heading").innerHTML = title;
document.getElementById("card-thumbnail").src = thumbnailUrl;
document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
tags.forEach(tag => {
document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
});
});
// 追加開始
let activeWidget;
const handleActionBarClick = ({ target }) => {
if (target.tagName !== "CALCITE-ACTION") {
return;
}
if (activeWidget) {
document.querySelector(`[data-action-id=${activeWidget}]`).active = false;
document.querySelector(`[data-block-id=${activeWidget}]`).hidden = true;
}
const nextWidget = target.dataset.actionId;
if (nextWidget !== activeWidget) {
document.querySelector(`[data-action-id=${nextWidget}]`).active = true;
document.querySelector(`[data-block-id=${nextWidget}]`).hidden = false;
activeWidget = nextWidget;
} else {
activeWidget = null;
}
};
document.querySelector("calcite-action-bar").addEventListener("click", handleActionBarClick);
// 追加終了
</script>ローダー コンポーネントの追加
ここまでで、アプリケーションがインタラクティブになりました。Calcite コンポーネントを使用して、マップ コンポーネントを開いたり閉じたりできます。しかし、アプリケーションのロードには1秒かかるので、それをユーザーに伝える必要があります。
- 要素内で、シェルの終了タグの後に calcite-loader を追加して、コンポーネントを表示します。
</calcite-shell>
<!-- 追加開始 -->
<calcite-loader></calcite-loader>
<!-- 追加終了 -->
</body>arcgisViewReadyChangeイベントの内部で、他の JavaScript コードの下に、calcite-loaderコンポーネントをhiddenプロパティをtrueに設定して非表示にし、calcite-panelを表示してください。マップとそのプロパティがアプリに読み込まれると、ローダーは非表示になり、パネルが UI に表示されます。
mapEl.addEventListener("arcgisViewReadyChange", () => {
const { title, thumbnailUrl, snippet, modified, tags } = mapEl.map.portalItem;
document.getElementById("app-heading").heading = `${title} Explorer`;
document.getElementById("card-heading").innerHTML = title;
document.getElementById("card-thumbnail").src = thumbnailUrl;
document.getElementById("card-description").innerHTML = `<p>${snippet}</p><p>Last modified on ${modified}.</p>`;
tags.forEach(tag => {
document.getElementById("card-tags").innerHTML += `<calcite-chip>${tag}</calcite-chip>`;
});
// 追加開始
document.querySelector("calcite-loader").hidden = true;
document.getElementById("app-heading").removeAttribute("hidden");
// 追加終了
});スタイルの追加
<style> 要素内で、見出しの calcite-panel と情報の calcite-card のユーザー インターフェースを強化するために、追加の CSS を記述します。
calcite-iconをパネルの"header-actions-start"にスロットしている場合、そのコンポーネントを整列させるために Flexbox の変数を追加します。次に、パネルの幅と高さを設定するためのスタイルを追加します。
- calcite-shell-panel に –calcite-shell-panel-min-width を追加します。
calcite-shell-panelがスマートフォンなどの小型デバイスに対応できるように、メディア クエリーを追加します。data-block-id属性を含むcalcite-blockコンポーネントに対して、max-heightを設定します。
<style>
html,
body,
#mapEl {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
display: flex;
}
/** 追加開始 */
#logo-icon {
align-self: center;
height: auto;
margin-inline-start: 0.5rem;
}
#shell-panel-nav {
--calcite-shell-panel-min-width: 18rem;
}
@media (max-width: 400px) {
#shell-panel-nav {
--calcite-shell-panel-min-width: 80vw;
}
}
calcite-block[data-block-id] {
max-height: 50vh;
overflow-y: auto;
}
/** 追加終了 */
</style>- 最後に、
calcite-cardにスタイルを追加してください。具体的には、コンポーネントにパディングを追加し、CSS 変数を使ってフォント サイズを更新し、タグをflex-wrapで折り返すようにしてください。
<style>
/** ~ 中略 ~ */
calcite-block[data-block-id] {
max-height: 50vh;
overflow-y: auto;
}
/* 追加開始 */
#card-heading {
font-size: var(--calcite-font-size-md);
}
#card-description {
font-size: var(--calcite-font-size);
}
#card-tags {
flex-wrap: wrap;
}
/* 追加終了 */
</style>アプリの実行
CodePen でコードを実行すると、アプリケーションが表示されます。
アプリケーションの読み込みが完了すると、マップが表示され、Web マップのタイトルと calcite-action-bar も一緒に表示されます。calcite-action コンポーネントをクリックすると、calcite-block コンポーネントが展開・折りたたみされます。これらのブロックには、ArcGIS Maps SDK for JavaScript のマップ コンポーネントが含まれています。