Map Marker Tooltip immediately disappearing on mobile devices

Hello,

I have a syncfusion map in my ASP.NET Core website. This map has markers which then have tooltips. On desktop devices they work as intended: hover over the marker and the tooltip shows up. On mobile it should stay there after clicking on it, but it disappears very quickly. It's less than a second. 

When clicking on it, it looks like there's a map refresh. Is there any way to make the tooltip stay on the refresh? Even when disabling my own refreshes (which are required for the site to properly function), there still seems to be a built-in refresh which causes the tooltip to disappear.

Could someone assist me in making this work?

Here's the code to my map:


        var tooltip = new MapsTooltipSettings
        {
            Visible = true,
            ValuePath = "name,description",
            Format = "<b>${name}</b><br />Letzte Positionsänderung:<br/>${description}",
            TextStyle = new MapsFont
            {
                FontFamily = "inherit"
            }
        };


<ejs-maps id="maps" load="window.onMapLoad" loaded="onCreated" markerClick="onMarkerClick" centerPosition="CenterPosition" class="vh-80" useGroupingSeparator="true">
    <e-maps-zoomsettings zoomFactor="@InitialZoom" maxZoom="18" minZoom="2" enable="true" DoubleClickZoom="true" MouseWheelZoom="true" PinchZooming="false" ></e-maps-zoomsettings>
    <e-maps-layers>
        <e-maps-layer layerType="@Syncfusion.EJ2.Maps.ShapeLayerType.OSM" markerClusterSettings="cluster">
            <e-layersettings-markers>
                <e-layersettings-marker visible="true" template="#template" tooltipSettings="tooltip" dataSource="data">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateSelected" tooltipSettings="tooltip">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateStart">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateEnd">
                </e-layersettings-marker>
            </e-layersettings-markers>
        </e-maps-layer>
    </e-maps-layers>
</ejs-maps>

Here are the JS functions relevant to the markers. All the other functions don't do much except trigger map refreshs (which like already mentioned are not responsible for the issue):

connection.on("ReceivePosition", (vehicle, position) => {
    if (!maps || !maps.layersCollection || !maps.layersCollection[0] || !markerLayers || markerLayers.vehicles === undefined) {
        return;
    }


    let markers = maps.layersCollection[0].markerSettings[markerLayers.vehicles];
    if (markers && markers.dataSource) {
        let dataSource = markers.dataSource;
        let marker = dataSource.find((element) => element && element.name === vehicle);
        if (marker && position) {
            marker.longitude = position.longitude;
            marker.latitude = position.latitude;
            // set marker description to position.timestamp in format dd.MM.yyyy hh:mm:ss
            if (position.timestamp) {
                var timestamp = new Date(position.timestamp);
                marker.description = timestamp.toLocaleDateString('de-CH') + ' ' + timestamp.toLocaleTimeString('de-CH');
            }
            //console.log("Update marker for " + vehicle + ":" + marker.longitude + " / " + marker.latitude + " " + marker.description);


            //Remove the marker and add it again to force a refresh
            let markerIndex = dataSource.indexOf(marker);
            if (markerIndex !== -1) {
                dataSource.splice(markerIndex, 1, marker);
                if (maps.dataBind) {
                    maps.dataBind();
                }


                if (selectedVehicleNumber == vehicle && selectMarkerByVehicle) {
                    selectMarkerByVehicle(vehicle);
                }


                if (runMapRefresh) {
                    runMapRefresh(10000);
                }
            }
        }
    }
});


function selectMarkerByVehicle(vehicle) {
    // Update the custom selection template based on your logic
    let markers = maps.layersCollection[0].markerSettings[markerLayers.vehicles];
    let selectedMarkers = maps.layersCollection[0].markerSettings[markerLayers.selectedVehicles];
    selectedMarkers.dataSource = [];
    for (var i = 0; i < markers.dataSource.length; i++) {
        var marker = markers.dataSource[i];
        if (vehicle != null) {
            var markerElement = document.querySelector('[data-vehicle="' + vehicle + '"].marker-unselected');
            if (markerElement) {
                if (marker.name === vehicle) {
                    //clone the marker and add it to the selected markers
                    let selectedMarker = Object.assign({}, marker);
                    marker.visible = false;
                    selectedMarkers.dataSource = [selectedMarker];
                } else {
                    marker.visible = true;
                }
            }
        }
        else {
            marker.visible = true;
        }
    }
}
function onMarkerClick(args) {
    console.log("Marker clicked: " + args.value + " data: "+JSON.stringify(args.data));
    if (args.marker.template !== "#templateStart" && args.marker.template !== "#templateEnd") {
        if (args && args.data) {
            const marker = args.data;
            if (marker.name) {
                console.log("Marker clicked: " + marker.name);
                //Find element in vehicle list and select it's item
                const vehicleListElements = document.getElementById('vehicleList').ej2_instances[0];
                const dataSource = vehicleListElements.dataSource;
                const item = dataSource.find((element) => element.Number == marker.name);
                vehicleListElements.value = item.Id;
                selectVehicle({ itemData: { Id: item.Id, Number: item.Number } });
            }
        }
    }
}

11 Replies

IR Indumathi Ravi Syncfusion Team August 13, 2024 12:50 PM UTC

Hi Patrik,


You can adjust the tooltip duration in mobile mode by setting the "Duration" property within "tooltipSettings." By default, the tooltip duration is set to 2000 milliseconds, which means it will disappear within the given time in mobile mode. If you set the duration to 0, the tooltip will not be removed automatically and will only disappear after the next interaction. This allows you to achieve the desired behavior. Please find the code snippet for the same below.


Code Snippet:

@{

    var tooltip = new MapsTooltipSettings

    {

        Visible = true,

        ValuePath = "city",

        Duration = 0,

        Format = "Name: ${city}<br />Latitude: ${latitude} <br/> Longitude: ${longitude}",

        TextStyle = new MapsFont

        {

            FontFamily = "inherit"

        }

    };

}

<ejs-maps id="maps" centerPosition="CenterPosition" useGroupingSeparator="true">

    <e-maps-layers>

        <e-maps-layer urlTemplate=https://tile.openstreetmap.org/level/tileX/tileY.png>

            <e-layersettings-markers>

                <e-layersettings-marker visible="true" template="#template" tooltipSettings="tooltip" dataSource="data">

                </e-layersettings-marker>

            </e-layersettings-markers>

        </e-maps-layer>

    </e-maps-layers>

</ejs-maps>


You can find the sample that demonstrates the same from the below link.

Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/CoreMaps-944561927

Video: https://www.syncfusion.com/downloads/support/directtrac/general/ze/maps-46547328


NOTE: In the provided code snippet, some variables are missing, which prevents us from making the sample runnable. As a result, we have assumed our own values and demonstrated the scenario using a single marker.


Please let us know if you need any further assistance.



PA Patrik Ackermann August 13, 2024 01:16 PM UTC

This solution did not work. I updated to the latest version to get the Duration feature but setting it to 0 or a high value like 10000 did not work. As already mentioned it seems to be a refresh or something that's happening. I disabled all of my own refreshes and it still happens.

I added a video to the reply so you see what's happening on my end.


Attachment: videomaptooltip_69d3d1f0.zip


IR Indumathi Ravi Syncfusion Team August 14, 2024 03:18 PM UTC

Hi Patrik,


When we attempted to reproduce the reported scenario by displaying the tooltip over the marker template element, the tooltip rendered as expected with the “Duration” property set to 0 and to greater values. You can view the video below, where we tried to replicate the reported issue:


https://www.syncfusion.com/downloads/support/directtrac/general/ze/Tested_Video-925064049


To help us replicate the issue more accurately, could you please provide the following details?

1. What type of tooltip is used in your application? Is it the default tooltip or a tooltip template? Note that the "Duration" property is supported only for the default tooltip.

