Select to view content in your preferred language

ArcGIS JS API v4.24 Web Scene Widgets and Water Level Slider Issues

163
2
02-08-2025 08:36 AM
IB3
by
Regular Contributor

Hi Community,

I'm developing a water-level viewer using the ArcGIS JS API and encountering two significant issues. I'm currently using version 4.24, although I've tested with 4.31 but then my web scene doesn't load. 

1. Default UI Widgets Not Displaying:

I'm unable to display UI widgets (like Zoom, Home, Legend, and Navigation) in my web scene view. I've tried including the necessary modules in my require statement, including "esri/widgets/UI", "esri/widgets/UIDefault", and even tried individual widgets like "esri/widgets/Zoom".

Despite this, the widgets are not visible. I suspect the issue might be related to the API version (4.24). Could this be a compatibility issue?

2. Water Level Slider Not Affecting Water Body:

I'm using a slider to control the water level of a water body (feature layer) in my scene. However, the water level doesn't change when I adjust the slider. I suspect there's a problem with how I'm interacting with the DEM (Digital Elevation Model). I'm wondering if using a Living Atlas DEM might be restricting my ability to manipulate it. If someone has done something similar and can provide guidance on how to correctly implement a dynamic water level using a slider and a DEM, that would be nice. 

I've attached my full code for reference. Any insights or suggestions on these issues would be greatly appreciated.

Thank you for your time and assistance.

Isabelle

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Waterhoogte Viewer</title>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet">
    <script src="https://js.arcgis.com/4.24/"></script>
    
    
    <style>
     
       html, body {
            font-family: 'Roboto', sans-serif;
            height: 100vh;
            margin: 0;
            padding: 0;
            overflow: hidden; /* Prevents scrollbars */
        }

        #MapView {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            position: fixed;
            background-color: lightgrey;
        }

        #MapView .esri-view-surface,
        #MapView .esri-scene-view {
            height: 100vh !important;
        }

        #sidebar {
            position: fixed; /* Overlay the map */
            width: 20%;
            height: 42vh; /* Sidebar takes full viewport height */
            top: 0;
            left: 0;
            display: flex;
            flex-direction: column;
            z-index: 300; /* Ensure sidebar is on top */
            /* Add a background color to the sidebar so the map doesn't show through */
            background-color: rgba(255, 255, 255, 0.9); /* Example: Semi-transparent white */
        }


        /* Dark Blue Top Section of Sidebar */
        #sidebarHeader {
            /* background-color: #274659; */
            color: #274659;
            padding: 20px;
            font-size: 18px;
            font-weight: bold;
            flex: 0 0 0;
            text-align: left; 
            display: flex; /* Add flexbox layout */
            justify-content: space-between; /* Push button to the right */
            align-items: center; /* Vertically center the content */
            flex-direction: column;
        }
        #logo{
            color: #274659;
        }


        /* White Bottom Section of Sidebar */
        #sidebarContent {
            background-color: white;
            padding: 20px;
            flex: 1;
            text-align: center;
           
        }

        #sidebarContent .info-title {
            font-size: 11px;
            font-weight: normal;
            color: #45718C;
            text-transform: uppercase;
            margin-bottom: 10px;
            text-align: left;
        }
        #sidebarContent .description {
            font-size: 13.5px;
            margin-bottom: 20px;
            color: #45718C;
            text-align: left;
        }
        #sidebarContent .detailsButton {
            background-color: white;
            color: #45718C;
            border: 1px solid #45718C;
            padding: 10px;
            width: 100%;
            cursor: pointer;
            text-transform: uppercase;
            font-weight: bold;
            border-radius: 5px;
        }
        #sidebarContent .detailsButton:hover {
            background-color: #45718C;
            color: white;
        }
        #sidebarContent .divider {
            border-bottom: 1px solid #ddd;
            margin: 20px 0;
        }

    

        /* Dark blue box styling for the description */
        .darkBlueBox {
            background-color: #F2E085;
            color: black;
            padding: 20px;
            text-align: left;
            font-size: 13px;
            font-weight: normal;
            border-radius: 0px;
            margin-bottom: 20px;
            margin-top: 20px;
        }


        #infoButton {
            background-color: transparent; /* Make the button transparent */
            border: none; /* Remove default button border */
            padding: 0; /* Remove any padding to make the SVG fill the button */
            cursor: pointer; /* Change cursor on hover */
            width: 20px; /* Set the button width */
            height: 20px; /* Set the button height */
        }

        #infoButton svg {
            width: 100%; /* Make the SVG fill the button */
            height: 100%; /* Make the SVG fill the button */
        }


        /* Water Slider Styles */
        #sliderDiv {
            margin-top: 20px;
            width: 100%;
        }

        #waterSliderLabel {
            text-align: left;
            font-size: 18px;
            color: #45718C;
            margin-bottom: 5px;
        }

        /* Custom Slider Colors */
        #waterSlider {
            -webkit-appearance: none; /* Remove default appearance */
            width: 100%;
            height: 10px;
            background: #ddd; /* Background color of the track */
            border-radius: 5px; /* Rounded track */
            outline: none;
            transition: background 0.3s ease-in-out;
        }

        #waterSlider::-webkit-slider-runnable-track {
            width: 100%;
            height: 8px; /* Track height */
            background: #d3d3d3; /* Track color */
            border-radius: 5px;
        }

        #waterSlider::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 25px;
            height: 25px;
            background: #45718C; /* Thumb color */
            border-radius: 50%; /* Circular thumb */
            cursor: pointer;
            transition: background 0.2s ease;
            margin-left: -10px; /* Centers the thumb horizontally */
            margin-top: -10px; /* Adjusts vertical alignment */
        }

        #waterSlider::-webkit-slider-thumb:hover {
            background: #45718C; 
            box-shadow: 0 0 10px 4px rgba(39, 70, 90, 0.6);
        }

        #waterSlider::-moz-range-track {
            width: 100%;
            height: 8px; /* Track height */
            background: #d3d3d3; /* Track color */
            border-radius: 5px;
}

        #waterSlider::-moz-range-thumb {
            width: 20px;
            height: 20px;
            background: #8c4557; /* Thumb color */
            border-radius: 50%; /* Circular thumb */
            cursor: pointer;
            transition: background 0.2s ease;
            margin-left: -10px; /* Centers the thumb horizontally */
            margin-top: -6px; /* Adjusts vertical alignment */
        }

        #waterSlider::-ms-track {
            width: 100%;
            height: 10px; /* Track height */
            background: #d3d3d3; /* Track color */
            border-radius: 5px;
            border-color: transparent; /* Remove border color */
            color: transparent; /* Remove color */
            /* For better visibility of the track */
        }

        #waterSlider::-moz-range-thumb:hover {
            background: #3a5f6b; 
        }
        

            /* Popup Styles */
        .popup {
            display: none; /* Hidden by default */
            position: fixed;
            top: 32%;
            left: 18%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3);
            z-index: 1000;
            border-radius: 8px;
            width: 150px;
            text-align: left;
        }

        .popup-content {
            font-size: 13px;
            color: #274659;
        }

        .popup_details {
            display: none; /* Hidden by default */
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.3);
            z-index: 1000;
            border-radius: 8px;
            width: 500px;
            text-align: left;
        }

        .popup-content_details {
            font-size: 13px;
            color: #274659;
        }

        .close {
            position: absolute;
            top: 10px;
            right: 15px;
            font-size: 18px;
            cursor: pointer;
            color: #274659;
        }

        .close:hover {
            color: #45718C;
        }

    </style>
