Arcade

字数统计: 6.1k
阅读时长: 约 15 分钟
当前版本: 4.29

什么是 Arcade?

Arcade是ArcGIS的一种表达式语言,GeoScene 应用程序 (GeoScene Pro、GeoScene Online、GeoScene Runtime API 和 GeoScene Maps SDK for JavaScript) 都支持在产品中执行数学计算并在可视化、弹出窗口内容和标注时调用Arcade语句。定义的表达式也可以保存到 web 地图,并在其他应用程序中加载和计算。

如何编写 Arcade 表达式

在许多方面,Arcade 的语法类似于 JavaScript,声明变量、执行逻辑操作、利用内置函数以及编写自定义函数等。但是,两种语言之间也存在差异。了解如何编写 Arcade 表达式,请参阅完整的 Arcade 文档,其中包括指南和函数参考。还可以通过访问设计器,使用测试数据集测试表达式。

配置文件变量介绍了如何在表达式中访问图层、地图或工作空间的数据值。例如,$feature 为表达式提供了对要素属性和几何的访问。

在 JavaScript 应用程序中,Arcade 表达式作为字符串值引用。编写单行表达式时,只需将其括在双引号或单引号中即可。

js
    // returns the % of the population that is age 18 and older
    renderer.valueExpression = "Round( ($feature.AGE_18UP / $feature.TOTAL_POP) \* 100 )";

可以通过模板文本 (ES6 或更高版本) 来编写多行 Arcade 表达式。

js
    renderer.valueExpression = `
        var republican = $feature.MP06025a_B;
        var democrat = $feature.MP06024a_B;
        var independent = $feature.MP06026a_B;

        var parties = [ republican, democrat, independent ];
        var total = Sum(parties);
        var max = Max(parties);
        return (max / total) \* 100;
    `;

Arcade 还还支持模板文本。因为 Arcade 表达式在 GeoScene Maps SDK for JavaScript 中存储为字符串,因此它们通常使用 JavaScript 中的模板文字编写。也可以在 JavaScript 模板文本中使用 Arcade 模板文本,但需要转义关键字符(如反引号和美元符号)才能识别 Arcade 模板文本。例如,该表达式在 PopupTemplate 的 JavaScript 模板文本中使用模板文本:

js
    layer.popupTemplate = {
        content: "{expression/percent-unemployed}",
        expressionInfos: [
            {
                name: "percent-unemployed",
                title: "Percent unemployed",
                expression: `
                var unemploymentRate = ( $feature.UNEMP_CY / $feature.LABOR_FORCE ) \* 100;
                var population = $feature.POP_16UP;
                var populationNotWorking = ( ( $feature.UNEMP_CY + $feature.NOT_LABORFORCE_16 ) / $feature.POP_16UP ) \* 100;

                // returns a string built using an Arcade template literal

                return \\\\{$feature.COUNTY} County

                - Unemployment rate: \\{Text(unemploymentRate, "##.#")}%
                - % population not working: \\{Text(populationNotWorking, "##.#")}%
                - Population: \\{Text(population, "#,###")}\\
                `
            }
        ]
    };

如果没有编写 ES6 代码,则可将表达式放置在 JavaScript 外部的一个单独的 <script> 标记中,并将类型设置为 text/plain,然后在 JavaScript 的适当位置处通过脚本唯一 ID 引用脚本。

js
    <script type="text/plain" id="adult-population">
        var republican = $feature.MP06025a_B;
        var democrat = $feature.MP06024a_B;
        var independent = $feature.MP06026a_B;

        var parties = [ republican, democrat, independent ];
        var total = Sum(parties);
        var max = Max(parties);
        return (max / total) \* 100;
    </script>

然后通过 document.getElementById() 方法将脚本作为字符串值引用。

js
    renderer.valueExpression = document.getElementById("adult-population").text;

Arcade 的使用场景

Arcade 只能在有效的配置文件中执行。配置文件可定义用于编写有效表达式的规则或规范。这包括定义有效的数据输入(配置文件变量)、支持的函数和返回类型,以及它们可以执行的上下文。

Arcade 是独立的,可以逐个要素执行。配置文件可确保表达式在给定的执行环境中是安全且高性能的。例如,Arcade 可以定义驱动可视化的数据值。如果您的图层具有十万个要素,并且具有一个使用 Arcade 表达式定义的渲染器,则该表达式必须执行十万次才能正确渲染数据。因此,可视化配置文件会阻止您访问来自原始要素之外的数据,因为这会严重降低应用程序的性能。但是,在弹出窗口中,您可在 Arcade 表达式中访问地图或服务中的任何图层数据,因一次只能执行一个表达式(打开弹出窗口时),您可高效执行此操作。

以下部分介绍了 JavaScript API 中可以编写 Arcade 表达式的位置。每个部分都提供有指向配置文件规范的链接,这些规范定义给定上下文的表达式规则.

标注

Arcade 用于为 FeatureLayerSceneLayer 中的要素创建标注表达式。从 API 版本 4.5 开始,这是唯一受支持的标记要素的方法。必须至少将一个 LabelClass 添加到图层的 labelingInfo 属性中。Arcade 表达式必须作为字符串值传递给 LabelClasslabelExpressionInfo 对象的 expression 属性。

js
    // returns the value of a field in the layer
    // the value of this field will be the label for each feature
    const arcade = "$feature.STATION_NAME";

    // this object autocasts as new LabelClass()
    const labelClass = {
        // set the arcade expression to the `expression` property of labelExpressionInfo
        labelExpressionInfo: {
            expression: arcade
        },
        labelPlacement: "below-right",
        minScale: 2500000,
        symbol: {
            type: "label-3d",
            symbolLayers: [{
                type: "text",
                material: { color: "white" },
                halo: {
                    color: "black",
                    size: 1
                },
                size: 8
            }]
        }
    };

    // set the label class to the feature layer
    featureLayer.labelingInfo = [ labelClass ];

在 Arcade 中编写的标注表达式可能更复杂,包含执行数学和逻辑运算的多行。Arcade 的When() 函数用于评估风向(0-360 度之间),其返回 NNEESESSWWNW 的相关罗盘方向。如果风速为 0,则不返回方向。表达式的最后一行返回标注,即 WIND 变量的值。

html
    <script type="text/plain" id="wind-direction">
        var DEG = $feature.WIND_DIRECT;
        var SPEED = $feature.WIND_SPEED;
        var DIR = When( SPEED == 0, '',
        (DEG < 22.5 && DEG >= 0)|| DEG > 337.5, 'N',
        DEG >= 22.5 && DEG < 67.5, 'NE',
        DEG >= 67.5 && DEG < 112.5, 'E',
        DEG >= 112.5 && DEG < 157.5, 'SE',
        DEG >= 157.5 && DEG < 202.5, 'S',
        DEG >= 202.5 && DEG < 247.5, 'SW',
        DEG >= 247.5 && DEG < 292.5, 'W',
        DEG >= 292.5 && DEG < 337.5, 'NW', '' );
        var WIND = SPEED + ' mph ' + DIR;
        return WIND;
    </script>

还有许多其他 Arcade 函数可用于标注,包括为文本格式设置提供逻辑的文本函数。请务必查看完整的 Arcade 文档,了解有关这些内置函数的更多信息。

弹出窗口 (Popups)

Arcade 在两个弹出配置文件中实现:

  • 弹出窗口 - 用于计算要在图层的弹出窗口内容或要素缩减弹出窗口中显示的属性。这对于简单的计算很有用。

  • 弹出元素 - 用于在图层的弹出窗口或要素缩减弹出窗口中有条件地创建弹出窗口元素。如果您希望单个表达式在单个弹出元素中返回多个值,则应使用此方法。

弹出窗口 (Popup)

可以在 PopupTemplate内容中引用 Arcade 表达式。当您想要显示图层中未作为属性值显示的数据时,这非常有用。在弹出配置文件中,表达式必须返回文本或数值,并且可以使用 $feature 访问要素的属性,或者使用 $layer, $map$datastore 访问其他要素和图层的数据。

js
// labor force participation rate
Round(($feature.CIVLBFR_CY / $feature.POP_16UP)\*100,2)

此表达式返回的值可以显示在图层的 popupTemplate 中。要查看弹出窗口中的值,必须在 PopupTemplate 的 expressionInfos 属性中引用它,并为其分配 nametitle

