Map on leaflet with popup next to key

I am facing a scenario where I have a map with a unique legend that is styled either as an SVG or a PNG. The legend is always positioned in the bottom left corner but can be quite large, as users have the option to toggle it on and off.

Additionally, the map contains numerous markers, each with a tooltip that can also be sizable. These tooltips are displayed when the mouse hovers over a marker. The issue arises when a user hovers over a marker close to the legend - the tooltip ends up hidden behind the legend. I aim to solve this problem by ensuring that the popups appear above the legend in the following order: marker, legend, marker popup.

You can see a demonstration of this situation on a JSFiddle https://jsfiddle.net/e51mydwa/9/. The legends are added in a similar manner, although the actual < div id="legend"> tag holds an < img> or < svg>.

<div id="map">
  <div id="legend">
    I am Legend
  </div>
</div>

I've reviewed the example at http://leafletjs.com/examples/choropleth/, but upon inspecting the DOM, I noticed that it encounters the same issue. This is because the legend is inserted into the same div as the leaflet controls, which are always positioned above the map layers (as expected, controls should always be on top).

Moreover, I attempted placing the legend within a div on a sibling layer to the popup-containing layer. Although this resolved the z-index problem, the parent div of both these elements includes a transform that changes as users drag the map around, causing the legends to move as well and lose their static position.

I welcome any suggestions or ideas to address this matter.

Answer №1

To achieve this customization, significant hacking is necessary due to the structure of the Leaflet layers and controls.

One method to consider is creating a specialized layer class that remains stationary by adjusting its pixel offset whenever the map's view changes.

I strongly suggest delving into the Leaflet tutorials, specifically those on map panes and custom layers, to gain a better grasp of this concept.

// Establish a 'static' map pane
L.Map.addInitHook(function(){
  this.createPane('static');
  this.getPane('static').style.zIndex = 675;
});

// Develop a custom layer class
L.Layer.StaticOverlay = L.Layer.extend({
  onAdd: function(map) {
    this._map = map;

    var pane = map.getPane('static');
    this._container = L.DomUtil.create('div');

    pane.appendChild(this._container);

    // styling, content, etc
    this._container.style.background = 'white';
    this._container.style.width = '100px';
    this._container.style.height = '50px';
    this._container.innerHTML = 'Hi!';


    map.on('move zoom viewreset zoomend moveend', this._update, this);

    this._update();
  },

  onRemove: function(map) {
    L.DomUtil.remove(this._container);
    map.off('move zoom viewreset zoomend moveend', this._update, this);
  },

  _update: function() {
    var offset = map.containerPointToLayerPoint([0, 0]);

    offset = offset.add([340, 220]);

    L.DomUtil.setPosition(this._container, offset);

  }
});

Once you have defined this, you can simply

var static = new L.Layer.StaticOverlay().addTo(map);

Of course, there are certain elements missing, like properly positioning the overlay (obtain the map's pixel size with getSize(), perform the appropriate calculations), and specifying the overlay's contents with custom options in the layer constructor.

These aspects are left as an exercise for the reader :-)

Check out a live example here.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Leveraging jQuery plugins within an AngularJs application

I am currently trying to implement the tinyColorPicker plugin from here in my Angular app, but I am facing difficulties with it. An error message keeps appearing: TypeError: element.colorPicker is not a function In my index.html file, I have included th ...

Turn off the chrome react DevTools when deploying to production to ensure the

I have successfully browserified my react app for production using gulp and envify to set up NODE_ENV. This has allowed me to remove react warnings, error reporting in the console, and even disable some features like the require of react-addons-perf. Afte ...

Is it possible to authenticate across multiple tables in a React/Node.js environment?

I am currently planning an online library management system project. For this project, I have identified **3 distinct roles** which are stored in separate database tables. Firstly, there is the user role, which will have an interface allowing them to view ...

What is the solution for getting rid of the "clear sort" state in an angular-ui-grid column header?

I am looking for information on how to remove the default behavior where the 3rd click disables sort and stays "neutral" on sortable headers. Having a disable sort state seems flawed as it does not change the sort order. How can I eliminate the 3rd state ...

