Skip to content

Instantly share code, notes, and snippets.

Last active Apr 30, 2017
What would you like to do?



Dashing widget (and associated job) to display recent earthquakes location and intensity. The included job can be easily altered to display other geospatial data sources (location of recent signups, bus stops, tweets, etc) via google heatmaps.


rest-client - convenient http client for retrieving quake data

Add to dashing's gemfile:

gem 'rest-client'

and run bundle install.


To use this widget, copy heatmap.html,, and heatmap.scss into the /widgets/heatmap directory. Put the heatmap.rb file in your /jobs folder.

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="<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="heatmap" data-view="Heatmap" data-title="Recent Earthquakes"></div>


Should you decide to use the heatmap 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 heatmaps cam be seen here and can be configured in the coffeescript.

class Dashing.Heatmap extends Dashing.Widget
@accessor 'values'
ready: ->
parseData = (raw_data) ->
pdata = (for d in raw_data.values
location: new google.maps.LatLng(, d.long), weight: (d.weight ? 1)
onData: (data) ->
# Handle incoming data
data = @get("values")
parsed_data = parseData(data)
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.SATELLITE
mapOptions = {
zoom: (@get('zoom') ? 2)
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(parsed_data);
heatmap = new google.maps.visualization.HeatmapLayer({data: pointArray})
# You can access the html node of this widget with `@node`
<h1 class="title" data-bind="title"></h1>
<div id="map-canvas"></div>
<p class="updated-at" data-bind="updatedAtMessage"></p>
require "rest-client"
SCHEDULER.every '4h', :first_in => '0s' do |job|
#Dummy data if you just want to see it work
#dummy_data = []
#10.times {dummy_data << {lat:(32 + rand(18)), long: (-118 + rand(42)), weight: rand(10)}}
#4.times {dummy_data << {lat:(41 + rand(12)), long: (0 + rand(25)), weight: rand(3)}}
eq_json_data = RestClient.get EARTHQUAKE_FEED_URL
raw_data = JSON.parse(eq_json_data)
real_data = []
raw_data['features'].each do |f|
w = f['properties']['mag'] rescue 1
coor = f['geometry']['coordinates'] rescue nil
next if coor == nil
lat = coor[1]
long = coor[0]
real_data << {lat: lat, long: long, weight: w}
send_event('heatmap', { values: real_data })
// ----------------------------------------------------------------------------
// Sass declarations
// ----------------------------------------------------------------------------
$background-color: #b4b4ff;
// ----------------------------------------------------------------------------
// Widget-heatmap styles
// ----------------------------------------------------------------------------
.widget-heatmap {
background-color: $background-color;
#map-canvas, #map_canvas {
height: 90%;
@media print {
html, body {
height: auto;
#map-canvas, #map_canvas {
height: 600px;
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment