Leaflet tooltip - json object properties as labels

I have a Leaflet map based on Tom’s example (thanks!!) that plots data points from a geojson file. I can call a specific property of each object in the geojson file as follows:

data_geojson.features[0].properties["Mining_Pro"]

The 0 identifies a specific object/property, and the map yeilds all object/properties from the file.

I would now like to add a tooltip that shows the [“Mining_Pro”] value for each point, so I try first

 .bindTooltip(data_geojson.features[0].properties["Mining_Pro"])

which, of course, returns that specific value [i.e. the one for [0]].

Mike’s shown me examples of using => in similar contexts - connected with array.filter. Is this also the right approach here?

This will return an array of 270 objects:

data_geojson.features.filter(f => f.properties["Mining_Pro"])

… but these won’t automatically produce tooltip labels:

  .bindTooltip(data_geojson.features.filter(f => f.properties["Mining_Pro"]))

… I assume this is because I haven’t specified which particular property to label – just that I’d changed the way the information in the geojson file is presented back to me – with a filter applied that essentially returns every object in the original file

Here’s a test notebook:

Thanks in advance for any help and guidance!

I think I got it following this example:

Here’s the code:

  let data_geojson_layer = L.geoJson(data_geojson, {
    onEachFeature: function(feature, layer){
        console.log(feature.properties);
        var content = "Project: " + feature.properties["Mining_Pro"]; 
        layer.bindPopup(content);
  }

I’ve also updated the notebook. If there’s a better way of doing this, please let me know!

1 Like

After getting this working on Observable, I emailed the authors to ask whether my attribution was OK on this parent notebook, which is published. I got their approval, and also a request if they can embed the rendered map on the project website. Very nice!

Wishing to help, and wishing for this to be available even on older browsers, I thought I would convert from Observable to HTML and see if I could walk back the necessary d3 version to a point where it would work on Internet Explorer (v3, I think).

I am not doing too well just yet. Specifically, I now can’t get Leaflet to load with geojson file, encountering the error leaflet.js:5 Uncaught Error: Invalid GeoJSON object.

Here’s the code I am trying:

<script>
	var data_geojson = d3.json('https://raw.githubusercontent.com/aaronkyle/geospatial-data/master/MIDR_Resettlement_Dataset_2019_Shapefile/MIDR_dataset_20190801.geojson');
	var map = L.map('mapid').setView([38.9, -77.03], 2);
	L.tileLayer('https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}@2x.png', {
      attribution: 'Wikimedia maps beta | &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
	}).addTo(map);
	var data_geojson_layer = L.geoJson(data_geojson, {
    onEachFeature: function(feature, layer){
        console.log(feature.properties);
        content = feature.properties["Mining_Pro"] + ", " + feature.properties["Country"];
        layer.bindPopup(content);
  }

  }).addTo(map);
  map.fitBounds(data_geojson_layer.getBounds());
</script>

I’lll keep poking around, but if anyone on here can easily spot my mistake, I’d really appreciate it!

In case it helps for troubleshooting, here’s the code on GitHub:

And as a rendered HTML page:

http://applied-anthro.com/thematic-issues/involuntary-resettlement/mining-displacement.html

Thanks to everyone!!

I got this working without D3.js (using an Ajax plug-in):

<script>
	var map = L.map('mapid').setView([22, 20], 2);
	L.tileLayer('https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}@2x.png', {
			attribution: 'Wikimedia maps beta | &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
	}).addTo(map);
	var data_geojson = new L.GeoJSON.AJAX('https://raw.githubusercontent.com/aaronkyle/geospatial-data/master/MIDR_Resettlement_Dataset_2019_Shapefile/MIDR_dataset_20190801.geojson', {
    onEachFeature: function(feature, layer){
        console.log(feature.properties);
        content = feature.properties["Mining_Pro"] + ", " + feature.properties["Country"];
        layer.bindPopup(content);
  }
  }).addTo(map);
  map.fitBounds(data_geojson.getBounds());
</script>

I’d be happy for tips on achieving this without Ajax!

Can you specify “older”? Which browsers, versions, and/or age are we talking about?

Assuming you’re talking about the Ajax plugin, the API you’re looking for is XMLHttpRequest.

1 Like

Thanks Fabian!

I meant, essentially, Internet Explorer, and used ‘older’ recalling somewhere where Mike suggested Observable works only with ‘modern’ browsers I guess I was looking for an antonym, and didn’t go with ‘archaic’ :wink:

As for Ajax / Ajax plug-in - i apologize, I often don’t know I’m talking about as I am haphazardly teaching myself (well, really you’re all teaching me). Thank you for the API reference. I’ll work through this and see if I can simplify the code to have fewer dependencies / plug-ins. Although I have no idea of this is the case, I assumed my challenge with the JSON object was originating from some improper use of d3.json. I used d3.group to explore the data (also thanks to a suggestion from Mike) and next will see if I can do to render out some views of these groupings in a non-Observable context (like the Github HTML page I linked), so I figured it might also be an easy / already in-use way to go about loading the geojson file. I’ll keep working at it!

Thanks again!!

I know it’s a side answer but… supporting older and discontinued browsers such as IE is really a pain, whereas setting up a correct experience for them is less time consuming (and also will free your mind and might even boost your rankings in the google).

a fixed image <img src="fixed rendering.png">

with progressive enhancement:

<script> if (modern browser) { remove the image and launch the beautiful js } </script>

2 Likes

This. One of the key factors in web development is knowing your audience and tradeoffs. E.g., @ workplace we have a clause in our contracts to only support browsers not older than a year by default (clients must explicitely request support for older browsers).

Supporting legacy browsers can be extremely time consuming, time that is effectively wasted if there is no real demand and benefit. And if you plan on doing it for the experience: don’t. Unless you’re doing frontend development and have to deal with that mess on a regular basis, that experience won’t be worth anything.

Fun fact: IE had reached end of life in 2015.

To add something of substance to my rant, here are some links to check browser compatibility:

1 Like

Hi folks, and thank you for all of this.

I agree with the overall message you’re both conveying here, and I don’t intend this message to speak against you in either way. That said:

This is exactly what I am trying to take into consideration and address with the (yes, painful) conversions I keep practicing.

As a bit of insight (and I’ll be explicit with names and hope this doesn’t come back to haunt me). I work at the World Bank Group–one of the leading international development institutions on the planet. Across the street is the International Monetary Fund, where my wife works–also a hugely influential and capital-rich organization. Only this year did the World Bank try to move away from Internet Explorer (that is, until this year it was our default browser… we had Chrome as a ‘backup’ when I joined a couple years back; otherwise we don’t have permission to install applications on work machines). By try I mean that we still have internal systems that I open in Chrome and they force open an IE browser rather than figure out whatever it is that’s preventing the page from working in Chrome. Apparently IMF hasn’t yet tried such a web system re-deployment.

I can’t tell you how many times I have tried sharing around notebooks with people within my organization–even noting that they’ll need to open the links in Chrome, Safari, Edge, etc–only to get back replies telling me that the links won’t open, that they’re seeing a blank page, etc.

This tiny modification I made to Tom’s notebook probably isn’t the right one for debating the pros- and cons- of me trying to look for ways to get a visualization working for IE, because it I think at the end of the day it doesn’t require D3 and, with that Leaflet AJAX plug-in, it plays equally nicely on IE and Chrome (and other browsers) [though I still don’t get why the leaflet.js was rejecting my attempt to load the geojson file using D3]. The point of doing this, however, was to ensure that any people from my institution or other similar IFIs stuck in the same archaic world (and I know this to be most of them, regrettably) would not end up missing this map rendering if they found themselves on the University of Queensland’s website for this ‘resettlement in mining’ database.

As to the other approaches:

I really like this alternative in most contexts, and I’ve been working to implement this where I’m producing graphs, pie charts, etc… so that IE users lose things like tooltips that add additional information / ease the analytics, but where the charts themselves will convey the idea equally well as static images. Observable’s new additions of the side-cell buttons that allow one to download rendered images as .png and .svg where an amazing boon to this sort of work (thank you Observable!)

In this case of a Leaflet map, however, it really wouldn’t be much of an enhancement, as the real benefit comes with zooming in to countries, locations to see which projects are where. I could, of course, have a message saying “You’re missing content here! Find a modern browser!” and have that get replaced with the launch of beautiful JS. I’ve also been learning about the concept of ‘browser calls’ as I have been learning this sort of a thing.

Anyway… all of this is just meant as context to explain why I am doing what I am doing. And I appreciate the reminder that what I am doing is sorta ridiculous :heart:

Thank you for your continued patience and guidance! I feel that I’ve come a very long way in the past year or so with your help, and I’ve nearly moved past using Excel for most of my data processing chores and instead do things with JS / D3.js. Thank you!!!

2 Likes

Not my words! Your motivation wasn’t clear from your earlier post, but as you’ve stated yourself in your latest post, there is no (apparent) alternative route for you.

Since this will probably not be the last time that you need to make a notebook “IE-ready” I’d look into tooling that will help you with the process by automatically injecting appropriate polyfills and shims (e.g. babel, webpack). Extending your tool chain is an experience from which you can, without question, profit in the future.

2 Likes

Thanks Fabian! This is helpful (as always).

… And they are very much my words :wink: [It is a bit ridiculous…]

As a bit of follow-up (and always with deep appreciation), we have a working map on the University of Queensland’s Centre for Social Responsibility in Mining Global mining induced displacement and resettlement (MIDR) events dataset project webpage. Very cool.

They credited me, but really the credit belongs to @tom and all my many teachers in the Observable community. Thanks to the help I’ve received here, I could figure out how to convert the shapefiles to geojson and then render them into Tom’s Leaflet template. I couldn’t have done this a year ago, and I am flattered that they chose to include this map on the project web page.

1 Like