Tips for sending multiple values in a data object using jQuery AJAX

I am currently working on a form that contains two input fields, with the possibility of more being added later. The first input is a text field and the second is a checkbox. I want to be able to send these inputs using $.ajax. To accomplish this, I have ...

How can Firebase effectively manage multiple URLs for referencing?

I am facing a scenario with multiple users, each with a unique hashId assigned to them that differentiates their URLs. users/hashId/bla/blah The only variation in these URLs is the hashId value. While the client side updates data in firebase, I need to ...

The underscore convention for defining members in Typescript allows for clear and concise

Let's talk about a class called Email class Email { private _from: string; private _to: Array<string>; private _subject: string; } When an email object is created, it will look something like this: { _from:'', _to:'&apo ...

JavaScript - AngularJS HTML parser

I am working with an array that contains content along with HTML tags, and here is the code snippet: for (car in cars.parking[0]){ content.push('<br />'); for (token in cars.parking[0].now) { content.pus ...

What is the best way to remove double quotes surrounding "name" and "count" when displayed in the JavaScript console output?

I am struggling to transform the input: ["apple", "banana", "carrot", "durian", "eggplant", "apple", "carrot"] into the desired output: [{ name: "Apple", count: 2 }, { name: ...

Having trouble retrieving all JSON properties

I am facing an issue with my json structure where I am unable to access certain properties. I can only access the main properties like type, properties, and so on within that hierarchy level. However, I cannot seem to access icon, iconURL, or title. The da ...

Have the getter functions for reactive objects in Vue 3 been transformed into computed values?

Is the memoization of bookCount in this instance handled equivalently to a computed reference? const author = reactive({ name: 'John Doe', books: [ 'Vue 2 - Advanced Guide', 'Vue 3 - Basic Guide', 'Vue 4 - ...

`There is a lack of props validation in the react/prop-types``

As I set up my Next-React app on Netlify, I encountered an error in the deploy log: Netlify deploy log indicates: "Error: 'Component' is missing in props validation", "Error: 'pageProps' is missing in props validation" within my ./page ...

Get the name of the array using JavaScript

Here is an example of my situation: var list1 = ['apple', 'banana', 'orange']; var list2 = ['carrot', 'lettuce', 'tomato']; When I use: alert(list1) I get: apple, banana, orange. This is corre ...

Guide on testing a function with a dependency in Angular through unit testing

Attempting to dive into unit testing, I have grasped some of the basics. However, my current challenge lies in testing a method within my code. This particular method involves calling a function from oidc-client.js that handles user sign-ins. My spec fi ...

Updating jQuery event behaviors based on the value of .html( 'string' )

Visit this link for more information. Feel free to modify the heading if you believe it needs improvement. General I manage a multilingual WordPress website with dynamic menu and navigation controlled through the WordPress admin panel. The multilingual ...

Encasing a variety of child elements within a div container

My goal is to group a range of children elements within a div so that I can manipulate them collectively in different locations. The challenge arises from having a list with randomly generated li tags, and no matter how many appear, I need every batch of t ...

Employing the include functionality within PHP

Currently, I am in the process of developing an eCommerce website and have my own host/domain. To ensure security, I understand that it is advisable to store PHP files in a location separate from public_html. The index.html file is located in /home/user/pu ...

The timing of jQuery's .load function appears to be off, catching us by surprise

My current challenge involves loading returned html from an .aspx page through AJAX, but facing a timing issue with a click event that needs to occur before executing some essential tasks. Specifically, the process begins when a user types in a text field ...

What is the best way to retrieve the data stored in a TD element within a TR row in an HTML table?

How can I retrieve the value of a clicked table cell? https://i.stack.imgur.com/HfXBK.png <table id="table" class="table" style="margin-right: auto; margin-left: auto" > <thead> <tr> <th>Request Number</th> ...

The catch-all route handler is triggered following a response being sent by a designated route handler

Currently, I am facing a peculiar issue with the routing on my Express-based server while trying to implement authentication. Here's a snippet of code that highlights the problem: app.get('/', function (req, res) { console.log('thi ...