Create a gist now

Instantly share code, notes, and snippets.

@SaMnCo /Gemfile
Last active Oct 25, 2016

What would you like to do?
Dashing Dynamic Map

Preview

Description

This dynamap was inspired by an answer to the Dashing Contest that displayed information about recent earthquakes

However I needed something where it would be easy to add new dots based on dynamic/push information, hence this widget.

Dependencies

rest-client - convenient http client for retrieving quake data

Add to dashing's gemfile:

gem 'rest-client'

and run bundle install.

Usage

To use this widget, copy dynamap.html, dynamap.coffee, and dynamap.scss into the /widgets/dynamap directory.

You'll need to add the following line inside the header in the dashboards/layouts.erb file. Replace the '<YOUR_KEY>' with the free google api key you get from following the instructions on this page

<script src="https://maps.googleapis.com/maps/api/js?key=<YOUR_KEY>&sensor=false&libraries=visualization"></script>

To include the widget in a dashboard, add the following snippet to the dashboard layout file:

<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
  <div data-id="dynamap" data-view="dynamap" data-zoom=1 data-title="Dynamic Heat Map"></div>
</li>

On it is installed, you can push new points by doing

curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "Country": "Spain" }' \http://DASHING_HOST:DASHING_PORT/widgets/dynamap

You should see a new dot appear on the map.

Testing

You may or may not have a usecase right away but still want to see how this behaves. If that is the case put the dynamap.rb file in your /jobs folder and restart Dashing. Every 10s, a random number will be selected and if it matches a country, a dot will be added to the map.

Settings

Should you decide to use the dynamap widget for another source of data, you may find these configuration attributes helpful.

  • data-zoom => [0-15], 0 is global and 15 is street level, default is 2
  • data-center-lat and data-center-long => the map's centerpoint, default is centerish of US
  • data-map-type => [HYBRID | ROADMAP | SATELLITE | TERRAIN], default is SATELLITE

The full options for google Heatmap cam be seen here and can be configured in the coffeescript.

class Dashing.Dynamap extends Dashing.Widget
json_path = 'https://s3-us-west-2.amazonaws.com/samnco-static-files/country-maps/countries.jsonp'
json_countries = null
plots = []
jsonCountriesLoader = (url) ->
$.ajax
'jsonpCallback':"jsonCountriesLoader"
'contentType':"application/json"
'async': false
'global': false
'url': url
'dataType': "jsonp"
'success': (data) ->
json_countries = data
return json_countries
newCountry = (req_country) ->
json_countries = jsonCountriesLoader json_path
json_countries.countries.forEach( (country) ->
if country.name.common == req_country
name = country.name.common
coordinates = country.latlng
lat = coordinates[0]
long = coordinates[1]
plots.push { "name": name, "lat": lat, "long": long, "weight": 1 }
)
plotCountries = (plot_array) ->
for d in plot_array
location: new google.maps.LatLng(d.lat, d.long), weight: (d.weight)
ready: ->
mtype = switch @get('mapType')
when "TERRAIN" then google.maps.MapTypeId.TERRAIN
when "HYBRID" then google.maps.MapTypeId.HYBRID
when "ROADMAP" then google.maps.MapTypeId.ROADMAP
else google.maps.MapTypeId.ROADMAP
mapOptions = {
zoom: (@get('zoom') ? 1)
center: new google.maps.LatLng((@get('centerLat') ? 20), (@get('centerLong') ? -102.5))
mapTypeId: mtype
zoomControl: false
panControl: false
streetViewControl: false
scrollwheel: false
disableDoubleClickZoom: false
draggable: true
mapTypeControl: false
}
new_map = plotCountries(plots)
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions)
pointArray = new google.maps.MVCArray(new_map)
heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray})
heatmap.setMap(map)
@onData(plots)
onData: (data) ->
if(!data)
data = plots
if(!data)
return
country = @get('country')
newCountry(country)
new_map = plotCountries(plots)
mtype = switch @get('mapType')
when "TERRAIN" then google.maps.MapTypeId.TERRAIN
when "HYBRID" then google.maps.MapTypeId.HYBRID
when "ROADMAP" then google.maps.MapTypeId.ROADMAP
else google.maps.MapTypeId.ROADMAP
mapOptions = {
zoom: (@get('zoom') ? 1)
center: new google.maps.LatLng((@get('centerLat') ? 20), (@get('centerLong') ? -102.5))
mapTypeId: mtype
zoomControl: false
panControl: false
streetViewControl: false
scrollwheel: false
disableDoubleClickZoom: false
draggable: true
mapTypeControl: false
}
map = new google.maps.Map(document.getElementById('map-canvas'),mapOptions)
pointArray = new google.maps.MVCArray(new_map)
heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray})
heatmap.setMap(map)
$(@node).fadeOut().fadeIn()
<% content_for :title do %>Dynamic Map<% end %>
<div class="gridster">
<ul>
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
<div data-id="dynamap" data-view="Dynamap" data-title="Dynamic Heat Map" data-zoom=1 data-map-type="ROADMAP"></div>
</li>
</ul>
<center><div style="font-size: 12px">Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "Country": "Spain" }' \http://<%=request.host%>:<%=request.port%>/widgets/dynamap</div></center>
</div>
<h1 class="title" data-bind="title"></h1>
<div id="map-canvas"></div>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require "rest-client"
COUNTRY_LOCATIONS_URL="https://s3-us-west-2.amazonaws.com/samnco-static-files/country-maps/countries.json"
COUNTRY_LOCATIONS = RestClient.get COUNTRY_LOCATIONS_URL
SCHEDULER.every '10s', :first_in => '0s' do |job|
index = rand(1000)
countries = JSON.parse(COUNTRY_LOCATIONS)
countries['countries'].each do |f|
if f['ccn3'].to_i == index
country_name = f['name']['common']
send_event('dynamap', { country: country_name } )
break
end
end
end
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #b4b4ff;
// ----------------------------------------------------------------------------
// Widget-dynamap styles
// ----------------------------------------------------------------------------
.widget-dynamap {
background-color: $background-color;
}
#map-canvas, #map_canvas {
height: 90%;
}
@media print {
html, body {
height: auto;
}
#map-canvas, #map_canvas {
height: 600px;
width:726px;
}
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
## This is for the Dynamic Map Widget
gem 'rest-client'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment