Select to view content in your preferred language

ArcGIS JavaScript Components - Update chart when selecting a feature.

1260
12
Jump to solution
04-10-2024 08:08 AM
dgreenin
New Contributor II

Good Morning,

I am currently working with ArcGIS JavaScript Components (beta). 

The current documentation shows how to highlight map features based on selections made within a chart component (ie. pie chart).

However, I would like to update the chart component (ie. pie chart) based on the selection of a feature within a feature layer on the map.

'Example: Feature layer contains county boundary polygons for a state and associated demographics for each county. Current pie chart shows demographics for entire feature layer (ie. state). Desired outcome would be to select an individuial county and update the pie chart to reflect demographics of that county only.'

There are currently no tutorials on how to do this. Is this possible using the current Components API (beta)?

0 Kudos
12 Replies
dgreenin
New Contributor II

Good Afternoon HaoyanChen,

I have continued testing to achieve the intial functionality I was in pursuit of.

Here is a detailed description of the problem/solution:

When initially configuring the format of pie charts within a web map, there are two choices for creating slices, 'Category' and 'Fields'.

  • 'Category' represents one field from a layer with each slice representing different unique value within the field.
  • 'Numeric' represents one or more numeric fields in a layer with each slice displaying the sum total of each individual numeric field.

The effort then becomes, how do you represent the 'Numeric' slices for a single feature within a layer rather than the sum of features for the entire layer. 

Through intitial testing, the selection functionality we have worked on didn't quite achieve this functionality.

My current solution is to introduce a definition query tied to the selection of an individual feature.

I have utilized your coding sample as a base for showing this functionality. I could use some assistance on clearing the definition query when selecting blank portion of the map.

 

 

 

<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Display a map using arcgis/map-components</title>

    <style>
        html,
        body {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #pie-chart {
            position: absolute;
            bottom: 30px;
            left: 30px;
            height: 40%;
            width: 50%;
        }
    </style>

    <!-- Load Map Components from CDN-->
    <link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css">
    <link rel="stylesheet" href="https://js.arcgis.com/4.29/@arcgis/core/assets/esri/themes/light/main.css">
    <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/2.5.1/calcite.css" />

    <script src="https://js.arcgis.com/4.29/"></script>
    <script type="module" src="https://js.arcgis.com/calcite-components/2.5.1/calcite.esm.js"></script>
    <script type="module" src="https://js.arcgis.com/map-components/4.29/arcgis-map-components.esm.js"></script>
    <script type="module" src="https://js.arcgis.com/charts-components/4.29/arcgis-charts-components.esm.js"></script>

</head>

<body>

    <arcgis-map item-id="9a043ed7a9ae42658459e4a5df9427e5"></arcgis-map>
    <arcgis-charts-pie-chart id="pie-chart">
        <arcgis-charts-action-bar slot="action-bar" disable-filter-by-selection="false"></arcgis-charts-action-bar>
    </arcgis-charts-pie-chart>

    <script type="module">

        const map = document.querySelector("arcgis-map");


        map.addEventListener("arcgisViewReadyChange", (event) => {
            const { map, view } = event.target;
            const layer = map.layers.find((layer) => layer.title === 'USA Census States');

            view.on("click", (event) => {
                queryFeatures(event);
            });

            function queryFeatures(event) {

                const layerQuery = {
                    geometry: event.mapPoint,
                    // distance and units will be null if basic query selected
                    spatialRelationship: "intersects",
                    returnGeometry: true,
                    outFields: ["STATE_ABBR"]
                };
                
                layer.queryFeatures(layerQuery)
                .then((results) => {

                const layerCount = results.features;
                layerCount.forEach((result) => {
                    const attributes = result.attributes;
                    const state = `${attributes.STATE_ABBR}`;
                    if (state.length > 0) {
                    layer.definitionExpression = `STATE_ABBR = '${state}'`;
                    } else {
                    // Insert code to clear definition query
                    }
                })
                
                }).catch((error) => {
                    console.log(error);
                });
            };
            const pieChartElement = document.getElementById("pie-chart");
            const pieChartConfig = layer.charts[1];
    
            pieChartElement.config = pieChartConfig;
            pieChartElement.layer = layer;
        });

    </script>

</body>

</html>

 

 

 

 

0 Kudos
HaoyanChen
Esri Contributor

Hi dgreenin,

I have modified the provided code below, please take a look and read thru the comments and let me know if this helped to achieve your initial goal. 

In the modified code, we first check if `layerCount.length > 0`. If it is, we proceed as before. If it's not (meaning we clicked on an empty part of the map), we clear the definition query by setting `layer.definitionExpression` to an empty string.

<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Display a map using arcgis/map-components</title>

    <style>
        html,
        body {
            padding: 0;
            margin: 0;
            height: 100%;
            width: 100%;
        }

        #pie-chart {
            position: absolute;
            bottom: 30px;
            left: 30px;
            height: 40%;
            width: 50%;
        }
    </style>

    <!-- Load Map Components from CDN-->
    <link rel="stylesheet" href="https://js.arcgis.com/4.29/esri/themes/light/main.css">
    <link rel="stylesheet" href="https://js.arcgis.com/4.29/@arcgis/core/assets/esri/themes/light/main.css">
    <link rel="stylesheet" type="text/css" href="https://js.arcgis.com/calcite-components/2.5.1/calcite.css" />

    <script src="https://js.arcgis.com/4.29/"></script>
    <script type="module" src="https://js.arcgis.com/calcite-components/2.5.1/calcite.esm.js"></script>
    <script type="module" src="https://js.arcgis.com/map-components/4.29/arcgis-map-components.esm.js"></script>
    <script type="module" src="https://js.arcgis.com/charts-components/4.29/arcgis-charts-components.esm.js"></script>

</head>

<body>

    <arcgis-map item-id="9a043ed7a9ae42658459e4a5df9427e5"></arcgis-map>
    <arcgis-charts-pie-chart id="pie-chart">
        <arcgis-charts-action-bar slot="action-bar" disable-filter-by-selection="false"></arcgis-charts-action-bar>
    </arcgis-charts-pie-chart>

    <script type="module">

        const map = document.querySelector("arcgis-map");


        map.addEventListener("arcgisViewReadyChange", (event) => {
            const { map, view } = event.target;
            const layer = map.layers.find((layer) => layer.title === 'USA Census States');

            view.on("click", (event) => {
                queryFeatures(event);
            });

            function queryFeatures(event) {

                const layerQuery = {
                    geometry: event.mapPoint,
                    spatialRelationship: "intersects",
                    returnGeometry: true,
                    outFields: ["STATE_ABBR"]
                };

                layer.queryFeatures(layerQuery)
                    .then((results) => {
                        const layerCount = results.features;
                        if (layerCount.length > 0) {
                            layerCount.forEach((result) => {
                                const attributes = result.attributes;
                                const state = `${attributes.STATE_ABBR}`;
                                if (state.length > 0) {
                                    layer.definitionExpression = `STATE_ABBR = '${state}'`;
                                }
                            });
                        } else {
                            // Clear definition query
                            layer.definitionExpression = '';
                        }

                    }).catch((error) => {
                        console.log(error);
                    });
            };
            const pieChartElement = document.getElementById("pie-chart");
            const pieChartConfig = layer.charts[1];

            pieChartElement.config = pieChartConfig;
            pieChartElement.layer = layer;
        });

    </script>

</body>

</html>

 

0 Kudos
dgreenin
New Contributor II

@HaoyanChen,

That works perfectly! Thank you!