js
layer.popupTemplate = {
    expressionInfos: [{
        name: "participation-rate",
        title: "% of population 16+ participating in the labor force",
        expression: "Round(($feature.CIVLBFR_CY / $feature.POP_16UP)\*100,2)"
    }],
    content: "In {NAME} county, {expression/participation-rate}% of the population"
    + " participates in the labor force."
};

请注意,一旦表达式存在于 expressionInfos 属性中,即可使用 PopupTemplate 内容中的 {expression/expression-name} 占位符模板引用从表达式返回的值。用户单击要素后,弹出窗口内容中将显示以下内容:

arcade-popup-text

您还可以在弹出窗口内容元素(包括 FieldsContentMediaContentTextContent)中引用从 Arcade 表达式返回的值。只需在对象的 fieldName 属性中引用表达式的名称。请记住使用 expression/expression-name 语法。

js
layer.popupTemplate = {
 expressionInfos: [{
    name: "participation-rate",
    title: "% of population 16+ participating in the labor force",
    expression: "Round(($feature.CIVLBFR_CY / $feature.POP_16UP)\*100,2)"
 }],
 content: [{
    type: "fields",
    fieldInfos: [{
            fieldName: "expression/participation-rate"
        }, {
            fieldName: "CIVLBFR_CY",
            label: "Civilian labor force",
            format: {
                places: 0,
                digitSeparator: true
            }
        }, {
            fieldName: "POP_16UP",
            label: "Population 16+",
            format: {
                places: 0,
                digitSeparator: true
            }
        }
    ]
 }]
};

弹出窗口将显示以下内容:

arcade-popup-table

要素缩减弹出窗口

除图层弹出窗口外,还可在聚类 popupTemplate内容中引用 Arcade 表达式。这与图层弹出窗口略有不同,因为 $feature 表示聚类本身,其中汇总了两个或多个要素。

$feature 始终包含 cluster_count 字段,除了汇总图层渲染器的其他字段 (例如 cluster_avg_fieldName)。

js
// returns the sum of the cost field for all features in the cluster
$feature.cluster_count \* $feature.cluster_avg_cost

该配置文件还允许您通过 $aggregatedFeatures 配置文件变量访问聚类中包含的要素。您可以过滤聚合的要素、遍历要素、对其进行排序,并使用它们计算统计数据。

js
// returns the total number of car crashes
// that resulted in at least one fatality in a
// cluster representing motor vehicle accidents
Count(Filter($aggregatedFeatures, "FATALITIES > 0"))

从这些表达式返回的值可以显示在聚类的 popupTemplate 中。要查看弹出窗口中的值,必须在 PopupTemplate 的 expressionInfos 属性中引用它,并为其分配 nametitle

js
layer.featureReduction = {
    type: "cluster",
    popupTemplate: {
        expressionInfos: [{
                name: "total-cost",
                title: "Total damages",
                expression: "Text($feature.cluster_count \* $feature.cluster_avg_cost, '$#,###.##')"
            }, {
                name: "fatalities",
                title: "Crashes with fatalities",
                expression: `
                Expects($aggregatedFeatures, 'FATALITIES')
                Count(Filter($aggregatedFeatures, 'FATALITIES > 0'))
                `
            }
        ],
        content: `
            This cluster represents {cluster_count} motor vehical accidents. {expression/fatalities} of these crashes
            had at least one fatality. These crashes resulted in {expression/total-cost} of damages.
            `
    }
};

请注意,一旦表达式存在于 expressionInfos 属性中,即可使用 PopupTemplate 内容中的 {expression/expression-name} 字符串模板引用从表达式返回的值。

弹出元素

弹出元素配置文件允许地图作者编写表达式,以返回表示 rich textfieldsmedia(即图表)弹出内容元素的字典(即对象)。返回的字典必须遵循 popupElementWeb 地图规范。与弹出窗口配置文件不同,此配置文件允许弹出窗口作者在单个元素中返回多个值。

在该配置文件中,表达式必须返回字典,并且可以使用 $feature 访问要素的属性,或者使用 $layer$map$datastore 访问其他要素和图层的数据。

在图表、表格或富文本元素中的内容基于逻辑条件的高级方案中,此配置文件非常有用。例如,以下表达式可创建一个字段内容元素,该元素仅包含具有数据值的字段。这可能比标准 FieldsContent 元素更精简,后者无法检查字段是否为空。

