はじめに
この投稿は、ArcGIS Online Experience Builder でテーブルウィジェット内の条件付き視覚書式設定のために開発およびテストされた実験的なワークフローを記録しています。このアプローチでは、計算された文字列フィールドを含む仮想 FeatureSet を生成するために Arcade Data ソースを使用します。これらのフィールドには、属性値に応じて生成された Unicode 記号や HTML/CSS を含めることができます。
生成された FeatureSet は、その後標準の Experience Builder Table のソースとして使用されます。テスト環境では、Unicode インジケーター、条件付きで色付けされたテキスト、色付けされた数値、および条件付き書式設定されたテーブルセルを視覚的に近似する実験的な色付きブロックが可能になりました。元のソースデータは変更されません。
Experience Builder の高度な書式設定についての注意点。Experience Builder はサポートされているウィジェットコンテキストで Arcade ベースの動的コンテンツとスタイリングもサポートしています。ここで説明するワークフローは別のケースに対応しています:Arcade Data FeatureSet 内で書式設定されたコンテンツを生成することによって標準の Table ウィジェット内に表示される値の条件付き視覚書式設定です。これは Table ウィジェットが提供するネイティブなセルレベルの条件付き書式設定として解釈すべきではありません。
1. 基本的な考え方
ワークフロー:
元のテーブル 12 Arcade Data 12 仮想 FeatureSet 12 Table ウィジェット
一般的な再現可能な例として、ソーステーブルに OBJECTID、REACH_ID(ユニークな共通キー)、AREA(数値)が含まれていると仮定します。デモンストレーションルールは意図的に任意です:AREA = -99999 はデータなし(No Data)、AREA < 100 は LOW、AREA >= 100 は HIGH を意味します。
2. Arcade Data ソースを作成する
Experience Builder でデータ 12 データ追加 12 Arcade を使用し、FeatureSetByPortalItem() でソーステーブルを読み込みます。
var p = Portal("https:\/\/YOURPORTAL.maps.arcgis.com");
var fs = FeatureSetByPortalItem(
p,
"YOUR_ITEM_ID",
2,
["OBJECTID", "REACH_ID", "AREA"],
false
);
YOURPORTAL、YOUR_ITEM_ID、およびテーブル/レイヤー ID をご自身の値に置き換えてください。このテーブル例ではジオメトリは不要なので includeGeometry は false にします。
3. 完全な Arcade 例
以下の完全なスクリプトは元の属性を保持し、結果を並べて比較できるように5つの実験的フィールドを作成します。
// ============================================================
// 1. ポータル接続
// ============================================================
var p = Portal("https:\/\/YOURPORTAL.maps.arcgis.com");
// ============================================================
// 2. 元のテーブルを読み込む
// ============================================================
var fs = FeatureSetByPortalItem(
p,
"YOUR_ITEM_ID",
2,
["OBJECTID", "REACH_ID", "AREA"],
false
);
// ============================================================
// 3. 仮想 FeatureSet を定義
// ============================================================
var output = {
fields: [
{
name: "OBJECTID",
alias: "OBJECTID",
type: "esriFieldTypeOID"
},
{
name: "REACH_ID",
alias: "Reach ID",
type: "esriFieldTypeString",
length: 50
},
{
name: "AREA",
alias: "Area",
type: "esriFieldTypeDouble"
},
{
name: "TEST_UNICODE",
alias: "Unicode",
type: "esriFieldTypeString",
length: 50
},
{
name: "TEST_HTML",
alias: "HTML text",
type: "esriFieldTypeString",
length: 150
},
{
name: "TEST_VALUE",
alias: "Unicode + value",
type: "esriFieldTypeString",
length: 50
},
{
name: "TEST_HTML_VALUE",
alias: "HTML value",
type: "esriFieldTypeString",
length: 150
},
{
name: "TEST_BACKGROUND",
alias: "Background test",
type: "esriFieldTypeString",
length: 300
}
],
geometryType: "",
features: []
};
// ============================================================
// 4. LOOP THROUGH SOURCE RECORDS
// ============================================================
for (var f in fs) {
var reachID = f.REACH_ID;
var area = f.AREA;
// TEST 1 - Unicode indicator
var unicodeResult = "";
if (area == -99999) {
unicodeResult = "⚪ ND";
}
else if (area < 100) {
unicodeResult = "🔴 LOW";
}
else {
unicodeResult = "🟢 HIGH";
}
// TEST 2 - HTML colored text
var htmlResult = "";
if (area == -99999) {
htmlResult = "<span style='color:gray'>ND</span>";
}
else if (area < 100) {
htmlResult = "<span style='color:red'>LOW</span>";
}
else {
htmlResult = "<span style='color:green'>HIGH</span>";
}
// TEST 3 - Unicode indicator + original value
var valueResult = "";
if (area == -99999) {
valueResult = "⚪ ND";
}
else if (area < 100) {
valueResult = "🔴 " + Text(area, "#,##0.00");
}
else {
valueResult = "🟢 " + Text(area, "#,##0.00");
}
// TEST 4 - Original value colored with HTML
var htmlValue = "";
if (area == -99999) {
htmlValue = "<span style='color:gray'>ND</span>";
}
else if (area < 100) {
htmlValue =
"<span style='color:red'>" +
Text(area, "#,##0.00") +
"</span>";
}
else {
htmlValue =
"<span style='color:green'>" +
Text(area, "#,##0.00") +
"</span>";
}
// TEST 5 - Experimental simulated cell background
// This styles a block inside the field; it does NOT
// modify the native Table cell itself.
var backgroundResult = "";
if (area == -99999) {
backgroundResult =
"<div style='" +
"background-color:gray;" +
"color:white;" +
"width:100%;" +
"padding:6px;" +
"text-align:center;" +
"font-weight:bold" +
"'>ND</div>";
}
else if (area < 100) {
backgroundResult =
"<div style='" +
"background-color:red;" +
"color:white;" +
"width:100%;" +
"padding:6px;" +
"text-align:center;" +
"font-weight:bold" +
"'>" +
Text(area, "#,##0.00") +
"</div>";
}
else {
backgroundResult =
"<div style='" +
"background-color:green;" +
"color:white;" +
"width:100%;" +
"padding:6px;" +
"text-align:center;" +
"font-weight:bold" +
"'>" +
Text(area, "#,##0.00") +
"</div>";
}
// BUILD OUTPUT RECORD
Push(
output.features,
{
attributes: {
OBJECTID: f.OBJECTID,
REACH_ID: reachID,
AREA: area,
TEST_UNICODE: unicodeResult,
TEST_HTML: htmlResult,
TEST_VALUE: valueResult,
TEST_HTML_VALUE: htmlValue,
TEST_BACKGROUND: backgroundResult
}
}
);
}
// ============================================================
// 5. RETURN THE VIRTUAL FEATURESET
// ============================================================
return FeatureSet(
Text(output)
);
4. Use the Arcade Data source in the Table widget
Run and apply the expression, then configure a Table widget to use the Arcade Data source. The output should expose OBJECTID, REACH_ID, AREA, TEST_UNICODE, TEST_HTML, TEST_VALUE, TEST_HTML_VALUE, and TEST_BACKGROUND.
Practical observation: after adding fields to the Arcade expression, the Table may continue to use the previous schema. If a new field appears in the Arcade output but not in the Table, make the Table re-read/refresh the Arcade Data source.
5. Filter the virtual table from a map selection
Retain the same common key in the source feature layer and in the virtual FeatureSet. Configure Map → Action → Record selection changes → Filter data.
Setting | Value |
|---|
Trigger data | Feature layer |
Trigger field | REACH_ID |
Action data | Arcade Data |
Action field | REACH_ID |
Mode | Default |
With a 1:1 relationship, selecting a map feature filters the virtual Table to the corresponding record.
6. Results verified in the tested environment
- Unicode indicators: worked.
- Unicode indicator + numeric value: worked.
- HTML text color using <span>: worked.
- HTML-colored numeric values: worked.
- Background-color block using <div>: worked experimentally.
Figure 1. Conditional visual formatting verified in the Experience Builder Table: Unicode indicator, HTML-colored text, Unicode indicator with numeric value, HTML-colored numeric value, and experimental simulated cell background.
7. Important distinction and limitations
This should not be described as native conditional formatting of the Table widget. A more accurate description is conditional visual formatting of the content of a virtual Arcade field displayed by the Table widget.
The background test does not style the native table cell. It renders an HTML block inside the field content and uses width, padding, background-color, text alignment, and font weight to visually approximate a colored cell.
The <div>-based background behavior should be treated as experimental. It was verified in the tested ArcGIS Online environment, but it should not be assumed to be a stable supported API contract. HTML/CSS sanitization or rendering behavior may change between updates or between ArcGIS Online and ArcGIS Enterprise. Keep production HTML simple and retest after updates.
フィーチャー数の制限と観察された挙動。Esriのドキュメントでは、FeatureSetを使用してフィーチャーコレクションを構築する場合、最大50,000フィーチャーと記載されています。この投稿で構築された仮想FeatureSetは、そのドキュメント化された制限が関連するワークフローのタイプに該当します。しかし、同じArcGIS Online環境での追加テストでは、Tableウィジェットで50,001および100,000の生成レコードが正常に使用され、OBJECTID 50001および100000の直接クエリも成功しました。セクション9ではこの不一致を詳細に記録しています。観察された挙動は実験的なものであり、Esriのドキュメント化された制限のサポートされた代替として扱うべきではありません。
8. 追加検証:1:Nフィルタリングと仮想wide-to-long変換
Arcade Dataがマップ選択によって駆動される1:Nワークフローをサポートできることを検証するために、2つの追加テストが実施されました。両方のテストは、マップレイヤーとテーブルまたは仮想FeatureSetで同じ共通リーチ識別子を使用しました。
テスト1 - 既存の物理的1:Nテーブル。既にロングフォームで整理されている既存のテーブルからArcade Dataソースが作成されました。各リーチに対して複数の流量-期間レコードがあります。マップアクション(レコード選択変更 → データレコードをフィルタ)がフィーチャーレイヤー内のリーチ識別子をArcade Dataソース内の同じ識別子に接続しました。1つのリーチを選択すると、単一レコードだけでなくすべての一致するレコードにテーブルがフィルタリングされました。これは、仮想Arcade Dataソースが1:Nフィルタリングワークフローに参加できることを確認します。
図2. テスト1:リーチArno_3629を選択すると、1:N Arcade Dataテーブルが同じリーチに対する複数の流量-期間レコードにフィルタリングされます。
テスト2 - 仮想wide-to-long変換。ソーステーブルは代わりに元のwide構造で読み込まれました。異なる期間の流量値が別々のフィールドに格納されています。Arcadeは各ソースレコードを動的に複数の仮想レコードに変換し、それらにはReach ID、流量、期間ラベル、および数値期間が含まれます。その結果得られた仮想1:N FeatureSetは同じマップ選択フィルタに接続されました。同じリーチを選択すると期待通り複数レコードが返され、流量値は表示上の丸めを除いて対応する物理的ロングフォームテーブルと一致しました。
図3. テスト2:Arcadeはwideソーステーブルから仮想1:Nテーブルを作成し、その結果は選択されたリーチによって正常にフィルタリングされます。
これらのテストは元の1:1検証を拡張します。テストされたArcGIS Online Experience Builder環境では、Arcade Dataは既存の1:N構造を公開できるだけでなく、ソースサービスを変更せずに派生した1:N構造を動的に作成できました。
より大きなデータセットの場合、結果として得られる仮想レコード数は上記のフィーチャーコレクション制限と合わせて考慮すべきです。
9. 追加検証:ドキュメント化された50,000フィーチャー制限を超えた挙動
Esriドキュメントでは、Arcade Data結果がフィーチャーコレクション構築に使用される場合、そのコレクション構築に使われるFeatureSetは最大50,000フィーチャーまでとされています。この投稿内の例ではFeatureSet(Text(output))で新しいFeatureSetを構築しているため、このドキュメント化された閾値を現在のArcGIS Online Experience Builder環境で超えた場合どうなるか追加テストが行われました。
ジオメトリなしで2つのフィールド(OBJECTIDとTEST_VALUE)を持つ合成Arcade Dataソースが作成されました。この式はメモリ内で連続したレコードを生成し、それらをFeatureSet(Text(output))で返しました。49,999および50,000レコードでテストは正常に実行されました。その後50,001レコードで式がテストされました。
50,001レコードではArcadeエディターは依然として式を正常に評価しました。データソースがExperience Builderに追加された後、標準Tableウィジェットは合計50,001レコードと報告しました。OBJECTID = 50001 のTableフィルターは期待通りのレコードを返し、ドキュメント化された50,000閾値を超えたレコードが単に表示カウントに含まれているだけでなく直接クエリ可能であることが確認されました。
次に100,000生成レコードでも同様のテストが繰り返されました。Tableウィジェットはデータソースを受け入れ、OBJECTID = 100000 のフィルターは期待通りのレコードとTEST_VALUE = 100,000 を返しました。このテスト環境では仮想FeatureSetは少なくとも100,000レコードまで使用可能なままでした。
この観察結果はEsriのドキュメント化された50,000フィーチャー制限を上書きするものでも、本番アプリケーション向けサポート保証でもありません。これは2026年8月時点のArcGIS Online Experience Builderで観察された挙動のみを記録しています。有効な挙動は実装詳細によって異なり将来のアップデートやArcGIS Enterpriseでは変わる可能性があります。Esriが仕様を明確化または更新しない限り、アプリケーション設計には引き続きドキュメント化された制限を考慮すべきです。
wide-to-long変換への実用的な影響。この変換は各ソースレコードから生成される仮想レコード数を増加させる可能性があります。上記テストでは50,000超過でも直ちに失敗しませんでしたが、この観察された挙動を無制限なクライアント側変換設計理由として使用すべきではありません。パフォーマンス、メモリ使用量、ブラウザ資源、および将来互換性も考慮すべきです。
図4. ドキュメント化された50,000フィーチャー閾値超過時の実験的検証。100,000生成レコードを含む仮想Arcade FeatureSetがExperience Builder Tableウィジェットで使用されています。OBJECTID = 100000 のフィルタリングは対応するレコードを正常に返し、このレコードが2026年8月時点でテストされたArcGIS Online環境で直接クエリ可能であることを確認しています。
図4に示された結果は観察された実験的挙動であり、Esriのドキュメント化された50,000フィーチャー制限より優先するものとは解釈すべきではありません。
10. なぜこの技術がフォーマット以外にも有用か
- 共通キーを使って複数テーブルから選択属性を結合すること。
- ソースサービスを変更せずにフィールド計算すること。
- -99999などのセンチネル値をNDに置き換えること。
- 1:N関係からレコード集約や要約処理すること。
- 派生した要約テーブルを作成すること。
- 結果がマップ選択に反応するよう関係キーを保持すること。
- 他ワークフロー向けジオメトリ含む派生FeatureSetも探求すること。
この意味でArcade DataはソースサービスとExperience Builderウィジェット間の軽量な仮想変換層として機能できます。
結論
ソースデータ → Arcade Data → 仮想FeatureSet → 計算HTMLフィールド → Experience Builder Table → 条件付きビジュアルフォーマット
ソーステーブルはそのままです。Unicodeおよび<span>ベース手法はより保守的なオプションです。ブロック背景技術は視覚的には強力ですが明示的に実験的として識別すべきです。
謝辞と透明性について
このワークフローはChatGPT(OpenAI)を技術アシスタントとして利用した反復的な実験シリーズによって開発されました。
ChatGPTは可能なアプローチ探索やArcadeコード生成・改良支援し、この投稿内で説明した各挙動は直接ArcGIS Online Experience Builderで検証されました。
実験的検証は重要でした:HTMLフォーマットがTableウィジェットでレンダリングされないという初期仮定などはいくつか誤りでした。それら観察結果から色付き数値や背景色ブロックによる後続テストにつながりました。
テスト環境:ArcGIS Online Experience Builder、2026年8月。
ドキュメント参照文献
・Esri, ArcGIS Experience Builder ドキュメント、「データ選択」 — Arcadeによるデータ追加;FeatureSet返却要件およびフィーチャーコレクション用ドキュメント化された50,000フィーチャー制限について。セクション9では別途テスト環境で観察されたより高いカウントも報告しています。
・Esri, ArcGIS Experience Builder ドキュメント、「高度なフォーマット設定」 — サポート対象ウィジェットコンテキスト内でのArcadeベース動的コンテンツおよびスタイリングについて。