From d5a9c52788d9da60518c4d48c8ba03656b9b1e26 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Tue, 21 Apr 2015 16:28:06 +0200 Subject: [PATCH] map/labels: dynamic labels (zoom levels, sizes) --- lib/map/labelslayer.js | 68 ++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/lib/map/labelslayer.js b/lib/map/labelslayer.js index f6c9a42..9134184 100644 --- a/lib/map/labelslayer.js +++ b/lib/map/labelslayer.js @@ -9,9 +9,7 @@ define(["leaflet", "rbush"], ["center", "ideographic", 2 / 8], ["right", "ideographic", 3 / 8]] - var labelOffset = 8 - var font = "10px Roboto" - var labelHeight = 12 + var fontFamily = "Roboto" var nodeRadius = 4 var ctx = document.createElement("canvas").getContext("2d") @@ -29,20 +27,25 @@ define(["leaflet", "rbush"], return o } - function prepareLabel(fillStyle) { + function prepareLabel(fillStyle, fontSize, offset, stroke, minZoom) { return function (d) { + var font = fontSize + "px " + fontFamily return { position: L.latLng(d.nodeinfo.location.latitude, d.nodeinfo.location.longitude), label: d.nodeinfo.hostname, + offset: offset, fillStyle: fillStyle, - height: labelHeight, + height: fontSize * 1.2, + font: font, + stroke: stroke, + minZoom: minZoom, width: measureText(font, d.nodeinfo.hostname).width } } } - function calcOffset(loc) { - return [ labelOffset * Math.cos(loc[2] * 2 * Math.PI), - -labelOffset * Math.sin(loc[2] * 2 * Math.PI)] + function calcOffset(offset, loc) { + return [ offset * Math.cos(loc[2] * 2 * Math.PI), + -offset * Math.sin(loc[2] * 2 * Math.PI)] } function labelRect(p, offset, anchor, label) { @@ -84,10 +87,10 @@ define(["leaflet", "rbush"], // - label (string) // - color (string) - var labelsOnline = d.online.map(prepareLabel("rgba(0, 0, 0, 0.9)")) - var labelsOffline = d.offline.map(prepareLabel("rgba(212, 62, 42, 0.9)")) - var labelsNew = d.new.map(prepareLabel("rgba(85, 128, 32, 0.9)")) - var labelsLost = d.lost.map(prepareLabel("rgba(212, 62, 42, 0.9)")) + var labelsOnline = d.online.map(prepareLabel("rgba(0, 0, 0, 0.9)", 10, 8, true, 13)) + var labelsOffline = d.offline.map(prepareLabel("rgba(212, 62, 42, 0.9)", 9, 5, false, 16)) + var labelsNew = d.new.map(prepareLabel("rgba(48, 99, 20, 0.9)", 11, 8, true, 0)) + var labelsLost = d.lost.map(prepareLabel("rgba(212, 62, 42, 0.9)", 11, 8, true, 0)) var labels = [] .concat(labelsNew) @@ -115,12 +118,12 @@ define(["leaflet", "rbush"], trees[z].load(labels.map(nodeToRect(z))) } - labels.forEach(function (d) { + labels = labels.map(function (d) { var best = labelLocations.map(function (loc) { - var offset = calcOffset(loc, d) + var offset = calcOffset(d.offset, loc) var z - for (z = maxZoom; z >= minZoom; z--) { + for (z = maxZoom; z >= d.minZoom; z--) { var p = map.project(d.position, z) var rect = labelRect(p, offset, loc, d) var candidates = trees[z].search(rect) @@ -136,23 +139,21 @@ define(["leaflet", "rbush"], return a.z - b.z })[0] - if (best === undefined) - return + if (best !== undefined) { + d.offset = calcOffset(d.offset, best.loc) + d.minZoom = best.z + d.anchor = best.loc - d.offset = calcOffset(best.loc, d) - d.minZoom = best.z - d.anchor = best.loc + for (var z = maxZoom; z >= best.z; z--) { + var p = map.project(d.position, z) + var rect = labelRect(p, d.offset, best.loc, d) + trees[z].insert(rect) + } - for (var z = maxZoom; z >= best.z; z--) { - var p = map.project(d.position, z) - var rect = labelRect(p, d.offset, best.loc, d) - trees[z].insert(rect) - } - }) - - labels = labels.filter(function (d) { - return d.minZoom !== undefined - }) + return d + } else + return undefined + }).filter(function (d) { return d !== undefined }) this.margin = 16 + labels.map(function (d) { return d.width @@ -193,16 +194,19 @@ define(["leaflet", "rbush"], var ctx = canvas.getContext("2d") - ctx.font = font ctx.lineWidth = 5 ctx.strokeStyle = "rgba(255, 255, 255, 0.8)" ctx.miterLimit = 2 function drawLabel(d) { + ctx.font = d.label.font ctx.textAlign = d.label.anchor[0] ctx.textBaseline = d.label.anchor[1] ctx.fillStyle = d.label.fillStyle - ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]) + + if (d.label.stroke) + ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]) + ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]) }