map/labels: dynamic labels (zoom levels, sizes)

This commit is contained in:
Nils Schneider 2015-04-21 16:28:06 +02:00
parent fc921e6c59
commit d5a9c52788

View file

@ -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])
}