d3-geo-scale-bar
Advanced tools
Comparing version 0.3.1 to 0.4.0
@@ -1,2 +0,2 @@ | ||
// https://github.com/HarryStevens/d3-geo-scale-bar Version 0.3.1. Copyright 2019 Harry Stevens. | ||
// https://github.com/HarryStevens/d3-geo-scale-bar Version 0.4.0. Copyright 2020 Harry Stevens. | ||
(function (global, factory) { | ||
@@ -8,126 +8,2 @@ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
// Adapted from d3-axis by Mike Bostock | ||
// Source: https://github.com/d3/d3-axis/blob/master/src/axis.js | ||
// License: https://github.com/d3/d3-axis/blob/master/LICENSE | ||
var slice = Array.prototype.slice; | ||
var bottom = 3, | ||
epsilon = 1e-6; | ||
function translateX(x) { | ||
return "translate(" + (x + 0.5) + ",0)"; | ||
} | ||
function number(scale) { | ||
return function (d) { | ||
return +scale(d); | ||
}; | ||
} | ||
function entering() { | ||
return !this.__axis; | ||
} | ||
function axis(orient, scale) { | ||
var tickArguments = [], | ||
tickValues = null, | ||
tickFormat = null, | ||
tickSizeInner = 6, | ||
tickSizeOuter = 6, | ||
tickPadding = 3, | ||
k = 1, | ||
x = "y", | ||
transform = translateX; | ||
function axis(context) { | ||
var values = tickValues == null ? scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain() : tickValues, | ||
format = tickFormat == null ? scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : function (x) { | ||
return x; | ||
} : tickFormat, | ||
spacing = Math.max(tickSizeInner, 0) + tickPadding, | ||
range = scale.range(), | ||
range0 = +range[0] + 0.5, | ||
range1 = +range[range.length - 1] + 0.5, | ||
position = number(scale.copy()), | ||
selection = context.selection ? context.selection() : context, | ||
path = selection.selectAll(".domain").data([null]), | ||
tick = selection.selectAll(".tick").data(values, scale).order(), | ||
tickExit = tick.exit(), | ||
tickEnter = tick.enter().append("g").attr("class", "tick"), | ||
line = tick.select("line"), | ||
text = tick.select("text"); | ||
path = path.merge(path.enter().insert("path", ".tick").attr("class", "domain").attr("stroke", "#000")); | ||
tick = tick.merge(tickEnter); | ||
line = line.merge(tickEnter.append("line").attr("stroke", "#000").attr(x + "2", k * tickSizeInner)); | ||
text = text.merge(tickEnter.append("text").attr("fill", "#000").attr(x, k * spacing).attr("dy", "0.71em")); | ||
if (context !== selection) { | ||
path = path.transition(context); | ||
tick = tick.transition(context); | ||
line = line.transition(context); | ||
text = text.transition(context); | ||
tickExit = tickExit.transition(context).attr("opacity", epsilon).attr("transform", function (d) { | ||
return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); | ||
}); | ||
tickEnter.attr("opacity", epsilon).attr("transform", function (d) { | ||
var p = this.parentNode.__axis; | ||
return transform(p && isFinite(p = p(d)) ? p : position(d)); | ||
}); | ||
} | ||
tickExit.remove(); | ||
path.attr("d", tickSizeOuter ? "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter : "M" + range0 + ",0.5H" + range1); | ||
tick.attr("opacity", 1).attr("transform", function (d) { | ||
return transform(position(d)); | ||
}); | ||
line.attr(x + "2", k * tickSizeInner); | ||
text.attr(x, k * spacing).text(format); | ||
selection.filter(entering).attr("fill", "none").attr("font-size", 10).attr("font-family", "sans-serif").attr("text-anchor", "middle"); | ||
selection.each(function () { | ||
this.__axis = position; | ||
}); | ||
} | ||
axis.scale = function (_) { | ||
return arguments.length ? (scale = _, axis) : scale; | ||
}; | ||
axis.ticks = function () { | ||
return tickArguments = slice.call(arguments), axis; | ||
}; | ||
axis.tickArguments = function (_) { | ||
return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), axis) : tickArguments.slice(); | ||
}; | ||
axis.tickValues = function (_) { | ||
return arguments.length ? (tickValues = _ == null ? null : slice.call(_), axis) : tickValues && tickValues.slice(); | ||
}; | ||
axis.tickFormat = function (_) { | ||
return arguments.length ? (tickFormat = _, axis) : tickFormat; | ||
}; | ||
axis.tickSize = function (_) { | ||
return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner; | ||
}; | ||
axis.tickSizeInner = function (_) { | ||
return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner; | ||
}; | ||
axis.tickSizeOuter = function (_) { | ||
return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter; | ||
}; | ||
axis.tickPadding = function (_) { | ||
return arguments.length ? (tickPadding = +_, axis) : tickPadding; | ||
}; | ||
return axis; | ||
} | ||
function axisBottom(scale) { | ||
return axis(bottom, scale); | ||
} | ||
// Adds floating point numbers with twice the normal precision. | ||
@@ -176,18 +52,3 @@ // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and | ||
// Adapted from d3-geo by Mike Bostock | ||
// Source: https://github.com/d3/d3-geo/blob/master/src/math.js | ||
// License: https://github.com/d3/d3-geo/blob/master/LICENSE | ||
var abs = Math.abs; | ||
var atan2 = Math.atan2; | ||
var cos = Math.cos; | ||
var radians = Math.PI / 180; | ||
var sin = Math.sin; | ||
var sqrt = Math.sqrt; | ||
// From d3-geo by Mike Bostock | ||
// Source: https://github.com/d3/d3-geo/blob/master/src/noop.js | ||
// License: https://github.com/d3/d3-geo/blob/master/LICENSE | ||
function noop() {} | ||
// From d3-geo by Mike Bostock | ||
// Source: https://github.com/d3/d3-geo/blob/master/src/stream.js | ||
@@ -300,3 +161,3 @@ // License: https://github.com/d3/d3-geo/blob/master/LICENSE | ||
// From d3-geo by Mike Bostock | ||
// Adapted from d3-geo by Mike Bostock | ||
var lengthSum = adder(), | ||
@@ -307,8 +168,8 @@ lambda0, | ||
var lengthStream = { | ||
sphere: noop, | ||
point: noop, | ||
sphere: function sphere(_) {}, | ||
point: function point(_) {}, | ||
lineStart: lengthLineStart, | ||
lineEnd: noop, | ||
polygonStart: noop, | ||
polygonEnd: noop | ||
lineEnd: function lineEnd(_) {}, | ||
polygonStart: function polygonStart(_) {}, | ||
polygonEnd: function polygonEnd(_) {} | ||
}; | ||
@@ -322,8 +183,8 @@ | ||
function lengthLineEnd() { | ||
lengthStream.point = lengthStream.lineEnd = noop; | ||
lengthStream.point = lengthStream.lineEnd = function (_) {}; | ||
} | ||
function lengthPointFirst(lambda, phi) { | ||
lambda *= radians, phi *= radians; | ||
lambda0 = lambda, sinPhi0 = sin(phi), cosPhi0 = cos(phi); | ||
lambda *= Math.PI / 180, phi *= Math.PI / 180; | ||
lambda0 = lambda, sinPhi0 = Math.sin(phi), cosPhi0 = Math.cos(phi); | ||
lengthStream.point = lengthPoint; | ||
@@ -333,12 +194,12 @@ } | ||
function lengthPoint(lambda, phi) { | ||
lambda *= radians, phi *= radians; | ||
var sinPhi = sin(phi), | ||
cosPhi = cos(phi), | ||
delta = abs(lambda - lambda0), | ||
cosDelta = cos(delta), | ||
sinDelta = sin(delta), | ||
lambda *= Math.PI / 180, phi *= Math.PI / 180; | ||
var sinPhi = Math.sin(phi), | ||
cosPhi = Math.cos(phi), | ||
delta = Math.abs(lambda - lambda0), | ||
cosDelta = Math.cos(delta), | ||
sinDelta = Math.sin(delta), | ||
x = cosPhi * sinDelta, | ||
y = cosPhi0 * sinPhi - sinPhi0 * cosPhi * cosDelta, | ||
z = sinPhi0 * sinPhi + cosPhi0 * cosPhi * cosDelta; | ||
lengthSum.add(atan2(sqrt(x * x + y * y), z)); | ||
lengthSum.add(Math.atan2(Math.sqrt(x * x + y * y), z)); | ||
lambda0 = lambda, sinPhi0 = sinPhi, cosPhi0 = cosPhi; | ||
@@ -365,663 +226,4 @@ } | ||
// From d3-array by Mike Bostock | ||
// Source: https://github.com/d3/d3-array/blob/master/src/ticks.js | ||
// License: https://github.com/d3/d3-array/blob/master/LICENSE | ||
var e10 = Math.sqrt(50), | ||
e5 = Math.sqrt(10), | ||
e2 = Math.sqrt(2); | ||
function ticks(start, stop, count) { | ||
var reverse, | ||
i = -1, | ||
n, | ||
ticks, | ||
step; | ||
stop = +stop, start = +start, count = +count; | ||
if (start === stop && count > 0) return [start]; | ||
if (reverse = stop < start) n = start, start = stop, stop = n; | ||
if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; | ||
if (step > 0) { | ||
start = Math.ceil(start / step); | ||
stop = Math.floor(stop / step); | ||
ticks = new Array(n = Math.ceil(stop - start + 1)); | ||
while (++i < n) { | ||
ticks[i] = (start + i) * step; | ||
} | ||
} else { | ||
start = Math.floor(start * step); | ||
stop = Math.ceil(stop * step); | ||
ticks = new Array(n = Math.ceil(start - stop + 1)); | ||
while (++i < n) { | ||
ticks[i] = (start - i) / step; | ||
} | ||
} | ||
if (reverse) ticks.reverse(); | ||
return ticks; | ||
} | ||
function tickIncrement(start, stop, count) { | ||
var step = (stop - start) / Math.max(0, count), | ||
power = Math.floor(Math.log(step) / Math.LN10), | ||
error = step / Math.pow(10, power); | ||
return power >= 0 ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power) : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1); | ||
} | ||
function tickStep(start, stop, count) { | ||
var step0 = Math.abs(stop - start) / Math.max(0, count), | ||
step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), | ||
error = step0 / step1; | ||
if (error >= e10) step1 *= 10;else if (error >= e5) step1 *= 5;else if (error >= e2) step1 *= 2; | ||
return stop < start ? -step1 : step1; | ||
} | ||
// From d3-array by Mike Bostock | ||
// Source: https://github.com/d3/d3-array/blob/master/src/ascending.js | ||
// License: https://github.com/d3/d3-array/blob/master/LICENSE | ||
function ascending (a, b) { | ||
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; | ||
} | ||
// From d3-array by Mike Bostock | ||
function bisector (compare) { | ||
if (compare.length === 1) compare = ascendingComparator(compare); | ||
return { | ||
left: function left(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
var mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) < 0) lo = mid + 1;else hi = mid; | ||
} | ||
return lo; | ||
}, | ||
right: function right(a, x, lo, hi) { | ||
if (lo == null) lo = 0; | ||
if (hi == null) hi = a.length; | ||
while (lo < hi) { | ||
var mid = lo + hi >>> 1; | ||
if (compare(a[mid], x) > 0) hi = mid;else lo = mid + 1; | ||
} | ||
return lo; | ||
} | ||
}; | ||
} | ||
function ascendingComparator(f) { | ||
return function (d, x) { | ||
return ascending(f(d), x); | ||
}; | ||
} | ||
// From d3-array by Mike Bostock | ||
var ascendingBisect = bisector(ascending); | ||
var bisectRight = ascendingBisect.right; | ||
// From d3-interpolate by Mike Bostock | ||
// Source: https://github.com/d3/d3-interpolate/blob/master/src/number.js | ||
// License: https://github.com/d3/d3-interpolate/blob/master/LICENSE | ||
function number$1 (a, b) { | ||
return a = +a, b = +b, function (t) { | ||
return a * (1 - t) + b * t; | ||
}; | ||
} | ||
// From d3-interpolate by Mike Bostock | ||
// Source: https://github.com/d3/d3-interpolate/blob/master/src/round.js | ||
// License: https://github.com/d3/d3-interpolate/blob/master/LICENSE | ||
function interpolateRound (a, b) { | ||
return a = +a, b = +b, function (t) { | ||
return Math.round(a * (1 - t) + b * t); | ||
}; | ||
} | ||
// Adapted from d3-interpolate by Mike Bostock | ||
function interpolateValue (a, b) { | ||
return number$1(a, b); | ||
} | ||
// From d3-scale by Mike Bostock | ||
// Source: https://github.com/d3/d3-scale/blob/master/src/constant.js | ||
// License: https://github.com/d3/d3-scale/blob/master/LICENSE | ||
function constant (x) { | ||
return function () { | ||
return x; | ||
}; | ||
} | ||
// From d3-scale by Mike Bostock | ||
// Source: https://github.com/d3/d3-scale/blob/master/src/number.js | ||
// License: https://github.com/d3/d3-scale/blob/master/LICENSE | ||
function number$2 (x) { | ||
return +x; | ||
} | ||
// From d3-scale by Mike Bostock | ||
var unit = [0, 1]; | ||
function identity(x) { | ||
return x; | ||
} | ||
function normalize(a, b) { | ||
return (b -= a = +a) ? function (x) { | ||
return (x - a) / b; | ||
} : constant(isNaN(b) ? NaN : 0.5); | ||
} | ||
function clamper(a, b) { | ||
var t; | ||
if (a > b) t = a, a = b, b = t; | ||
return function (x) { | ||
return Math.max(a, Math.min(b, x)); | ||
}; | ||
} // normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. | ||
// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b]. | ||
function bimap(domain, range, interpolate) { | ||
var d0 = domain[0], | ||
d1 = domain[1], | ||
r0 = range[0], | ||
r1 = range[1]; | ||
if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);else d0 = normalize(d0, d1), r0 = interpolate(r0, r1); | ||
return function (x) { | ||
return r0(d0(x)); | ||
}; | ||
} | ||
function polymap(domain, range, interpolate) { | ||
var j = Math.min(domain.length, range.length) - 1, | ||
d = new Array(j), | ||
r = new Array(j), | ||
i = -1; // Reverse descending domains. | ||
if (domain[j] < domain[0]) { | ||
domain = domain.slice().reverse(); | ||
range = range.slice().reverse(); | ||
} | ||
while (++i < j) { | ||
d[i] = normalize(domain[i], domain[i + 1]); | ||
r[i] = interpolate(range[i], range[i + 1]); | ||
} | ||
return function (x) { | ||
var i = bisectRight(domain, x, 1, j) - 1; | ||
return r[i](d[i](x)); | ||
}; | ||
} | ||
function copy(source, target) { | ||
return target.domain(source.domain()).range(source.range()).interpolate(source.interpolate()).clamp(source.clamp()).unknown(source.unknown()); | ||
} | ||
function transformer() { | ||
var domain = unit, | ||
range = unit, | ||
interpolate = interpolateValue, | ||
transform, | ||
untransform, | ||
unknown, | ||
clamp = identity, | ||
piecewise, | ||
output, | ||
input; | ||
function rescale() { | ||
var n = Math.min(domain.length, range.length); | ||
if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]); | ||
piecewise = n > 2 ? polymap : bimap; | ||
output = input = null; | ||
return scale; | ||
} | ||
function scale(x) { | ||
return isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x))); | ||
} | ||
scale.invert = function (y) { | ||
return clamp(untransform((input || (input = piecewise(range, domain.map(transform), number$1)))(y))); | ||
}; | ||
scale.domain = function (_) { | ||
return arguments.length ? (domain = Array.from(_, number$2), rescale()) : domain.slice(); | ||
}; | ||
scale.range = function (_) { | ||
return arguments.length ? (range = Array.from(_), rescale()) : range.slice(); | ||
}; | ||
scale.rangeRound = function (_) { | ||
return range = Array.from(_), interpolate = interpolateRound, rescale(); | ||
}; | ||
scale.clamp = function (_) { | ||
return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity; | ||
}; | ||
scale.interpolate = function (_) { | ||
return arguments.length ? (interpolate = _, rescale()) : interpolate; | ||
}; | ||
scale.unknown = function (_) { | ||
return arguments.length ? (unknown = _, scale) : unknown; | ||
}; | ||
return function (t, u) { | ||
transform = t, untransform = u; | ||
return rescale(); | ||
}; | ||
} | ||
function continuous() { | ||
return transformer()(identity, identity); | ||
} | ||
// From d3-scale by Mike Bostock | ||
// Source: https://github.com/d3/d3-scale/blob/master/src/init.js | ||
// License: https://github.com/d3/d3-scale/blob/master/LICENSE | ||
function initRange(domain, range) { | ||
switch (arguments.length) { | ||
case 0: | ||
break; | ||
case 1: | ||
this.range(domain); | ||
break; | ||
default: | ||
this.range(range).domain(domain); | ||
break; | ||
} | ||
return this; | ||
} | ||
// Computes the decimal coefficient and exponent of the specified number x with | ||
// significant digits p, where x is positive and p is in [1, 21] or undefined. | ||
// For example, formatDecimal(1.23) returns ["123", 0]. | ||
function formatDecimal(x, p) { | ||
if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity | ||
var i, coefficient = x.slice(0, i); | ||
// The string returned by toExponential either has the form \d\.\d+e[-+]\d+ | ||
// (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). | ||
return [ | ||
coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, | ||
+x.slice(i + 1) | ||
]; | ||
} | ||
function exponent(x) { | ||
return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; | ||
} | ||
function formatGroup(grouping, thousands) { | ||
return function(value, width) { | ||
var i = value.length, | ||
t = [], | ||
j = 0, | ||
g = grouping[0], | ||
length = 0; | ||
while (i > 0 && g > 0) { | ||
if (length + g + 1 > width) g = Math.max(1, width - length); | ||
t.push(value.substring(i -= g, i + g)); | ||
if ((length += g + 1) > width) break; | ||
g = grouping[j = (j + 1) % grouping.length]; | ||
} | ||
return t.reverse().join(thousands); | ||
}; | ||
} | ||
function formatNumerals(numerals) { | ||
return function(value) { | ||
return value.replace(/[0-9]/g, function(i) { | ||
return numerals[+i]; | ||
}); | ||
}; | ||
} | ||
// [[fill]align][sign][symbol][0][width][,][.precision][~][type] | ||
var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; | ||
function formatSpecifier(specifier) { | ||
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); | ||
var match; | ||
return new FormatSpecifier({ | ||
fill: match[1], | ||
align: match[2], | ||
sign: match[3], | ||
symbol: match[4], | ||
zero: match[5], | ||
width: match[6], | ||
comma: match[7], | ||
precision: match[8] && match[8].slice(1), | ||
trim: match[9], | ||
type: match[10] | ||
}); | ||
} | ||
formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof | ||
function FormatSpecifier(specifier) { | ||
this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; | ||
this.align = specifier.align === undefined ? ">" : specifier.align + ""; | ||
this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; | ||
this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; | ||
this.zero = !!specifier.zero; | ||
this.width = specifier.width === undefined ? undefined : +specifier.width; | ||
this.comma = !!specifier.comma; | ||
this.precision = specifier.precision === undefined ? undefined : +specifier.precision; | ||
this.trim = !!specifier.trim; | ||
this.type = specifier.type === undefined ? "" : specifier.type + ""; | ||
} | ||
FormatSpecifier.prototype.toString = function() { | ||
return this.fill | ||
+ this.align | ||
+ this.sign | ||
+ this.symbol | ||
+ (this.zero ? "0" : "") | ||
+ (this.width === undefined ? "" : Math.max(1, this.width | 0)) | ||
+ (this.comma ? "," : "") | ||
+ (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) | ||
+ (this.trim ? "~" : "") | ||
+ this.type; | ||
}; | ||
// Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. | ||
function formatTrim(s) { | ||
out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { | ||
switch (s[i]) { | ||
case ".": i0 = i1 = i; break; | ||
case "0": if (i0 === 0) i0 = i; i1 = i; break; | ||
default: if (i0 > 0) { if (!+s[i]) break out; i0 = 0; } break; | ||
} | ||
} | ||
return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; | ||
} | ||
var prefixExponent; | ||
function formatPrefixAuto(x, p) { | ||
var d = formatDecimal(x, p); | ||
if (!d) return x + ""; | ||
var coefficient = d[0], | ||
exponent = d[1], | ||
i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, | ||
n = coefficient.length; | ||
return i === n ? coefficient | ||
: i > n ? coefficient + new Array(i - n + 1).join("0") | ||
: i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) | ||
: "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! | ||
} | ||
function formatRounded(x, p) { | ||
var d = formatDecimal(x, p); | ||
if (!d) return x + ""; | ||
var coefficient = d[0], | ||
exponent = d[1]; | ||
return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient | ||
: coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) | ||
: coefficient + new Array(exponent - coefficient.length + 2).join("0"); | ||
} | ||
var formatTypes = { | ||
"%": function(x, p) { return (x * 100).toFixed(p); }, | ||
"b": function(x) { return Math.round(x).toString(2); }, | ||
"c": function(x) { return x + ""; }, | ||
"d": function(x) { return Math.round(x).toString(10); }, | ||
"e": function(x, p) { return x.toExponential(p); }, | ||
"f": function(x, p) { return x.toFixed(p); }, | ||
"g": function(x, p) { return x.toPrecision(p); }, | ||
"o": function(x) { return Math.round(x).toString(8); }, | ||
"p": function(x, p) { return formatRounded(x * 100, p); }, | ||
"r": formatRounded, | ||
"s": formatPrefixAuto, | ||
"X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, | ||
"x": function(x) { return Math.round(x).toString(16); } | ||
}; | ||
function identity$1(x) { | ||
return x; | ||
} | ||
var map = Array.prototype.map, | ||
prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; | ||
function formatLocale(locale) { | ||
var group = locale.grouping === undefined || locale.thousands === undefined ? identity$1 : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""), | ||
currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", | ||
currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", | ||
decimal = locale.decimal === undefined ? "." : locale.decimal + "", | ||
numerals = locale.numerals === undefined ? identity$1 : formatNumerals(map.call(locale.numerals, String)), | ||
percent = locale.percent === undefined ? "%" : locale.percent + "", | ||
minus = locale.minus === undefined ? "-" : locale.minus + "", | ||
nan = locale.nan === undefined ? "NaN" : locale.nan + ""; | ||
function newFormat(specifier) { | ||
specifier = formatSpecifier(specifier); | ||
var fill = specifier.fill, | ||
align = specifier.align, | ||
sign = specifier.sign, | ||
symbol = specifier.symbol, | ||
zero = specifier.zero, | ||
width = specifier.width, | ||
comma = specifier.comma, | ||
precision = specifier.precision, | ||
trim = specifier.trim, | ||
type = specifier.type; | ||
// The "n" type is an alias for ",g". | ||
if (type === "n") comma = true, type = "g"; | ||
// The "" type, and any invalid type, is an alias for ".12~g". | ||
else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; | ||
// If zero fill is specified, padding goes after sign and before digits. | ||
if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; | ||
// Compute the prefix and suffix. | ||
// For SI-prefix, the suffix is lazily computed. | ||
var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", | ||
suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; | ||
// What format function should we use? | ||
// Is this an integer type? | ||
// Can this type generate exponential notation? | ||
var formatType = formatTypes[type], | ||
maybeSuffix = /[defgprs%]/.test(type); | ||
// Set the default precision if not specified, | ||
// or clamp the specified precision to the supported range. | ||
// For significant precision, it must be in [1, 21]. | ||
// For fixed precision, it must be in [0, 20]. | ||
precision = precision === undefined ? 6 | ||
: /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) | ||
: Math.max(0, Math.min(20, precision)); | ||
function format(value) { | ||
var valuePrefix = prefix, | ||
valueSuffix = suffix, | ||
i, n, c; | ||
if (type === "c") { | ||
valueSuffix = formatType(value) + valueSuffix; | ||
value = ""; | ||
} else { | ||
value = +value; | ||
// Perform the initial formatting. | ||
var valueNegative = value < 0; | ||
value = isNaN(value) ? nan : formatType(Math.abs(value), precision); | ||
// Trim insignificant zeros. | ||
if (trim) value = formatTrim(value); | ||
// If a negative value rounds to zero during formatting, treat as positive. | ||
if (valueNegative && +value === 0) valueNegative = false; | ||
// Compute the prefix and suffix. | ||
valuePrefix = (valueNegative ? (sign === "(" ? sign : minus) : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; | ||
valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); | ||
// Break the formatted value into the integer “value” part that can be | ||
// grouped, and fractional or exponential “suffix” part that is not. | ||
if (maybeSuffix) { | ||
i = -1, n = value.length; | ||
while (++i < n) { | ||
if (c = value.charCodeAt(i), 48 > c || c > 57) { | ||
valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; | ||
value = value.slice(0, i); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
// If the fill character is not "0", grouping is applied before padding. | ||
if (comma && !zero) value = group(value, Infinity); | ||
// Compute the padding. | ||
var length = valuePrefix.length + value.length + valueSuffix.length, | ||
padding = length < width ? new Array(width - length + 1).join(fill) : ""; | ||
// If the fill character is "0", grouping is applied after padding. | ||
if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; | ||
// Reconstruct the final output based on the desired alignment. | ||
switch (align) { | ||
case "<": value = valuePrefix + value + valueSuffix + padding; break; | ||
case "=": value = valuePrefix + padding + value + valueSuffix; break; | ||
case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; | ||
default: value = padding + valuePrefix + value + valueSuffix; break; | ||
} | ||
return numerals(value); | ||
} | ||
format.toString = function() { | ||
return specifier + ""; | ||
}; | ||
return format; | ||
} | ||
function formatPrefix(specifier, value) { | ||
var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), | ||
e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, | ||
k = Math.pow(10, -e), | ||
prefix = prefixes[8 + e / 3]; | ||
return function(value) { | ||
return f(k * value) + prefix; | ||
}; | ||
} | ||
return { | ||
format: newFormat, | ||
formatPrefix: formatPrefix | ||
}; | ||
} | ||
var locale; | ||
var format; | ||
var formatPrefix; | ||
defaultLocale({ | ||
decimal: ".", | ||
thousands: ",", | ||
grouping: [3], | ||
currency: ["$", ""], | ||
minus: "-" | ||
}); | ||
function defaultLocale(definition) { | ||
locale = formatLocale(definition); | ||
format = locale.format; | ||
formatPrefix = locale.formatPrefix; | ||
return locale; | ||
} | ||
function precisionFixed(step) { | ||
return Math.max(0, -exponent(Math.abs(step))); | ||
} | ||
function precisionPrefix(step, value) { | ||
return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); | ||
} | ||
function precisionRound(step, max) { | ||
step = Math.abs(step), max = Math.abs(max) - step; | ||
return Math.max(0, exponent(max) - exponent(step)) + 1; | ||
} | ||
function tickFormat (start, stop, count, specifier) { | ||
var step = tickStep(start, stop, count), | ||
precision; | ||
specifier = formatSpecifier(specifier == null ? ",f" : specifier); | ||
switch (specifier.type) { | ||
case "s": | ||
{ | ||
var value = Math.max(Math.abs(start), Math.abs(stop)); | ||
if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; | ||
return formatPrefix(specifier, value); | ||
} | ||
case "": | ||
case "e": | ||
case "g": | ||
case "p": | ||
case "r": | ||
{ | ||
if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); | ||
break; | ||
} | ||
case "f": | ||
case "%": | ||
{ | ||
if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; | ||
break; | ||
} | ||
} | ||
return format(specifier); | ||
} | ||
// Adapted from d3-scale by Mike Bostock | ||
function linearish(scale) { | ||
var domain = scale.domain; | ||
scale.tickFormat = function (count, specifier) { | ||
var d = domain(); | ||
return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier); | ||
}; | ||
scale.ticks = function (count) { | ||
var d = domain(); | ||
return ticks(d[0], d[d.length - 1], count == null ? 10 : count); | ||
}; | ||
return scale; | ||
} | ||
function linear() { | ||
var scale = continuous(); | ||
scale.copy = function () { | ||
return copy(scale, linear()); | ||
}; | ||
initRange.apply(scale, arguments); | ||
return linearish(scale); | ||
} | ||
function geoScaleBar () { | ||
var extent, | ||
var extent = null, | ||
projection, | ||
@@ -1035,4 +237,9 @@ height = 4, | ||
tickValues, | ||
tickFormat = function tickFormat(d) { | ||
return Math.round(d); | ||
}, | ||
label, | ||
labelAnchor = "start", | ||
scaleFactor = 1; | ||
var unitPresets = { | ||
@@ -1048,24 +255,32 @@ "miles": { | ||
function scaleBar(context) { | ||
context.attr("width", extent[0]).attr("height", extent[1]); | ||
var x = extent[0] * left, | ||
y = extent[1] * top, | ||
var barWidth = extent[1][0] - extent[0][0], | ||
barHeight = extent[1][1] - extent[0][1]; | ||
context.attr("width", barWidth).attr("height", barHeight); | ||
var x = extent[0][0] + barWidth * left, | ||
y = extent[0][1] + barHeight * top, | ||
start = projection.invert([x, y]); | ||
distance = distance || Math.pow(10, countDigits(geoDistance(projection.invert([0, 0]), projection.invert([0, extent[1]])) * radius) - 1); | ||
var w = distance / (geoDistance(start, projection.invert([x + 1, y])) * radius); | ||
var scale = linear().range([0, w]).domain([0, distance]); | ||
distance = distance || Math.pow(10, countDigits(geoDistance(projection.invert(extent[0]), projection.invert([extent[1][0], extent[0][1]])) * radius) - 1); | ||
if (scaleFactor !== 1) { | ||
scale.domain([0, scale.invert(w / scaleFactor)]); | ||
} | ||
var w = distance / (geoDistance(start, projection.invert([x + 1, y])) * radius), | ||
scale = function scale(dist) { | ||
return dist * w / (distance / scaleFactor); | ||
}, | ||
tickMax = distance / scaleFactor, | ||
ticks = tickValues === null ? [] : tickValues ? tickValues : [0, tickMax / 4, tickMax / 2, tickMax]; | ||
var tickMax = scale.domain()[1]; | ||
var axis = axisBottom().scale(scale).tickValues(tickValues ? tickValues : [0, tickMax / 4, tickMax / 2, tickMax]).tickSize(height); | ||
var g = context.select("g"); | ||
if (!g._groups[0][0]) { | ||
g = context.append("g").attr("class", "scale-bar"); | ||
g = context.append("g"); | ||
} | ||
g.attr("transform", "translate(" + extent[0] * left + ", " + extent[1] * top + ")").call(axis); | ||
var rects = g.selectAll("rect").data(axis.tickValues().map(function (d, i, data) { | ||
g.attr("transform", "translate(".concat([x, y], ")")); | ||
var baseline = g.select(".baseline"); | ||
if (!baseline._groups[0][0]) { | ||
baseline = g.append("rect").attr("class", "baseline"); | ||
} | ||
baseline.attr("fill", "black").attr("height", height).attr("width", scale(tickMax)); | ||
var rects = g.selectAll(".rectangle").data(ticks.map(function (d, i, data) { | ||
return [d, data[i + 1]]; | ||
@@ -1076,3 +291,3 @@ }).filter(function (d, i, data) { | ||
rects.exit().remove(); | ||
rects.enter().append("rect").attr("height", height).style("stroke", "#000").style("fill", function (d, i) { | ||
rects.enter().append("rect").attr("class", "rectangle").attr("height", height).attr("stroke", "#000").attr("fill", function (d, i) { | ||
return i % 2 === 0 ? "#000" : "#fff"; | ||
@@ -1084,10 +299,13 @@ }).merge(rects).attr("x", function (d) { | ||
}); | ||
var text = g.select(".label"); | ||
var valueText = g.selectAll(".value").data(ticks); | ||
valueText.exit().remove(); | ||
valueText.enter().append("text").attr("class", "value").attr("text-anchor", "middle").attr("font-family", "sans-serif").attr("font-size", 12).merge(valueText).attr("x", scale).attr("y", height + 11).text(tickFormat); | ||
var labelText = g.select(".label"); | ||
if (!text._groups[0][0]) { | ||
text = g.append("text").attr("class", "label"); | ||
if (!labelText._groups[0][0]) { | ||
labelText = g.append("text").attr("class", "label"); | ||
} | ||
text.attr("class", "label").style("fill", "#000").style("text-anchor", "start").style("font-size", "12px").attr("y", -4); | ||
text.text(label || capitalizeFirstLetter(units)); | ||
labelText.attr("x", labelAnchor === "start" ? 0 : labelAnchor === "middle" ? scale(tickMax / 2) : scale(tickMax)).attr("class", "label").attr("fill", "#000").attr("text-anchor", labelAnchor).attr("font-size", 14).attr("font-family", "sans-serif").attr("y", -4); | ||
labelText.text(label || capitalizeFirstLetter(units)); | ||
} | ||
@@ -1099,2 +317,6 @@ | ||
scaleBar.size = function (_) { | ||
return arguments.length ? (extent = [[0, 0], _], scaleBar) : extent[1]; | ||
}; | ||
scaleBar.projection = function (_) { | ||
@@ -1130,2 +352,6 @@ return arguments.length ? (projection = _, scaleBar) : projection; | ||
scaleBar.tickFormat = function (_) { | ||
return arguments.length ? (tickFormat = _, scaleBar) : tickFormat; | ||
}; | ||
scaleBar.label = function (_) { | ||
@@ -1135,2 +361,6 @@ return arguments.length ? (label = _, scaleBar) : label; | ||
scaleBar.labelAnchor = function (_) { | ||
return arguments.length ? (labelAnchor = _, scaleBar) : labelAnchor; | ||
}; | ||
scaleBar.height = function (_) { | ||
@@ -1137,0 +367,0 @@ return arguments.length ? (height = +_, scaleBar) : height; |
@@ -1,1 +0,1 @@ | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(t){"use strict";function n(t){return"translate("+(t+.5)+",0)"}function r(t){return function(n){return+t(n)}}function e(){return!this.__axis}function i(t,i){function o(t){var n=null==u?i.ticks?i.ticks.apply(i,a):i.domain():u,o=null==c?i.tickFormat?i.tickFormat.apply(i,a):function(t){return t}:c,d=Math.max(l,0)+f,m=i.range(),v=+m[0]+.5,M=+m[m.length-1]+.5,y=r(i.copy()),x=t.selection?t.selection():t,b=x.selectAll(".domain").data([null]),k=x.selectAll(".tick").data(n,i).order(),w=k.exit(),N=k.enter().append("g").attr("class","tick"),S=k.select("line"),A=k.select("text");b=b.merge(b.enter().insert("path",".tick").attr("class","domain").attr("stroke","#000")),k=k.merge(N),S=S.merge(N.append("line").attr("stroke","#000").attr(g+"2",h*l)),A=A.merge(N.append("text").attr("fill","#000").attr(g,h*d).attr("dy","0.71em")),t!==x&&(b=b.transition(t),k=k.transition(t),S=S.transition(t),A=A.transition(t),w=w.transition(t).attr("opacity",it).attr("transform",function(t){return isFinite(t=y(t))?p(t):this.getAttribute("transform")}),N.attr("opacity",it).attr("transform",function(t){var n=this.parentNode.__axis;return p(n&&isFinite(n=n(t))?n:y(t))})),w.remove(),b.attr("d",s?"M"+v+","+h*s+"V0.5H"+M+"V"+h*s:"M"+v+",0.5H"+M),k.attr("opacity",1).attr("transform",function(t){return p(y(t))}),S.attr(g+"2",h*l),A.attr(g,h*d).text(o),x.filter(e).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor","middle"),x.each(function(){this.__axis=y})}var a=[],u=null,c=null,l=6,s=6,f=3,h=1,g="y",p=n;return o.scale=function(t){return arguments.length?(i=t,o):i},o.ticks=function(){return a=rt.call(arguments),o},o.tickArguments=function(t){return arguments.length?(a=null==t?[]:rt.call(t),o):a.slice()},o.tickValues=function(t){return arguments.length?(u=null==t?null:rt.call(t),o):u&&u.slice()},o.tickFormat=function(t){return arguments.length?(c=t,o):c},o.tickSize=function(t){return arguments.length?(l=s=+t,o):l},o.tickSizeInner=function(t){return arguments.length?(l=+t,o):l},o.tickSizeOuter=function(t){return arguments.length?(s=+t,o):s},o.tickPadding=function(t){return arguments.length?(f=+t,o):f},o}function o(t){return i(et,t)}function a(){this.reset()}function u(t,n,r){var e=t.s=n+r,i=e-n,o=e-i;t.t=n-o+(r-i)}function c(){}function l(t,n){t&&mt.hasOwnProperty(t.type)&&mt[t.type](t,n)}function s(t,n,r){var e,i=-1,o=t.length-r;for(n.lineStart();++i<o;)e=t[i],n.point(e[0],e[1],e[2]);n.lineEnd()}function f(t,n){var r=-1,e=t.length;for(n.polygonStart();++r<e;)s(t[r],n,1);n.polygonEnd()}function h(t,n){t&&dt.hasOwnProperty(t.type)?dt[t.type](t,n):l(t,n)}function g(){Mt.point=d,Mt.lineEnd=p}function p(){Mt.point=Mt.lineEnd=c}function d(t,n){t*=ht,n*=ht,ot=t,at=gt(n),ut=ft(n),Mt.point=m}function m(t,n){t*=ht,n*=ht;var r=gt(n),e=ft(n),i=lt(t-ot),o=ft(i),a=gt(i),u=e*a,c=ut*r-at*e*o,l=at*r+ut*e*o;vt.add(st(pt(u*u+c*c),l)),ot=t,at=r,ut=e}function v(t){return vt.reset(),h(t,Mt),+vt}function M(t,n){return yt[0]=t,yt[1]=n,v(xt)}function y(t,n,r){var e,i,o,a,u=-1;if(n=+n,t=+t,r=+r,t===n&&r>0)return[t];if((e=n<t)&&(i=t,t=n,n=i),0===(a=x(t,n,r))||!isFinite(a))return[];if(a>0)for(t=Math.ceil(t/a),n=Math.floor(n/a),o=new Array(i=Math.ceil(n-t+1));++u<i;)o[u]=(t+u)*a;else for(t=Math.floor(t*a),n=Math.ceil(n*a),o=new Array(i=Math.ceil(t-n+1));++u<i;)o[u]=(t-u)/a;return e&&o.reverse(),o}function x(t,n,r){var e=(n-t)/Math.max(0,r),i=Math.floor(Math.log(e)/Math.LN10),o=e/Math.pow(10,i);return i>=0?(o>=bt?10:o>=kt?5:o>=wt?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(o>=bt?10:o>=kt?5:o>=wt?2:1)}function b(t,n,r){var e=Math.abs(n-t)/Math.max(0,r),i=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),o=e/i;return o>=bt?i*=10:o>=kt?i*=5:o>=wt&&(i*=2),n<t?-i:i}function k(t,n){return t<n?-1:t>n?1:t>=n?0:NaN}function w(t){return function(n,r){return k(t(n),r)}}function N(t,n){return t=+t,n=+n,function(r){return t*(1-r)+n*r}}function S(t,n){return t=+t,n=+n,function(r){return Math.round(t*(1-r)+n*r)}}function A(t,n){return N(t,n)}function z(t){return function(){return t}}function P(t){return+t}function F(t){return t}function E(t,n){return(n-=t=+t)?function(r){return(r-t)/n}:z(isNaN(n)?NaN:.5)}function j(t,n){var r;return t>n&&(r=t,t=n,n=r),function(r){return Math.max(t,Math.min(n,r))}}function _(t,n,r){var e=t[0],i=t[1],o=n[0],a=n[1];return i<e?(e=E(i,e),o=r(a,o)):(e=E(e,i),o=r(o,a)),function(t){return o(e(t))}}function O(t,n,r){var e=Math.min(t.length,n.length)-1,i=new Array(e),o=new Array(e),a=-1;for(t[e]<t[0]&&(t=t.slice().reverse(),n=n.slice().reverse());++a<e;)i[a]=E(t[a],t[a+1]),o[a]=r(n[a],n[a+1]);return function(n){var r=St(t,n,1,e)-1;return o[r](i[r](n))}}function C(t,n){return n.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function L(){function t(){var t=Math.min(c.length,l.length);return f!==F&&(f=j(c[0],c[t-1])),o=t>2?O:_,a=u=null,n}function n(t){return isNaN(t=+t)?i:(a||(a=o(c.map(r),l,s)))(r(f(t)))}var r,e,i,o,a,u,c=At,l=At,s=A,f=F;return n.invert=function(t){return f(e((u||(u=o(l,c.map(r),N)))(t)))},n.domain=function(n){return arguments.length?(c=Array.from(n,P),t()):c.slice()},n.range=function(n){return arguments.length?(l=Array.from(n),t()):l.slice()},n.rangeRound=function(n){return l=Array.from(n),s=S,t()},n.clamp=function(n){return arguments.length?(f=!!n||F,t()):f!==F},n.interpolate=function(n){return arguments.length?(s=n,t()):s},n.unknown=function(t){return arguments.length?(i=t,n):i},function(n,i){return r=n,e=i,t()}}function V(){return L()(F,F)}function $(t,n){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(n).domain(t)}return this}function q(t,n){if((r=(t=n?t.toExponential(n-1):t.toExponential()).indexOf("e"))<0)return null;var r,e=t.slice(0,r);return[e.length>1?e[0]+e.slice(2):e,+t.slice(r+1)]}function G(t){return t=q(Math.abs(t)),t?t[1]:NaN}function H(t,n){return function(r,e){for(var i=r.length,o=[],a=0,u=t[0],c=0;i>0&&u>0&&(c+u+1>e&&(u=Math.max(1,e-c)),o.push(r.substring(i-=u,i+u)),!((c+=u+1)>e));)u=t[a=(a+1)%t.length];return o.reverse().join(n)}}function I(t){return function(n){return n.replace(/[0-9]/g,function(n){return t[+n]})}}function U(t){if(!(n=zt.exec(t)))throw new Error("invalid format: "+t);var n;return new X({fill:n[1],align:n[2],sign:n[3],symbol:n[4],zero:n[5],width:n[6],comma:n[7],precision:n[8]&&n[8].slice(1),trim:n[9],type:n[10]})}function X(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function B(t){t:for(var n,r=t.length,e=1,i=-1;e<r;++e)switch(t[e]){case".":i=n=e;break;case"0":0===i&&(i=e),n=e;break;default:if(i>0){if(!+t[e])break t;i=0}}return i>0?t.slice(0,i)+t.slice(n+1):t}function R(t,n){var r=q(t,n);if(!r)return t+"";var e=r[0],i=r[1],o=i-(Pt=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,a=e.length;return o===a?e:o>a?e+new Array(o-a+1).join("0"):o>0?e.slice(0,o)+"."+e.slice(o):"0."+new Array(1-o).join("0")+q(t,Math.max(0,n+o-1))[0]}function T(t,n){var r=q(t,n);if(!r)return t+"";var e=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+e:e.length>i+1?e.slice(0,i+1)+"."+e.slice(i+1):e+new Array(i-e.length+2).join("0")}function Y(t){return t}function Z(t){function n(t){function n(t){var n,i,o,c=x,g=b;if("c"===y)g=k(t)+g,t="";else{t=+t;var N=t<0;if(t=isNaN(t)?s:k(Math.abs(t),v),M&&(t=B(t)),N&&0==+t&&(N=!1),c=(N?"("===h?h:l:"-"===h||"("===h?"":h)+c,g=("s"===y?Ct[8+Pt/3]:"")+g+(N&&"("===h?")":""),w)for(n=-1,i=t.length;++n<i;)if(48>(o=t.charCodeAt(n))||o>57){g=(46===o?a+t.slice(n+1):t.slice(n))+g,t=t.slice(0,n);break}}m&&!p&&(t=e(t,1/0));var S=c.length+t.length+g.length,A=S<d?new Array(d-S+1).join(r):"";switch(m&&p&&(t=e(A+t,A.length?d-g.length:1/0),A=""),f){case"<":t=c+t+g+A;break;case"=":t=c+A+t+g;break;case"^":t=A.slice(0,S=A.length>>1)+c+t+g+A.slice(S);break;default:t=A+c+t+g}return u(t)}t=U(t);var r=t.fill,f=t.align,h=t.sign,g=t.symbol,p=t.zero,d=t.width,m=t.comma,v=t.precision,M=t.trim,y=t.type;"n"===y?(m=!0,y="g"):_t[y]||(void 0===v&&(v=12),M=!0,y="g"),(p||"0"===r&&"="===f)&&(p=!0,r="0",f="=");var x="$"===g?i:"#"===g&&/[boxX]/.test(y)?"0"+y.toLowerCase():"",b="$"===g?o:/[%p]/.test(y)?c:"",k=_t[y],w=/[defgprs%]/.test(y);return v=void 0===v?6:/[gprs]/.test(y)?Math.max(1,Math.min(21,v)):Math.max(0,Math.min(20,v)),n.toString=function(){return t+""},n}function r(t,r){var e=n((t=U(t),t.type="f",t)),i=3*Math.max(-8,Math.min(8,Math.floor(G(r)/3))),o=Math.pow(10,-i),a=Ct[8+i/3];return function(t){return e(o*t)+a}}var e=void 0===t.grouping||void 0===t.thousands?Y:H(Ot.call(t.grouping,Number),t.thousands+""),i=void 0===t.currency?"":t.currency[0]+"",o=void 0===t.currency?"":t.currency[1]+"",a=void 0===t.decimal?".":t.decimal+"",u=void 0===t.numerals?Y:I(Ot.call(t.numerals,String)),c=void 0===t.percent?"%":t.percent+"",l=void 0===t.minus?"-":t.minus+"",s=void 0===t.nan?"NaN":t.nan+"";return{format:n,formatPrefix:r}}function D(t){return Math.max(0,-G(Math.abs(t)))}function J(t,n){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(G(n)/3)))-G(Math.abs(t)))}function K(t,n){return t=Math.abs(t),n=Math.abs(n)-t,Math.max(0,G(n)-G(t))+1}function Q(t,n,r,e){var i,o=b(t,n,r);switch(e=U(null==e?",f":e),e.type){case"s":var a=Math.max(Math.abs(t),Math.abs(n));return null!=e.precision||isNaN(i=J(o,a))||(e.precision=i),jt(e,a);case"":case"e":case"g":case"p":case"r":null!=e.precision||isNaN(i=K(o,Math.max(Math.abs(t),Math.abs(n))))||(e.precision=i-("e"===e.type));break;case"f":case"%":null!=e.precision||isNaN(i=D(o))||(e.precision=i-2*("%"===e.type))}return Et(e)}function W(t){var n=t.domain;return t.tickFormat=function(t,r){var e=n();return Q(e[0],e[e.length-1],null==t?10:t,r)},t.ticks=function(t){var r=n();return y(r[0],r[r.length-1],null==t?10:t)},t}function tt(){var t=V();return t.copy=function(){return C(t,tt())},$.apply(t,arguments),W(t)}function nt(){function t(t){t.attr("width",e[0]).attr("height",e[1]);var d=e[0]*s,m=e[1]*f,v=i.invert([d,m]);a=a||Math.pow(10,n(M(i.invert([0,0]),i.invert([0,e[1]]))*g)-1);var y=a/(M(v,i.invert([d+1,m]))*g),x=tt().range([0,y]).domain([0,a]);1!==p&&x.domain([0,x.invert(y/p)]);var b=x.domain()[1],k=o().scale(x).tickValues(u||[0,b/4,b/2,b]).tickSize(l),w=t.select("g");w._groups[0][0]||(w=t.append("g").attr("class","scale-bar")),w.attr("transform","translate("+e[0]*s+", "+e[1]*f+")").call(k);var N=w.selectAll("rect").data(k.tickValues().map(function(t,n,r){return[t,r[n+1]]}).filter(function(t,n,r){return n!==r.length-1}));N.exit().remove(),N.enter().append("rect").attr("height",l).style("stroke","#000").style("fill",function(t,n){return n%2==0?"#000":"#fff"}).merge(N).attr("x",function(t){return x(t[0])}).attr("width",function(t){return x(t[1]-t[0])});var S=w.select(".label");S._groups[0][0]||(S=w.append("text").attr("class","label")),S.attr("class","label").style("fill","#000").style("text-anchor","start").style("font-size","12px").attr("y",-4),S.text(c||r(h))}function n(t){return Math.floor(t).toString().length}function r(t){return t.charAt(0).toUpperCase()+t.slice(1)}var e,i,a,u,c,l=4,s=0,f=0,h="kilometers",g=6371,p=1,d={miles:{radius:3959},kilometers:{radius:6371}};return t.extent=function(n){return arguments.length?(e=n,t):e},t.projection=function(n){return arguments.length?(i=n,t):i},t.units=function(n){return arguments.length?(h=n,Object.keys(d).includes(n)&&(g=d[n].radius),t):h},t.distance=function(n){return arguments.length?(a=+n,t):a},t.radius=function(n){return arguments.length?(g=+n,t):g},t.tickValues=function(n){return arguments.length?(u=n,t):u},t.label=function(n){return arguments.length?(c=n,t):c},t.height=function(n){return arguments.length?(l=+n,t):l},t.left=function(n){return arguments.length?(s=n>1?1:n<0?0:+n,t):s},t.top=function(n){return arguments.length?(f=n>1?1:n<0?0:+n,t):f},t.scaleFactor=function(n){return arguments.length?(p=n,t):p},t}var rt=Array.prototype.slice,et=3,it=1e-6;a.prototype={constructor:a,reset:function(){this.s=this.t=0},add:function(t){u(ct,t,this.t),u(this,ct.s,this.s),this.s?this.t+=ct.t:this.s=ct.t},valueOf:function(){return this.s}};var ot,at,ut,ct=new a,lt=Math.abs,st=Math.atan2,ft=Math.cos,ht=Math.PI/180,gt=Math.sin,pt=Math.sqrt,dt={Feature:function(t,n){l(t.geometry,n)},FeatureCollection:function(t,n){for(var r=t.features,e=-1,i=r.length;++e<i;)l(r[e].geometry,n)}},mt={Sphere:function(t,n){n.sphere()},Point:function(t,n){t=t.coordinates,n.point(t[0],t[1],t[2])},MultiPoint:function(t,n){for(var r=t.coordinates,e=-1,i=r.length;++e<i;)t=r[e],n.point(t[0],t[1],t[2])},LineString:function(t,n){s(t.coordinates,n,0)},MultiLineString:function(t,n){for(var r=t.coordinates,e=-1,i=r.length;++e<i;)s(r[e],n,0)},Polygon:function(t,n){f(t.coordinates,n)},MultiPolygon:function(t,n){for(var r=t.coordinates,e=-1,i=r.length;++e<i;)f(r[e],n)},GeometryCollection:function(t,n){for(var r=t.geometries,e=-1,i=r.length;++e<i;)l(r[e],n)}},vt=function(){return new a}(),Mt={sphere:c,point:c,lineStart:g,lineEnd:c,polygonStart:c,polygonEnd:c},yt=[null,null],xt={type:"LineString",coordinates:yt},bt=Math.sqrt(50),kt=Math.sqrt(10),wt=Math.sqrt(2),Nt=function(t){return 1===t.length&&(t=w(t)),{left:function(n,r,e,i){for(null==e&&(e=0),null==i&&(i=n.length);e<i;){var o=e+i>>>1;t(n[o],r)<0?e=o+1:i=o}return e},right:function(n,r,e,i){for(null==e&&(e=0),null==i&&(i=n.length);e<i;){var o=e+i>>>1;t(n[o],r)>0?i=o:e=o+1}return e}}}(k),St=Nt.right,At=[0,1],zt=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;U.prototype=X.prototype,X.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};var Pt,Ft,Et,jt,_t={"%":function(t,n){return(100*t).toFixed(n)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},g:function(t,n){return t.toPrecision(n)},o:function(t){return Math.round(t).toString(8)},p:function(t,n){return T(100*t,n)},r:T,s:R,X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},Ot=Array.prototype.map,Ct=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];!function(t){Ft=Z(t),Et=Ft.format,jt=Ft.formatPrefix}({decimal:".",thousands:",",grouping:[3],currency:["$",""],minus:"-"}),t.geoScaleBar=nt,Object.defineProperty(t,"__esModule",{value:!0})}); | ||
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(t.d3=t.d3||{})}(this,function(t){"use strict";function n(){this.reset()}function e(t,n,e){var r=t.s=n+e,o=r-n,i=r-o;t.t=n-i+(e-o)}function r(t,n){t&&M.hasOwnProperty(t.type)&&M[t.type](t,n)}function o(t,n,e){var r,o=-1,i=t.length-e;for(n.lineStart();++o<i;)r=t[o],n.point(r[0],r[1],r[2]);n.lineEnd()}function i(t,n){var e=-1,r=t.length;for(n.polygonStart();++e<r;)o(t[e],n,1);n.polygonEnd()}function a(t,n){t&&m.hasOwnProperty(t.type)?m[t.type](t,n):r(t,n)}function u(){b.point=l,b.lineEnd=c}function c(){b.point=b.lineEnd=function(t){}}function l(t,n){t*=Math.PI/180,n*=Math.PI/180,d=t,p=Math.sin(n),v=Math.cos(n),b.point=s}function s(t,n){t*=Math.PI/180,n*=Math.PI/180;var e=Math.sin(n),r=Math.cos(n),o=Math.abs(t-d),i=Math.cos(o),a=Math.sin(o),u=r*a,c=v*e-p*r*i,l=p*e+v*r*i;x.add(Math.atan2(Math.sqrt(u*u+c*c),l)),d=t,p=e,v=r}function f(t){return x.reset(),a(t,b),+x}function h(t,n){return P[0]=t,P[1]=n,f(S)}function g(){function t(t){var y=u[1][0]-u[0][0],m=u[1][1]-u[0][1];t.attr("width",y).attr("height",m);var M=u[0][0]+y*l,x=u[0][1]+m*s,b=r.invert([M,x]);o=o||Math.pow(10,n(h(r.invert(u[0]),r.invert([u[1][0],u[0][1]]))*g)-1);var P=o/(h(b,r.invert([M+1,x]))*g),S=function(t){return t*P/(o/v)},w=o/v,k=null===i?[]:i||[0,w/4,w/2,w],E=t.select("g");E._groups[0][0]||(E=t.append("g")),E.attr("transform","translate(".concat([M,x],")"));var O=E.select(".baseline");O._groups[0][0]||(O=E.append("rect").attr("class","baseline")),O.attr("fill","black").attr("height",c).attr("width",S(w));var _=E.selectAll(".rectangle").data(k.map(function(t,n,e){return[t,e[n+1]]}).filter(function(t,n,e){return n!==e.length-1}));_.exit().remove(),_.enter().append("rect").attr("class","rectangle").attr("height",c).attr("stroke","#000").attr("fill",function(t,n){return n%2==0?"#000":"#fff"}).merge(_).attr("x",function(t){return S(t[0])}).attr("width",function(t){return S(t[1]-t[0])});var j=E.selectAll(".value").data(k);j.exit().remove(),j.enter().append("text").attr("class","value").attr("text-anchor","middle").attr("font-family","sans-serif").attr("font-size",12).merge(j).attr("x",S).attr("y",c+11).text(d);var A=E.select(".label");A._groups[0][0]||(A=E.append("text").attr("class","label")),A.attr("x","start"===p?0:S("middle"===p?w/2:w)).attr("class","label").attr("fill","#000").attr("text-anchor",p).attr("font-size",14).attr("font-family","sans-serif").attr("y",-4),A.text(a||e(f))}function n(t){return Math.floor(t).toString().length}function e(t){return t.charAt(0).toUpperCase()+t.slice(1)}var r,o,i,a,u=null,c=4,l=0,s=0,f="kilometers",g=6371,d=function(t){return Math.round(t)},p="start",v=1,y={miles:{radius:3959},kilometers:{radius:6371}};return t.extent=function(n){return arguments.length?(u=n,t):u},t.size=function(n){return arguments.length?(u=[[0,0],n],t):u[1]},t.projection=function(n){return arguments.length?(r=n,t):r},t.units=function(n){return arguments.length?(f=n,Object.keys(y).includes(n)&&(g=y[n].radius),t):f},t.distance=function(n){return arguments.length?(o=+n,t):o},t.radius=function(n){return arguments.length?(g=+n,t):g},t.tickValues=function(n){return arguments.length?(i=n,t):i},t.tickFormat=function(n){return arguments.length?(d=n,t):d},t.label=function(n){return arguments.length?(a=n,t):a},t.labelAnchor=function(n){return arguments.length?(p=n,t):p},t.height=function(n){return arguments.length?(c=+n,t):c},t.left=function(n){return arguments.length?(l=n>1?1:n<0?0:+n,t):l},t.top=function(n){return arguments.length?(s=n>1?1:n<0?0:+n,t):s},t.scaleFactor=function(n){return arguments.length?(v=n,t):v},t}n.prototype={constructor:n,reset:function(){this.s=this.t=0},add:function(t){e(y,t,this.t),e(this,y.s,this.s),this.s?this.t+=y.t:this.s=y.t},valueOf:function(){return this.s}};var d,p,v,y=new n,m={Feature:function(t,n){r(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,o=-1,i=e.length;++o<i;)r(e[o].geometry,n)}},M={Sphere:function(t,n){n.sphere()},Point:function(t,n){t=t.coordinates,n.point(t[0],t[1],t[2])},MultiPoint:function(t,n){for(var e=t.coordinates,r=-1,o=e.length;++r<o;)t=e[r],n.point(t[0],t[1],t[2])},LineString:function(t,n){o(t.coordinates,n,0)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,i=e.length;++r<i;)o(e[r],n,0)},Polygon:function(t,n){i(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,o=e.length;++r<o;)i(e[r],n)},GeometryCollection:function(t,n){for(var e=t.geometries,o=-1,i=e.length;++o<i;)r(e[o],n)}},x=function(){return new n}(),b={sphere:function(t){},point:function(t){},lineStart:u,lineEnd:function(t){},polygonStart:function(t){},polygonEnd:function(t){}},P=[null,null],S={type:"LineString",coordinates:P};t.geoScaleBar=g,Object.defineProperty(t,"__esModule",{value:!0})}); |
{ | ||
"name": "d3-geo-scale-bar", | ||
"version": "0.3.1", | ||
"version": "0.4.0", | ||
"description": "Displays automatic scale bars for projected geospatial data.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -14,11 +14,17 @@ # d3-geo-scale-bar | ||
```html | ||
<script src="https://unpkg.com/d3-geo-scale-bar@0.3.1/build/d3-geo-scale-bar.min.js"></script> | ||
<script src="https://unpkg.com/d3-geo-scale-bar@0.4.0/build/d3-geo-scale-bar.min.js"></script> | ||
<script> | ||
var scaleBar = d3.geoScaleBar() | ||
.projection(d3GeoProjection) | ||
.extent([width, height]); | ||
const projection = d3.geoMercator() | ||
.fitSize([width, height], geoJSON) | ||
d3.select("svg").append("g").call(scaleBar); | ||
const scaleBar = d3.geoScaleBar() | ||
.projection() | ||
.size([width, height]); | ||
d3.select("svg") | ||
.attr("width", width) | ||
.attr("height", height) | ||
.append("g").call(scaleBar); | ||
</script> | ||
@@ -35,37 +41,15 @@ ``` | ||
A scale bar consists of a [g element](https://www.w3.org/TR/SVG/struct.html#Groups) of class "scale-bar". That element contains an [axis](https://github.com/d3/d3-axis#api-reference) with a [path element](https://www.w3.org/TR/SVG/paths.html#PathElement) of class "domain", g elements of class "tick" representing each of the scale's ticks, [rect elements](https://www.w3.org/TR/SVG/shapes.html#RectElement) of alternating black and white fill, and finally a [text element](https://www.w3.org/TR/SVG/text.html#TextElement) of class "label" containing the units of the corresponding scale bar. All of these can be styled and manipulated like normal SVG elements. | ||
A scale bar consists of a [g element](https://www.w3.org/TR/SVG/struct.html#Groups) which, by default, contains one [rect element](https://www.w3.org/TR/SVG/paths.html#RectElement) of class "baseline", three rect elements of class "rectangle" with alternating black and white fill, four [text elements](https://www.w3.org/TR/SVG/text.html#TextElement) of class "value", and one text element of class "label". All of these can be styled and manipulated like normal SVG elements. | ||
```svg | ||
<g class="scale-bar" transform="translate(2, 14)" font-size="10" font-family="sans-serif" text-anchor="middle"> | ||
<path class="domain" stroke="#000" d="M0.5,4V0.5H200V4"></path> | ||
<g class="tick" opacity="1" transform="translate(0.5,0)"> | ||
<line stroke="#000" y2="4"></line> | ||
<text fill="#000" y="7" dy="0.71em"> | ||
0 | ||
</text> | ||
</g> | ||
<g class="tick" opacity="1" transform="translate(50,0)"> | ||
<line stroke="#000" y2="4"></line> | ||
<text fill="#000" y="7" dy="0.71em"> | ||
250 | ||
</text> | ||
</g> | ||
<g class="tick" opacity="1" transform="translate(100,0)"> | ||
<line stroke="#000" y2="4"></line> | ||
<text fill="#000" y="7" dy="0.71em"> | ||
500 | ||
</text> | ||
</g> | ||
<g class="tick" opacity="1" transform="translate(200,0)"> | ||
<line stroke="#000" y2="4"></line> | ||
<text fill="#000" y="7" dy="0.71em"> | ||
1,000 | ||
</text> | ||
</g> | ||
<rect height="4" x="0" width="50" style="stroke: #000; fill: #000;"></rect> | ||
<rect height="4" x="50" width="50" style="stroke: #000; fill: #fff;"></rect> | ||
<rect height="4" x="100" width="100" style="stroke: #000; fill: #000;"></rect> | ||
<text class="label" y="-4" style="fill: #000; text-anchor: start; font-size: 12px;"> | ||
Kilometers | ||
</text> | ||
<g transform="translate(0,0)"> | ||
<rect class="baseline" fill="black" height="4" width="200"></rect> | ||
<rect class="rectangle" height="4" stroke="#000" fill="#000" x="0" width="50"></rect> | ||
<rect class="rectangle" height="4" stroke="#000" fill="#fff" x="50" width="50"></rect> | ||
<rect class="rectangle" height="4" stroke="#000" fill="#000" x="100" width="100"></rect> | ||
<text class="value" text-anchor="middle" font-family="sans-serif" font-size="12" x="0" y="15">0</text> | ||
<text class="value" text-anchor="middle" font-family="sans-serif" font-size="12" x="50" y="15">250</text> | ||
<text class="value" text-anchor="middle" font-family="sans-serif" font-size="12" x="100" y="15">500</text> | ||
<text class="value" text-anchor="middle" font-family="sans-serif" font-size="12" x="200" y="15">1000</text> | ||
<text class="label" x="0" fill="#000" text-anchor="start" font-size="14" font-family="sans-serif" y="-4">Kilometers</text> | ||
</g> | ||
@@ -76,3 +60,3 @@ ``` | ||
Constructs a new scale bar generator. | ||
Constructs a new scale bar generator with the default settings. | ||
@@ -89,4 +73,12 @@ <a name="_scaleBar" href="#_scaleBar">#</a> <i>scaleBar</i>(<i>context</i>) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L27 "Source") | ||
If *extent* is specified, sets the extent such that (1) the scale bar's default top-left corner aligns with the top-left corner of the extent, and (2) you can position the scale bar vertically with [*scaleBar*.top](#scaleBar_top) and horizontally with [*scaleBar*.left](#scaleBar_left). If *extent* is not specified, returns the current extent. | ||
If <i>extent</i> is specified, sets the extent of the scale bar generator to the specified bounds and returns the scale bar generator. The extent bounds are specified as an array [[<i>x0</i>, <i>y0</i>], [<i>x1</i>, <i>y1</i>]], where <i>x0</i> is the left side of the extent, <i>y0</i> is the top, <i>x1</i> is the right and <i>y1</i> is the bottom. If extent is not specified, returns the current extent which defaults to null. An extent is required. | ||
<a name="scaleBar_size" href="#scaleBar_size">#</a> <i>scaleBar</i>.<b>size</b>([<i>size</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L91 "Source") | ||
An alias for [<i>scaleBar</i>.extent](#scaleBar_extent) where the minimum x and y of the extent are ⟨0,0⟩. Equivalent to: | ||
```js | ||
scaleBar.extent([[0, 0], size]); | ||
``` | ||
<a name="scaleBar_units" href="#scaleBar_units">#</a> <i>scaleBar</i>.<b>units</b>([<i>units</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L99 "Source") | ||
@@ -106,8 +98,16 @@ | ||
If a *values* array is specified, the specified values are used for ticks rather than using the scale bar’s automatic tick generator. Defaults to [0, kilometers / 4, kilometers / 2, kilometers]. If *values* is not specified, returns the current tick values. | ||
If a <i>values</i> array is specified, the specified values are used for ticks rather than using the scale bar’s automatic tick generator. Defaults to [0, kilometers / 4, kilometers / 2, kilometers]. Passing <i>null</i> removes the values from the scale bar. If <i>values</i> is not specified, returns the current tick values. | ||
<a name="scaleBar_tickFormat" href="#scaleBar_tickFormat">#</a> <i>scaleBar</i>.<b>tickFormat</b>([<i>formatter</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L122 "Source") | ||
If a <i>formatter</i> function is specified, each tick is passed through the formatter before being displayed. Defaults to (d, i, e) => Math.round(d), where d is the tick number, i is the tick index, and e is an array of all tick data. If a <i>formatter</i> is not specified, returns the current formatter. | ||
<a name="scaleBar_label" href="#scaleBar_label">#</a> <i>scaleBar</i>.<b>label</b>([<i>label</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L126 "Source") | ||
If a *label* string is specified, updates the text in the scale bar's label to the specified string. Defaults to the capitalized unit, e.g. "Kilometers". If *label* is not specified, returns the current label. | ||
If a <i>label</i> string is specified, updates the text in the scale bar's label to the specified string. Defaults to the capitalized unit, e.g. "Kilometers". If *label* is not specified, returns the current label. | ||
<a name="scaleBar_labelAnchor" href="#scaleBar_labelAnchor">#</a> <i>scaleBar</i>.<b>labelAnchor</b>([<i>anchor</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L126 "Source") | ||
If an <i>anchor</i> string is specified, aligns the scale bar's label such that it is either at the "start" of the scale bar, the "middle" of the scale bar, or the "end" of the scale bar. Defaults to "start". If an <i>anchor</i> string is not specified, returns the current anchor. | ||
<a name="scaleBar_scaleFactor" href="#scaleBar_scaleFactor">#</a> <i>scaleBar</i>.<b>scaleFactor</b>([<i>k</i>]) [<>](https://github.com/HarryStevens/d3-geo-scale-bar/blob/master/src/geoScaleBar.js#L142 "Source") | ||
@@ -118,4 +118,3 @@ | ||
```js | ||
var zoom = d3.zoom() | ||
const zoom = d3.zoom() | ||
.on("zoom", _ => { | ||
@@ -122,0 +121,0 @@ const t = d3.event.transform; |
@@ -1,2 +0,2 @@ | ||
// From d3-geo by Mike Bostock | ||
// Adapted from d3-geo by Mike Bostock | ||
// Source: https://github.com/d3/d3-geo/blob/master/src/length.js | ||
@@ -6,4 +6,2 @@ // License: https://github.com/d3/d3-geo/blob/master/LICENSE | ||
import adder from "./adder.js"; | ||
import { abs, atan2, cos, radians, sin, sqrt } from "./math.js"; | ||
import noop from "./noop.js"; | ||
import stream from "./stream.js"; | ||
@@ -17,8 +15,8 @@ | ||
const lengthStream = { | ||
sphere: noop, | ||
point: noop, | ||
sphere: _ => {}, | ||
point: _ => {}, | ||
lineStart: lengthLineStart, | ||
lineEnd: noop, | ||
polygonStart: noop, | ||
polygonEnd: noop | ||
lineEnd: _ => {}, | ||
polygonStart: _ => {}, | ||
polygonEnd: _ => {} | ||
}; | ||
@@ -32,8 +30,8 @@ | ||
function lengthLineEnd() { | ||
lengthStream.point = lengthStream.lineEnd = noop; | ||
lengthStream.point = lengthStream.lineEnd = _ => {}; | ||
} | ||
function lengthPointFirst(lambda, phi) { | ||
lambda *= radians, phi *= radians; | ||
lambda0 = lambda, sinPhi0 = sin(phi), cosPhi0 = cos(phi); | ||
lambda *= Math.PI / 180, phi *= Math.PI / 180; | ||
lambda0 = lambda, sinPhi0 = Math.sin(phi), cosPhi0 = Math.cos(phi); | ||
lengthStream.point = lengthPoint; | ||
@@ -43,12 +41,12 @@ } | ||
function lengthPoint(lambda, phi) { | ||
lambda *= radians, phi *= radians; | ||
const sinPhi = sin(phi), | ||
cosPhi = cos(phi), | ||
delta = abs(lambda - lambda0), | ||
cosDelta = cos(delta), | ||
sinDelta = sin(delta), | ||
lambda *= Math.PI / 180, phi *= Math.PI / 180; | ||
const sinPhi = Math.sin(phi), | ||
cosPhi = Math.cos(phi), | ||
delta = Math.abs(lambda - lambda0), | ||
cosDelta = Math.cos(delta), | ||
sinDelta = Math.sin(delta), | ||
x = cosPhi * sinDelta, | ||
y = cosPhi0 * sinPhi - sinPhi0 * cosPhi * cosDelta, | ||
z = sinPhi0 * sinPhi + cosPhi0 * cosPhi * cosDelta; | ||
lengthSum.add(atan2(sqrt(x * x + y * y), z)); | ||
lengthSum.add(Math.atan2(Math.sqrt(x * x + y * y), z)); | ||
lambda0 = lambda, sinPhi0 = sinPhi, cosPhi0 = cosPhi; | ||
@@ -55,0 +53,0 @@ } |
@@ -1,7 +0,5 @@ | ||
import { axisBottom } from "./axis/axis"; | ||
import { default as geoDistance } from "./geo/distance"; | ||
import { default as scaleLinear } from "./scale/linear"; | ||
export default function(){ | ||
let extent, | ||
let extent = null, | ||
projection, | ||
@@ -15,3 +13,5 @@ height = 4, | ||
tickValues, | ||
tickFormat = d => Math.round(d), | ||
label, | ||
labelAnchor = "start", | ||
scaleFactor = 1; | ||
@@ -29,39 +29,36 @@ | ||
function scaleBar(context){ | ||
context.attr("width", extent[0]).attr("height", extent[1]); | ||
const barWidth = extent[1][0] - extent[0][0], | ||
barHeight = extent[1][1] - extent[0][1]; | ||
const x = extent[0] * left, | ||
y = extent[1] * top, | ||
context.attr("width", barWidth).attr("height", barHeight); | ||
const x = extent[0][0] + barWidth * left, | ||
y = extent[0][1] + barHeight * top, | ||
start = projection.invert([x, y]); | ||
distance = distance || Math.pow(10, countDigits(geoDistance(projection.invert([0, 0]), projection.invert([0, extent[1]])) * radius) - 1); | ||
distance = distance || Math.pow(10, countDigits(geoDistance(projection.invert(extent[0]), projection.invert([extent[1][0], extent[0][1]])) * radius) - 1); | ||
const w = distance / (geoDistance(start, projection.invert([x + 1, y])) * radius); | ||
const w = distance / (geoDistance(start, projection.invert([x + 1, y])) * radius), | ||
scale = dist => dist * w / (distance / scaleFactor), | ||
tickMax = distance / scaleFactor, | ||
ticks = tickValues === null ? [] : tickValues ? tickValues : [0, tickMax / 4, tickMax / 2, tickMax]; | ||
const scale = scaleLinear() | ||
.range([0, w]) | ||
.domain([0, distance]); | ||
if (scaleFactor !== 1){ | ||
scale | ||
.domain([0, scale.invert(w / scaleFactor)]); | ||
} | ||
const tickMax = scale.domain()[1]; | ||
const axis = axisBottom() | ||
.scale(scale) | ||
.tickValues(tickValues ? tickValues : [0, tickMax / 4, tickMax / 2, tickMax]) | ||
.tickSize(height); | ||
let g = context.select("g") | ||
if (!g._groups[0][0]) { | ||
g = context.append("g") | ||
.attr("class", "scale-bar"); | ||
g = context.append("g"); | ||
} | ||
g | ||
.attr("transform", "translate(" + (extent[0] * left) + ", " + (extent[1] * top) + ")") | ||
.call(axis); | ||
g.attr("transform", `translate(${[x, y]})`); | ||
let baseline = g.select(".baseline") | ||
if (!baseline._groups[0][0]) { | ||
baseline = g.append("rect") | ||
.attr("class", "baseline"); | ||
} | ||
baseline | ||
.attr("fill", "black") | ||
.attr("height", height) | ||
.attr("width", scale(tickMax)); | ||
const rects = g.selectAll("rect") | ||
.data(axis.tickValues().map((d, i, data) => [d, data[i + 1]]).filter((d, i, data) => i !== data.length - 1)); | ||
const rects = g.selectAll(".rectangle") | ||
.data(ticks.map((d, i, data) => [d, data[i + 1]]).filter((d, i, data) => i !== data.length - 1)); | ||
@@ -71,5 +68,6 @@ rects.exit().remove(); | ||
rects.enter().append("rect") | ||
.attr("class", "rectangle") | ||
.attr("height", height) | ||
.style("stroke", "#000") | ||
.style("fill", (d, i) => i % 2 === 0 ? "#000" : "#fff") | ||
.attr("stroke", "#000") | ||
.attr("fill", (d, i) => i % 2 === 0 ? "#000" : "#fff") | ||
.merge(rects) | ||
@@ -79,15 +77,32 @@ .attr("x", d => scale(d[0])) | ||
let text = g.select(".label"); | ||
if (!text._groups[0][0]){ | ||
text = g.append("text") | ||
const valueText = g.selectAll(".value") | ||
.data(ticks); | ||
valueText.exit().remove(); | ||
valueText.enter().append("text") | ||
.attr("class", "value") | ||
.attr("text-anchor", "middle") | ||
.attr("font-family", "sans-serif") | ||
.attr("font-size", 12) | ||
.merge(valueText) | ||
.attr("x", scale) | ||
.attr("y", height + 11) | ||
.text(tickFormat); | ||
let labelText = g.select(".label"); | ||
if (!labelText._groups[0][0]){ | ||
labelText = g.append("text") | ||
.attr("class", "label") | ||
} | ||
text | ||
.attr("class", "label") | ||
.style("fill", "#000") | ||
.style("text-anchor", "start") | ||
.style("font-size", "12px") | ||
.attr("y", -4); | ||
labelText | ||
.attr("x", labelAnchor === "start" ? 0 : labelAnchor === "middle" ? scale(tickMax / 2) : scale(tickMax)) | ||
.attr("class", "label") | ||
.attr("fill", "#000") | ||
.attr("text-anchor", labelAnchor) | ||
.attr("font-size", 14) | ||
.attr("font-family", "sans-serif") | ||
.attr("y", -4); | ||
text.text(label || capitalizeFirstLetter(units)); | ||
labelText.text(label || capitalizeFirstLetter(units)); | ||
} | ||
@@ -98,2 +113,6 @@ | ||
} | ||
scaleBar.size = function(_) { | ||
return arguments.length ? (extent = [[0, 0], _], scaleBar) : extent[1]; | ||
} | ||
@@ -130,2 +149,6 @@ scaleBar.projection = function(_) { | ||
} | ||
scaleBar.tickFormat = function(_) { | ||
return arguments.length ? (tickFormat = _, scaleBar) : tickFormat; | ||
} | ||
@@ -135,2 +158,6 @@ scaleBar.label = function(_) { | ||
} | ||
scaleBar.labelAnchor = function(_) { | ||
return arguments.length ? (labelAnchor = _, scaleBar) : labelAnchor; | ||
} | ||
@@ -137,0 +164,0 @@ scaleBar.height = function(_) { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 2 instances in 1 package
2
60688
17
648
138