Moving map2014 to trunk.

This commit is contained in:
2014-05-06 11:26:47 +00:00
commit a38905569c
Notes: subgit 2018-03-07 17:58:45 +01:00
r605 www/trunk
25 changed files with 2615 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
* text=auto !eol
www/TileLayer.Grayscale.js -text
www/first.png -text
www/jquery.localtime-0.9.1.min.js -text
www/jquery.tablesorter.min.js -text
www/jquery.tablesorter.pager.css -text
www/jquery.tablesorter.pager.min.js -text
www/jquery.tablesorter.widgets.min.js -text
www/last.png -text
www/leaflet.css -text
www/leaflet.js -text
www/logo_RUB_155x30.png -text
www/next.png -text
www/prev.png -text
www/sprintf.min.js -text
www/theme.blue.css -text
www/widget-pager.js -text
+3
View File
@@ -0,0 +1,3 @@
www/event.xml
www/geolocation.js
www/stations.xml
+61
View File
@@ -0,0 +1,61 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# $Id$
'''
Script to lookup city names of events with Nominatim service
The input should be an valid quakeML file passed to stdin.
The output will will be a javascript structure to be included in the
SeisObs map service.
the script should be updated regulary keep the total number of all
AJAX calls to the Nominatim service small
'''
# imports
try:
import xml.etree.cElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
from sys import stdin
import urllib2 as URL
import json as JSON
# constants
namespaces = {'sc3': 'http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.7',
'qml': 'http://quakeml.org/xmlns/bed/1.2'}
# initialise variables
geolocationTable = {};
# parse event.xml
DOM = ET.parse(stdin).getroot()
#DOM = ET.parse('../www/event.xml').getroot()
# iterate over all events
for event in DOM.iterfind('qml:eventParameters/qml:event', namespaces):
publicID = event.attrib['publicID'].split('/')[2]
lat = event.find('./qml:origin/qml:latitude/qml:value', namespaces).text
lng = event.find('./qml:origin/qml:longitude/qml:value', namespaces).text
url = 'https://open.mapquestapi.com/nominatim/v1/reverse.php?lat={0}&lon={1}&zoom=10&format=json'.format(lat, lng)
# send and evaluate nominatim request
response = URL.urlopen(url)
if ( response.msg == 'OK' ):
data = JSON.loads(response.read())
try:
city = data['address']['city']
country = data['address']['country']
countryCode = data['address']['country_code'].upper()
value = city
if ( countryCode != 'DE' ):
value = '{0} ({1})'.format(value, countryCode)
geolocationTable[publicID] = value
except:
print 'Could not etract city for event {0}'.format(publicID)
else:
print 'Request {0} failed'.format(url)
# dump json
print 'var geolocationTable = '+JSON.dumps(geolocationTable)
+51
View File
@@ -0,0 +1,51 @@
/*
* L.TileLayer.Grayscale is a regular tilelayer with grayscale makeover.
*/
L.TileLayer.Grayscale = L.TileLayer.extend({
options: {
enableCanvas: true
},
initialize: function (url, options) {
var canvasEl = document.createElement('canvas');
if( !(canvasEl.getContext && canvasEl.getContext('2d')) ) {
options.enableCanvas = false;
}
L.TileLayer.prototype.initialize.call(this, url, options);
},
_loadTile: function (tile, tilePoint) {
tile.setAttribute('crossorigin', 'anonymous');
L.TileLayer.prototype._loadTile.call(this, tile, tilePoint);
},
_tileOnLoad: function () {
if (this._layer.options.enableCanvas && !this.canvasContext) {
var canvas = document.createElement("canvas");
canvas.width = canvas.height = this._layer.options.tileSize;
this.canvasContext = canvas.getContext("2d");
}
var ctx = this.canvasContext;
if (ctx) {
this.onload = null; // to prevent an infinite loop
ctx.drawImage(this, 0, 0);
var imgd = ctx.getImageData(0, 0, this._layer.options.tileSize, this._layer.options.tileSize);
var pix = imgd.data;
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i] = pix[i + 1] = pix[i + 2] = (3 * pix[i] + 4 * pix[i + 1] + pix[i + 2]) / 8;
}
ctx.putImageData(imgd, 0, 0);
this.removeAttribute("crossorigin");
this.src = ctx.canvas.toDataURL();
}
L.TileLayer.prototype._tileOnLoad.call(this);
}
});
L.tileLayer.grayscale = function (url, options) {
return new L.TileLayer.Grayscale(url, options);
};
+239
View File
@@ -0,0 +1,239 @@
/* do reverse geolocation lookup */
function getGeolocation(id, lat, lng) {
if ( !geolocationTable[id] ) {
// $.getJSON( "//nominatim.openstreetmap.org/reverse", { lat: lat, lon: lng, zoom: 10, format: "json" } )
$.getJSON( "//open.mapquestapi.com/nominatim/v1/reverse.php", { lat: lat, lon: lng, zoom: 10, format: "json" } )
.done(function( json ) {
var city = json.address["city"];
var country = json.address["country"];
var countryCode = json.address["country_code"].toUpperCase();
geolocationTable[id] = city;
( country != "Deutschland" ) ? geolocationTable[id] = geolocationTable[id] + " ("+countryCode+")" : null;
if ( city ) {
$("#eventstable a.toggle[eventid="+id+"]").text(geolocationTable[id]);
var sort = [[0,1],[1,1],[2,1]];
$("#eventstable").trigger("update", [true]);
$("#eventstable").trigger("updateCache");
$("#eventstable").trigger("sorton", [sort]);
} else {
console.log("Nominatim did not provide a city tag for "+lat+" / "+lng);
};
})
.fail(function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
});
};
};
/* Load events using ajax */
function ajaxLoadEvents(stime, etime) {
var mapBounds = map.getBounds();
var N = mapBounds.getNorth();
var E = mapBounds.getEast();
var S = mapBounds.getSouth();
var W = mapBounds.getWest();
var d = 0.1;
if ( !stime ) {
var stime = new Date();
stime.setDate(stime.getDate()-180);
};
if ( !etime ) {
var etime = new Date();
etime.setDate(etime.getDate()+1);
};
var url = "https://ariadne.geophysik.ruhr-uni-bochum.de/fdsnws/event/1/query"
var request_data = {
starttime: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
endtime: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
minlat: S-d,
maxlat: N+d,
minlon: W-d,
maxlon: E+d,
minmag: minMag-0.1,
};
$.ajax({
type: "GET",
url: url,
data: request_data,
dataType: "xml",
success: function (xml) {
$(xml).find('event').each(function () {
var id = $(this).attr('publicID').split('/')[2];
var mag = $(this).find('magnitude > mag > value').text();
var otime = $(this).find('origin > time > value').text();
var lng = $(this).find('origin > longitude > value').text();
var lat = $(this).find('origin > latitude > value').text();
var mag = $(this).find('magnitude > mag > value').text();
var evaluationMode = $(this).find('evaluationMode').text();
var evaluationStatus = $(this).find('evaluationStatus').text();
var type = $(this).find('type').last().text();
var location = getLocation(Number(lat), Number(lng))[0];
( location ) ? null : location = $(this).find('description > text').text();
// create table row: Date, Time, Mag, Location
if ( !eventTable[id] && ( type == 'earthquake' || type == 'induced or triggered event' || type == 'outside of network interest') && evaluationMode != 'automatic' && evaluationStatus != 'preliminary' && Number(mag)+0.05 >= minMag ) {
var row = '<tr class="tablesorter-hasChildRow">'
+ '<td class="utctime-date">'+otime.split('.')[0]+'Z</td>'
+ '<td class="utctime-time">'+otime.split('.')[0]+'Z</td>'
+ sprintf('<td class="ar">%.1f</td>', Number(mag))
+ '<td><a href="#" class="toggle" eventid="'+id+'">'+location+'</a><a class="map-link" href="#" eventid="'+id+'">Karte</a></td>'
+ '</tr>';
row += '<tr class="tablesorter-childRow">'
+ '<td colspan="4" eventid="'+id+'">not implemented</td></tr>';
var added = $('#eventstable tbody').append(row);
added.find('.tablesorter-childRow td').hide();
$('#eventstable').find('td.utctime-date').each(function() {
$.localtime.formatObject($(this), "dd.MM.yyyy");
$(this).removeClass('utctime-date');
$(this).addClass('localtime-date');
});
$('#eventstable').find('td.utctime-time').each(function() {
$.localtime.formatObject($(this), "HH:mm");
$(this).removeClass('utctime-time');
$(this).addClass('localtime-time');
});
// create marker
var marker = addEventMarker(id, Number(lat), Number(lng), Number(mag));
var text = sprintf('<h3 eventid="%s">%s</h3>', id, location)
+ sprintf('<p>Ereignis: %s</br>', id)
+ sprintf('Ort: %.4f °N, %.4f °O </br>', Number(lat), Number(lng))
+ sprintf('Zeit: <span class="utctime">%sZ</span></p>', otime.split('.')[0], otime.split('.')[0]);
marker.bindPopup(text);
// try to get better location with reverse geolocation lookup (nominatim), check cache first
( geolocationTable[id] ) ? $("#eventstable a.toggle[eventid="+id+"]").text(geolocationTable[id]) : getGeolocation(id, lat, lng);
};
});
},
complete: function () {
initStationTable();
var sort = [[0,1],[1,1],[2,1]];
$("#eventstable").trigger("update", [true]);
$("#eventstable").trigger("updateCache");
$("#eventstable").trigger("sorton", [sort]);
initMapLink();
},
error: function( jqxhr, textStatus, error ) {
var err = textStatus + ", " + error;
console.log( "Request Failed: " + err );
}
});
};
// add row to table
function addEventRow(id, props) {
$('#eventstable').tablesorter({
sortList: "[[0,0], [1,1]], [2,1]",
resort: true,
showProcessing: true,
pager_size: 35
});
var html = '<tr class="tablesorter-hasChildRow">'
+ '<td class="utctime-date">'+props.date+'T'+props.time.split('.')[0]+'Z</td>'
+ '<td class="utctime-time">'+props.date+'T'+props.time.split('.')[0]+'Z</td>'
+ '<td class="ar">'+props.mag+'</td>'
+ '<td><a href="#" class="toggle">'+props.location+'</a><a class="map-link" href="#" eventid="'+id+'">Karte</a></td>'
+ '</tr>'
+ '<tr class="tablesorter-childRow">'
+ '<td colspan="4" eventid="'+id+'">'
+ "<pre>ID "+id+"\n\n"
+ "Origin\n"
+ "Date "+props.date+"\n"
+ "Time "+props.time+"\n"
+ "Latitude "+props.lat+" deg +/- "+props.lat_err+" km\n"
+ "Longitude "+props.lon+" deg +/- "+props.lon_err+" km\n"
+ "Depth "+props.depth+" km +/- "+props.depth_err+" km\n"
+ "Residual RMS "+props.rms+" s\n"
+ "Azimuthal gap "+props.gap+" deg\n\n"
+ props.no_phases + " Phase arrivals:\n"
+ "sta net dist azi phase time res wt sta\n";
for ( i = 0 ; i < props.no_phases ; i++ ) {
html += props.phases[i];
( i < props.no_phases -1 ) ? html += "\n" : null ;
};
html += "</pre></td></tr>\n";
var added = $('#eventstable tbody').append(html);
added.find('.tablesorter-childRow td').hide();
$('#eventstable').find('td.utctime-date').each(function() {
$.localtime.formatObject($(this), "dd. MM. yyyy");
$(this).removeClass('utctime-date');
$(this).addClass('localtime-date');
});
$('#eventstable').find('td.utctime-time').each(function() {
$.localtime.formatObject($(this), "HH:mm");
$(this).removeClass('utctime-time');
$(this).addClass('localtime-time');
});
// force resorting
$("#eventstable").trigger("update", [true]);
};
$(document).ready(function() {
// tablesorter for event list
$("#eventstable").tablesorter(
{
theme : 'blue',
dateFormat : "ddmmyyyy",
headers: {
0: { sorter: "shortDate" }
},
cssChildRow: "tablesorter-childRow", // this is the default setting
widgets: ["uitheme", "zebra", "filter", "pager"], // initialize zebra and filter widgets, "scroller"
widgetOptions: {
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '# {startRow} - {endRow} ({totalRows}) | Seite {page} ({totalPages})',
pager_removeRows: false,
pager_size: 35,
filter_childRows : true,
filter_cssFilter : 'tablesorter-filter',
filter_startsWith : false,
filter_ignoreCase : true,
scroller_height: $('div.map').height() - 250,
scroller_barWidth: 10,
scroller_jumpToHeader: false,
sortList: "[[0,1], [1,1], [2,1]]",
resort: true,
showProcessing: true,
}
});
// hide child rows
$('#eventstable > tbody > tr.tablesorter-childRow td').hide();
// update map after filtering
$('#eventstable').bind('filterEnd', function(){
toggleFilteredMarkers();
});
// highlight first event
$('#eventstable').bind('sortEnd', function(){
highlightFirstEvent();
});
// show / hide event info
$('#eventstable').delegate('.toggle', 'click' , function(){
// toggle visibility of selected row
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').toggle('slow');
// mark currently selected row and remove class selected from all other rows
// hide other rows
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').addClass('selected-now');
$(this).closest('tbody').find('td.selected').each(function(){
if ( ! $(this).hasClass('selected-now') ) {
$(this).hide('slow');
$(this).removeClass('selected');
};
});
$(this).closest('tr').nextUntil('tr.tablesorter-hasChildRow').find('td').each(function(){
$(this).removeClass('selected-now');
var selected = $(this).hasClass('selected');
if ( selected ) {
$(this).removeClass('selected');
} else {
$(this).addClass('selected');
};
});
return false;
});
});
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 720 B

+140
View File
@@ -0,0 +1,140 @@
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>
<!-- $Id$ -->
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='de' lang='de'>
<head>
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
<title>RUB SeisObs - Ereignis- und Stationskarte</title>
<!-- Style definitions -->
<link rel="stylesheet" href="main.css">
<!-- jQuery & jQueryUI -->
<link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/cupertino/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<!-- Localtime -->
<script type="text/javascript" src="jquery.localtime-0.9.1.min.js"></script>
<!-- Tablesorter: required -->
<link rel="stylesheet" href="theme.blue.css">
<script src="jquery.tablesorter.min.js"></script>
<!-- script src="widget-scroller.js"></script -->
<script src="jquery.tablesorter.widgets.min.js"></script>
<script src="jquery.tablesorter.pager.min.js"></script>
<!-- misc functions -->
<script src="misc.js"></script>
<script src="geolocation.js"></script>
<script src="sprintf.min.js"></script>
<!-- Tablesorter: pager -->
<link rel="stylesheet" href="jquery.tablesorter.pager.css">
<script src="widget-pager.js"></script>
<script src="events.js"></script>
<!-- Leaflet -->
<link rel="stylesheet" href="leaflet.css" />
<script src="leaflet.js"></script>
<!-- script src="TileLayer.Grayscale.js"></script -->
<script src="map.js"></script>
<!-- Stations -->
<script src="stations.js"></script>
</head>
<body>
<div class="info" id="tabs">
<ul>
<li><a href="#eventstab"><span>Ereignisse</span></a></li>
<li><a href="#stationstab"><span>Stationen</span></a></li>
<li><a href="#moretab"><span>Mehr</span></a></li>
<li class="infotab"><a href="#infotab"><span>Info</span></a></li>
</ul>
<!-- Ereignisse -->
<div class="tab" id="eventstab">
<div class="pager events" id="eventspager">
<img src="first.png" class="first" alt="First" />
<img src="prev.png" class="prev" alt="Prev" />
<span class="pagedisplay"></span>
<img src="next.png" class="next" alt="Next" />
<img src="last.png" class="last" alt="Last" />
<select class="pagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="gotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="eventstable" data-sortlist="[[0,0],[1,1],[2,1]]">
<colgroup>
<col width="85" />
<col width="50" />
<col width="50" />
<col />
</colgroup>
<thead>
<tr>
<th>Datum</th>
<th>Zeit</th>
<th>Mag.</th>
<th>Ort</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<p>Nominatim Search Courtesy of <a href="http://www.mapquest.com/" target="_blank">MapQuest</a> <img src="http://developer.mapquest.com/content/osm/mq_logo.png"></p>
</div>
<!-- Stations -->
<div class="tab" id="stationstab">
<div class="pager stationspager" id="stationspager">
<img src="first.png" class="stationsfirst" alt="First" />
<img src="prev.png" class="stationsprev" alt="Prev" />
<span class="stationspagedisplay"></span>
<img src="next.png" class="stationsnext" alt="Next" />
<img src="last.png" class="stationslast" alt="Last" />
<select class="stationspagesize" title="Select page size">
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
</select>
<select class="stationsgotoPage" title="Select page number"></select>
</div>
<table class="tablesorter" id="stationstable">
<colgroup>
<col width="77" />
<col/>
<col width="77" />
<col width="77" />
</colgroup>
<thead>
<tr>
<th>Network</th>
<th>Station</th>
<th>Breite [°]</th>
<th>Länge [°]</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<!-- More -->
<div class="tab" id="moretab"></div>
<!-- Info -->
<div class="tab" id="infotab"></div>
</div>
<div class="rublogo"><img class="rublogo" src="logo_RUB_155x30.png" alt="Ruhr-Universität Bochum" title="Ruhr-Universität Bochum"/></div>
<div id="map" class="map"></div>
</body>
+4
View File
@@ -0,0 +1,4 @@
/*! jQuery localtime - v0.9.1 - 2014-01-11
* https://github.com/GregDThomas/jquery-localtime
* Copyright (c) 2014 Greg Thomas; Licensed Apache-2.0 */
(function(e){"use strict";e.localtime=function(){var a={localtime:"yyyy-MM-dd HH:mm:ss"},t=["January","February","March","April","May","June","July","August","September","October","November","December"],r=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],c=["th","st","nd","rd"],s=function(e){return e>=13?e-12:"0"===e?12:e},i=function(e,i){var o=""+e.getFullYear(),n=""+(e.getMonth()+1),l=""+e.getDate(),m=e.getDay(),d=""+e.getHours(),u=""+e.getMinutes(),b=""+e.getSeconds(),f=""+e.getMilliseconds(),k=e.getTimezoneOffset(),h=k>0?"-":"+";if(k=Math.abs(k),void 0===i){var y;for(y in a)if(a.hasOwnProperty(y)){i=a[y];break}if(void 0===i)return""+e}for(var g="",p="",M=0;i.length>M;M++)if(p+=i.charAt(M),"'"===p)for(M++;i.length>M;M++){var T=i.charAt(M);if("'"===T){p="";break}g+=T}else if("\\"===p&&i.length-1>M&&"'"===i.charAt(M+1))M++,g+="'",p="";else if(M===i.length-1||i.charAt(M)!==i.charAt(M+1)){switch(p){case"d":g+=l;break;case"dd":g+=("0"+l).slice(-2);break;case"ddd":g+=r[m].substr(0,3);break;case"ddddd":g+=r[m];break;case"M":g+=n;break;case"MM":g+=("0"+n).slice(-2);break;case"MMM":g+=t[n-1].substr(0,3);break;case"MMMMM":g+=t[n-1];break;case"yy":g+=o.slice(-2);break;case"yyyy":g+=o;break;case"H":g+=d;break;case"HH":g+=("0"+d).slice(-2);break;case"h":g+=s(d);break;case"hh":g+=("0"+s(d)).slice(-2);break;case"m":g+=u;break;case"mm":g+=("0"+u).slice(-2);break;case"s":g+=b;break;case"ss":g+=("0"+b).slice(-2);break;case"S":g+=f;break;case"SS":g+=("0"+f).slice(-2);break;case"SSS":g+=("00"+f).slice(-3);break;case"o":switch(l){case"11":case"12":case"13":g+=c[0];break;default:var v=l%10;v>3&&(v=0),g+=c[v]}break;case"a":case"TT":g+=d>=12?"PM":"AM";break;case"tt":g+=d>=12?"pm":"am";break;case"T":g+=d>=12?"P":"A";break;case"t":g+=d>=12?"p":"a";break;case"z":g+=h+parseInt(k/60,10);break;case"zz":g+=h+("0"+parseInt(k/60,10)).slice(-2);break;case"zzz":g+=h+("0"+parseInt(k/60,10)).slice(-2)+":"+("0"+k%60).slice(-2);break;default:g+=p}p=""}return g};return{setFormat:function(e){a="object"==typeof e?e:{localtime:e}},getFormat:function(){return a},parseISOTimeString:function(a){a=e.trim(""+a);var t=/^(\d{4})-([01]\d)-([0-3]\d)[T| ]([0-2]\d):([0-5]\d)(?::([0-5]\d)(?:\.(\d{3}))?)?Z$/.exec(a);if(t){var r=parseInt(t[1],10),c=parseInt(t[2],10)-1,s=parseInt(t[3],10),i=parseInt(t[4],10),o=parseInt(t[5],10),n=t[6]?parseInt(t[6],10):0,l=t[7]?parseInt(t[7],10):0,m=new Date(Date.UTC(r,c,s,i,o,n,l));if(m.getUTCFullYear()!==r||m.getUTCMonth()!==c||m.getUTCDate()!==s)throw Error(t[1]+"-"+t[2]+"-"+t[3]+" is not a valid date");if(m.getUTCHours()!==i)throw Error(t[4]+":"+t[5]+" is not a valid time");return m}throw Error(a+" is not a supported date/time string")},toLocalTime:function(a,t){return"[object Date]"!==Object.prototype.toString.call(a)&&(a=e.localtime.parseISOTimeString(a)),""===t&&(t=void 0),i(a,t)},formatObject:function(a,t){a.is(":input")?a.val(e.localtime.toLocalTime(a.val(),t)):a.is("time")?a.text(e.localtime.toLocalTime(a.attr("datetime"),t)):a.text(e.localtime.toLocalTime(a.text(),t))},formatPage:function(){e.localtime.format()},format:function(a){var t,r,c=function(){e.localtime.formatObject(e(this),t)},s=e.localtime.getFormat();for(r in s)s.hasOwnProperty(r)&&(t=s[r],e("."+r,a).each(c));e("[data-localtime-format]",a).each(function(){e.localtime.formatObject(e(this),e(this).attr("data-localtime-format"))})}}}()})(jQuery),jQuery(document).ready(function(e){"use strict";e.localtime.format()});
+5
View File
File diff suppressed because one or more lines are too long
+42
View File
@@ -0,0 +1,42 @@
/* pager wrapper, div */
.tablesorter-pager {
padding: 5px;
}
/* pager wrapper, in thead/tfoot */
td.tablesorter-pager {
background-color: #e6eeee;
margin: 0; /* needed for bootstrap .pager gets a 18px bottom margin */
}
/* pager navigation arrows */
.tablesorter-pager img {
vertical-align: middle;
margin-right: 2px;
cursor: pointer;
}
/* pager output text */
.tablesorter-pager .pagedisplay {
padding: 0 5px 0 5px;
width: auto;
white-space: nowrap;
text-align: center;
}
/* pager element reset (needed for bootstrap) */
.tablesorter-pager select {
margin: 0;
padding: 0;
}
/*** css used when "updateArrows" option is true ***/
/* the pager itself gets a disabled class when the number of rows is less than the size */
.tablesorter-pager.disabled {
display: none;
}
/* hide or fade out pager arrows when the first or last row is visible */
.tablesorter-pager .disabled {
/* visibility: hidden */
opacity: 0.5;
filter: alpha(opacity=50);
cursor: default;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 737 B

+478
View File
@@ -0,0 +1,478 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-tile-container,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
-webkit-user-drag: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
.leaflet-overlay-pane svg {
-moz-user-select: none;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
.leaflet-vml-shape {
width: 1px;
height: 1px;
}
.lvml {
behavior: url(#default#VML);
display: inline-block;
position: absolute;
}
/* control positioning */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile,
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging .leaflet-container,
.leaflet-dragging .leaflet-clickable {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #38f;
background: rgba(255,255,255,0.5);
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
border-radius: 4px;
}
.leaflet-bar a,
.leaflet-bar a:hover {
background-color: #fff;
border-bottom: 1px solid #ccc;
width: 26px;
height: 26px;
line-height: 26px;
display: block;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-bar a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-bar a:hover {
background-color: #f4f4f4;
}
.leaflet-bar a:first-child {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.leaflet-bar a:last-child {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom: none;
}
.leaflet-bar a.leaflet-disabled {
cursor: default;
background-color: #f4f4f4;
color: #bbb;
}
.leaflet-touch .leaflet-bar a {
width: 30px;
height: 30px;
line-height: 30px;
}
/* zoom control */
.leaflet-control-zoom-in,
.leaflet-control-zoom-out {
font: bold 18px 'Lucida Console', Monaco, monospace;
text-indent: 1px;
}
.leaflet-control-zoom-out {
font-size: 20px;
}
.leaflet-touch .leaflet-control-zoom-in {
font-size: 22px;
}
.leaflet-touch .leaflet-control-zoom-out {
font-size: 24px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
background: #fff;
border-radius: 5px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-retina .leaflet-control-layers-toggle {
background-image: url(images/layers-2x.png);
background-size: 26px 26px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background: #fff;
background: rgba(255, 255, 255, 0.7);
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-control-attribution a {
text-decoration: none;
}
.leaflet-control-attribution a:hover {
text-decoration: underline;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
white-space: nowrap;
overflow: hidden;
-moz-box-sizing: content-box;
box-sizing: content-box;
background: #fff;
background: rgba(255, 255, 255, 0.5);
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-bar {
border: 2px solid rgba(0,0,0,0.2);
background-clip: padding-box;
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
border-radius: 12px;
}
.leaflet-popup-content {
margin: 13px 19px;
line-height: 1.4;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 17px;
height: 17px;
padding: 1px;
margin: -10px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper,
.leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
position: absolute;
top: 0;
right: 0;
padding: 4px 4px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
.leaflet-oldie .leaflet-popup-content-wrapper {
zoom: 1;
}
.leaflet-oldie .leaflet-popup-tip {
width: 24px;
margin: 0 auto;
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
}
.leaflet-oldie .leaflet-popup-tip-container {
margin-top: -1px;
}
.leaflet-oldie .leaflet-control-zoom,
.leaflet-oldie .leaflet-control-layers,
.leaflet-oldie .leaflet-popup-content-wrapper,
.leaflet-oldie .leaflet-popup-tip {
border: 1px solid #999;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
+9
View File
File diff suppressed because one or more lines are too long
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

+67
View File
@@ -0,0 +1,67 @@
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
z-index: 1;
position: absolute;
top: 0;
left: 0;
margin: 0;
width: 100%;
height: 100%;
font-family: sans-serif;
}
div.info {
z-index: 10000;
position: absolute;
left: 10px;
top: 14px;
padding: 4px;
width: 435px;
font-size: small;
font: sans-serif;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.95);
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
overflow: auto;
}
div.tab {
z-index: 10010;
width: 400px;
padding: 0px;
float: left;
font-size: small;
font: sans-serif;
background: rgb(255, 255, 255);
background: rgba(25, 255, 255, 0.95);
}
div.rublogo {
z-index: 10000;
position: absolute;
top: 10px;
right: 46px;
height: 33px;
padding: 10px;
width: 155px;
font-size: x-small;
font: sans-serif;
color: #003560;
background: rgb(255, 255, 255);
background: rgba(255, 255, 255, 0.95);
border-radius: 4px;
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
}
a.map-link {
float: right;
}
li.infotab {
float: right!important;
}
td.ar {
text-align: right;
}
</style>
+192
View File
@@ -0,0 +1,192 @@
/* toggles visibility of filtered markers
* only events in the event list are shown */
function toggleFilteredMarkers() {
// show all shown events in map
$("#eventstable > tbody > tr:not(.filtered) > td > a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle({opacity: 1, strokeOpacity: 1, fillOpacity: eventMarkerOpacity});
};
});
// hide filtered events in map
$("#eventstable > tbody > tr.filtered > td > a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle({opacity: 0, strokeOpacity: 0, fillOpacity: 0});
};
});
highlightFirstEvent();
};
/* Highlight the first event of the event list on the map if no
* other event is selected */
function highlightFirstEvent() {
var highlightStyle = {
color: 'red',
fillColor: '#f03',
};
var normalStyle = {
fillColor: "#FFF500",
color: "#FFF500"
};
$("#eventstable a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
$(this).removeClass('first');
$(this).text('Karte');
};
});
$("#eventstable > tbody > tr:not(.filtered)").first().find("a.map-link").each(function() {
if ( $(this).attr("eventid") ) {
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
$(this).addClass('first');
$(this).text('Karte (rot)');
};
});
};
function highlightEvent( id ) {
var highlightStyle = {
color: 'red',
fillColor: '#f03',
};
var normalStyle = {
fillColor: "#FFF500",
color: "#FFF500"
};
$("#eventstable > tbody > tr:not(.filtered)").find("a.map-link").each( function() {
if ( $(this).attr("eventid") ) {
if ( $(this).attr("eventid") == id ) {
eventTable[$(this).attr("eventid")].setStyle(highlightStyle);
$(this).addClass('first');
$(this).text('Karte (rot)');
} else {
eventTable[$(this).attr("eventid")].setStyle(normalStyle);
$(this).removeClass('first');
$(this).text('Karte');
}
};
});
};
/* add station marker */
function addStationMarker(id, lat, lng) {
var a = 0.0025,
b = Math.sqrt(3)*a,
a = a * Math.cos(lat*Math.PI/180);
var corners = [L.latLng(lat+2*a, lng), L.latLng(lat-a, lng+b), L.latLng(lat-a, lng-b)];
var marker = L.polygon(corners,
{
fillColor: "#1C771C",
color: "#1C771C",
weight: 1,
opacity: 1,
fillOpacity: stationMarkerOpacity,
className: id+' stationMarker',
}).addTo(stationLayer);
stationTable[id] = marker;
};
/* add event marker */
function addEventMarker(id, lat, lng, mag) {
var markerOptions = {
fillColor: "#FFF500",
color: "#FFF500",
weight: 1,
opacity: 1,
fillOpacity: eventMarkerOpacity,
className: id+' eventMarker',
};
var marker = L.circle(L.latLng(lat, lng), mag2radius(mag), markerOptions).addTo(eventLayer);
eventTable[id] = marker;
return marker;
};
/* handle to show events on map */
function initMapLink() {
$("#eventstable > tbody > tr > td > a.map-link").on('click' , function(){
var highlightStyle = {
color: 'red',
fillColor: '#f03',
className: $(this).attr('eventid')
}
var normalStyle = {
fillColor: "#FFF500",
color: "#FFF500"
};
// mark currently selected link and remove class selected from all other links
// set everything to normal state
$(this).addClass('selected-now');
$("#eventstable > tbody > tr:not(.filtered) > td > a.map-link:not(.selected-now)").each(function(){
$(this).removeClass('selected');
$(this).text('Karte');
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
});
// switch event of first row to normalStyle if it is not the selected one
( $(this).hasClass('first') ) ? null : eventTable[$("#eventstable > tbody > tr:not(.filtered)").first().find("a.map-link").attr("eventid")].setStyle(normalStyle);
$(this).each(function(){
$(this).removeClass('selected-now');
// selected -> unselected
if ( $(this).hasClass('selected') ) {
$(this).removeClass('selected');
$(this).text('Karte');
eventTable[$(this).attr('eventid')].setStyle(normalStyle);
map.setView(mapCentreDefault, zoomDefault);
highlightFirstEvent();
// unselected -> selected
} else {
$(this).addClass('selected');
$(this).text('im Fokus (rot)');
eventTable[$(this).attr('eventid')].setStyle(highlightStyle);
map.setView(eventTable[$(this).attr('eventid')].getLatLng(), zoomFocus);
};
});
return false;
});
};
/******************
* document ready *
******************/
$(document).ready(function() {
// create a map in the "map" div, set the view to a given place and zoom
map = L.map('map', { zoomControl: false }).setView(mapCentreDefault, zoomDefault);
new L.Control.Zoom({ position: 'topright' }).addTo(map);
// add MapQuestOSM tile layer
// L.tileLayer.grayscale('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg',
L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg',
{
subdomains: '1234',
detectRetina: true,
attribution: 'Map data &copy; <a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a> | Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png">',
}).addTo(map);
// add ESRI Grayscale World Map (neither city nor road names)
/* L.tileLayer('//server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
{
attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
maxZoom: 16
}).addTo(map); */
// read in stations
stationLayer = L.geoJson().addTo(map);
// read in events, process filter
eventLayer = L.geoJson().addTo(map);
ajaxLoadEvents();
toggleFilteredMarkers();
// bind popupopen event
map.on('popupopen', function() {
// convert date/time to localtime
$("div.leaflet-popup span.utctime").each(function(){$(this).addClass("localtime").removeClass("utctime");$.localtime.formatObject($(this), "dd.MM.yyyy - HH:mm")});
var eventid = $("div.leaflet-popup h3").attr("eventid");
if ( eventid ) {
// highlight event in table
highlightEvent(eventid);
// update city in popup
$("div.leaflet-popup h3").text(geolocationTable[eventid]);
};
});
});
+85
View File
@@ -0,0 +1,85 @@
// calculate marker radius from magnitude, both formulas have equal radii at mag=1.2
function mag2radius(mag) {
return 400*mag; // radius proportional to magagnitude
// return 8.104*Math.pow(30,mag) // radius proportional to energy
};
// set height of eventlist div
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
function setInfoHeight() {
var height = $('div.map').height() - 36;
$('div.info').height(height);
//$('.tab').height(height-80);
//$('#eventtable').height(height-100);
};
/* get region and regionID of a location */
function getLocation(lat, lng) {
var region = false;
var regionID;
var regions = [
['Monschau', 'Schleiden', 'Bad Münstereifel', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Hessen', 'Hessen', 'Hessen', 'Hessen'],
['Aachen', 'Zülpich', 'Euskirchen', 'Bonn', 'Rheinland-Pfalz', 'Rheinland-Pfalz', 'Hessen', 'Hessen', 'Hessen', 'Hessen'],
['Geilenkirchen', 'Düren', 'Köln', 'Köln-Mülheim', 'Waldbröl', 'Freudenberg', 'Siegen', 'Hessen', 'Hessen', 'Hessen'],
['Heinsberg', 'Mönchengladbach', 'Neuss', 'Solingen', 'Gummersbach', 'Olpe', 'Schmallenberg', 'Bad Berleburg', 'Hessen', 'Hessen'],
['Nettetal', 'Krefeld', 'Düsseldorf', 'Wuppertal', 'Hagen', 'Iserlohn', 'Arnsberg', 'Brilon', 'Hessen', 'Hessen'],
['Geldern', 'Moers', 'Duisburg', 'Essen', 'Dortmund', 'Unna', 'Soest', 'Büren', 'Marsberg', 'Warburg'],
['Kleve', 'Wesel', 'Dorsten', 'Recklinghausen', 'Lünen', 'Hamm/Westfalen', 'Beckum', 'Lippstadt', 'Paderborn', 'Bad Driburg'],
['Emmerich am Rhein', 'Bocholt', 'Borken', 'Coesfeld', 'Münster', 'Warendorf', 'Rheda-Wiedenbrück', 'Gütersloh', 'Detmold', 'Bad Pyrmont'],
['The Netherlands', 'The Netherlands', 'Vreden', 'Ahaus', 'Steinfurt', 'Lengerich', 'Bad Ilburg', 'Bielefeld', 'Herford', 'Niedersachsen'],
['The Netherlands', 'The Netherlands', 'The Netherlands', 'Niedersachsen', 'Rheine', 'Ibbenbüren', 'Niedersachsen', 'Lübbecke', 'Minden', 'Niedersachsen']
];
if ( lat >= 50.4 && lat < 52.4 && lng >= 6.0 && lng < 9.333333 ) {
var latIndex = Math.floor((lat-50.4)*5); // 5 tiles per degree
var lngIndex = Math.floor((lng-6.0)*3); // 3 tiles per degree
region = regions[latIndex][lngIndex];
};
if ( region != 'The Netherlands' ) {
regionID = 5500-latIndex*200+lngIndex*2+2;
};
if ( lat >= 50.9 && lat < 51.1 && lng >= 5.666666 && lng < 6.0 ) {
region = 'Selfkant';
regionID = 5000;
};
return [ region, regionID ];
};
// window resize
$( window ).resize(function() {
setInfoHeight();
});
// create global vars
var map
var eventTable = {};
var eventDetails = {};
var stationTable = {};
var eventMarkerOpacity = 0.3;
var stationMarkerOpacity = 0.5;
var zoomFocus = 12;
var zoomDefault = 9;
var mapCentreDefault = [51.85, 7.0];
var minMag = 1.2;
// run when ready
$(document).ready(function() {
// AJAX setup
$.ajaxSetup({timeout: 15000}); // 15 seconds
// adjust height of infocontainer
setInfoHeight();
// create tabs
var tabOptions = {
active: 0,
disabled: [2, 3],
};
$('#tabs').tabs(tabOptions);
// $('.ui-tabs-nav').sortable();
});
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

+1
View File
@@ -0,0 +1 @@
/*! sprintf.js | Copyright (c) 2007-2013 Alexandru Marasteanu <hello at alexei dot ro> | 3 clause BSD license */(function(e){function r(e){return Object.prototype.toString.call(e).slice(8,-1).toLowerCase()}function i(e,t){for(var n=[];t>0;n[--t]=e);return n.join("")}var t=function(){return t.cache.hasOwnProperty(arguments[0])||(t.cache[arguments[0]]=t.parse(arguments[0])),t.format.call(null,t.cache[arguments[0]],arguments)};t.format=function(e,n){var s=1,o=e.length,u="",a,f=[],l,c,h,p,d,v;for(l=0;l<o;l++){u=r(e[l]);if(u==="string")f.push(e[l]);else if(u==="array"){h=e[l];if(h[2]){a=n[s];for(c=0;c<h[2].length;c++){if(!a.hasOwnProperty(h[2][c]))throw t('[sprintf] property "%s" does not exist',h[2][c]);a=a[h[2][c]]}}else h[1]?a=n[h[1]]:a=n[s++];if(/[^s]/.test(h[8])&&r(a)!="number")throw t("[sprintf] expecting number but found %s",r(a));switch(h[8]){case"b":a=a.toString(2);break;case"c":a=String.fromCharCode(a);break;case"d":a=parseInt(a,10);break;case"e":a=h[7]?a.toExponential(h[7]):a.toExponential();break;case"f":a=h[7]?parseFloat(a).toFixed(h[7]):parseFloat(a);break;case"o":a=a.toString(8);break;case"s":a=(a=String(a))&&h[7]?a.substring(0,h[7]):a;break;case"u":a>>>=0;break;case"x":a=a.toString(16);break;case"X":a=a.toString(16).toUpperCase()}a=/[def]/.test(h[8])&&h[3]&&a>=0?"+"+a:a,d=h[4]?h[4]=="0"?"0":h[4].charAt(1):" ",v=h[6]-String(a).length,p=h[6]?i(d,v):"",f.push(h[5]?a+p:p+a)}}return f.join("")},t.cache={},t.parse=function(e){var t=e,n=[],r=[],i=0;while(t){if((n=/^[^\x25]+/.exec(t))!==null)r.push(n[0]);else if((n=/^\x25{2}/.exec(t))!==null)r.push("%");else{if((n=/^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(t))===null)throw"[sprintf] huh?";if(n[2]){i|=1;var s=[],o=n[2],u=[];if((u=/^([a-z_][a-z_\d]*)/i.exec(o))===null)throw"[sprintf] huh?";s.push(u[1]);while((o=o.substring(u[0].length))!=="")if((u=/^\.([a-z_][a-z_\d]*)/i.exec(o))!==null)s.push(u[1]);else{if((u=/^\[(\d+)\]/.exec(o))===null)throw"[sprintf] huh?";s.push(u[1])}n[2]=s}else i|=2;if(i===3)throw"[sprintf] mixing positional and named placeholders is not (yet) supported";r.push(n)}t=t.substring(n[0].length)}return r};var n=function(e,n,r){return r=n.slice(0),r.splice(0,0,e),t.apply(null,r)};e.sprintf=t,e.vsprintf=n})(typeof exports!="undefined"?exports:window);
+118
View File
@@ -0,0 +1,118 @@
// Load the stations using ajax
function loadStations(stime, etime) {
var mapBounds = map.getBounds();
var N = mapBounds.getNorth();
var E = mapBounds.getEast();
var S = mapBounds.getSouth();
var W = mapBounds.getWest();
var d = 0.1;
var url = "https://ariadne.geophysik.ruhr-uni-bochum.de/fdsnws/station/1/query";
if ( !stime ) {
var stime = new Date();
stime.setDate(stime.getDate()-180);
};
if ( !etime ) {
var etime = new Date();
etime.setDate(etime.getDate()+1);
};
var request_data = {
endafter: sprintf("%d-%02d-%02d", stime.getFullYear(), stime.getMonth()+1, stime.getDate()),
startbefore: sprintf("%d-%02d-%02d", etime.getFullYear(), etime.getMonth()+1, etime.getDate()),
minlat: S-d,
maxlat: N+d,
minlon: W-d,
maxlon: E+d,
};
$.ajax({
type: "GET",
url: url,
dataType: "xml",
data: request_data,
success: function (xml) {
$(xml).find('Network').each(function () {
var network = $(this).attr('code');
$(this).find('Station').each(function () {
var station = $(this).attr('code'),
lat = $(this).find('Latitude').text(),
lng = $(this).find('Longitude').text(),
stationID = network+'.'+station;
if ( !stationTable[stationID] ) { // && N >= lat && S <= lat && W<= lng && E >= lng
var row = sprintf('<tr><td>%s</td><td>%s</td><td class="ar">%7.4f</td><td class="ar">%7.4f</td></tr>' , network, station, Number(lat), Number(lng));
var r = $(row);
$('#stationstable tbody').append(r);
addStationMarker(stationID, Number(lat), Number(lng));
};
});
});
},
complete: function () {
initStationTable();
var sort = [[0,0],[1,0]];
$("#stationstable").trigger("update", [true]);
$("#stationstable").trigger("updateCache");
$("#stationstable").trigger("sorton", [sort]);
$("#stationstable > tbody > tr:even").addClass("odd");
$("#stationstable > tbody > tr:odd").addClass("even");
}
});
};
function initStationTable() {
// tablesorter for station list
$("#stationstable").tablesorter(
{
theme : 'blue',
cssChildRow: "tablesorter-childRow", // this is the default setting
widgets: ["uitheme", "zebra", "filter", "pager"], // initialize zebra and filter widgets, "scroller"
widgetOptions: {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '# {startRow} - {endRow} ({totalRows}) | Seite {page} ({totalPages})',
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
pager_startPage: 0,
// Number of visible rows
pager_size: 35,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager_savePages: true,
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager_fixedHeight: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager_removeRows: false,
// css class names of pager arrows
pager_css: {
container : 'stations-tablesorter-pager',
errorRow : 'tablesorter-errorRow', // error information row (don't include period at beginning)
disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
},
// jQuery pager selectors
pager_selectors: {
container : '.stationspager', // target the pager markup (wrapper)
first : '.stationsfirst', // go to first page arrow
prev : '.stationsprev', // previous page arrow
next : '.stationsnext', // next page arrow
last : '.stationslast', // go to last page arrow
goto : '.stationsgotoPage', // go to page selector - select dropdown that sets the current page
pageDisplay : '.stationspagedisplay', // location of where the "output" is displayed
pageSize : '.stationspagesize' // page size selector - select dropdown that sets the "size" option
},
filter_childRows : true,
filter_cssFilter : 'tablesorter-filter',
filter_startsWith : false,
filter_ignoreCase : true,
scroller_height: $('div.map').height() - 250,
scroller_barWidth: 10,
scroller_jumpToHeader: false,
sortList: "[[0,0], [1,0]]",
resort: true,
showProcessing: true,
}
});
};
$(document).ready(function() {
loadStations();
});
+221
View File
@@ -0,0 +1,221 @@
/*************
Blue Theme
*************/
/* overall */
.tablesorter-blue {
width: 100%;
background-color: #fff;
margin: 10px 0 15px;
text-align: left;
border-spacing: 0;
border: #cdcdcd 1px solid;
border-width: 1px 0 0 1px;
}
.tablesorter-blue th,
.tablesorter-blue td {
border: #cdcdcd 1px solid;
border-width: 0 1px 1px 0;
}
/* header */
.tablesorter-blue th,
.tablesorter-blue thead td {
font: bold 12px/18px Arial, Sans-serif;
color: #000;
background-color: #99bfe6;
border-collapse: collapse;
padding: 4px;
text-shadow: 0 1px 0 rgba(204, 204, 204, 0.7);
}
.tablesorter-blue tbody td,
.tablesorter-blue tfoot th,
.tablesorter-blue tfoot td {
padding: 4px;
vertical-align: top;
}
.tablesorter-blue .header,
.tablesorter-blue .tablesorter-header {
/* black (unsorted) double arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==);
/* white (unsorted) double arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAJAIAAAP///////yH5BAEAAAEALAAAAAAVAAkAAAIXjI+AywnaYnhUMoqt3gZXPmVg94yJVQAAOw==); */
/* image */
/* background-image: url(images/black-unsorted.gif); */
background-repeat: no-repeat;
background-position: center right;
padding: 4px 18px 4px 4px;
white-space: normal;
cursor: pointer;
}
.tablesorter-blue .headerSortUp,
.tablesorter-blue .tablesorter-headerSortUp,
.tablesorter-blue .tablesorter-headerAsc {
background-color: #9fbfdf;
/* black asc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7);
/* white asc arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjI8Bya2wnINUMopZAQA7); */
/* image */
/* background-image: url(images/black-asc.gif); */
}
.tablesorter-blue .headerSortDown,
.tablesorter-blue .tablesorter-headerSortDown,
.tablesorter-blue .tablesorter-headerDesc {
background-color: #8cb3d9;
/* black desc arrow */
background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAACMtMP///yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7);
/* white desc arrow */
/* background-image: url(data:image/gif;base64,R0lGODlhFQAEAIAAAP///////yH5BAEAAAEALAAAAAAVAAQAAAINjB+gC+jP2ptn0WskLQA7); */
/* image */
/* background-image: url(images/black-desc.gif); */
}
.tablesorter-blue thead .sorter-false {
background-image: none;
cursor: default;
padding: 4px;
}
/* tfoot */
.tablesorter-blue tfoot .tablesorter-headerSortUp,
.tablesorter-blue tfoot .tablesorter-headerSortDown,
.tablesorter-blue tfoot .tablesorter-headerAsc,
.tablesorter-blue tfoot .tablesorter-headerDesc {
/* remove sort arrows from footer */
background-image: none;
}
/* tbody */
.tablesorter-blue td {
color: #3d3d3d;
background-color: #fff;
padding: 4px;
vertical-align: top;
}
/* hovered row colors
you'll need to add additional lines for
rows with more than 2 child rows
*/
.tablesorter-blue tbody > tr:hover > td,
.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.even:hover > td,
.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.even:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #d9d9d9;
}
.tablesorter-blue tbody > tr.odd:hover > td,
.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow > td,
.tablesorter-blue tbody > tr.odd:hover + tr.tablesorter-childRow + tr.tablesorter-childRow > td {
background: #bfbfbf;
}
/* table processing indicator */
.tablesorter-blue .tablesorter-processing {
background-position: center center !important;
background-repeat: no-repeat !important;
/* background-image: url(../addons/pager/icons/loading.gif) !important; */
background-image: url('data:image/gif;base64,R0lGODlhFAAUAKEAAO7u7lpaWgAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQBCgACACwAAAAAFAAUAAACQZRvoIDtu1wLQUAlqKTVxqwhXIiBnDg6Y4eyx4lKW5XK7wrLeK3vbq8J2W4T4e1nMhpWrZCTt3xKZ8kgsggdJmUFACH5BAEKAAIALAcAAAALAAcAAAIUVB6ii7jajgCAuUmtovxtXnmdUAAAIfkEAQoAAgAsDQACAAcACwAAAhRUIpmHy/3gUVQAQO9NetuugCFWAAAh+QQBCgACACwNAAcABwALAAACE5QVcZjKbVo6ck2AF95m5/6BSwEAIfkEAQoAAgAsBwANAAsABwAAAhOUH3kr6QaAcSrGWe1VQl+mMUIBACH5BAEKAAIALAIADQALAAcAAAIUlICmh7ncTAgqijkruDiv7n2YUAAAIfkEAQoAAgAsAAAHAAcACwAAAhQUIGmHyedehIoqFXLKfPOAaZdWAAAh+QQFCgACACwAAAIABwALAAACFJQFcJiXb15zLYRl7cla8OtlGGgUADs=') !important;
}
/* Zebra Widget - row alternating colors */
.tablesorter-blue tbody tr.odd td {
background-color: #ebf2fa;
}
.tablesorter-blue tbody tr.even td {
background-color: #fff;
}
/* Column Widget - column sort colors */
.tablesorter-blue td.primary,
.tablesorter-blue tr.odd td.primary {
background-color: #99b3e6;
}
.tablesorter-blue tr.even td.primary {
background-color: #c2d1f0;
}
.tablesorter-blue td.secondary,
.tablesorter-blue tr.odd td.secondary {
background-color: #c2d1f0;
}
.tablesorter-blue tr.even td.secondary {
background-color: #d6e0f5;
}
.tablesorter-blue td.tertiary,
.tablesorter-blue tr.odd td.tertiary {
background-color: #d6e0f5;
}
.tablesorter-blue tr.even td.tertiary {
background-color: #ebf0fa;
}
/* caption */
caption {
background: #fff;
}
/* filter widget */
.tablesorter-blue .tablesorter-filter-row td {
background: #eee;
line-height: normal;
text-align: center; /* center the input */
-webkit-transition: line-height 0.1s ease;
-moz-transition: line-height 0.1s ease;
-o-transition: line-height 0.1s ease;
transition: line-height 0.1s ease;
}
/* optional disabled input styling */
.tablesorter-blue .tablesorter-filter-row .disabled {
opacity: 0.5;
filter: alpha(opacity=50);
cursor: not-allowed;
}
/* hidden filter row */
.tablesorter-blue .tablesorter-filter-row.hideme td {
/*** *********************************************** ***/
/*** change this padding to modify the thickness ***/
/*** of the closed filter row (height = padding x 2) ***/
padding: 2px;
/*** *********************************************** ***/
margin: 0;
line-height: 0;
cursor: pointer;
}
.tablesorter-blue .tablesorter-filter-row.hideme .tablesorter-filter {
height: 1px;
min-height: 0;
border: 0;
padding: 0;
margin: 0;
/* don't use visibility: hidden because it disables tabbing */
opacity: 0;
filter: alpha(opacity=0);
}
/* filters */
.tablesorter-blue .tablesorter-filter {
width: 98%;
height: auto;
margin: 0;
padding: 4px;
background-color: #fff;
border: 1px solid #bbb;
color: #333;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: height 0.1s ease;
-moz-transition: height 0.1s ease;
-o-transition: height 0.1s ease;
transition: height 0.1s ease;
}
/* rows hidden by filtering (needed for child rows) */
.tablesorter .filtered {
display: none;
}
/* ajax error row */
.tablesorter .tablesorter-errorRow td {
text-align: center;
cursor: pointer;
background-color: #e6bf99;
}
+863
View File
@@ -0,0 +1,863 @@
/* Pager widget (beta) for TableSorter 3/31/2014 (v2.15.12) */
/*jshint browser:true, jquery:true, unused:false */
;(function($){
"use strict";
var tsp,
ts = $.tablesorter;
ts.addWidget({
id: "pager",
priority: 55, // load pager after filter widget
options : {
// output default: '{page}/{totalPages}'
// possible variables: {page}, {totalPages}, {filteredPages}, {startRow}, {endRow}, {filteredRows} and {totalRows}
pager_output: '{startRow} to {endRow} of {totalRows} rows', // '{page}/{totalPages}'
// apply disabled classname to the pager arrows when the rows at either extreme is visible
pager_updateArrows: true,
// starting page of the pager (zero based index)
pager_startPage: 0,
// Number of visible rows
pager_size: 10,
// Save pager page & size if the storage script is loaded (requires $.tablesorter.storage in jquery.tablesorter.widgets.js)
pager_savePages: true,
//defines custom storage key
pager_storageKey: 'tablesorter-pager',
// if true, the table will remain the same height no matter how many records are displayed. The space is made up by an empty
// table row set to a height to compensate; default is false
pager_fixedHeight: false,
// count child rows towards the set page size? (set true if it is a visible table row within the pager)
// if true, child row(s) may not appear to be attached to its parent row, may be split across pages or
// may distort the table if rowspan or cellspans are included.
pager_countChildRows: false,
// remove rows from the table to speed up the sort of large tables.
// setting this to false, only hides the non-visible rows; needed if you plan to add/remove rows with the pager enabled.
pager_removeRows: false, // removing rows in larger tables speeds up the sort
// use this format: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
// where {page} is replaced by the page number, {size} is replaced by the number of records to show,
// {sortList:col} adds the sortList to the url into a "col" array, and {filterList:fcol} adds
// the filterList to the url into an "fcol" array.
// So a sortList = [[2,0],[3,0]] becomes "&col[2]=0&col[3]=0" in the url
// and a filterList = [[2,Blue],[3,13]] becomes "&fcol[2]=Blue&fcol[3]=13" in the url
pager_ajaxUrl: null,
// modify the url after all processing has been applied
pager_customAjaxUrl: function(table, url) { return url; },
// modify the $.ajax object to allow complete control over your ajax requests
pager_ajaxObject: {
dataType: 'json'
},
// set this to false if you want to block ajax loading on init
pager_processAjaxOnInit: true,
// process ajax so that the following information is returned:
// [ total_rows (number), rows (array of arrays), headers (array; optional) ]
// example:
// [
// 100, // total rows
// [
// [ "row1cell1", "row1cell2", ... "row1cellN" ],
// [ "row2cell1", "row2cell2", ... "row2cellN" ],
// ...
// [ "rowNcell1", "rowNcell2", ... "rowNcellN" ]
// ],
// [ "header1", "header2", ... "headerN" ] // optional
// ]
pager_ajaxProcessing: function(ajax){ return [ 0, [], null ]; },
// css class names of pager arrows
pager_css: {
container : 'tablesorter-pager',
errorRow : 'tablesorter-errorRow', // error information row (don't include period at beginning)
disabled : 'disabled' // class added to arrows @ extremes (i.e. prev/first arrows "disabled" on first page)
},
// jQuery selectors
pager_selectors: {
container : '.pager', // target the pager markup
first : '.first', // go to first page arrow
prev : '.prev', // previous page arrow
next : '.next', // next page arrow
last : '.last', // go to last page arrow
goto : '.gotoPage', // go to page selector - select dropdown that sets the current page
pageDisplay : '.pagedisplay', // location of where the "output" is displayed
pageSize : '.pagesize' // page size selector - select dropdown that sets the "size" option
}
},
init: function(table){
tsp.init(table);
},
// only update to complete sorter initialization
format: function(table, c){
if (!(c.pager && c.pager.initialized)){
return tsp.initComplete(table, c);
}
tsp.moveToPage(table, c.pager, false);
},
remove: function(table, c){
tsp.destroyPager(table, c);
}
});
/* pager widget functions */
tsp = ts.pager = {
init: function(table) {
// check if tablesorter has initialized
if (table.hasInitialized && table.config.pager.initialized) { return; }
var t,
c = table.config,
wo = c.widgetOptions,
s = wo.pager_selectors,
// save pager variables
p = c.pager = $.extend({
totalPages: 0,
filteredRows: 0,
filteredPages: 0,
currentFilters: [],
page: wo.pager_startPage,
size: wo.pager_size,
startRow: 0,
endRow: 0,
ajaxCounter: 0,
$size: null,
last: {}
}, c.pager);
// pager initializes multiple times before table has completed initialization
if (p.isInitializing) { return; }
p.isInitializing = true;
if (c.debug) {
ts.log('Pager initializing');
}
// added in case the pager is reinitialized after being destroyed.
p.$container = $(s.container).addClass(wo.pager_css.container).show();
// goto selector
p.$goto = p.$container.find(s.goto);
// page size selector
p.$size = p.$container.find(s.pageSize);
p.totalRows = c.$tbodies.eq(0).children().length;
p.oldAjaxSuccess = p.oldAjaxSuccess || wo.pager_ajaxObject.success;
c.appender = tsp.appender;
if (ts.filter && $.inArray('filter', c.widgets) >= 0) {
// get any default filter settings (data-value attribute) fixes #388
p.currentFilters = c.$table.data('lastSearch') || ts.filter.setDefaults(table, c, wo) || [];
// set, but don't apply current filters
ts.setFilters(table, p.currentFilters, false);
}
if (wo.pager_savePages && ts.storage) {
t = ts.storage(table, wo.pager_storageKey) || {}; // fixes #387
p.page = isNaN(t.page) ? p.page : t.page;
p.size = ( isNaN(t.size) ? p.size : t.size ) || 10;
$.data(table, 'pagerLastSize', p.size);
}
// clear initialized flag
p.initialized = false;
// before initialization event
c.$table.trigger('pagerBeforeInitialized', c);
tsp.enablePager(table, c, false);
if ( typeof(wo.pager_ajaxUrl) === 'string' ) {
// ajax pager; interact with database
p.ajax = true;
// When filtering with ajax, allow only custom filtering function, disable default filtering since it will be done server side.
wo.filter_serversideFiltering = true;
c.serverSideSorting = true;
tsp.moveToPage(table, p);
} else {
p.ajax = false;
// Regular pager; all rows stored in memory
c.$table.trigger("appendCache", [{}, true]);
tsp.hideRowsSetup(table, c);
}
},
initComplete: function(table, c){
var p = c.pager;
tsp.changeHeight(table, c);
tsp.bindEvents(table, c);
// pager initialized
p.initialized = true;
p.isInitializing = false;
tsp.setPageSize(table, 0, c); // page size 0 is ignored
c.$table.trigger('pagerInitialized', c);
},
bindEvents: function(table, c){
var ctrls, fxn,
p = c.pager,
wo = c.widgetOptions,
s = wo.pager_selectors;
c.$table
.unbind('filterStart filterEnd sortEnd disable enable destroy update updateRows updateAll addRows pageSize '.split(' ').join('.pager '))
.bind('filterStart.pager', function(e, filters) {
p.currentFilters = filters;
p.page = 0; // fixes #456
})
// update pager after filter widget completes
.bind('filterEnd.pager sortEnd.pager', function() {
if (p.initialized) {
tsp.moveToPage(table, p, false);
tsp.updatePageDisplay(table, c, false);
tsp.fixHeight(table, c);
}
})
.bind('disable.pager', function(e){
e.stopPropagation();
tsp.showAllRows(table, c);
})
.on('enable.pager', function(e){
e.stopPropagation();
tsp.enablePager(table, c, true);
})
.on('destroy.pager', function(e){
e.stopPropagation();
tsp.destroyPager(table, c);
})
.on('update updateRows updateAll addRows '.split(' ').join('.pager '), function(e){
e.stopPropagation();
tsp.hideRows(table, c);
// make sure widgets are applied - fixes #450
c.$table.trigger('applyWidgets');
})
.on('pageSize.pager', function(e,v){
e.stopPropagation();
tsp.setPageSize(table, parseInt(v, 10) || 10, c);
tsp.hideRows(table, c);
tsp.updatePageDisplay(table, c, false);
if (p.$size.length) { p.$size.val(p.size); } // twice?
})
.on('pageSet.pager', function(e,v){
e.stopPropagation();
p.page = (parseInt(v, 10) || 1) - 1;
if (p.$goto.length) { p.$goto.val(c.size); } // twice?
tsp.moveToPage(table, p);
tsp.updatePageDisplay(table, c, false);
});
// clicked controls
ctrls = [ s.first, s.prev, s.next, s.last ];
fxn = [ 'moveToFirstPage', 'moveToPrevPage', 'moveToNextPage', 'moveToLastPage' ];
p.$container.find(ctrls.join(','))
.attr("tabindex", 0)
.unbind('click.pager')
.bind('click.pager', function(e){
e.stopPropagation();
var i,
$c = $(this),
l = ctrls.length;
if ( !$c.hasClass(wo.pager_css.disabled) ) {
for (i = 0; i < l; i++) {
if ($c.is(ctrls[i])) {
tsp[fxn[i]](table, p);
break;
}
}
}
});
if ( p.$goto.length ) {
p.$goto
.unbind('change')
.bind('change', function(){
p.page = $(this).val() - 1;
tsp.moveToPage(table, p);
tsp.updatePageDisplay(table, c, false);
});
}
if ( p.$size.length ) {
p.$size
.unbind('change.pager')
.bind('change.pager', function() {
p.$size.val( $(this).val() ); // in case there are more than one pagers
if ( !$(this).hasClass(wo.pager_css.disabled) ) {
tsp.setPageSize(table, parseInt( $(this).val(), 10 ), c);
tsp.changeHeight(table, c);
}
return false;
});
}
},
// hide arrows at extremes
pagerArrows: function(c, disable) {
var p = c.pager,
dis = !!disable,
first = dis || p.page === 0,
tp = Math.min( p.totalPages, p.filteredPages ),
last = dis || p.page === tp - 1 || p.totalPages === 0,
wo = c.widgetOptions,
s = wo.pager_selectors;
if ( wo.pager_updateArrows ) {
p.$container.find(s.first + ',' + s.prev).toggleClass(wo.pager_css.disabled, first).attr('aria-disabled', first);
p.$container.find(s.next + ',' + s.last).toggleClass(wo.pager_css.disabled, last).attr('aria-disabled', last);
}
},
updatePageDisplay: function(table, c, completed) {
var i, pg, s, out,
wo = c.widgetOptions,
p = c.pager,
f = c.$table.hasClass('hasFilters') && !wo.pager_ajaxUrl,
t = (c.widgetOptions && c.widgetOptions.filter_filteredRow || 'filtered') + ',' + c.selectorRemove +
(wo.pager_countChildRows ? '' : ',.' + c.cssChildRow),
sz = p.size || 10; // don't allow dividing by zero
p.$size.add(p.$goto).removeClass(wo.pager_css.disabled).removeAttr('disabled').attr('aria-disabled', 'false');
p.totalPages = Math.ceil( p.totalRows / sz ); // needed for "pageSize" method
p.filteredRows = (f) ? c.$tbodies.eq(0).children('tr').not('.' + t).length : p.totalRows;
p.filteredPages = (f) ? Math.ceil( p.filteredRows / sz ) || 1 : p.totalPages;
if ( Math.min( p.totalPages, p.filteredPages ) >= 0 ) {
t = (p.size * p.page > p.filteredRows);
p.startRow = (t) ? 1 : (p.filteredRows === 0 ? 0 : p.size * p.page + 1);
p.page = (t) ? 0 : p.page;
p.endRow = Math.min( p.filteredRows, p.totalRows, p.size * ( p.page + 1 ) );
out = p.$container.find(wo.pager_selectors.pageDisplay);
// form the output string (can now get a new output string from the server)
s = ( p.ajaxData && p.ajaxData.output ? p.ajaxData.output || wo.pager_output : wo.pager_output )
// {page} = one-based index; {page+#} = zero based index +/- value
.replace(/\{page([\-+]\d+)?\}/gi, function(m,n){
return p.totalPages ? p.page + (n ? parseInt(n, 10) : 1) : 0;
})
// {totalPages}, {extra}, {extra:0} (array) or {extra : key} (object)
.replace(/\{\w+(\s*:\s*\w+)?\}/gi, function(m){
var str = m.replace(/[{}\s]/g,''),
extra = str.split(':'),
data = p.ajaxData,
// return zero for default page/row numbers
deflt = /(rows?|pages?)$/i.test(str) ? 0 : '';
return extra.length > 1 && data && data[extra[0]] ? data[extra[0]][extra[1]] : p[str] || (data ? data[str] : deflt) || deflt;
});
if (out.length) {
out[ (out[0].tagName === 'INPUT') ? 'val' : 'html' ](s);
if ( p.$goto.length ) {
t = '';
pg = Math.min( p.totalPages, p.filteredPages );
for ( i = 1; i <= pg; i++ ) {
t += '<option>' + i + '</option>';
}
p.$goto.html(t).val( p.page + 1 );
}
}
}
tsp.pagerArrows(c);
if (p.initialized && completed !== false) {
c.$table.trigger('pagerComplete', c);
// save pager info to storage
if (wo.pager_savePages && ts.storage) {
ts.storage(table, wo.pager_storageKey, {
page : p.page,
size : p.size
});
}
}
},
fixHeight: function(table, c) {
var d, h,
p = c.pager,
wo = c.widgetOptions,
$b = c.$tbodies.eq(0);
if (wo.pager_fixedHeight) {
$b.find('tr.pagerSavedHeightSpacer').remove();
h = $.data(table, 'pagerSavedHeight');
if (h) {
d = h - $b.height();
if ( d > 5 && $.data(table, 'pagerLastSize') === p.size && $b.children('tr:visible').length < p.size ) {
$b.append('<tr class="pagerSavedHeightSpacer ' + wo.pager_selectors.remove.replace(/(tr)?\./g,'') + '" style="height:' + d + 'px;"></tr>');
}
}
}
},
changeHeight: function(table, c) {
var $b = c.$tbodies.eq(0);
$b.find('tr.pagerSavedHeightSpacer').remove();
$.data(table, 'pagerSavedHeight', $b.height());
tsp.fixHeight(table, c);
$.data(table, 'pagerLastSize', c.pager.size);
},
hideRows: function(table, c){
if (!c.widgetOptions.pager_ajaxUrl) {
var i,
lastIndex = 0,
p = c.pager,
wo = c.widgetOptions,
rows = c.$tbodies.eq(0).children(),
l = rows.length,
s = ( p.page * p.size ),
e = s + p.size,
f = wo && wo.filter_filteredRow || 'filtered',
j = 0; // size counter
for ( i = 0; i < l; i++ ){
if ( !rows[i].className.match(f) ) {
if (j === s && rows[i].className.match(c.cssChildRow)) {
// hide child rows @ start of pager (if already visible)
rows[i].style.display = 'none';
} else {
rows[i].style.display = ( j >= s && j < e ) ? '' : 'none';
// don't count child rows
j += rows[i].className.match(c.cssChildRow + '|' + c.selectorRemove.slice(1)) && !wo.pager_countChildRows ? 0 : 1;
if ( j === e && rows[i].style.display !== 'none' && rows[i].className.match(ts.css.cssHasChild) ) {
lastIndex = i;
}
}
}
}
// add any attached child rows to last row of pager. Fixes part of issue #396
if ( lastIndex > 0 && rows[lastIndex].className.match(ts.css.cssHasChild) ) {
while ( ++lastIndex < l && rows[lastIndex].className.match(c.cssChildRow) ) {
rows[lastIndex].style.display = '';
}
}
}
},
hideRowsSetup: function(table, c){
var p = c.pager;
p.size = parseInt( p.$size.val(), 10 ) || p.size;
$.data(table, 'pagerLastSize', p.size);
tsp.pagerArrows(c);
if ( !c.widgetOptions.pager_removeRows ) {
tsp.hideRows(table, c);
c.$table.on('sortEnd.pager filterEnd.pager', function(){
tsp.hideRows(table, c);
});
}
},
renderAjax: function(data, table, c, xhr, exception){
var p = c.pager,
wo = c.widgetOptions;
// process data
if ( $.isFunction(wo.pager_ajaxProcessing) ) {
// ajaxProcessing result: [ total, rows, headers ]
var i, j, t, hsh, $f, $sh, th, d, l, rr_count,
$t = c.$table,
tds = '',
result = wo.pager_ajaxProcessing(data, table) || [ 0, [] ],
hl = $t.find('thead th').length;
// Clean up any previous error.
ts.showError(table);
if ( exception ) {
if (c.debug) {
ts.log('Ajax Error', xhr, exception);
}
ts.showError(table, exception.message + ' (' + xhr.status + ')');
c.$tbodies.eq(0).empty();
p.totalRows = 0;
} else {
// process ajax object
if (!$.isArray(result)) {
p.ajaxData = result;
p.totalRows = result.total;
th = result.headers;
d = result.rows;
} else {
// allow [ total, rows, headers ] or [ rows, total, headers ]
t = isNaN(result[0]) && !isNaN(result[1]);
// ensure a zero returned row count doesn't fail the logical ||
rr_count = result[t ? 1 : 0];
p.totalRows = isNaN(rr_count) ? p.totalRows || 0 : rr_count;
d = p.totalRows === 0 ? [""] : result[t ? 0 : 1] || []; // row data
th = result[2]; // headers
}
l = d.length;
if (d instanceof jQuery) {
// append jQuery object
c.$tbodies.eq(0).empty().append(d);
} else if (l) {
// build table from array
for ( i = 0; i < l; i++ ) {
tds += '<tr>';
for ( j = 0; j < d[i].length; j++ ) {
// build tbody cells; watch for data containing HTML markup - see #434
tds += /^\s*<td/.test(d[i][j]) ? $.trim(d[i][j]) : '<td>' + d[i][j] + '</td>';
}
tds += '</tr>';
}
// add rows to first tbody
if (wo.pager_processAjaxOnInit) {
c.$tbodies.eq(0).html( tds );
} else {
wo.pager_processAjaxOnInit = true;
}
}
// only add new header text if the length matches
if ( th && th.length === hl ) {
hsh = $t.hasClass('hasStickyHeaders');
$sh = hsh ? wo.$sticky.children('thead:first').children().children() : '';
$f = $t.find('tfoot tr:first').children();
// don't change td headers (may contain pager)
c.$headers.filter('th').each(function(j){
var $t = $(this), icn;
// add new test within the first span it finds, or just in the header
if ( $t.find('.' + ts.css.icon).length ) {
icn = $t.find('.' + ts.css.icon).clone(true);
$t.find('.tablesorter-header-inner').html( th[j] ).append(icn);
if ( hsh && $sh.length ) {
icn = $sh.eq(j).find('.' + ts.css.icon).clone(true);
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] ).append(icn);
}
} else {
$t.find('.tablesorter-header-inner').html( th[j] );
if (hsh && $sh.length) {
$sh.eq(j).find('.tablesorter-header-inner').html( th[j] );
}
}
$f.eq(j).html( th[j] );
});
}
}
if (c.showProcessing) {
ts.isProcessing(table); // remove loading icon
}
// make sure last pager settings are saved, prevents multiple server side calls with
// the same parameters
p.totalPages = Math.ceil( p.totalRows / ( p.size || 10 ) );
p.last.totalRows = p.totalRows;
p.last.currentFilters = p.currentFilters;
p.last.sortList = (c.sortList || []).join(',');
tsp.updatePageDisplay(table, c);
tsp.fixHeight(table, c);
$t.trigger('updateCache', [function(){
if (p.initialized) {
// apply widgets after table has rendered
$t.trigger('applyWidgets');
$t.trigger('pagerChange', p);
}
}]);
}
if (!p.initialized) {
c.$table.trigger('applyWidgets');
}
},
getAjax: function(table, c){
var counter,
url = tsp.getAjaxUrl(table, c),
$doc = $(document),
wo = c.widgetOptions,
p = c.pager;
if ( url !== '' ) {
if (c.showProcessing) {
ts.isProcessing(table, true); // show loading icon
}
$doc.on('ajaxError.pager', function(e, xhr, settings, exception) {
tsp.renderAjax(null, table, c, xhr, exception);
$doc.unbind('ajaxError.pager');
});
counter = ++p.ajaxCounter;
wo.pager_ajaxObject.url = url; // from the ajaxUrl option and modified by customAjaxUrl
wo.pager_ajaxObject.success = function(data) {
// Refuse to process old ajax commands that were overwritten by new ones - see #443
if (counter < p.ajaxCounter){
return;
}
tsp.renderAjax(data, table, c);
$doc.unbind('ajaxError.pager');
if (typeof p.oldAjaxSuccess === 'function') {
p.oldAjaxSuccess(data);
}
};
if (c.debug) {
ts.log('ajax initialized', wo.pager_ajaxObject);
}
$.ajax(wo.pager_ajaxObject);
}
},
getAjaxUrl: function(table, c) {
var p = c.pager,
wo = c.widgetOptions,
url = (wo.pager_ajaxUrl) ? wo.pager_ajaxUrl
// allow using "{page+1}" in the url string to switch to a non-zero based index
.replace(/\{page([\-+]\d+)?\}/, function(s,n){ return p.page + (n ? parseInt(n, 10) : 0); })
.replace(/\{size\}/g, p.size) : '',
sl = c.sortList,
fl = p.currentFilters || $(table).data('lastSearch') || [],
sortCol = url.match(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/),
filterCol = url.match(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/),
arry = [];
if (sortCol) {
sortCol = sortCol[1];
$.each(sl, function(i,v){
arry.push(sortCol + '[' + v[0] + ']=' + v[1]);
});
// if the arry is empty, just add the col parameter... "&{sortList:col}" becomes "&col"
url = url.replace(/\{\s*sort(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : sortCol );
arry = [];
}
if (filterCol) {
filterCol = filterCol[1];
$.each(fl, function(i,v){
if (v) {
arry.push(filterCol + '[' + i + ']=' + encodeURIComponent(v));
}
});
// if the arry is empty, just add the fcol parameter... "&{filterList:fcol}" becomes "&fcol"
url = url.replace(/\{\s*filter(?:List)?\s*:\s*(\w*)\s*\}/g, arry.length ? arry.join('&') : filterCol );
p.currentFilters = fl;
}
if ( $.isFunction(wo.pager_customAjaxUrl) ) {
url = wo.pager_customAjaxUrl(table, url);
}
if (c.debug) {
ts.log('Pager ajax url: ' + url);
}
return url;
},
renderTable: function(table, rows) {
var i, $tb,
c = table.config,
p = c.pager,
wo = c.widgetOptions,
l = rows && rows.length || 0, // rows may be undefined
s = ( p.page * p.size ),
e = ( s + p.size );
if ( l < 1 ) { return; } // empty table, abort!
if ( p.page >= p.totalPages ) {
// lets not render the table more than once
return tsp.moveToLastPage(table, p);
}
p.isDisabled = false; // needed because sorting will change the page and re-enable the pager
if (p.initialized) { c.$table.trigger('pagerChange', c); }
if ( !wo.pager_removeRows ) {
tsp.hideRows(table, c);
} else {
if ( e > rows.length ) {
e = rows.length;
}
ts.clearTableBody(table);
$tb = ts.processTbody(table, c.$tbodies.eq(0), true);
for ( i = s; i < e; i++ ) {
$tb.append(rows[i]);
}
ts.processTbody(table, $tb, false);
}
tsp.updatePageDisplay(table, c);
if ( !p.isDisabled ) { tsp.fixHeight(table, c); }
wo.pager_startPage = p.page;
wo.pager_size = p.size;
c.$table.trigger('applyWidgets');
if (table.isUpdating) {
c.$table.trigger('updateComplete');
}
},
showAllRows: function(table, c){
var p = c.pager,
wo = c.widgetOptions;
if ( p.ajax ) {
tsp.pagerArrows(c, true);
} else {
p.isDisabled = true;
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.page = 0;
p.size = p.totalRows;
p.totalPages = 1;
c.$table
.addClass('pagerDisabled')
.removeAttr('aria-describedby')
.find('tr.pagerSavedHeightSpacer').remove();
tsp.renderTable(table, c.rowsCopy);
if (c.debug) {
ts.log('pager disabled');
}
}
// disable size selector
p.$size.add(p.$goto).each(function(){
$(this).attr('aria-disabled', 'true').addClass(wo.pager_css.disabled)[0].disabled = true;
});
},
moveToPage: function(table, p, pageMoved) {
if ( p.isDisabled ) { return; }
var c = table.config,
l = p.last,
pg = Math.min( p.totalPages, p.filteredPages );
if ( p.page < 0 ) { p.page = 0; }
if ( p.page > ( pg - 1 ) && pg !== 0 ) { p.page = pg - 1; }
// fixes issue where one current filter is [] and the other is ['','',''],
// making the next if comparison think the filters as different. Fixes #202.
l.currentFilters = (l.currentFilters || []).join('') === '' ? [] : l.currentFilters;
p.currentFilters = (p.currentFilters || []).join('') === '' ? [] : p.currentFilters;
// don't allow rendering multiple times on the same page/size/totalRows/filters/sorts
if ( l.page === p.page && l.size === p.size && l.totalRows === p.totalRows &&
(l.currentFilters || []).join(',') === (p.currentFilters || []).join(',') &&
l.sortList === (c.sortList || []).join(',') ) {
return;
}
if (c.debug) {
ts.log('Pager changing to page ' + p.page);
}
p.last = {
page : p.page,
size : p.size,
// fixes #408; modify sortList otherwise it auto-updates
sortList : (c.sortList || []).join(','),
totalRows : p.totalRows,
currentFilters : p.currentFilters || []
};
if (p.ajax) {
tsp.getAjax(table, c);
} else if (!p.ajax) {
tsp.renderTable(table, c.rowsCopy);
}
$.data(table, 'pagerLastPage', p.page);
if (p.initialized && pageMoved !== false) {
c.$table.trigger('pageMoved', c);
if (!p.ajax && table.isUpdating) {
c.$table.trigger('updateComplete');
}
}
},
setPageSize: function(table, size, c) {
var p = c.pager;
p.size = size || p.size || 10;
p.$size.val(p.size);
$.data(table, 'pagerLastPage', p.page);
$.data(table, 'pagerLastSize', p.size);
p.totalPages = Math.ceil( p.totalRows / p.size );
p.filteredPages = Math.ceil( p.filteredRows / p.size );
tsp.moveToPage(table, p);
},
moveToFirstPage: function(table, p) {
p.page = 0;
tsp.moveToPage(table, p);
},
moveToLastPage: function(table, p) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
tsp.moveToPage(table, p);
},
moveToNextPage: function(table, p) {
p.page++;
if ( p.page >= ( Math.min( p.totalPages, p.filteredPages ) - 1 ) ) {
p.page = ( Math.min( p.totalPages, p.filteredPages ) - 1 );
}
tsp.moveToPage(table, p);
},
moveToPrevPage: function(table, p) {
p.page--;
if ( p.page <= 0 ) {
p.page = 0;
}
tsp.moveToPage(table, p);
},
destroyPager: function(table, c){
var p = c.pager;
tsp.showAllRows(table, c);
p.$container.hide(); // hide pager
c.appender = null; // remove pager appender function
p.initialized = false;
c.$table.unbind('destroy.pager sortEnd.pager filterEnd.pager enable.pager disable.pager');
if (ts.storage) {
ts.storage(table, c.widgetOptions.pager_storageKey, '');
}
},
enablePager: function(table, c, triggered){
var info, p = c.pager;
p.isDisabled = false;
p.page = $.data(table, 'pagerLastPage') || p.page || 0;
p.size = $.data(table, 'pagerLastSize') || parseInt(p.$size.find('option[selected]').val(), 10) || p.size || 10;
p.$size.val(p.size); // set page size
p.totalPages = Math.ceil( Math.min( p.totalRows, p.filteredRows ) / p.size );
c.$table.removeClass('pagerDisabled');
// if table id exists, include page display with aria info
if ( table.id ) {
info = table.id + '_pager_info';
p.$container.find(c.widgetOptions.pager_selectors.pageDisplay).attr('id', info);
c.$table.attr('aria-describedby', info);
}
if ( triggered ) {
c.$table.trigger('updateRows');
tsp.setPageSize(table, p.size, c);
tsp.hideRowsSetup(table, c);
tsp.fixHeight(table, c);
if (c.debug) {
ts.log('pager enabled');
}
}
},
appender: function(table, rows) {
var c = table.config,
wo = c.widgetOptions,
p = c.pager;
if ( !p.ajax ) {
c.rowsCopy = rows;
p.totalRows = c.widgetOptions.pager_countChildRows ? c.$tbodies.eq(0).children().length : rows.length;
p.size = $.data(table, 'pagerLastSize') || p.size || wo.pager_size || 10;
p.totalPages = Math.ceil( p.totalRows / p.size );
tsp.moveToPage(table, p, true);
// update display here in case all rows are removed
tsp.updatePageDisplay(table, c, false);
} else {
tsp.moveToPage(table, p, true);
}
}
};
// see #486
ts.showError = function(table, message){
$(table).each(function(){
var $row,
c = this.config,
errorRow = c.pager && c.pager.cssErrorRow || c.widgetOptions.pager_css && c.widgetOptions.pager_css.errorRow || 'tablesorter-errorRow';
if (c) {
if (typeof message === 'undefined') {
c.$table.find('thead').find(c.selectorRemove).remove();
} else {
$row = ( /tr\>/.test(message) ? $(message) : $('<tr><td colspan="' + c.columns + '">' + message + '</td></tr>') )
.click(function(){
$(this).remove();
})
// add error row to thead instead of tbody, or clicking on the header will result in a parser error
.appendTo( c.$table.find('thead:first') )
.addClass( errorRow + ' ' + c.selectorRemove.replace(/^[.#]/, '') )
.attr({
role : 'alert',
'aria-live' : 'assertive'
});
}
}
});
};
})(jQuery);