js
// Creates a table with only fields that contain data
var fields = Schema($feature).fields;
function getNames(field){
    return field.name;
}
function filterValidFields(fieldName){
    var invalidNames = ["objectid", "fid", "shape__area", "shape__length"];
    return !includes(invalidNames, lower(fieldName)) && !IsEmpty($feature[fieldName]) && !IsNan($feature[fieldName]);
}

var validFields = Filter(Map(fields, getNames), filterValidFields);
var attributes = {};
var fieldInfos = [];

for (var f in validFields){
    var fieldName = validFields[f];
    Push(fieldInfos, { fieldName: fieldName });
    // format numbers with digit separator and one decimal place
    var value = IIF(TypeOf($feature[fieldName] == "Number"), Text($feature[fieldName], "#,#.#"), $feature[fieldName]);
    attributes[fieldName] = value;
}

return {
    type: "fields",
    fieldInfos: fieldInfos,
    attributes: attributes
};

弹出元素表达式在 ExpressionContent 元素的 expressionInfo 属性中定义。

js
// Creates an column chart where each category/value
// is an aggregate of two or more fields
layer.popupTemplate = {
    title: "Educational Attainment",
    content: [{
        type: "expression",
        expressionInfo: {
            expression: `
                // Create a dictionary of attributes representing the values
                // to display in the chart
                var attributes = {
                "No School": $feature.no_school + $feature.some_primary,
                "Primary": $feature.primary_complete + $feature.some_secondary,
                "Secondary": $feature.secondary_complete + $feature.some_highSchool,
                "High School": $feature.highSchool_diploma + $feature.highSchool_ged + $feature.some_college,
                "College/University": $feature.associates + $feature.bachelors + $feature.masters + $feature.doctorate + $feature.professional;
                };

                var fields = [];

                // Create an array representing the attribute names (or keys)
                for (var k in attributes){
                Push(fields, k);
                }

                // Returns a dictionary providing the information
                // required by the popup to render a column chart
                return {
                type: "media",
                attributes: attributes,
                title: "Educational attainment",
                mediaInfos: [{
                type: "columnchart",
                value: {
                // The list of attribute names (keys) to include in the chart
                fields: fields
                }
                }]
                };
                `,
            title: "Educational Attainment"
        }
    }]
};

您还可以使用此元素创建由聚合数据值组成的图表或其他内容类型。这在 FeatureReductionCluster 中特别有用。以下示例描述了可在 Arcade 表达式中定义的各种内容类型。

HTML 列表

此示例演示了如何在弹出窗口中将值的有序列表显示为富文本元素,其中所有值都派生自 Arcade 表达式。要创建有序列表,请在 Arcade 表达式中执行以下操作:

  1. 使用 GroupBy 查询聚类内每种燃料类型的计数。

  2. 按总计数对类型进行排序。

  3. 遍历类型,并构建一个有序的 HTML 列表,其中显示具有要素数的类型。

  4. 将列表作为由 popupElement 规范定义的富文本元素返回。

全球发电厂。单击聚类,查看聚类内用于发电的所有类型燃料的列表。燃料类型显示为按计数排序的列表。

富文本形式的 HTML 列表

js
 let popupTemplate = {
    title: "Power plant summary",
    content: [
        {
            type: "text",
            text: "The following list describes the number of power plants used to generate power for each fuel type in this cluster."
        },
        {
            type: "expression",
            expressionInfo: {
                expression: `
                Expects($aggregatedFeatures, "fuel1")

                var statsFS = GroupBy($aggregatedFeatures,
                [
                { name: 'Type', expression: 'fuel1'},
                ],
                [ // statistics to return for each fuel type
                { name: 'num_features', expression: '1', statistic: 'COUNT' }
                ]
                );
                var ordered = OrderBy(statsFs, 'num_features DESC');

                var list = "<ol>";

                for (var group in ordered){
                list += \\<li>\\{group.Type} (\\{Text(group.num_features, "#,###")})</li>\\
                }
                list += "</ol>";

                return {
                type: "text",
                text: list
                }
                `,
                title: "Total Capacity List"
            }
        }
    ]
 };
字段表