2. You mentioned that the refresh method is not called anywhere in your application. However, we observed that the tile images of the online maps are refreshed. Are there any property changes in the Maps component at this instance or UI interactions like zoom on click?

3. Are any events assigned to the Maps component?

4. Can you confirm if any properties are being altered elsewhere that might affect the tooltip behavior?

5. On which mobile device was the testing performed?


Alternatively, if possible, please modify the previously shared sample code to replicate the reported issue. This will help us analyze the problem more effectively and provide you with better assistance.



PA Patrik Ackermann replied to Indumathi Ravi August 19, 2024 03:18 PM UTC

  1. The marker is using templates which are seen below. The tooltip seems to be default (as seen at the top in the original post). Here are the marker templates:
  2. <div id='template' style="display:none" type="text/x-jsrender">
        ${if(visible === true)}
        <div class="shadow-lg rounded border border-1 border-primary p-1 map-marker-box marker-template marker-unselected marker-{{:type}}" data-vehicle="{{:name}}">
            <p class="text-center pb-0 mb-0">
                <i class="fa-duotone {{:icon}} fa-xl map-marker-icon marker-{{:type}}"></i><br />
                <strong>{{:name}}</strong>
            </p>
        </div>
        ${else}
        <div class="shadow-lg rounded border border-1 border-primary p-1 map-marker-box marker-template marker-unselected d-none marker-{{:type}}" data-vehicle="{{:name}}">
            <p class="text-center pb-0 mb-0">
                <i class="fa-duotone {{:icon}} fa-xl map-marker-icon marker-{{:type}}"></i><br />
                <strong>{{:name}}</strong>
            </p>
        </div>
        ${/if}
    </div>
    <div id='templateSelected' style="display:none" type="text/x-jsrender">
        <div class="shadow-lg rounded border border-3 border-primary p-1 map-marker-box marker-template marker-selected marker-{{:type}}" data-vehicle="{{:name}}">
            <p class="text-center pb-0 mb-0">
                <i class="fa-duotone {{:icon}} fa-xl map-marker-icon marker-{{:type}}"></i><br />
                <strong>{{:name}}</strong>
            </p>
        </div>
    </div>
    <div id='templateStart' style="display:none">
        <div class="shadow-lg rounded border border-1 border-primary p-1 map-marker-box marker-template">
            <p class="text-center pb-0 mb-0">
                <i class="fa-duotone fa-map-pin fa-xl map-marker-icon"></i>
            </p>
        </div>
    </div>
    <div id='templateEnd' style="display:none">
        <div class="shadow-lg rounded border border-1 border-primary p-1 map-marker-box marker-template">
            <p class="text-center pb-0 mb-0">
                <i class="fa-duotone fa-flag-checkered fa-xl map-marker-icon"></i>
            </p>
        </div>
    </div>
  3. There is a centerPosition and zoom upon selecting a marker to focus on it. Code (from selectVehicle() in the main post):
    maps.centerPosition = { latitude: marker.latitude, longitude: marker.longitude };
    maps.zoomSettings.zoomFactor = 10;
  4. There isn't any events outside of the initial map loading and some unregular updates from the API. So nothing that triggers when choosing a marker or anything.

  5. I wasn't able to find anything in our codenbase.

  6. The error is occurring on chrome/edge dev tools mobile mode, on my android phone with edge/firefox, and on our customers phones with unknown info. So it seems to be happening universally.



IR Indumathi Ravi Syncfusion Team August 20, 2024 05:37 PM UTC

Hi Patrik ,


Upon analyzing the provided details, we observed that the centerPosition and zoomFactor properties are used to change the center position (focus) of the map. This property changes updates the map control, causing the center position to shift to the marker's location while the mouse pointer remains in the same place. As a result, the tooltip is not updated and is removed. This is the current behavior in the Maps component.


Please provide detailed information about your requirements, and we will analyze them to offer a suitable solution.



PA Patrik Ackermann replied to Indumathi Ravi August 21, 2024 09:01 AM UTC

