We sometimes talk as if there’s just one asset, but almost always we have many that we’re tracking. There are insights to be gained at the fleet level, too. Is there a bottleneck in the transit line, batteries consistently left to run down, or a certain receiving warehouse that handles our crates roughly?
We can make these insights visible at a glance by showing them directly on a map. This is dramatically better than hiding them behind map info windows, where the user has to click each one to see what’s happening. It’s even better than our traditional approach, which is to color-code the markers based on some criteria. Instead, let’s show the actual battery levels, the actual temperature, or whatever other piece of real datawe care about— as the map marker itself.
Google Map’s new Advanced Markers make this simple, as they allow you to easily use custom HTML as the marker. In our example, we’ll dynamically create SVG icons that visually show the data (i.e. as a gauge). To prevent clutter, we’ll let the user choose from a dropdown which data they want to see: battery level, temperature, or humidity. We’ll also color code the markers based on thresholds, use animations to call attention, and let the users click markers to drill down for more details. We’ll then embed this map in a Losant Dashboard for easy visualization.
Before we begin, we’ll need to have a Google Maps API key, following these instructions.
For our demo, we set up a Device Recipe for simulated trackers with attributes for battery, temperature, humidity, and location.
Device Attributes within Losant support tags for meta information. This is a perfect place to store information about our data; specifically, we can track the minimum value, maximum value, the unit, and the thresholds we consider problematic.
We’ll use these values to know how to fill the gauges on our map markers, and to color code them based on the thresholds.
Using this recipe we can create a few test devices, and then use Losant’s built-in simulator to fill them with some data.
Next, we’ll set up a dashboard and add a Custom HTML Block. In this block, we need to define a dataset so that our block is aware of our device data. This is as simple as adding a dataset, naming it, picking which devices apply (we use a tag for the device type), and making sure to include the attributes we want.
Now we’re ready to drop in the custom head content and the custom body content. You can find the full example code for these sections at the GitHub repository.
We’ll go through a few interesting sections of the code below, but once the block is saved, the dashboard should be up and running!
Custom Map Code
The code for the map is placed inside the custom head content. There are a few variables that we keep as globals outside of the functions, so that both Google’s library and our custom code can access and update them. Dashboards update regularly with new data, so we need to make sure our map does, too.
We’ll run the map setup just once, but the marker setup every time (a) the user changes which attribute to show, or (b) Losant gives us updated device data.
When we create the markers, we store them in a persistent object(a dictionary with the device ID as the key) so we can update them. So our first step is to see if we’ve created this marker before, and create it if we haven’t. Conversely, if a marker did exist but shouldn’t show any more-for instance, it does not have the selected attribute—then we remove it from the dictionary.
The first time we set up a marker, we add an event listener for clicks. This includes adding a class (“selected”) which makes the expanded view of each marker visible, and setting the z-index so that it shows on top.
That setup only happens once, but every time we update we rebuild the marker’s HTML so that the gauge visually updates. We have three attributes in our example, and we will build all three gauges each time. One of the gauges will serve as the map marker, and the others will show when the user clicks on the marker.
We also need to update the position of the marker, and make sure that its expanded view’s visibility is in sync with its state (since the markers might be rebuilt while some are selected).
Thanks to the new Advanced Markers, once we have the marker content ready, setting our HTML element as the marker is as easy as marker.content = container;
The icon creation is where the real magic happens. Since the SVG format is defined by text, we can use the device data to proportionally fill out gauges. To do this, we’ll rely on the attribute tags we set up earlier. In most cases, we want to calculate the percentage that the value represents and use that as the percentage that our gauge is filled. The tags also determine the color, based on how the value relates to the “warning” and “critical” ranges we defined.
Note that we throw an exception if we’re missing a value, so that the calling code can remove the map marker if it doesn’t apply.
We have three different SVG schemas, one for each type of gauge we are showing: a battery meter, a thermometer, and a generic circle display. The first of those is shown in the gist below.
To keep things easy, we’ve created the battery and thermometer gauges to have an inner height of 100 pixels. This lets us use the percentage we calculated as the height of the fill color in pixels. As you can see, there’s a bit of tweaking with the positions to account for borders and offsets.
Finally, we noted earlier that we create all three possible icons and only use one of them as the marker. The others appear when the user clicks on a marker, which adds the “selected” class to it to make it visible.
To support this, each marker’s HTML content actually contains the expanded view as well. Building this is mostly a matter of wrapping the icons we already have inside of a container. CSS will handle the visibility based on the “selected” class.
Once again, you can access the full source in this GitHub repository. This example can easily be built upon to match the specific needs of various asset tracking cases. Another benefit of the new markers that we did not touch on here is their increased performance. Google’s team found a 60% increase in performance, which is hugely relevant when we view a single asset’s location history on a map as a series of markers (sometimes numbering in the thousands of points).
Asset tracking is more than just knowing where our assets are; it's about understanding how they're faring and how they're moving. Google's Advanced Markers, combined with the powerful Losant Enterprise IoT Platform, helps us visually show this level of understanding at a single glance.