此示例演示了如何将值的有序列表显示为字段弹出元素,其中所有值都派生自 Arcade 表达式。要创建字段元素,请在 Arcade 表达式中执行以下操作:

  1. 创建一个空 fieldsInfos 数组和一个空 attributes 字典。attributes 字典将包含要在弹出窗口中显示的计算值。

  2. 使用 GroupBy 对聚类中每种燃料类型的功率容量求和。

  3. 按总容量对类型进行排序。

  4. 遍历类型,并将每个类型添加为属性,将其总容量设置为属性的值。

  5. 将类型推送到 fieldsInfos 数组。

  6. 将列表作为由 popupElement 规范定义的字段内容元素返回。

全球发电厂。单击聚类,查看聚类内用于发电的所有类型燃料的表格。燃料类型按其总 mW 容量的顺序显示。

js
 let popupTemplate = {
    title: "Power plant summary",
    content: [
        {
            type: "text",
            text: "The following table describes the total megawatt capacity of power plants used to generate power for each fuel type in this cluster."
        },
        {
            type: "expression",
            expressionInfo: {
                expression: `
                    Expects($aggregatedFeatures, "fuel1", "capacity_mw")
                    var attributes = {};
                    var fieldInfos = [];

                    var statsFS = GroupBy($aggregatedFeatures,
                    [
                    { name: 'Type', expression: 'fuel1'},
                    ],
                    [ // statistics to return for each unique category
                    { name: 'capacity_total', expression: 'capacity_mw', statistic: 'SUM' }
                    ]
                    );
                    var ordered = OrderBy(statsFs, 'capacity_total DESC');

                    for(var f in ordered){
                    var type = f.Type;
                    attributes[type] = Text(f.capacity_total, "#,### mW");
                    Push(fieldInfos, {
                    fieldName: type
                    });
                    }

                    return {
                    type: "fields",
                    attributes: attributes,
                    fieldInfos: fieldInfos,
                    }
                    `,
                title: "Table of fuel types"
            }
        }
    ]
 };
饼图

此示例演示了如何将饼图创建为媒体弹出元素,其中饼图的所有值都派生自 Arcade 表达式。要创建饼图,请在 Arcade 表达式中执行以下操作:

  1. 创建一个空 fieldNames 数组和一个空 attributes 字典。attributes 字典将包含饼图中每个切片的值。

  2. 使用 Distinct 查找聚类中的每种燃料类型。

  3. 遍历类型,并将每个类型添加为属性,将其总计数设置为属性的值。

  4. 将类型推送到 fieldNames 数组。

  5. 返回字典,用于定义由 popupElement 规范定义的媒体内容元素。此元素必须包含属性和 piechart 对象,该对象包含要包含在图表中的 fieldNames 数组。

全球发电厂。单击聚类可查看饼图,该饼图对聚类中每种燃料类型的发电厂数量进行了可视化。

js
 let popupTemplate = {
    title: "Power plant summary",
    content: [{
        type: "expression",
        expressionInfo: {
            expression: `
                Expects($aggregatedFeatures, "fuel1")
                var attributes = {};
                var fieldNames = [];

                var types = Distinct($aggregatedFeatures, "fuel1");

                for(var t in types){
                var type = t.fuel1;
                Push(fieldNames, type);
                attributes[type] = Count(Filter($aggregatedFeatures, "fuel1 = @type" ));
                }

                return {
                type: "media",
                attributes: attributes,
                title: "Total power plants",
                mediaInfos: [{
                type: "piechart",
                value: {
                fields: fieldNames
                }
                }]
                }
                `,
            title: "Total Power Plants Pie Chart"
        }
    }]
 };

可视化

在可视化配置文件中,Arcade 允许您在运行时计算图层中每个要素的值,并将这些值用于数据驱动可视化。这是一种基于图层单个字段创建数据驱动可视化的替代方法。为了实现这一点,可以将 Arcade 表达式传递到 ClassBreaksRendererUniqueValueRenderer 中的 valueExpression 属性中或任何视觉变量 (color, size, opacity, and rotation) 中,而不是引用 field/normalizationField。您还可以使用 Arcade 在符号的 primitiveOverridesvalueExpressionInfo.expression 属性中覆盖 CIMSymbol 属性。

在 ClassBreaksRenderer 或任何视觉变量中使用时,表达式可以使用 $feature 访问要素的属性,并且必须计算为数字。表达式可以计算为 UniqueValueRenderer 中的字符串或数字。