We require the map to be centered and zoomed upon clicking the marker. On mobile devices the tooltip has to stay there so the user can read the data inside of it. Maybe there is some way of reversing the order of the actions so it is centered first and then the tooltip is displayed? 

I already tried this myself in a custom javascript approach without any success. It wouldn't be an ideal solution anyways though: Wait for center/zoom, get element, click it with javascript. For some reason the markerClick function isn't called on my js click, only the user click. I verified that it is the same element that's being clicked.



IR Indumathi Ravi Syncfusion Team August 22, 2024 06:19 PM UTC

Hi Patrik,


We validated the provided scenario and modified our source code to display the tooltip when the centerPosition and zoomFactor properties change. When a marker is clicked, its position is updated to the center position of the map. However, when this position changes, the tooltip—which is shown based on the click event argument—may not update correctly. As a result, the tooltip appears at its previous location based on the mouse pointer's position. You can see this behavior in the video below.

https://www.syncfusion.com/downloads/support/directtrac/general/ze/maps_tooltip-1705568966


However, the tooltip is designed to display details only during interaction with the marker, not programmatically. This is the intended behavior of the tooltip in the Maps component. Consequently, we cannot update the tooltip’s position when focused on the marker. Instead, you can use annotation features to display the required values. Please find the code snippet for this approach below.


Code Snippet:

@{

    var CenterPosition = new MapsCenterPosition { Latitude = 40.7489, Longitude = -73.9680 };

    var tooltip = new MapsTooltipSettings

            {

                Visible = true,

                ValuePath = "name",

                Duration = 0,

                Format = "Name: ${name}<br />Latitude: ${latitude} <br/> Longitude: ${longitude}",

                TextStyle = new MapsFont

                {

                    FontFamily = "inherit"

                }

            };

 

    var shapeBorder = new Syncfusion.EJ2.Maps.MapsBorder

            {

                Width = 1,

                Color = "#000000",

                Opacity = 1

            };

 

    var data = new[]

           {

       new {latitude= 37.0000, longitude= -120.0000, name= "California" },

       new {latitude= 40.7127, longitude= -74.0059, name= "New York" },

       new {latitude= 42.0000, longitude= -93.0000, name= "Iowa" }

    };

}

 

<ejs-maps id="maps" centerPosition="CenterPosition" useGroupingSeparator="true" zoomComplete="zoom" loaded="onCreated" click="window.click" markerClick="window.markerClick">

  

    //..

   //..

    <e-maps-annotations>

        <e-maps-annotation content="#annotationContent" x="37%" y="35%" zIndex="1"></e-maps-annotation>

    </e-maps-annotations>

</ejs-maps>

 

<div id="annotationContent" style="display:none;">

    <div id="tooltipContent" style="background-color: black; border: 1px solid black; color:white; padding: 10px;width:130px;height:110px;display:none;">

        <p id="tooltipName"></p>

        <p id="tooltipLatitude"></p>

        <p id="tooltipLongitude"></p>

    </div>

</div>

 

<script>

    var maps;

    var zoomFactor = 10;

    function onCreated() {

        maps = document.getElementById('maps').ej2_instances[0];

    }

    function click(args) {

        document.getElementById('tooltipContent').style.display = 'none';

    }

 

    function zoom(args) {

        document.getElementById('tooltipContent').style.display = 'none';

    }

 

    function markerClick(args) {

        var centerPosition = { latitude: args.latitude, longitude: args.longitude };

        maps.zoomByPosition(centerPosition, zoomFactor);

        document.getElementById('tooltipContent').style.display = 'block';

        document.getElementById('tooltipName').innerText = "Name: " + args.data.name;

        document.getElementById('tooltipLatitude').innerText = "Latitude: " + args.data.latitude;

        document.getElementById('tooltipLongitude').innerText = "Longitude: " + args.data.longitude;

        var tooltipContent = document.getElementById('annotationContent').innerHTML;

        maps.annotations[0].content = tooltipContent;

        var x = (((args.longitude + 180) / 360) * 100);

        var y = (((90 - args.latitude) / 180) * 100);

        maps.annotations[0].x = (x + 25).toString() + ' %';

        maps.annotations[0].y = (y - 5).toString() + ' %';

    }

