function get(url) { return new Promise(function(resolve, reject) { var req = new XMLHttpRequest(); req.open('GET', url); req.onload = function() { if (req.status == 200) { resolve(req.response); } else { reject(Error(req.statusText)); } }; req.onerror = function() { reject(Error("Network Error")); }; req.send(); }); } function getJSON(url) { return get(url).then(JSON.parse) } function sortByKey(key, d) { return d.slice().sort( function (a, b) { return a[key] - b[key] }).reverse() } function limit(key, m, d) { return d.filter( function (d) { return d[key].isAfter(m) }) } function sum(a) { return a.reduce( function (a, b) { return a + b }, 0) } function one() { return 1 } function trueDefault(d) { return d === undefined ? true : d } function dictGet(dict, key) { var k = key.shift() if (!(k in dict)) return null if (key.length == 0) return dict[k] return dictGet(dict[k], key) } /* Helpers working with nodes */ function offline(d) { return !d.flags.online } function online(d) { return d.flags.online } function has_location(d) { return "location" in d.nodeinfo } function subtract(a, b) { var ids = {} b.forEach( function (d) { ids[d.nodeinfo.node_id] = true }) return a.filter( function (d) { return !(d.nodeinfo.node_id in ids) }) } /* Helpers working with links */ function showDistance(d) { if (isNaN(d.distance)) return return (new Intl.NumberFormat("de-DE", {maximumFractionDigits: 0}).format(d.distance)) + " m" } function showTq(d) { var opts = { maximumFractionDigits: 0 } return (new Intl.NumberFormat("de-DE", opts).format(100/d.tq)) + "%" } function linkId(d) { var ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id] return ids.sort().join("-") } /* Infobox stuff (XXX: move to module) */ function attributeEntry(el, label, value) { if (value === null || value == undefined) return var tr = document.createElement("tr") var th = document.createElement("th") th.textContent = label tr.appendChild(th) var td = document.createElement("td") if (typeof value == "function") value(td) else td.appendChild(document.createTextNode(value)) tr.appendChild(td) el.appendChild(tr) return td }