diff --git a/lib/map.js b/lib/map.js index 7149ecb..a6fe0b4 100644 --- a/lib/map.js +++ b/lib/map.js @@ -1,6 +1,7 @@ -define(["map/clientlayer", "d3", "leaflet", "moment", "locationmarker", +define(["map/clientlayer", "map/labelslayer", + "d3", "leaflet", "moment", "locationmarker", "leaflet.label", "leaflet.providers"], - function (ClientLayer, d3, L, moment, LocationMarker) { + function (ClientLayer, LabelsLayer, d3, L, moment, LocationMarker) { var options = { worldCopyJump: true, zoomControl: false } @@ -220,6 +221,10 @@ define(["map/clientlayer", "d3", "leaflet", "moment", "locationmarker", clientLayer.addTo(map) clientLayer.setZIndex(5) + var labelsLayer = new LabelsLayer({minZoom: 15}) + labelsLayer.addTo(map) + labelsLayer.setZIndex(6) + var nodeDict = {} var linkDict = {} var highlight @@ -345,6 +350,11 @@ define(["map/clientlayer", "d3", "leaflet", "moment", "locationmarker", groupLost = L.featureGroup(markersLost).addTo(map) clientLayer.setData(data.nodes.all.filter(online).filter(has_location)) + labelsLayer.setData({online: nodesOnline.filter(has_location), + offline: nodesOffline.filter(has_location), + new: data.nodes.new.filter(has_location), + lost: data.nodes.lost.filter(has_location) + }) updateView(true) } diff --git a/lib/map/labelslayer.js b/lib/map/labelslayer.js new file mode 100644 index 0000000..500ccba --- /dev/null +++ b/lib/map/labelslayer.js @@ -0,0 +1,70 @@ +define(["leaflet"], + function (L) { + return L.TileLayer.Canvas.extend({ + setData: function (d) { + this.data = d + this.redraw() + }, + drawTile: function (canvas, tilePoint) { + if (!this.data) + return + + var tileSize = this.options.tileSize + var s = tilePoint.multiplyBy(tileSize) + var map = this._map + + function project(coords) { + var p = map.project(new L.LatLng(coords[0], coords[1])) + return {x: p.x - s.x, y: p.y - s.y} + } + + function projectNodes(d) { + return { p: project([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude]), + o: d + } + } + + var margin = 150 + function onTile(d) { + return d.p.x + margin > 0 || + d.p.y + margin > 0 || + d.p.x - tileSize - margin < 0 || + d.p.y - tileSize - margin < 0 + } + + var ctx = canvas.getContext("2d") + + var nodesOnline = this.data.online.map(projectNodes).filter(onTile) + var nodesOffline = this.data.offline.map(projectNodes).filter(onTile) + var nodesNew = this.data.new.map(projectNodes).filter(onTile) + var nodesLost = this.data.lost.map(projectNodes).filter(onTile) + + var distance = 10 + ctx.font = "12px Roboto" + ctx.textBaseline = "middle" + ctx.textAlign = "left" + ctx.lineWidth = 2.5 + + function drawLabel(d) { + ctx.strokeText(d.o.nodeinfo.hostname, d.p.x + distance, d.p.y) + ctx.fillText(d.o.nodeinfo.hostname, d.p.x + distance, d.p.y) + } + + ctx.fillStyle = "rgba(212, 62, 42, 0.6)" + ctx.strokeStyle = "rgba(255, 255, 255, 0.6)" + nodesOffline.forEach(drawLabel) + + ctx.fillStyle = "rgba(0, 0, 0, 0.6)" + ctx.strokeStyle = "rgba(255, 255, 255, 0.9)" + nodesOnline.forEach(drawLabel) + + ctx.fillStyle = "rgba(212, 62, 42, 0.6)" + ctx.strokeStyle = "rgba(255, 255, 255, 0.9)" + nodesLost.forEach(drawLabel) + + ctx.fillStyle = "rgba(0, 0, 0, 0.6)" + ctx.strokeStyle = "rgba(255, 255, 255, 1.0)" + nodesNew.forEach(drawLabel) + } + }) +})