</script>


You can find the sample that demonstrates the same from the below link.

Sample: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Maps-2106000861

Video: https://www.syncfusion.com/downloads/support/directtrac/general/ze/maps-1156528986


Please let us know if you need any further assistance.



CH Chris August 27, 2024 01:34 PM UTC

We were able to keep the implementation with the Tooltip by delaying the Zoom and Map refresh for a couple Seconds. Now the Problem we are facing is that the duration Property doesn't change anything on the Tooltip and it doesn't seem to take effect. 

When we checked the tooltip duration in the tooltipRenderComplete event it always returned 300 as value and changing it didn't actually change the duration it is displayed. Example of when we set Duration to 0 is attached as video.



This is how we configured the Tooltip and the Map: 

var tooltip = new MapsTooltipSettings
{
    Visible = true,
    ValuePath = "name,description",
    Duration = 0,
    Format = "<b>${name}</b><br />Letzte Positionsänderung:<br/>${description}",
    TextStyle = new MapsFont
    {
        FontFamily = "inherit"
    }
};

<ejs-maps id="maps" load="window.onMapLoad" loaded="onCreated" markerClick="onMarkerClick" centerPosition="CenterPosition" class="vh-80" useGroupingSeparator="true">
    <e-maps-zoomsettings zoomFactor="@InitialZoom" maxZoom="18" minZoom="2" enable="true" DoubleClickZoom="true" MouseWheelZoom="true" PinchZooming="false" ></e-maps-zoomsettings>
    <e-maps-layers>
        <e-maps-layer urlTemplate="http://a.tile.openstreetmap.org/level/tileX/tileY.png" markerClusterSettings="cluster">
            <e-layersettings-markers>
                <e-layersettings-marker visible="true" template="#template" tooltipSettings="tooltip" dataSource="data">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateSelected" tooltipSettings="tooltip">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateStart">
                </e-layersettings-marker>
                <e-layersettings-marker visible="true" template="#templateEnd">
                </e-layersettings-marker>
            </e-layersettings-markers>
        </e-maps-layer>
    </e-maps-layers>
</ejs-maps>

Attachment: DurationNotWorking_2a12e67e.zip


IR Indumathi Ravi Syncfusion Team August 28, 2024 04:47 PM UTC

Hi Patrik,


We have tested the reported scenario by setting a 4000-millisecond delay for focusing the marker and a 2000-millisecond for “Duration” property of the “MapsTooltipSettings” class. As a result, the tooltip is removed after 2 seconds, and the marker is then focused after next 2 seconds. This confirms that the duration property is working as expected.


Since you have set the duration property to 0, the tooltip will not be removed until the next interaction or property change. In your case, the tooltip disappears when the marker is focused (which is a property change), as this change triggers the tooltip's removal. This is the intended behavior.


You can find a video demonstrating our attempt to reproduce the reported scenario at the link below.


https://www.syncfusion.com/downloads/support/directtrac/general/ze/maps_tooltip-908011926


Meanwhile, if you need to display content after focusing the marker, as mentioned in our previous update, you should use the annotation feature. This approach offers a more persistent display option for the information you want to show.


Please let us know if you need any further assistance.



CH Chris August 30, 2024 12:50 PM UTC

No, the duration does not work as intended in our Case. No Matter what value we set the "Duration" to, it disappeared after only two seconds, WE tested this by settings the Delay for the focus to over 10 Seconds. The behaviour of our tooltip didn't change even when we manually set the Duration to over 2000 ms or set it to 0, it always just disappeared after 2 Seconds. 



MA Maryline Atieno Nyanjong’ Syncfusion Team September 2, 2024 11:16 AM UTC

Hi Chris,

We have created a ticket under your account, please follow further updates in the ticket.

Regards,

Maryline A.



Loader.
Up arrow icon