在以下代码片段中,FeatureLayer 已添加到地图中。该服务具有三个字段,用于标识各郡县的共和党、民主党和独立/非党派选民的数量。我们可以编写一个 Arcade 表达式,以根据哪个政党的优势超过其他政党来为每个县着色。

首先,在具有唯一 ID 的脚本标记中编写 Arcade 表达式。

html
<script type="text/plain" id="winning-party">
    // Write the expression and reference the value
    // of each field with a meaningful variable name within
    // the expression. Then calculate the max number with
    // the Max() function and use Decode() to return a string
    // value representing the party whose field value matches
    // the max value.

    var republican = $feature.MP06025a_B;
    var democrat = $feature.MP06024a_B;
    var independent = $feature.MP06026a_B;
    var parties = [republican, democrat, independent];
    // Decode() and Max() are built-in Arcade functions
    return Decode( Max(parties),
        republican, 'republican',
        democrat, 'democrat',
        independent, 'independent',
        'n/a'
    );
</script>

然后在 UniqueValueRenderer 的 valueExpression 属性上使用 document.getElementById() 将表达式设置为字符串值。

js
// Assign the expression to the `valueExpression` property and
// set up the unique value infos based on the decode values
// you set up in the expression.

const winnerArcade = document.getElementById("winning-party").text;

const renderer = new UniqueValueRenderer({
    valueExpression: winnerArcade,
    valueExpressionTitle: "Counties by dominant party among registered voters",
    uniqueValueInfos: [{
        value: "democrat",
        symbol: createSymbol("#00c3ff"),
        label: "Democrat"
    }, {
        value: "republican",
        symbol: createSymbol("#ff002e"),
        label: "Republican"
    }, {
        value: "independent",
        symbol: createSymbol("#faff00"),
        label: "Independent/non-affiliated"
    }]
});

您还可以向渲染器添加不透明度视觉变量,以可视化每个县中优势政党的相对强度。单个政党人数较多的县将被绘制为高不透明度,而每个政党的人数比例相对相等的县将以低不透明度绘制。

首先,在 <script> 标记中编写表达式。

html
<script type="text/plain" id="strength">
    // Write the expression and reference the value
    // of each field with a meaningful variable name within
    // the expression. Then calculate the max number with
    // the Max() function and the total using Sum().
    // Calculate the share of the max population within the
    // county. This value will be between 33 - 100 and will
    // be used to determine the feature's opacity.
    // Note the value is explicitly returned; it could also
    // be implicitly returned like the previous example

    var republican = $feature.MP06025a_B;
    var democrat = $feature.MP06024a_B;
    var independent = $feature.MP06026a_B;
    var parties = [republican, democrat, independent];
    var total = Sum(parties);
    var max = Max(parties);

    return (max / total) \* 100;
</script>

然后在 JavaScript 中将其作为字符串值引用。

js
// Assign the expression to the `valueExpression` property and
// set up the unique value infos based on the decode values
// you set up in the expression.

const strengthArcade = document.getElementById("strength").text;

const opacityVV = {
    type: "opacity",
    valueExpression: strengthArcade,
    stops: [
        { value: 33, opacity: 0.1 },
        { value: 50, opacity: 1.0 }
    ]
};

// Add the visual variable to the renderer

renderer.visualVariables = [ opacityVV ];

表单

Arcade 以两种表单配置文件实现:

  • 表单约束 - 用于指示字段在表单中是否应可见、可编辑或是否为必需项。

  • 表单计算 - 用于根据其他字段的输入有条件地计算字段值。

表单约束

表单约束配置文件在 FeatureForm 微件中实现,允许您指示字段在编辑工作流期间是否可见、是否为必填项或可编辑。例如,您可以将某些字段配置为使用可见性 Arcade 表达式有条件地显示,而不是在各种字段配置中显示所有指定的字段。可见性表达式允许您使用 $feature 访问要素的属性,并且必须返回一个 Boolean 值。

表达式在 ExpressionInfo 对象的 expression 属性中定义。ExpressionInfos 是在 FormTemplate.expressionInfos 属性上设置的。要有条件地设置表单元素的可见性,必须在元素visibilityExpression 属性中引用该表达式的 name

此配置文件也在 requiredExpressioneditableExpression 属性中实现。这些属性允许您指示字段是必填字段还是可编辑字段。