</head>
<body>

    <!-- Sidebar -->
    <div id="sidebar">
        <div id="sidebarHeader">
            WATERHOOGTE VIEWER
            <div id="logo"><svg width="60pt" height="60pt" version="1.1" viewBox="0 0 90 100" xmlns="http://www.w3.org/2000/svg">
                <path d="m15.016 78.445c2.4453-0.015624 4.7812-1.0312 6.4609-2.8047 0.875-0.92969 2.0898-1.4609 3.3633-1.4766 1.2812 0.035157 2.4961 0.55469 3.4062 1.4531 1.6719 1.6992 3.9492 2.6602 6.3359 2.6602s4.6641-0.96094 6.3359-2.6602c0.85547-0.96875 2.0742-1.5469 3.3711-1.5781 1.2969-0.039062 2.5469 0.45313 3.4609 1.375 1.7188 1.7109 4.0664 2.6445 6.4883 2.5781 2.4258-0.058594 4.7188-1.1133 6.3438-2.9141 1.0039-0.92188 2.3516-1.3711 3.7031-1.2383 1.3555 0.12891 2.5898 0.82812 3.3984 1.9258 3.3281 3.3438 8.7109 3.4648 12.191 0.26953 0.83594-1.125 2.1055-1.8516 3.5-1.9961 1.3945-0.14062 2.7852 0.30859 3.8281 1.25 1.7305 2.0352 4.2852 3.1953 6.9609 3.1562 2.3516-0.035156 4.5938-1.0039 6.2305-2.6992 0.86328-0.91016 2.0664-1.4219 3.3203-1.4102 1.2812 0.015624 2.5039 0.53125 3.4102 1.4297 3.3281 3.3438 8.7109 3.4648 12.191 0.26953 0.82422-0.76953 0.875-2.0664 0.11328-2.8984-0.76563-0.83594-2.0547-0.89844-2.8984-0.14844-1.8867 1.6992-4.7812 1.5938-6.5391-0.23047-1.6836-1.6562-3.9531-2.5859-6.3164-2.5742-2.375 0.011718-4.6406 0.97656-6.2891 2.6797-1.8008 1.8438-4.7539 1.8945-6.6055 0.10156-1.5742-1.8203-3.8086-2.9414-6.2148-3.0938-2.3984-0.15625-4.7656 0.66016-6.5586 2.2656-0.92187 1.2812-2.3906 2.0469-3.9609 2.0664-1.5742 0.019531-3.0664-0.70312-4.0156-1.9609-1.7188-1.7109-4.0664-2.6445-6.4883-2.5781-2.4258 0.058594-4.7148 1.1133-6.3438 2.9141-1.8398 1.7461-4.7344 1.6992-6.5195-0.10547-1.6719-1.6719-3.9414-2.5938-6.3008-2.5781s-4.6133 0.97656-6.2656 2.6602c-0.88672 1.0234-2.1758 1.6094-3.5312 1.6016-1.5859-0.074219-3.0664-0.82812-4.0508-2.0742-3.6016-2.9961-8.9062-2.6641-12.109 0.74609-0.89453 0.92188-2.1211 1.4336-3.4062 1.4336-1.2812 0-2.5117-0.51562-3.4062-1.4336-0.375-0.39844-0.89453-0.62891-1.4453-0.64453-0.55078-0.019532-1.0859 0.18359-1.4844 0.56641-2.6445 3.2969 3.7109 5.8164 6.3359 5.7109z" fill="#logo"/>
                <path d="m119.45 87.895c-0.37109-0.41016-0.89062-0.64844-1.4414-0.67578-0.55078-0.023438-1.0898 0.17188-1.4961 0.53906-1.8789 1.7109-4.7734 1.6094-6.5352-0.21875-1.6758-1.6719-3.9492-2.6055-6.3203-2.5859s-4.6289 0.99609-6.2734 2.6992c-1.8086 1.8242-4.7461 1.8711-6.6094 0.09375-1.5703-1.8281-3.8047-2.9492-6.2109-3.1055s-4.7695 0.66406-6.5664 2.2734c-0.92188 1.2734-2.3867 2.0352-3.9531 2.0586-1.5703 0.019532-3.0586-0.70312-4.0156-1.9492-3.3633-3.3945-8.8242-3.4805-12.289-0.19141-0.84375 1.0508-2.0938 1.6914-3.4414 1.7695-1.3516 0.074219-2.6641-0.42187-3.625-1.3633-1.7031-1.6914-4.0234-2.6133-6.4297-2.5664-2.3984 0.050781-4.6797 1.0703-6.3164 2.8281-1.8711 1.8516-4.8789 1.8359-6.7305-0.023438-1.6914-1.7148-3.9961-2.6836-6.3984-2.6797-2.4258 0.011719-4.7383 1.0234-6.3906 2.8047-0.89844 0.91016-2.125 1.4219-3.4062 1.4219-1.2734 0-2.5-0.51172-3.3984-1.4219-0.79688-0.80469-2.0859-0.82812-2.9062-0.054687-0.82422 0.77344-0.875 2.0664-0.12109 2.9062 1.6758 1.7734 4.0117 2.7734 6.4492 2.7695 2.4414-0.003906 4.7656-1.0195 6.4297-2.8047 0.875-0.92969 2.0898-1.4609 3.3711-1.4648 1.2812 0.023437 2.5 0.54688 3.4102 1.4453 1.6641 1.7109 3.9453 2.6758 6.3359 2.6758 2.3867 0.003906 4.6719-0.96094 6.3281-2.6758 0.88672-1 2.1562-1.5859 3.4883-1.5938 1.2617-0.019532 2.4766 0.48047 3.3555 1.3789 1.7148 1.7148 4.0586 2.6484 6.4844 2.5898 2.4297-0.058594 4.7266-1.1133 6.3516-2.9141 1.0039-0.91406 2.3516-1.3633 3.6992-1.2344 1.3555 0.12891 2.5898 0.82812 3.3945 1.9258 3.3359 3.3438 8.7188 3.4648 12.199 0.27344 0.82812-1.1367 2.1016-1.8633 3.5-2.0117 1.3984-0.14062 2.7891 0.32031 3.8281 1.2656 1.6289 1.9062 3.9844 3.0352 6.4883 3.1211 2.5039 0.085937 4.9297-0.88672 6.6797-2.6758 0.89453-0.89844 2.1094-1.4062 3.375-1.3984 1.2695 0.003906 2.4805 0.51562 3.3633 1.4258 3.3359 3.3438 8.7148 3.4688 12.199 0.26953 0.84375-0.76953 0.90625-2.0859 0.12891-2.9297z" fill="#logo"/>
                <path d="m27.52 69.082c2.4297-3.3242 6.8359-5.1719 11.051-6.1719h-0.003906c-3.4414-0.60547-6.9805-0.17578-10.176 1.2461-0.62109 0.32031-1.3633 0.30469-1.9688-0.039062-3.2617-1.4492-6.8711-1.9062-10.387-1.3086 4.3398 1 8.9492 2.8438 11.484 6.2734z" fill="#logo"/>
                <path d="m57.258 43.613c1.4531-3.8203 5.1914-6.75 8.9688-8.8438-3.4688 0.33984-6.7617 1.7109-9.4492 3.9258-0.51172 0.46094-1.2188 0.64063-1.8906 0.47656v0.003906c-3.5195-0.51562-7.1094 0.003907-10.34 1.4961 4.3984-0.16016 9.3633 0.32031 12.711 2.9453z" fill="#logo"/>
               </svg>
            </div>
        </div>
        
        <!-- Dark Blue Box with description -->
        <div class="darkBlueBox">
            Breng snel in beeld welke gebieden overstromen en optimaliseer de gebiedsinrichting voor weidevogels.
        </div>

        <div id="sidebarContent">
            <div class="info-title"></div>
            <div class="description">GROND ONDER 8,0 METER WATER</div>
            <button class="detailsButton">EXTRA INFORMATIE</button>
            <div class="divider"></div>
            <div class="info-title">WATERHOOGTE
                <button id="infoButton" onclick="openPopup()"><svg width="100%" height="100%" version="1.1" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
                    <path d="m106.66 64c0 23.566-19.102 42.664-42.664 42.664-23.566 0-42.664-19.102-42.664-42.664 0-23.566 19.102-42.664 42.664-42.664 23.566 0 42.664 19.102 42.664 42.664zm10.672 0c0 29.457-23.879 53.336-53.336 53.336s-53.336-23.879-53.336-53.336 23.879-53.336 53.336-53.336 53.336 23.879 53.336 53.336zm-58.672-26.664c0-2.9453 2.3906-5.3359 5.3359-5.3359s5.3359 2.3906 5.3359 5.3359v32c0 2.9453-2.3906 5.3281-5.3359 5.3281s-5.3359-2.3867-5.3359-5.3281zm0 53.328c0-2.9453 2.3906-5.3281 5.3359-5.3281s5.3359 2.3867 5.3359 5.3281c0 2.9453-2.3906 5.3359-5.3359 5.3359s-5.3359-2.3906-5.3359-5.3359z" fill="#f29e04" fill-rule="evenodd"/>
                </svg>   
                </button>
            </div>

                     <!-- Popup details button content-->
            <div id="popup_details" class="popup_details">
                <div class="popup-content_details">
                    <H3>Ttile</H3>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
                    <span class="close" id="closePopupDetails">&times;</span>
                </div>
            </div>

                    <!-- Popup info button content-->
            <div id="popup" class="popup">
                <div class="popup-content">
                    <p>De waterhoogte getoond is gebaseerd op het NAP.</p>
                    <span class="close" id="closePopup">&times;</span>
                </div>
            </div>

             <!-- Water Level Slider -->
             <div id="sliderDiv">
                <div id="waterSliderLabel"> <span id="waterLevelValue">0 m</div>
                <input type="range" id="waterSlider" min="0" max="8" step="0.1" value="0">
            </div>

        </div>
    </div>
    <div id="MapView"></div>
  
    <!-- Script -->
    <script>

        require([
            "esri/WebScene",
            "esri/views/SceneView",
            "esri/layers/FeatureLayer",
            "esri/layers/ImageryLayer",
            "esri/widgets/Slider",
            "esri/widgets/Zoom",
            "dojo/domReady!"
        ], function (WebScene, SceneView, FeatureLayer, ImageryLayer, Zoom, Slider) {

            /***********************************
             * Create the WebScene
             ***********************************/
        // Load a webscene
        const scene = new WebScene({
            portalItem: {
                id: "1c7d3fb71e2c4e439e6a2eda7aa94549"  // Your WebScene ID
            }
        });

        /***********************************
         * Create the SceneView
         ***********************************/
        const view = new SceneView({
            container: "MapView",  // ID of the div where the scene will be rendered
            map: scene
        });

        /***********************************
         * Add additional layers
         ***********************************/
         view.when(() => {
            view.popupEnabled = false; // Disable popups
            
            // Create the Zoom widget
            const zoom = new Zoom({
                view: view
            });
            
            // Add the Zoom widget to the top-right of the view
            view.ui.add(zoom, "top-right");
            });

        // Add a FeatureLayer (e.g., for the waterbody layer)
        const waterLayer = new FeatureLayer({
            url: "https://services6.arcgis.com/CCjY1EiGjW8RjsOP/arcgis/rest/services/Waterbody/FeatureServer"
        });

        // Add the ImageryLayer for AHN4 DEM
        const demLayer = new ImageryLayer({
            url: "https://ahn.arcgisonline.nl/arcgis/rest/services/Hoogtebestand/AHN4_DTM_50cm/ImageServer"
        });

        // Add the layers to the WebScene
        scene.addMany([waterLayer, demLayer]);

        /***********************************
         * Add the Water Slider UI
         ***********************************/
        const waterSlider = document.getElementById('waterSlider');
        const waterLevelValue = document.getElementById('waterLevelValue');

        // Add event listener to adjust water level based on slider
        waterSlider.addEventListener('input', function () {
            const value = waterSlider.value;
            waterLevelValue.textContent = `${value} m`;

            // Now apply the mask for areas below the water level
            const waterLevel = value;

            // Update the DEM layer with a new renderer to simulate water level effect
            const waterMaskExpression = `AHN4_DTM_50cm <= ${waterLevel}`;  // Submerged areas (below water level)

            // Create a renderer to visualize submerged areas (e.g., blue for submerged)
            demLayer.renderer = {
                type: "simple",
                symbol: {
                    type: "simple-fill", // A fill symbol for visualizing the submerged areas
                    color: [0, 0, 255, 0.5], // Semi-transparent blue color for water
                    style: "solid",
                    outline: {
                        color: [255, 255, 255, 0.8],
                        width: 1
                    }
                },
                visualVariables: [{
                    type: "color",
                    field: "AHN4_DTM_50cm",  // Field with terrain height
                    stops: [
                        { value: waterLevel, color: [0, 0, 255, 0.5] },  // Below water level
                        { value: 0, color: [0, 0, 0, 0] }  // Above water level, no color
                    ]
                }]
            };

            // Optionally, apply a definition expression to further filter out submerged areas
            demLayer.definitionExpression = waterMaskExpression;
        });

    }, function (error) {
        console.error("WebScene failed to load:", error);
    });

        // Info Button - Show/Hide Popup
        const infoButton = document.getElementById("infoButton");
        const popup = document.getElementById("popup");
        const closePopup = document.querySelector(".popup .close");

        infoButton.addEventListener("click", function () {
            popup.style.display = "block"; // Show the popup
        });

        closePopup.addEventListener("click", function () {
            popup.style.display = "none"; // Close the popup
        });

        // Details Button - Show/Hide Details Popup
        const detailsButton = document.querySelector(".detailsButton");
        const popupDetails = document.getElementById("popup_details");
        const closeDetails = document.querySelector(".popup_details .close");

        detailsButton.addEventListener("click", function () {
            popupDetails.style.display = "block"; // Show the details popup
        });

        closeDetails.addEventListener("click", function () {
            popupDetails.style.display = "none"; // Close the details popup
        });

        
            

    </script>

</body>
</html>

 

0 Kudos
2 Replies
Sage_Wall
Esri Contributor

Hi @IB3 ,

It looks like you've forgotten to include the JS SDK CSS Tag

<link rel="stylesheet" href="https://js.arcgis.com/4.24/esri/themes/light/main.css" />

 You also have the names for your slider and zoom widgets in the wrong order in the require statement.  The class imports and the variable names need to be in the same order.  domReady is unnecessary with the 4.x api.  Try making these changes I hope your app will work correctly, I did noticed a lot of layer and web scene errors in the console.  I'd make sure you can open the web scene without any errors outside the app and that all the layers load correctly inside it.  Hope this helps, this looks like an awesome app 🙂

require([
            "esri/WebScene",
            "esri/views/SceneView",
            "esri/layers/FeatureLayer",
            "esri/layers/ImageryLayer",
            "esri/widgets/Slider",
            "esri/widgets/Zoom",
        ], function (WebScene,
            SceneView,
            FeatureLayer,
            ImageryLayer,
            Slider,
            Zoom
         ) {

 

0 Kudos
IB3
by
Regular Contributor

Thanks, UI works! Now, I need to solve the water slider issue and the apps is finished 🙂

0 Kudos