在以下示例中,第二个字段配置显示标注为 "Issue status”的字段。如果 status 值为 Completed 并且 resolution 字段有值,则会显示第三个字段 resolution

js
const formTemplate = new FormTemplate({
    title: "Inspector report",
    description: "Enter all relevant information below",
    elements: [
        new FieldElement({
            fieldName: "inspector",
            label: "Inspector name"
        }),
        new FieldElement({
            fieldName: "status",
            label: "Issue status"
        }),
        new FieldElement({
            fieldName: "resolution",
            label: "Resolution",
            // expression defined below
            visibilityExpression: "resolutionVisible"
        })
    ],
    expressionInfos: [{
        name: "resolutionVisible",
        title: "Resolution if status is completed",
        expression: "$feature.status == 'Completed' && !IsEmpty($feature.resolution)"
    }]
});

表单计算

表单计算配置文件在 FeatureForm 微件中实现,允许您在编辑工作流期间有条件地计算字段值。您可使用 $feature 访问要素的属性、原始要素中的属性 ($originalFeature) 和编辑类型 ($editcontext.editType)。表达式必须返回 TextNumberDate 值。

表达式在 ExpressionInfo 对象的 expression 属性中定义。ExpressionInfos 是在 FormTemplate.expressionInfos 属性上设置的。要基于其他表单输入有条件地计算表单元素的值,必须在 FieldElementvalueExpression 属性中引用该表达式的 name

在以下示例中,第一个字段是根据要素的几何计算的。最后一个字段 FullName 将根据 InspectorFirstInspectorLast 的值进行计算。

js
const formTemplate = new FormTemplate({
    title: "Inspector report",
    description: "Enter all relevant information below",
    elements: [
        new FieldElement({
            fieldName: "Area",
            label: "Area (square meters)",
            // expression defined in expressionInfos
            valueExpression: "area"
        }),
        new FieldElement({
            fieldName: "InspectorFirst",
            label: "First Name"
        })
        new FieldElement({
            fieldName: "InspectorLast",
            label: "Last Name"
        })
        new FieldElement({
            fieldName: "FullName",
            label: "Full Name",
            // expression defined in expressionInfos
            valueExpression: "fullName"
        }),
    ],
    expressionInfos: [{
        name: "area",
        title: "Area (square meters)",
        expression: "Round(AreaGeodetic($feature, 'square-meters'), 2)"
    }, {
        name: "fullName",
        title: "Inspector full name",
        expression: `IIF(!IsEmpty($feature.InspectorFirst) && !IsEmpty($feature.InspectorLast)){
            return $feature.InspectorFirst + " " + $feature.InspectorLast;
            }`
    }]
});

要素排序

在 2D MapView 中,您可使用 Arcade 表达式来确定要素在视图中渲染的排序顺序。要素排序是在 FeatureLayerorderBy 属性中配置的。用于排序要素绘制顺序的表达式必须遵循要素 Z 配置文件规范。它们可以使用 $feature 引用属性,并且必须返回数字或日期值。

js
// Orders features by storm warning duration in descending order.
// Warnings with longer durations will be
// rendered on top of warnings with shorter durations.
layer.orderBy = [{
    valueExpression: "DateDiff($feature.Watch_End, $feature.Watch_Start, 'hours' )",
    order: "descending"
}];

Z 值

在 3D SceneView 中,您可使用 Arcade 表达式在要素上设置自定义 Z 值。尽管要素的几何中可以包含 Z 值,但您可能希望基于属性值来计算或替换它们,或者使用 Z 值从公式中获取该值。您也可能具有几何中不包含 Z 值,但将 Z 相关信息存储在属性字段中的要素。在这些情况下,可以在 featureExpressionInfo.expression 属性中设置表达式。用于覆盖 Z 值的表达式必须遵循要素 Z 配置文件规范。它们可以使用 $feature 引用属性,并且必须返回一个数字。例如,以下示例显示了如何使用 Arcade 更改点的 Z 值:

js
layer.elevationInfo = {
    mode: "absolute-height",
    featureExpressionInfo: {
        expression: "Geometry($feature).z + $feature.HEIGHT"
    },
    unit: "meters"
};

在以上示例中,字段属性 HEIGHT 被添加到几何的 Z 值,以设置最终图形的高程。对于折线或多边形要素,每个要素的所有折点都将使用从 expression 返回的相同 Z 值。