|
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ |
|
/* |
|
|
|
This file needs to be compiled with Browserify to `bundle.js` in order that the visualisation can be displayed in the browser. |
|
|
|
*/ |
|
|
|
var d3 = require("d3") |
|
d3.legend = require("d3-svg-legend") |
|
|
|
var margin = {top: 20, right: 100, bottom: 10, left: 100} |
|
var width = 960 - margin.left - margin.right |
|
var height = 500 - margin.top - margin.bottom |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
.append("g") |
|
.attr("transform", `translate(${margin.left}, ${margin.top})`) |
|
|
|
var x = d3.scaleOrdinal() |
|
.domain(["2015", "2017"]) |
|
.range([0, width / 2]) |
|
|
|
var y = d3.scaleLinear() |
|
.rangeRound([height, 50]) |
|
|
|
var line = d3.line() |
|
.x(d => x(d.year)) |
|
.y(d => y(d.seats)) |
|
|
|
d3.csv("raw.csv", function(error, data) { |
|
|
|
if (error) throw error |
|
|
|
var partyHashTable = data.reduce((p, c) => { |
|
p[c["2015"]] = p[c["2015"]] || { "2015": 0, "2017": 0 } |
|
p[c["2017"]] = p[c["2017"]] || { "2015": 0, "2017": 0 } |
|
p[c["2015"]]["2015"] += 1 |
|
p[c["2017"]]["2017"] += 1 |
|
return p |
|
}, {}) |
|
|
|
var partyPairs = Object.keys(partyHashTable) |
|
.map(k => [{ |
|
"party": k, |
|
"year": "2015", |
|
"seats": partyHashTable[k]["2015"] |
|
}, { |
|
"party": k, |
|
"year": "2017", |
|
"seats": partyHashTable[k]["2017"] |
|
}]) |
|
|
|
var partyData = partyPairs.reduce((p, c) => p.concat(c), []) |
|
|
|
y.domain(d3.extent(partyData, d => d.seats)) |
|
|
|
svg.append("g") |
|
.call(d3.axisLeft(y)) |
|
.classed("axis", true) |
|
|
|
svg.append("g") |
|
.attr("transform", `translate(${width / 2}, 0)`) |
|
.call(d3.axisRight(y)) |
|
.classed("axis", true) |
|
|
|
svg.selectAll(".axis-label") |
|
.data(["2015", "2017"]) |
|
.enter().append("text") |
|
.attr("x", (d, i, a) => ((width / 2) / (a.length - 1 || 0)) * i) |
|
.attr("y", 0) |
|
.attr("dy", "1em") |
|
.attr("text-anchor", "end") |
|
.attr("id", d => `label${d}`) |
|
.classed("axis-label", true) |
|
.text(d => d) |
|
.attr("transform", d => `translate(${d3.select("#label" + d).node().getBBox().width / 2})`) |
|
|
|
svg.append("path") |
|
.classed("majorityline", true) |
|
.attr("d", line([ |
|
{ "year": "2015", "seats": 325 }, |
|
{ "year": "2017", "seats": 325 } |
|
])) |
|
|
|
svg.selectAll(".dot") |
|
.data(partyData) |
|
.enter().append("circle") |
|
.attr("class", d => d.party |
|
.replace(/\s\(\d{4}\)$/, "") |
|
.replace(/\s+/g, "-") |
|
.toLowerCase()) |
|
.classed("dot", true) |
|
.attr("cx", d => x(d.year)) |
|
.attr("cy", d => y(d.seats)) |
|
|
|
svg.selectAll(".partyline") |
|
.data(partyPairs) |
|
.enter().append("path") |
|
.attr("class", d => `line ${d[0].party.replace(/\s\(\d{4}\)$/, "") |
|
.replace(/\s+/g, "-") |
|
.toLowerCase()}`) |
|
.classed("partyline", true) |
|
.attr("d", d => line(d)) |
|
|
|
var z = d3.scaleOrdinal() |
|
.domain(Object.keys(partyHashTable) |
|
.sort((a, b) => partyHashTable[b]["2017"] - partyHashTable[a]["2017"]) |
|
) |
|
.range(Object.keys(partyHashTable) |
|
.sort((a, b) => partyHashTable[b]["2017"] - partyHashTable[a]["2017"]) |
|
.map(p => p.replace(/\s/g, "-").toLowerCase()) |
|
) |
|
|
|
svg.append("g") |
|
.attr("class", "legendOrdinal") |
|
.attr("transform", `translate(${width / 2 + margin.left}, 20)`) |
|
|
|
var legend = d3.legend.legendColor() |
|
.labelFormat(d => d) |
|
.useClass(true) |
|
.title("Parties") |
|
.titleWidth(100) |
|
.scale(z) |
|
|
|
svg.select(".legendOrdinal") |
|
.call(legend) |
|
|
|
}) |
|
|
|
},{"d3":13,"d3-svg-legend":5}],2:[function(require,module,exports){ |
|
// https://d3js.org/d3-collection/ Version 1.0.3. Copyright 2017 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}))); |
|
}(this, (function (exports) { 'use strict'; |
|
|
|
var prefix = "$"; |
|
|
|
function Map() {} |
|
|
|
Map.prototype = map.prototype = { |
|
constructor: Map, |
|
has: function(key) { |
|
return (prefix + key) in this; |
|
}, |
|
get: function(key) { |
|
return this[prefix + key]; |
|
}, |
|
set: function(key, value) { |
|
this[prefix + key] = value; |
|
return this; |
|
}, |
|
remove: function(key) { |
|
var property = prefix + key; |
|
return property in this && delete this[property]; |
|
}, |
|
clear: function() { |
|
for (var property in this) if (property[0] === prefix) delete this[property]; |
|
}, |
|
keys: function() { |
|
var keys = []; |
|
for (var property in this) if (property[0] === prefix) keys.push(property.slice(1)); |
|
return keys; |
|
}, |
|
values: function() { |
|
var values = []; |
|
for (var property in this) if (property[0] === prefix) values.push(this[property]); |
|
return values; |
|
}, |
|
entries: function() { |
|
var entries = []; |
|
for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]}); |
|
return entries; |
|
}, |
|
size: function() { |
|
var size = 0; |
|
for (var property in this) if (property[0] === prefix) ++size; |
|
return size; |
|
}, |
|
empty: function() { |
|
for (var property in this) if (property[0] === prefix) return false; |
|
return true; |
|
}, |
|
each: function(f) { |
|
for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this); |
|
} |
|
}; |
|
|
|
function map(object, f) { |
|
var map = new Map; |
|
|
|
// Copy constructor. |
|
if (object instanceof Map) object.each(function(value, key) { map.set(key, value); }); |
|
|
|
// Index array by numeric index or specified key function. |
|
else if (Array.isArray(object)) { |
|
var i = -1, |
|
n = object.length, |
|
o; |
|
|
|
if (f == null) while (++i < n) map.set(i, object[i]); |
|
else while (++i < n) map.set(f(o = object[i], i, object), o); |
|
} |
|
|
|
// Convert object to map. |
|
else if (object) for (var key in object) map.set(key, object[key]); |
|
|
|
return map; |
|
} |
|
|
|
var nest = function() { |
|
var keys = [], |
|
sortKeys = [], |
|
sortValues, |
|
rollup, |
|
nest; |
|
|
|
function apply(array, depth, createResult, setResult) { |
|
if (depth >= keys.length) return rollup != null |
|
? rollup(array) : (sortValues != null |
|
? array.sort(sortValues) |
|
: array); |
|
|
|
var i = -1, |
|
n = array.length, |
|
key = keys[depth++], |
|
keyValue, |
|
value, |
|
valuesByKey = map(), |
|
values, |
|
result = createResult(); |
|
|
|
while (++i < n) { |
|
if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { |
|
values.push(value); |
|
} else { |
|
valuesByKey.set(keyValue, [value]); |
|
} |
|
} |
|
|
|
valuesByKey.each(function(values, key) { |
|
setResult(result, key, apply(values, depth, createResult, setResult)); |
|
}); |
|
|
|
return result; |
|
} |
|
|
|
function entries(map$$1, depth) { |
|
if (++depth > keys.length) return map$$1; |
|
var array, sortKey = sortKeys[depth - 1]; |
|
if (rollup != null && depth >= keys.length) array = map$$1.entries(); |
|
else array = [], map$$1.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); |
|
return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; |
|
} |
|
|
|
return nest = { |
|
object: function(array) { return apply(array, 0, createObject, setObject); }, |
|
map: function(array) { return apply(array, 0, createMap, setMap); }, |
|
entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, |
|
key: function(d) { keys.push(d); return nest; }, |
|
sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, |
|
sortValues: function(order) { sortValues = order; return nest; }, |
|
rollup: function(f) { rollup = f; return nest; } |
|
}; |
|
}; |
|
|
|
function createObject() { |
|
return {}; |
|
} |
|
|
|
function setObject(object, key, value) { |
|
object[key] = value; |
|
} |
|
|
|
function createMap() { |
|
return map(); |
|
} |
|
|
|
function setMap(map$$1, key, value) { |
|
map$$1.set(key, value); |
|
} |
|
|
|
function Set() {} |
|
|
|
var proto = map.prototype; |
|
|
|
Set.prototype = set.prototype = { |
|
constructor: Set, |
|
has: proto.has, |
|
add: function(value) { |
|
value += ""; |
|
this[prefix + value] = value; |
|
return this; |
|
}, |
|
remove: proto.remove, |
|
clear: proto.clear, |
|
values: proto.keys, |
|
size: proto.size, |
|
empty: proto.empty, |
|
each: proto.each |
|
}; |
|
|
|
function set(object, f) { |
|
var set = new Set; |
|
|
|
// Copy constructor. |
|
if (object instanceof Set) object.each(function(value) { set.add(value); }); |
|
|
|
// Otherwise, assume it’s an array. |
|
else if (object) { |
|
var i = -1, n = object.length; |
|
if (f == null) while (++i < n) set.add(object[i]); |
|
else while (++i < n) set.add(f(object[i], i, object)); |
|
} |
|
|
|
return set; |
|
} |
|
|
|
var keys = function(map) { |
|
var keys = []; |
|
for (var key in map) keys.push(key); |
|
return keys; |
|
}; |
|
|
|
var values = function(map) { |
|
var values = []; |
|
for (var key in map) values.push(map[key]); |
|
return values; |
|
}; |
|
|
|
var entries = function(map) { |
|
var entries = []; |
|
for (var key in map) entries.push({key: key, value: map[key]}); |
|
return entries; |
|
}; |
|
|
|
exports.nest = nest; |
|
exports.set = set; |
|
exports.map = map; |
|
exports.keys = keys; |
|
exports.values = values; |
|
exports.entries = entries; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
}))); |
|
|
|
},{}],3:[function(require,module,exports){ |
|
// https://d3js.org/d3-color/ Version 1.0.3. Copyright 2017 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}))); |
|
}(this, (function (exports) { 'use strict'; |
|
|
|
var define = function(constructor, factory, prototype) { |
|
constructor.prototype = factory.prototype = prototype; |
|
prototype.constructor = constructor; |
|
}; |
|
|
|
function extend(parent, definition) { |
|
var prototype = Object.create(parent.prototype); |
|
for (var key in definition) prototype[key] = definition[key]; |
|
return prototype; |
|
} |
|
|
|
function Color() {} |
|
|
|
var darker = 0.7; |
|
var brighter = 1 / darker; |
|
|
|
var reI = "\\s*([+-]?\\d+)\\s*"; |
|
var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; |
|
var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; |
|
var reHex3 = /^#([0-9a-f]{3})$/; |
|
var reHex6 = /^#([0-9a-f]{6})$/; |
|
var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); |
|
var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); |
|
var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); |
|
var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); |
|
var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); |
|
var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); |
|
|
|
var named = { |
|
aliceblue: 0xf0f8ff, |
|
antiquewhite: 0xfaebd7, |
|
aqua: 0x00ffff, |
|
aquamarine: 0x7fffd4, |
|
azure: 0xf0ffff, |
|
beige: 0xf5f5dc, |
|
bisque: 0xffe4c4, |
|
black: 0x000000, |
|
blanchedalmond: 0xffebcd, |
|
blue: 0x0000ff, |
|
blueviolet: 0x8a2be2, |
|
brown: 0xa52a2a, |
|
burlywood: 0xdeb887, |
|
cadetblue: 0x5f9ea0, |
|
chartreuse: 0x7fff00, |
|
chocolate: 0xd2691e, |
|
coral: 0xff7f50, |
|
cornflowerblue: 0x6495ed, |
|
cornsilk: 0xfff8dc, |
|
crimson: 0xdc143c, |
|
cyan: 0x00ffff, |
|
darkblue: 0x00008b, |
|
darkcyan: 0x008b8b, |
|
darkgoldenrod: 0xb8860b, |
|
darkgray: 0xa9a9a9, |
|
darkgreen: 0x006400, |
|
darkgrey: 0xa9a9a9, |
|
darkkhaki: 0xbdb76b, |
|
darkmagenta: 0x8b008b, |
|
darkolivegreen: 0x556b2f, |
|
darkorange: 0xff8c00, |
|
darkorchid: 0x9932cc, |
|
darkred: 0x8b0000, |
|
darksalmon: 0xe9967a, |
|
darkseagreen: 0x8fbc8f, |
|
darkslateblue: 0x483d8b, |
|
darkslategray: 0x2f4f4f, |
|
darkslategrey: 0x2f4f4f, |
|
darkturquoise: 0x00ced1, |
|
darkviolet: 0x9400d3, |
|
deeppink: 0xff1493, |
|
deepskyblue: 0x00bfff, |
|
dimgray: 0x696969, |
|
dimgrey: 0x696969, |
|
dodgerblue: 0x1e90ff, |
|
firebrick: 0xb22222, |
|
floralwhite: 0xfffaf0, |
|
forestgreen: 0x228b22, |
|
fuchsia: 0xff00ff, |
|
gainsboro: 0xdcdcdc, |
|
ghostwhite: 0xf8f8ff, |
|
gold: 0xffd700, |
|
goldenrod: 0xdaa520, |
|
gray: 0x808080, |
|
green: 0x008000, |
|
greenyellow: 0xadff2f, |
|
grey: 0x808080, |
|
honeydew: 0xf0fff0, |
|
hotpink: 0xff69b4, |
|
indianred: 0xcd5c5c, |
|
indigo: 0x4b0082, |
|
ivory: 0xfffff0, |
|
khaki: 0xf0e68c, |
|
lavender: 0xe6e6fa, |
|
lavenderblush: 0xfff0f5, |
|
lawngreen: 0x7cfc00, |
|
lemonchiffon: 0xfffacd, |
|
lightblue: 0xadd8e6, |
|
lightcoral: 0xf08080, |
|
lightcyan: 0xe0ffff, |
|
lightgoldenrodyellow: 0xfafad2, |
|
lightgray: 0xd3d3d3, |
|
lightgreen: 0x90ee90, |
|
lightgrey: 0xd3d3d3, |
|
lightpink: 0xffb6c1, |
|
lightsalmon: 0xffa07a, |
|
lightseagreen: 0x20b2aa, |
|
lightskyblue: 0x87cefa, |
|
lightslategray: 0x778899, |
|
lightslategrey: 0x778899, |
|
lightsteelblue: 0xb0c4de, |
|
lightyellow: 0xffffe0, |
|
lime: 0x00ff00, |
|
limegreen: 0x32cd32, |
|
linen: 0xfaf0e6, |
|
magenta: 0xff00ff, |
|
maroon: 0x800000, |
|
mediumaquamarine: 0x66cdaa, |
|
mediumblue: 0x0000cd, |
|
mediumorchid: 0xba55d3, |
|
mediumpurple: 0x9370db, |
|
mediumseagreen: 0x3cb371, |
|
mediumslateblue: 0x7b68ee, |
|
mediumspringgreen: 0x00fa9a, |
|
mediumturquoise: 0x48d1cc, |
|
mediumvioletred: 0xc71585, |
|
midnightblue: 0x191970, |
|
mintcream: 0xf5fffa, |
|
mistyrose: 0xffe4e1, |
|
moccasin: 0xffe4b5, |
|
navajowhite: 0xffdead, |
|
navy: 0x000080, |
|
oldlace: 0xfdf5e6, |
|
olive: 0x808000, |
|
olivedrab: 0x6b8e23, |
|
orange: 0xffa500, |
|
orangered: 0xff4500, |
|
orchid: 0xda70d6, |
|
palegoldenrod: 0xeee8aa, |
|
palegreen: 0x98fb98, |
|
paleturquoise: 0xafeeee, |
|
palevioletred: 0xdb7093, |
|
papayawhip: 0xffefd5, |
|
peachpuff: 0xffdab9, |
|
peru: 0xcd853f, |
|
pink: 0xffc0cb, |
|
plum: 0xdda0dd, |
|
powderblue: 0xb0e0e6, |
|
purple: 0x800080, |
|
rebeccapurple: 0x663399, |
|
red: 0xff0000, |
|
rosybrown: 0xbc8f8f, |
|
royalblue: 0x4169e1, |
|
saddlebrown: 0x8b4513, |
|
salmon: 0xfa8072, |
|
sandybrown: 0xf4a460, |
|
seagreen: 0x2e8b57, |
|
seashell: 0xfff5ee, |
|
sienna: 0xa0522d, |
|
silver: 0xc0c0c0, |
|
skyblue: 0x87ceeb, |
|
slateblue: 0x6a5acd, |
|
slategray: 0x708090, |
|
slategrey: 0x708090, |
|
snow: 0xfffafa, |
|
springgreen: 0x00ff7f, |
|
steelblue: 0x4682b4, |
|
tan: 0xd2b48c, |
|
teal: 0x008080, |
|
thistle: 0xd8bfd8, |
|
tomato: 0xff6347, |
|
turquoise: 0x40e0d0, |
|
violet: 0xee82ee, |
|
wheat: 0xf5deb3, |
|
white: 0xffffff, |
|
whitesmoke: 0xf5f5f5, |
|
yellow: 0xffff00, |
|
yellowgreen: 0x9acd32 |
|
}; |
|
|
|
define(Color, color, { |
|
displayable: function() { |
|
return this.rgb().displayable(); |
|
}, |
|
toString: function() { |
|
return this.rgb() + ""; |
|
} |
|
}); |
|
|
|
function color(format) { |
|
var m; |
|
format = (format + "").trim().toLowerCase(); |
|
return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 |
|
: (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 |
|
: (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) |
|
: (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) |
|
: (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) |
|
: (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) |
|
: (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) |
|
: (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) |
|
: named.hasOwnProperty(format) ? rgbn(named[format]) |
|
: format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) |
|
: null; |
|
} |
|
|
|
function rgbn(n) { |
|
return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); |
|
} |
|
|
|
function rgba(r, g, b, a) { |
|
if (a <= 0) r = g = b = NaN; |
|
return new Rgb(r, g, b, a); |
|
} |
|
|
|
function rgbConvert(o) { |
|
if (!(o instanceof Color)) o = color(o); |
|
if (!o) return new Rgb; |
|
o = o.rgb(); |
|
return new Rgb(o.r, o.g, o.b, o.opacity); |
|
} |
|
|
|
function rgb(r, g, b, opacity) { |
|
return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); |
|
} |
|
|
|
function Rgb(r, g, b, opacity) { |
|
this.r = +r; |
|
this.g = +g; |
|
this.b = +b; |
|
this.opacity = +opacity; |
|
} |
|
|
|
define(Rgb, rgb, extend(Color, { |
|
brighter: function(k) { |
|
k = k == null ? brighter : Math.pow(brighter, k); |
|
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); |
|
}, |
|
darker: function(k) { |
|
k = k == null ? darker : Math.pow(darker, k); |
|
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); |
|
}, |
|
rgb: function() { |
|
return this; |
|
}, |
|
displayable: function() { |
|
return (0 <= this.r && this.r <= 255) |
|
&& (0 <= this.g && this.g <= 255) |
|
&& (0 <= this.b && this.b <= 255) |
|
&& (0 <= this.opacity && this.opacity <= 1); |
|
}, |
|
toString: function() { |
|
var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); |
|
return (a === 1 ? "rgb(" : "rgba(") |
|
+ Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " |
|
+ Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " |
|
+ Math.max(0, Math.min(255, Math.round(this.b) || 0)) |
|
+ (a === 1 ? ")" : ", " + a + ")"); |
|
} |
|
})); |
|
|
|
function hsla(h, s, l, a) { |
|
if (a <= 0) h = s = l = NaN; |
|
else if (l <= 0 || l >= 1) h = s = NaN; |
|
else if (s <= 0) h = NaN; |
|
return new Hsl(h, s, l, a); |
|
} |
|
|
|
function hslConvert(o) { |
|
if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); |
|
if (!(o instanceof Color)) o = color(o); |
|
if (!o) return new Hsl; |
|
if (o instanceof Hsl) return o; |
|
o = o.rgb(); |
|
var r = o.r / 255, |
|
g = o.g / 255, |
|
b = o.b / 255, |
|
min = Math.min(r, g, b), |
|
max = Math.max(r, g, b), |
|
h = NaN, |
|
s = max - min, |
|
l = (max + min) / 2; |
|
if (s) { |
|
if (r === max) h = (g - b) / s + (g < b) * 6; |
|
else if (g === max) h = (b - r) / s + 2; |
|
else h = (r - g) / s + 4; |
|
s /= l < 0.5 ? max + min : 2 - max - min; |
|
h *= 60; |
|
} else { |
|
s = l > 0 && l < 1 ? 0 : h; |
|
} |
|
return new Hsl(h, s, l, o.opacity); |
|
} |
|
|
|
function hsl(h, s, l, opacity) { |
|
return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); |
|
} |
|
|
|
function Hsl(h, s, l, opacity) { |
|
this.h = +h; |
|
this.s = +s; |
|
this.l = +l; |
|
this.opacity = +opacity; |
|
} |
|
|
|
define(Hsl, hsl, extend(Color, { |
|
brighter: function(k) { |
|
k = k == null ? brighter : Math.pow(brighter, k); |
|
return new Hsl(this.h, this.s, this.l * k, this.opacity); |
|
}, |
|
darker: function(k) { |
|
k = k == null ? darker : Math.pow(darker, k); |
|
return new Hsl(this.h, this.s, this.l * k, this.opacity); |
|
}, |
|
rgb: function() { |
|
var h = this.h % 360 + (this.h < 0) * 360, |
|
s = isNaN(h) || isNaN(this.s) ? 0 : this.s, |
|
l = this.l, |
|
m2 = l + (l < 0.5 ? l : 1 - l) * s, |
|
m1 = 2 * l - m2; |
|
return new Rgb( |
|
hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), |
|
hsl2rgb(h, m1, m2), |
|
hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), |
|
this.opacity |
|
); |
|
}, |
|
displayable: function() { |
|
return (0 <= this.s && this.s <= 1 || isNaN(this.s)) |
|
&& (0 <= this.l && this.l <= 1) |
|
&& (0 <= this.opacity && this.opacity <= 1); |
|
} |
|
})); |
|
|
|
/* From FvD 13.37, CSS Color Module Level 3 */ |
|
function hsl2rgb(h, m1, m2) { |
|
return (h < 60 ? m1 + (m2 - m1) * h / 60 |
|
: h < 180 ? m2 |
|
: h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 |
|
: m1) * 255; |
|
} |
|
|
|
var deg2rad = Math.PI / 180; |
|
var rad2deg = 180 / Math.PI; |
|
|
|
var Kn = 18; |
|
var Xn = 0.950470; |
|
var Yn = 1; |
|
var Zn = 1.088830; |
|
var t0 = 4 / 29; |
|
var t1 = 6 / 29; |
|
var t2 = 3 * t1 * t1; |
|
var t3 = t1 * t1 * t1; |
|
|
|
function labConvert(o) { |
|
if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); |
|
if (o instanceof Hcl) { |
|
var h = o.h * deg2rad; |
|
return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); |
|
} |
|
if (!(o instanceof Rgb)) o = rgbConvert(o); |
|
var b = rgb2xyz(o.r), |
|
a = rgb2xyz(o.g), |
|
l = rgb2xyz(o.b), |
|
x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), |
|
y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), |
|
z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); |
|
return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); |
|
} |
|
|
|
function lab(l, a, b, opacity) { |
|
return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); |
|
} |
|
|
|
function Lab(l, a, b, opacity) { |
|
this.l = +l; |
|
this.a = +a; |
|
this.b = +b; |
|
this.opacity = +opacity; |
|
} |
|
|
|
define(Lab, lab, extend(Color, { |
|
brighter: function(k) { |
|
return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); |
|
}, |
|
darker: function(k) { |
|
return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); |
|
}, |
|
rgb: function() { |
|
var y = (this.l + 16) / 116, |
|
x = isNaN(this.a) ? y : y + this.a / 500, |
|
z = isNaN(this.b) ? y : y - this.b / 200; |
|
y = Yn * lab2xyz(y); |
|
x = Xn * lab2xyz(x); |
|
z = Zn * lab2xyz(z); |
|
return new Rgb( |
|
xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB |
|
xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), |
|
xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), |
|
this.opacity |
|
); |
|
} |
|
})); |
|
|
|
function xyz2lab(t) { |
|
return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0; |
|
} |
|
|
|
function lab2xyz(t) { |
|
return t > t1 ? t * t * t : t2 * (t - t0); |
|
} |
|
|
|
function xyz2rgb(x) { |
|
return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); |
|
} |
|
|
|
function rgb2xyz(x) { |
|
return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); |
|
} |
|
|
|
function hclConvert(o) { |
|
if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); |
|
if (!(o instanceof Lab)) o = labConvert(o); |
|
var h = Math.atan2(o.b, o.a) * rad2deg; |
|
return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); |
|
} |
|
|
|
function hcl(h, c, l, opacity) { |
|
return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); |
|
} |
|
|
|
function Hcl(h, c, l, opacity) { |
|
this.h = +h; |
|
this.c = +c; |
|
this.l = +l; |
|
this.opacity = +opacity; |
|
} |
|
|
|
define(Hcl, hcl, extend(Color, { |
|
brighter: function(k) { |
|
return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); |
|
}, |
|
darker: function(k) { |
|
return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); |
|
}, |
|
rgb: function() { |
|
return labConvert(this).rgb(); |
|
} |
|
})); |
|
|
|
var A = -0.14861; |
|
var B = +1.78277; |
|
var C = -0.29227; |
|
var D = -0.90649; |
|
var E = +1.97294; |
|
var ED = E * D; |
|
var EB = E * B; |
|
var BC_DA = B * C - D * A; |
|
|
|
function cubehelixConvert(o) { |
|
if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); |
|
if (!(o instanceof Rgb)) o = rgbConvert(o); |
|
var r = o.r / 255, |
|
g = o.g / 255, |
|
b = o.b / 255, |
|
l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), |
|
bl = b - l, |
|
k = (E * (g - l) - C * bl) / D, |
|
s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 |
|
h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; |
|
return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); |
|
} |
|
|
|
function cubehelix(h, s, l, opacity) { |
|
return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); |
|
} |
|
|
|
function Cubehelix(h, s, l, opacity) { |
|
this.h = +h; |
|
this.s = +s; |
|
this.l = +l; |
|
this.opacity = +opacity; |
|
} |
|
|
|
define(Cubehelix, cubehelix, extend(Color, { |
|
brighter: function(k) { |
|
k = k == null ? brighter : Math.pow(brighter, k); |
|
return new Cubehelix(this.h, this.s, this.l * k, this.opacity); |
|
}, |
|
darker: function(k) { |
|
k = k == null ? darker : Math.pow(darker, k); |
|
return new Cubehelix(this.h, this.s, this.l * k, this.opacity); |
|
}, |
|
rgb: function() { |
|
var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, |
|
l = +this.l, |
|
a = isNaN(this.s) ? 0 : this.s * l * (1 - l), |
|
cosh = Math.cos(h), |
|
sinh = Math.sin(h); |
|
return new Rgb( |
|
255 * (l + a * (A * cosh + B * sinh)), |
|
255 * (l + a * (C * cosh + D * sinh)), |
|
255 * (l + a * (E * cosh)), |
|
this.opacity |
|
); |
|
} |
|
})); |
|
|
|
exports.color = color; |
|
exports.rgb = rgb; |
|
exports.hsl = hsl; |
|
exports.lab = lab; |
|
exports.hcl = hcl; |
|
exports.cubehelix = cubehelix; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
}))); |
|
|
|
},{}],4:[function(require,module,exports){ |
|
// https://d3js.org/d3-interpolate/ Version 1.1.5. Copyright 2017 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) : |
|
typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) : |
|
(factory((global.d3 = global.d3 || {}),global.d3)); |
|
}(this, (function (exports,d3Color) { 'use strict'; |
|
|
|
function basis(t1, v0, v1, v2, v3) { |
|
var t2 = t1 * t1, t3 = t2 * t1; |
|
return ((1 - 3 * t1 + 3 * t2 - t3) * v0 |
|
+ (4 - 6 * t2 + 3 * t3) * v1 |
|
+ (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 |
|
+ t3 * v3) / 6; |
|
} |
|
|
|
var basis$1 = function(values) { |
|
var n = values.length - 1; |
|
return function(t) { |
|
var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), |
|
v1 = values[i], |
|
v2 = values[i + 1], |
|
v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, |
|
v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; |
|
return basis((t - i / n) * n, v0, v1, v2, v3); |
|
}; |
|
}; |
|
|
|
var basisClosed = function(values) { |
|
var n = values.length; |
|
return function(t) { |
|
var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), |
|
v0 = values[(i + n - 1) % n], |
|
v1 = values[i % n], |
|
v2 = values[(i + 1) % n], |
|
v3 = values[(i + 2) % n]; |
|
return basis((t - i / n) * n, v0, v1, v2, v3); |
|
}; |
|
}; |
|
|
|
var constant = function(x) { |
|
return function() { |
|
return x; |
|
}; |
|
}; |
|
|
|
function linear(a, d) { |
|
return function(t) { |
|
return a + t * d; |
|
}; |
|
} |
|
|
|
function exponential(a, b, y) { |
|
return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { |
|
return Math.pow(a + t * b, y); |
|
}; |
|
} |
|
|
|
function hue(a, b) { |
|
var d = b - a; |
|
return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a); |
|
} |
|
|
|
function gamma(y) { |
|
return (y = +y) === 1 ? nogamma : function(a, b) { |
|
return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a); |
|
}; |
|
} |
|
|
|
function nogamma(a, b) { |
|
var d = b - a; |
|
return d ? linear(a, d) : constant(isNaN(a) ? b : a); |
|
} |
|
|
|
var rgb$1 = ((function rgbGamma(y) { |
|
var color$$1 = gamma(y); |
|
|
|
function rgb$$1(start, end) { |
|
var r = color$$1((start = d3Color.rgb(start)).r, (end = d3Color.rgb(end)).r), |
|
g = color$$1(start.g, end.g), |
|
b = color$$1(start.b, end.b), |
|
opacity = nogamma(start.opacity, end.opacity); |
|
return function(t) { |
|
start.r = r(t); |
|
start.g = g(t); |
|
start.b = b(t); |
|
start.opacity = opacity(t); |
|
return start + ""; |
|
}; |
|
} |
|
|
|
rgb$$1.gamma = rgbGamma; |
|
|
|
return rgb$$1; |
|
}))(1); |
|
|
|
function rgbSpline(spline) { |
|
return function(colors) { |
|
var n = colors.length, |
|
r = new Array(n), |
|
g = new Array(n), |
|
b = new Array(n), |
|
i, color$$1; |
|
for (i = 0; i < n; ++i) { |
|
color$$1 = d3Color.rgb(colors[i]); |
|
r[i] = color$$1.r || 0; |
|
g[i] = color$$1.g || 0; |
|
b[i] = color$$1.b || 0; |
|
} |
|
r = spline(r); |
|
g = spline(g); |
|
b = spline(b); |
|
color$$1.opacity = 1; |
|
return function(t) { |
|
color$$1.r = r(t); |
|
color$$1.g = g(t); |
|
color$$1.b = b(t); |
|
return color$$1 + ""; |
|
}; |
|
}; |
|
} |
|
|
|
var rgbBasis = rgbSpline(basis$1); |
|
var rgbBasisClosed = rgbSpline(basisClosed); |
|
|
|
var array = function(a, b) { |
|
var nb = b ? b.length : 0, |
|
na = a ? Math.min(nb, a.length) : 0, |
|
x = new Array(nb), |
|
c = new Array(nb), |
|
i; |
|
|
|
for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]); |
|
for (; i < nb; ++i) c[i] = b[i]; |
|
|
|
return function(t) { |
|
for (i = 0; i < na; ++i) c[i] = x[i](t); |
|
return c; |
|
}; |
|
}; |
|
|
|
var date = function(a, b) { |
|
var d = new Date; |
|
return a = +a, b -= a, function(t) { |
|
return d.setTime(a + b * t), d; |
|
}; |
|
}; |
|
|
|
var number = function(a, b) { |
|
return a = +a, b -= a, function(t) { |
|
return a + b * t; |
|
}; |
|
}; |
|
|
|
var object = function(a, b) { |
|
var i = {}, |
|
c = {}, |
|
k; |
|
|
|
if (a === null || typeof a !== "object") a = {}; |
|
if (b === null || typeof b !== "object") b = {}; |
|
|
|
for (k in b) { |
|
if (k in a) { |
|
i[k] = value(a[k], b[k]); |
|
} else { |
|
c[k] = b[k]; |
|
} |
|
} |
|
|
|
return function(t) { |
|
for (k in i) c[k] = i[k](t); |
|
return c; |
|
}; |
|
}; |
|
|
|
var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; |
|
var reB = new RegExp(reA.source, "g"); |
|
|
|
function zero(b) { |
|
return function() { |
|
return b; |
|
}; |
|
} |
|
|
|
function one(b) { |
|
return function(t) { |
|
return b(t) + ""; |
|
}; |
|
} |
|
|
|
var string = function(a, b) { |
|
var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b |
|
am, // current match in a |
|
bm, // current match in b |
|
bs, // string preceding current number in b, if any |
|
i = -1, // index in s |
|
s = [], // string constants and placeholders |
|
q = []; // number interpolators |
|
|
|
// Coerce inputs to strings. |
|
a = a + "", b = b + ""; |
|
|
|
// Interpolate pairs of numbers in a & b. |
|
while ((am = reA.exec(a)) |
|
&& (bm = reB.exec(b))) { |
|
if ((bs = bm.index) > bi) { // a string precedes the next number in b |
|
bs = b.slice(bi, bs); |
|
if (s[i]) s[i] += bs; // coalesce with previous string |
|
else s[++i] = bs; |
|
} |
|
if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match |
|
if (s[i]) s[i] += bm; // coalesce with previous string |
|
else s[++i] = bm; |
|
} else { // interpolate non-matching numbers |
|
s[++i] = null; |
|
q.push({i: i, x: number(am, bm)}); |
|
} |
|
bi = reB.lastIndex; |
|
} |
|
|
|
// Add remains of b. |
|
if (bi < b.length) { |
|
bs = b.slice(bi); |
|
if (s[i]) s[i] += bs; // coalesce with previous string |
|
else s[++i] = bs; |
|
} |
|
|
|
// Special optimization for only a single match. |
|
// Otherwise, interpolate each of the numbers and rejoin the string. |
|
return s.length < 2 ? (q[0] |
|
? one(q[0].x) |
|
: zero(b)) |
|
: (b = q.length, function(t) { |
|
for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); |
|
return s.join(""); |
|
}); |
|
}; |
|
|
|
var value = function(a, b) { |
|
var t = typeof b, c; |
|
return b == null || t === "boolean" ? constant(b) |
|
: (t === "number" ? number |
|
: t === "string" ? ((c = d3Color.color(b)) ? (b = c, rgb$1) : string) |
|
: b instanceof d3Color.color ? rgb$1 |
|
: b instanceof Date ? date |
|
: Array.isArray(b) ? array |
|
: typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object |
|
: number)(a, b); |
|
}; |
|
|
|
var round = function(a, b) { |
|
return a = +a, b -= a, function(t) { |
|
return Math.round(a + b * t); |
|
}; |
|
}; |
|
|
|
var degrees = 180 / Math.PI; |
|
|
|
var identity = { |
|
translateX: 0, |
|
translateY: 0, |
|
rotate: 0, |
|
skewX: 0, |
|
scaleX: 1, |
|
scaleY: 1 |
|
}; |
|
|
|
var decompose = function(a, b, c, d, e, f) { |
|
var scaleX, scaleY, skewX; |
|
if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; |
|
if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; |
|
if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; |
|
if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; |
|
return { |
|
translateX: e, |
|
translateY: f, |
|
rotate: Math.atan2(b, a) * degrees, |
|
skewX: Math.atan(skewX) * degrees, |
|
scaleX: scaleX, |
|
scaleY: scaleY |
|
}; |
|
}; |
|
|
|
var cssNode; |
|
var cssRoot; |
|
var cssView; |
|
var svgNode; |
|
|
|
function parseCss(value) { |
|
if (value === "none") return identity; |
|
if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; |
|
cssNode.style.transform = value; |
|
value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); |
|
cssRoot.removeChild(cssNode); |
|
value = value.slice(7, -1).split(","); |
|
return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); |
|
} |
|
|
|
function parseSvg(value) { |
|
if (value == null) return identity; |
|
if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); |
|
svgNode.setAttribute("transform", value); |
|
if (!(value = svgNode.transform.baseVal.consolidate())) return identity; |
|
value = value.matrix; |
|
return decompose(value.a, value.b, value.c, value.d, value.e, value.f); |
|
} |
|
|
|
function interpolateTransform(parse, pxComma, pxParen, degParen) { |
|
|
|
function pop(s) { |
|
return s.length ? s.pop() + " " : ""; |
|
} |
|
|
|
function translate(xa, ya, xb, yb, s, q) { |
|
if (xa !== xb || ya !== yb) { |
|
var i = s.push("translate(", null, pxComma, null, pxParen); |
|
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); |
|
} else if (xb || yb) { |
|
s.push("translate(" + xb + pxComma + yb + pxParen); |
|
} |
|
} |
|
|
|
function rotate(a, b, s, q) { |
|
if (a !== b) { |
|
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path |
|
q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)}); |
|
} else if (b) { |
|
s.push(pop(s) + "rotate(" + b + degParen); |
|
} |
|
} |
|
|
|
function skewX(a, b, s, q) { |
|
if (a !== b) { |
|
q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)}); |
|
} else if (b) { |
|
s.push(pop(s) + "skewX(" + b + degParen); |
|
} |
|
} |
|
|
|
function scale(xa, ya, xb, yb, s, q) { |
|
if (xa !== xb || ya !== yb) { |
|
var i = s.push(pop(s) + "scale(", null, ",", null, ")"); |
|
q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)}); |
|
} else if (xb !== 1 || yb !== 1) { |
|
s.push(pop(s) + "scale(" + xb + "," + yb + ")"); |
|
} |
|
} |
|
|
|
return function(a, b) { |
|
var s = [], // string constants and placeholders |
|
q = []; // number interpolators |
|
a = parse(a), b = parse(b); |
|
translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); |
|
rotate(a.rotate, b.rotate, s, q); |
|
skewX(a.skewX, b.skewX, s, q); |
|
scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); |
|
a = b = null; // gc |
|
return function(t) { |
|
var i = -1, n = q.length, o; |
|
while (++i < n) s[(o = q[i]).i] = o.x(t); |
|
return s.join(""); |
|
}; |
|
}; |
|
} |
|
|
|
var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); |
|
var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); |
|
|
|
var rho = Math.SQRT2; |
|
var rho2 = 2; |
|
var rho4 = 4; |
|
var epsilon2 = 1e-12; |
|
|
|
function cosh(x) { |
|
return ((x = Math.exp(x)) + 1 / x) / 2; |
|
} |
|
|
|
function sinh(x) { |
|
return ((x = Math.exp(x)) - 1 / x) / 2; |
|
} |
|
|
|
function tanh(x) { |
|
return ((x = Math.exp(2 * x)) - 1) / (x + 1); |
|
} |
|
|
|
// p0 = [ux0, uy0, w0] |
|
// p1 = [ux1, uy1, w1] |
|
var zoom = function(p0, p1) { |
|
var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], |
|
ux1 = p1[0], uy1 = p1[1], w1 = p1[2], |
|
dx = ux1 - ux0, |
|
dy = uy1 - uy0, |
|
d2 = dx * dx + dy * dy, |
|
i, |
|
S; |
|
|
|
// Special case for u0 ≅ u1. |
|
if (d2 < epsilon2) { |
|
S = Math.log(w1 / w0) / rho; |
|
i = function(t) { |
|
return [ |
|
ux0 + t * dx, |
|
uy0 + t * dy, |
|
w0 * Math.exp(rho * t * S) |
|
]; |
|
}; |
|
} |
|
|
|
// General case. |
|
else { |
|
var d1 = Math.sqrt(d2), |
|
b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), |
|
b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), |
|
r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), |
|
r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); |
|
S = (r1 - r0) / rho; |
|
i = function(t) { |
|
var s = t * S, |
|
coshr0 = cosh(r0), |
|
u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); |
|
return [ |
|
ux0 + u * dx, |
|
uy0 + u * dy, |
|
w0 * coshr0 / cosh(rho * s + r0) |
|
]; |
|
}; |
|
} |
|
|
|
i.duration = S * 1000; |
|
|
|
return i; |
|
}; |
|
|
|
function hsl$1(hue$$1) { |
|
return function(start, end) { |
|
var h = hue$$1((start = d3Color.hsl(start)).h, (end = d3Color.hsl(end)).h), |
|
s = nogamma(start.s, end.s), |
|
l = nogamma(start.l, end.l), |
|
opacity = nogamma(start.opacity, end.opacity); |
|
return function(t) { |
|
start.h = h(t); |
|
start.s = s(t); |
|
start.l = l(t); |
|
start.opacity = opacity(t); |
|
return start + ""; |
|
}; |
|
} |
|
} |
|
|
|
var hsl$2 = hsl$1(hue); |
|
var hslLong = hsl$1(nogamma); |
|
|
|
function lab$1(start, end) { |
|
var l = nogamma((start = d3Color.lab(start)).l, (end = d3Color.lab(end)).l), |
|
a = nogamma(start.a, end.a), |
|
b = nogamma(start.b, end.b), |
|
opacity = nogamma(start.opacity, end.opacity); |
|
return function(t) { |
|
start.l = l(t); |
|
start.a = a(t); |
|
start.b = b(t); |
|
start.opacity = opacity(t); |
|
return start + ""; |
|
}; |
|
} |
|
|
|
function hcl$1(hue$$1) { |
|
return function(start, end) { |
|
var h = hue$$1((start = d3Color.hcl(start)).h, (end = d3Color.hcl(end)).h), |
|
c = nogamma(start.c, end.c), |
|
l = nogamma(start.l, end.l), |
|
opacity = nogamma(start.opacity, end.opacity); |
|
return function(t) { |
|
start.h = h(t); |
|
start.c = c(t); |
|
start.l = l(t); |
|
start.opacity = opacity(t); |
|
return start + ""; |
|
}; |
|
} |
|
} |
|
|
|
var hcl$2 = hcl$1(hue); |
|
var hclLong = hcl$1(nogamma); |
|
|
|
function cubehelix$1(hue$$1) { |
|
return (function cubehelixGamma(y) { |
|
y = +y; |
|
|
|
function cubehelix$$1(start, end) { |
|
var h = hue$$1((start = d3Color.cubehelix(start)).h, (end = d3Color.cubehelix(end)).h), |
|
s = nogamma(start.s, end.s), |
|
l = nogamma(start.l, end.l), |
|
opacity = nogamma(start.opacity, end.opacity); |
|
return function(t) { |
|
start.h = h(t); |
|
start.s = s(t); |
|
start.l = l(Math.pow(t, y)); |
|
start.opacity = opacity(t); |
|
return start + ""; |
|
}; |
|
} |
|
|
|
cubehelix$$1.gamma = cubehelixGamma; |
|
|
|
return cubehelix$$1; |
|
})(1); |
|
} |
|
|
|
var cubehelix$2 = cubehelix$1(hue); |
|
var cubehelixLong = cubehelix$1(nogamma); |
|
|
|
var quantize = function(interpolator, n) { |
|
var samples = new Array(n); |
|
for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); |
|
return samples; |
|
}; |
|
|
|
exports.interpolate = value; |
|
exports.interpolateArray = array; |
|
exports.interpolateBasis = basis$1; |
|
exports.interpolateBasisClosed = basisClosed; |
|
exports.interpolateDate = date; |
|
exports.interpolateNumber = number; |
|
exports.interpolateObject = object; |
|
exports.interpolateRound = round; |
|
exports.interpolateString = string; |
|
exports.interpolateTransformCss = interpolateTransformCss; |
|
exports.interpolateTransformSvg = interpolateTransformSvg; |
|
exports.interpolateZoom = zoom; |
|
exports.interpolateRgb = rgb$1; |
|
exports.interpolateRgbBasis = rgbBasis; |
|
exports.interpolateRgbBasisClosed = rgbBasisClosed; |
|
exports.interpolateHsl = hsl$2; |
|
exports.interpolateHslLong = hslLong; |
|
exports.interpolateLab = lab$1; |
|
exports.interpolateHcl = hcl$2; |
|
exports.interpolateHclLong = hclLong; |
|
exports.interpolateCubehelix = cubehelix$2; |
|
exports.interpolateCubehelixLong = cubehelixLong; |
|
exports.quantize = quantize; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
}))); |
|
|
|
},{"d3-color":3}],5:[function(require,module,exports){ |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-dispatch'), require('d3-scale'), require('d3-format'), require('d3-array')) : |
|
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-dispatch', 'd3-scale', 'd3-format', 'd3-array'], factory) : |
|
(factory((global.indexRollup = global.indexRollup || {}),global.d3Selection,global.d3Dispatch,global.d3Scale,global.d3Format,global.d3Array)); |
|
}(this, (function (exports,d3Selection,d3Dispatch,d3Scale,d3Format,d3Array) { 'use strict'; |
|
|
|
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { |
|
return typeof obj; |
|
} : function (obj) { |
|
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; |
|
}; |
|
|
|
var d3_identity = function d3_identity(d) { |
|
return d; |
|
}; |
|
|
|
var d3_reverse = function d3_reverse(arr) { |
|
var mirror = []; |
|
for (var i = 0, l = arr.length; i < l; i++) { |
|
mirror[i] = arr[l - i - 1]; |
|
} |
|
return mirror; |
|
}; |
|
|
|
//Text wrapping code adapted from Mike Bostock |
|
var d3_textWrapping = function d3_textWrapping(text, width) { |
|
text.each(function () { |
|
var text = d3Selection.select(this), |
|
words = text.text().split(/\s+/).reverse(), |
|
word, |
|
line = [], |
|
lineNumber = 0, |
|
lineHeight = 1.2, |
|
//ems |
|
y = text.attr("y"), |
|
dy = parseFloat(text.attr("dy")) || 0, |
|
tspan = text.text(null).append("tspan").attr("x", 0).attr("dy", dy + "em"); |
|
|
|
while (word = words.pop()) { |
|
line.push(word); |
|
tspan.text(line.join(" ")); |
|
if (tspan.node().getComputedTextLength() > width && line.length > 1) { |
|
line.pop(); |
|
tspan.text(line.join(" ")); |
|
line = [word]; |
|
tspan = text.append("tspan").attr("x", 0).attr("dy", lineHeight + dy + "em").text(word); |
|
} |
|
} |
|
}); |
|
}; |
|
|
|
var d3_mergeLabels = function d3_mergeLabels() { |
|
var gen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; |
|
var labels = arguments[1]; |
|
var domain = arguments[2]; |
|
var range = arguments[3]; |
|
|
|
|
|
if ((typeof labels === "undefined" ? "undefined" : _typeof(labels)) === "object") { |
|
if (labels.length === 0) return gen; |
|
|
|
var i = labels.length; |
|
for (; i < gen.length; i++) { |
|
labels.push(gen[i]); |
|
} |
|
return labels; |
|
} else if (typeof labels === "function") { |
|
var customLabels = []; |
|
var genLength = gen.length; |
|
for (var _i = 0; _i < genLength; _i++) { |
|
customLabels.push(labels({ |
|
i: _i, |
|
genLength: genLength, |
|
generatedLabels: gen, |
|
domain: domain, |
|
range: range })); |
|
} |
|
return customLabels; |
|
} |
|
|
|
return gen; |
|
}; |
|
|
|
var d3_linearLegend = function d3_linearLegend(scale, cells, labelFormat) { |
|
var data = []; |
|
|
|
if (cells.length > 1) { |
|
data = cells; |
|
} else { |
|
var domain = scale.domain(), |
|
increment = (domain[domain.length - 1] - domain[0]) / (cells - 1); |
|
var i = 0; |
|
|
|
for (; i < cells; i++) { |
|
data.push(domain[0] + i * increment); |
|
} |
|
} |
|
|
|
var labels = data.map(labelFormat); |
|
return { data: data, |
|
labels: labels, |
|
feature: function feature(d) { |
|
return scale(d); |
|
} }; |
|
}; |
|
|
|
var d3_quantLegend = function d3_quantLegend(scale, labelFormat, labelDelimiter) { |
|
var labels = scale.range().map(function (d) { |
|
var invert = scale.invertExtent(d); |
|
return labelFormat(invert[0]) + " " + labelDelimiter + " " + labelFormat(invert[1]); |
|
}); |
|
|
|
return { data: scale.range(), |
|
labels: labels, |
|
feature: d3_identity |
|
}; |
|
}; |
|
|
|
var d3_ordinalLegend = function d3_ordinalLegend(scale) { |
|
return { data: scale.domain(), |
|
labels: scale.domain(), |
|
feature: function feature(d) { |
|
return scale(d); |
|
} }; |
|
}; |
|
|
|
var d3_cellOver = function d3_cellOver(cellDispatcher, d, obj) { |
|
cellDispatcher.call("cellover", obj, d); |
|
}; |
|
|
|
var d3_cellOut = function d3_cellOut(cellDispatcher, d, obj) { |
|
cellDispatcher.call("cellout", obj, d); |
|
}; |
|
|
|
var d3_cellClick = function d3_cellClick(cellDispatcher, d, obj) { |
|
cellDispatcher.call("cellclick", obj, d); |
|
}; |
|
|
|
var helper = { |
|
|
|
d3_drawShapes: function d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path) { |
|
if (shape === "rect") { |
|
shapes.attr("height", shapeHeight).attr("width", shapeWidth); |
|
} else if (shape === "circle") { |
|
shapes.attr("r", shapeRadius); |
|
} else if (shape === "line") { |
|
shapes.attr("x1", 0).attr("x2", shapeWidth).attr("y1", 0).attr("y2", 0); |
|
} else if (shape === "path") { |
|
shapes.attr("d", path); |
|
} |
|
}, |
|
|
|
d3_addText: function d3_addText(svg, enter, labels, classPrefix, labelWidth) { |
|
enter.append("text").attr("class", classPrefix + "label"); |
|
var text = svg.selectAll("g." + classPrefix + "cell text." + classPrefix + "label").data(labels).text(d3_identity); |
|
|
|
if (labelWidth) { |
|
svg.selectAll("g." + classPrefix + "cell text." + classPrefix + "label").call(d3_textWrapping, labelWidth); |
|
} |
|
|
|
return text; |
|
}, |
|
|
|
d3_calcType: function d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter) { |
|
var type = scale.invertExtent ? d3_quantLegend(scale, labelFormat, labelDelimiter) : scale.ticks ? d3_linearLegend(scale, cells, labelFormat) : d3_ordinalLegend(scale); |
|
|
|
//for d3.scaleSequential that doesn't have a range function |
|
var range = scale.range && scale.range() || scale.domain(); |
|
type.labels = d3_mergeLabels(type.labels, labels, scale.domain(), range); |
|
|
|
if (ascending) { |
|
type.labels = d3_reverse(type.labels); |
|
type.data = d3_reverse(type.data); |
|
} |
|
|
|
return type; |
|
}, |
|
|
|
d3_filterCells: function d3_filterCells(type, cellFilter) { |
|
var filterCells = type.data.map(function (d, i) { |
|
return { data: d, label: type.labels[i] }; |
|
}).filter(cellFilter); |
|
var dataValues = filterCells.map(function (d) { |
|
return d.data; |
|
}); |
|
var labelValues = filterCells.map(function (d) { |
|
return d.label; |
|
}); |
|
type.data = type.data.filter(function (d) { |
|
return dataValues.indexOf(d) !== -1; |
|
}); |
|
type.labels = type.labels.filter(function (d) { |
|
return labelValues.indexOf(d) !== -1; |
|
}); |
|
return type; |
|
}, |
|
|
|
d3_placement: function d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign) { |
|
cell.attr("transform", cellTrans); |
|
text.attr("transform", textTrans); |
|
if (orient === "horizontal") { |
|
text.style("text-anchor", labelAlign); |
|
} |
|
}, |
|
|
|
d3_addEvents: function d3_addEvents(cells, dispatcher) { |
|
cells.on("mouseover.legend", function (d) { |
|
d3_cellOver(dispatcher, d, this); |
|
}).on("mouseout.legend", function (d) { |
|
d3_cellOut(dispatcher, d, this); |
|
}).on("click.legend", function (d) { |
|
d3_cellClick(dispatcher, d, this); |
|
}); |
|
}, |
|
|
|
d3_title: function d3_title(svg, title, classPrefix, titleWidth) { |
|
if (title !== "") { |
|
|
|
var titleText = svg.selectAll('text.' + classPrefix + 'legendTitle'); |
|
|
|
titleText.data([title]).enter().append('text').attr('class', classPrefix + 'legendTitle'); |
|
|
|
svg.selectAll('text.' + classPrefix + 'legendTitle').text(title); |
|
|
|
if (titleWidth) { |
|
svg.selectAll('text.' + classPrefix + 'legendTitle').call(d3_textWrapping, titleWidth); |
|
} |
|
|
|
var cellsSvg = svg.select('.' + classPrefix + 'legendCells'); |
|
var yOffset = svg.select('.' + classPrefix + 'legendTitle').nodes().map(function (d) { |
|
return d.getBBox().height; |
|
})[0], |
|
xOffset = -cellsSvg.nodes().map(function (d) { |
|
return d.getBBox().x; |
|
})[0]; |
|
cellsSvg.attr('transform', 'translate(' + xOffset + ',' + yOffset + ')'); |
|
} |
|
} |
|
}; |
|
|
|
function color() { |
|
|
|
var scale = d3Scale.scaleLinear(), |
|
shape = "rect", |
|
shapeWidth = 15, |
|
shapeHeight = 15, |
|
shapeRadius = 10, |
|
shapePadding = 2, |
|
cells = [5], |
|
cellFilter = void 0, |
|
labels = [], |
|
classPrefix = "", |
|
useClass = false, |
|
title = "", |
|
labelFormat = d3Format.format(".01f"), |
|
labelOffset = 10, |
|
labelAlign = "middle", |
|
labelDelimiter = "to", |
|
labelWrap = void 0, |
|
orient = "vertical", |
|
ascending = false, |
|
path = void 0, |
|
titleWidth = void 0, |
|
legendDispatcher = d3Dispatch.dispatch("cellover", "cellout", "cellclick"); |
|
|
|
function legend(svg) { |
|
|
|
var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter), |
|
legendG = svg.selectAll('g').data([scale]); |
|
|
|
legendG.enter().append('g').attr('class', classPrefix + 'legendCells'); |
|
|
|
if (cellFilter) { |
|
helper.d3_filterCells(type, cellFilter); |
|
} |
|
|
|
var cell = svg.select('.' + classPrefix + 'legendCells').selectAll("." + classPrefix + "cell").data(type.data); |
|
|
|
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell"); |
|
cellEnter.append(shape).attr("class", classPrefix + "swatch"); |
|
|
|
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape); |
|
|
|
//add event handlers |
|
helper.d3_addEvents(cellEnter, legendDispatcher); |
|
|
|
cell.exit().transition().style("opacity", 0).remove(); |
|
|
|
helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, path); |
|
helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap); |
|
|
|
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones. |
|
cell = cellEnter.merge(cell); |
|
|
|
// sets placement |
|
var text = cell.selectAll("text"), |
|
textSize = text.nodes().map(function (d) { |
|
return d.getBBox(); |
|
}), |
|
shapeSize = shapes.nodes().map(function (d) { |
|
return d.getBBox(); |
|
}); |
|
//sets scale |
|
//everything is fill except for line which is stroke, |
|
if (!useClass) { |
|
if (shape == "line") { |
|
shapes.style("stroke", type.feature); |
|
} else { |
|
shapes.style("fill", type.feature); |
|
} |
|
} else { |
|
shapes.attr("class", function (d) { |
|
return classPrefix + 'swatch ' + type.feature(d); |
|
}); |
|
} |
|
|
|
var cellTrans = void 0, |
|
textTrans = void 0, |
|
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1; |
|
|
|
//positions cells and text |
|
if (orient === "vertical") { |
|
(function () { |
|
var cellSize = textSize.map(function (d, i) { |
|
return Math.max(d.height, shapeSize[i].height); |
|
}); |
|
|
|
cellTrans = function cellTrans(d, i) { |
|
var height = d3Array.sum(cellSize.slice(0, i)); |
|
return 'translate(0, ' + (height + i * shapePadding) + ')'; |
|
}; |
|
|
|
textTrans = function textTrans(d, i) { |
|
return 'translate( ' + (shapeSize[i].width + shapeSize[i].x + labelOffset) + ', ' + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ')'; |
|
}; |
|
})(); |
|
} else if (orient === "horizontal") { |
|
cellTrans = function cellTrans(d, i) { |
|
return 'translate(' + i * (shapeSize[i].width + shapePadding) + ',0)'; |
|
}; |
|
textTrans = function textTrans(d, i) { |
|
return 'translate(' + (shapeSize[i].width * textAlign + shapeSize[i].x) + ',\n ' + (shapeSize[i].height + shapeSize[i].y + labelOffset + 8) + ')'; |
|
}; |
|
} |
|
|
|
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); |
|
helper.d3_title(svg, title, classPrefix, titleWidth); |
|
|
|
cell.transition().style("opacity", 1); |
|
} |
|
|
|
legend.scale = function (_) { |
|
if (!arguments.length) return scale; |
|
scale = _; |
|
return legend; |
|
}; |
|
|
|
legend.cells = function (_) { |
|
if (!arguments.length) return cells; |
|
if (_.length > 1 || _ >= 2) { |
|
cells = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.cellFilter = function (_) { |
|
if (!arguments.length) return cellFilter; |
|
cellFilter = _; |
|
return legend; |
|
}; |
|
|
|
legend.shape = function (_, d) { |
|
if (!arguments.length) return shape; |
|
if (_ == "rect" || _ == "circle" || _ == "line" || _ == "path" && typeof d === 'string') { |
|
shape = _; |
|
path = d; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.shapeWidth = function (_) { |
|
if (!arguments.length) return shapeWidth; |
|
shapeWidth = +_; |
|
return legend; |
|
}; |
|
|
|
legend.shapeHeight = function (_) { |
|
if (!arguments.length) return shapeHeight; |
|
shapeHeight = +_; |
|
return legend; |
|
}; |
|
|
|
legend.shapeRadius = function (_) { |
|
if (!arguments.length) return shapeRadius; |
|
shapeRadius = +_; |
|
return legend; |
|
}; |
|
|
|
legend.shapePadding = function (_) { |
|
if (!arguments.length) return shapePadding; |
|
shapePadding = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labels = function (_) { |
|
if (!arguments.length) return labels; |
|
labels = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelAlign = function (_) { |
|
if (!arguments.length) return labelAlign; |
|
if (_ == "start" || _ == "end" || _ == "middle") { |
|
labelAlign = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.labelFormat = function (_) { |
|
if (!arguments.length) return labelFormat; |
|
labelFormat = typeof _ === 'string' ? d3Format.format(_) : _; |
|
return legend; |
|
}; |
|
|
|
legend.labelOffset = function (_) { |
|
if (!arguments.length) return labelOffset; |
|
labelOffset = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labelDelimiter = function (_) { |
|
if (!arguments.length) return labelDelimiter; |
|
labelDelimiter = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelWrap = function (_) { |
|
if (!arguments.length) return labelWrap; |
|
labelWrap = _; |
|
return legend; |
|
}; |
|
|
|
legend.useClass = function (_) { |
|
if (!arguments.length) return useClass; |
|
if (_ === true || _ === false) { |
|
useClass = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.orient = function (_) { |
|
if (!arguments.length) return orient; |
|
_ = _.toLowerCase(); |
|
if (_ == "horizontal" || _ == "vertical") { |
|
orient = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.ascending = function (_) { |
|
if (!arguments.length) return ascending; |
|
ascending = !!_; |
|
return legend; |
|
}; |
|
|
|
legend.classPrefix = function (_) { |
|
if (!arguments.length) return classPrefix; |
|
classPrefix = _; |
|
return legend; |
|
}; |
|
|
|
legend.title = function (_) { |
|
if (!arguments.length) return title; |
|
title = _; |
|
return legend; |
|
}; |
|
|
|
legend.titleWidth = function (_) { |
|
if (!arguments.length) return titleWidth; |
|
titleWidth = _; |
|
return legend; |
|
}; |
|
|
|
legend.textWrap = function (_) { |
|
if (!arguments.length) return textWrap; |
|
textWrap = _; |
|
return legend; |
|
}; |
|
|
|
legend.on = function () { |
|
var value = legendDispatcher.on.apply(legendDispatcher, arguments); |
|
return value === legendDispatcher ? legend : value; |
|
}; |
|
|
|
return legend; |
|
} |
|
|
|
function size() { |
|
|
|
var scale = d3Scale.scaleLinear(), |
|
shape = "rect", |
|
shapeWidth = 15, |
|
shapePadding = 2, |
|
cells = [5], |
|
cellFilter = void 0, |
|
labels = [], |
|
classPrefix = "", |
|
title = "", |
|
labelFormat = d3Format.format(".01f"), |
|
labelOffset = 10, |
|
labelAlign = "middle", |
|
labelDelimiter = "to", |
|
labelWrap = void 0, |
|
orient = "vertical", |
|
ascending = false, |
|
path = void 0, |
|
titleWidth = void 0, |
|
legendDispatcher = d3Dispatch.dispatch("cellover", "cellout", "cellclick"); |
|
|
|
function legend(svg) { |
|
|
|
var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter), |
|
legendG = svg.selectAll('g').data([scale]); |
|
|
|
if (cellFilter) { |
|
helper.d3_filterCells(type, cellFilter); |
|
} |
|
|
|
legendG.enter().append('g').attr('class', classPrefix + 'legendCells'); |
|
|
|
var cell = svg.select('.' + classPrefix + 'legendCells').selectAll("." + classPrefix + "cell").data(type.data); |
|
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell"); |
|
cellEnter.append(shape).attr("class", classPrefix + "swatch"); |
|
|
|
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape); |
|
|
|
//add event handlers |
|
helper.d3_addEvents(cellEnter, legendDispatcher); |
|
|
|
cell.exit().transition().style("opacity", 0).remove(); |
|
|
|
//creates shape |
|
if (shape === "line") { |
|
helper.d3_drawShapes(shape, shapes, 0, shapeWidth); |
|
shapes.attr("stroke-width", type.feature); |
|
} else { |
|
helper.d3_drawShapes(shape, shapes, type.feature, type.feature, type.feature, path); |
|
} |
|
|
|
var text = helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap); |
|
|
|
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones. |
|
cell = cellEnter.merge(cell); |
|
|
|
//sets placement |
|
|
|
var textSize = text.nodes().map(function (d) { |
|
return d.getBBox(); |
|
}), |
|
shapeSize = shapes.nodes().map(function (d, i) { |
|
var bbox = d.getBBox(); |
|
var stroke = scale(type.data[i]); |
|
|
|
if (shape === "line" && orient === "horizontal") { |
|
bbox.height = bbox.height + stroke; |
|
} else if (shape === "line" && orient === "vertical") { |
|
bbox.width = bbox.width; |
|
} |
|
return bbox; |
|
}); |
|
//console.log('SHAPESIZE') |
|
var maxH = d3Array.max(shapeSize, function (d) { |
|
return d.height + d.y; |
|
}), |
|
maxW = d3Array.max(shapeSize, function (d) { |
|
return d.width + d.x; |
|
}); |
|
|
|
var cellTrans = void 0, |
|
textTrans = void 0, |
|
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1; |
|
|
|
//positions cells and text |
|
if (orient === "vertical") { |
|
(function () { |
|
var cellSize = textSize.map(function (d, i) { |
|
return Math.max(d.height, shapeSize[i].height); |
|
}); |
|
var y = shape == "circle" || shape == "line" ? shapeSize[0].height / 2 : 0; |
|
cellTrans = function cellTrans(d, i) { |
|
var height = d3Array.sum(cellSize.slice(0, i)); |
|
|
|
return 'translate(0, ' + (y + height + i * shapePadding) + ')'; |
|
}; |
|
|
|
textTrans = function textTrans(d, i) { |
|
return 'translate( ' + (maxW + labelOffset) + ',\n ' + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ')'; |
|
}; |
|
})(); |
|
} else if (orient === "horizontal") { |
|
cellTrans = function cellTrans(d, i) { |
|
var width = d3Array.sum(shapeSize.slice(0, i), function (d) { |
|
return d.width; |
|
}); |
|
var y = shape == "circle" || shape == "line" ? maxH / 2 : 0; |
|
return 'translate(' + (width + i * shapePadding) + ', ' + y + ')'; |
|
}; |
|
|
|
textTrans = function textTrans(d, i) { |
|
return 'translate( ' + (shapeSize[i].width * textAlign + shapeSize[i].x) + ',\n ' + (maxH + labelOffset) + ')'; |
|
}; |
|
} |
|
|
|
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); |
|
helper.d3_title(svg, title, classPrefix, titleWidth); |
|
|
|
cell.transition().style("opacity", 1); |
|
} |
|
|
|
legend.scale = function (_) { |
|
if (!arguments.length) return scale; |
|
scale = _; |
|
return legend; |
|
}; |
|
|
|
legend.cells = function (_) { |
|
if (!arguments.length) return cells; |
|
if (_.length > 1 || _ >= 2) { |
|
cells = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.cellFilter = function (_) { |
|
if (!arguments.length) return cellFilter; |
|
cellFilter = _; |
|
return legend; |
|
}; |
|
|
|
legend.shape = function (_, d) { |
|
if (!arguments.length) return shape; |
|
if (_ == "rect" || _ == "circle" || _ == "line") { |
|
shape = _; |
|
path = d; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.shapeWidth = function (_) { |
|
if (!arguments.length) return shapeWidth; |
|
shapeWidth = +_; |
|
return legend; |
|
}; |
|
|
|
legend.shapePadding = function (_) { |
|
if (!arguments.length) return shapePadding; |
|
shapePadding = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labels = function (_) { |
|
if (!arguments.length) return labels; |
|
labels = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelAlign = function (_) { |
|
if (!arguments.length) return labelAlign; |
|
if (_ == "start" || _ == "end" || _ == "middle") { |
|
labelAlign = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.labelFormat = function (_) { |
|
if (!arguments.length) return labelFormat; |
|
labelFormat = typeof _ === 'string' ? d3Format.format(_) : _; |
|
return legend; |
|
}; |
|
|
|
legend.labelOffset = function (_) { |
|
if (!arguments.length) return labelOffset; |
|
labelOffset = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labelDelimiter = function (_) { |
|
if (!arguments.length) return labelDelimiter; |
|
labelDelimiter = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelWrap = function (_) { |
|
if (!arguments.length) return labelWrap; |
|
labelWrap = _; |
|
return legend; |
|
}; |
|
|
|
legend.orient = function (_) { |
|
if (!arguments.length) return orient; |
|
_ = _.toLowerCase(); |
|
if (_ == "horizontal" || _ == "vertical") { |
|
orient = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.ascending = function (_) { |
|
if (!arguments.length) return ascending; |
|
ascending = !!_; |
|
return legend; |
|
}; |
|
|
|
legend.classPrefix = function (_) { |
|
if (!arguments.length) return classPrefix; |
|
classPrefix = _; |
|
return legend; |
|
}; |
|
|
|
legend.title = function (_) { |
|
if (!arguments.length) return title; |
|
title = _; |
|
return legend; |
|
}; |
|
|
|
legend.titleWidth = function (_) { |
|
if (!arguments.length) return titleWidth; |
|
titleWidth = _; |
|
return legend; |
|
}; |
|
|
|
legend.on = function () { |
|
var value = legendDispatcher.on.apply(legendDispatcher, arguments); |
|
return value === legendDispatcher ? legend : value; |
|
}; |
|
|
|
return legend; |
|
} |
|
|
|
function symbol() { |
|
|
|
var scale = d3Scale.scaleLinear(), |
|
shape = "path", |
|
shapeWidth = 15, |
|
shapeHeight = 15, |
|
shapeRadius = 10, |
|
shapePadding = 5, |
|
cells = [5], |
|
cellFilter = void 0, |
|
labels = [], |
|
classPrefix = "", |
|
title = "", |
|
labelFormat = d3Format.format(".01f"), |
|
labelAlign = "middle", |
|
labelOffset = 10, |
|
labelDelimiter = "to", |
|
labelWrap = void 0, |
|
orient = "vertical", |
|
ascending = false, |
|
titleWidth = void 0, |
|
legendDispatcher = d3Dispatch.dispatch("cellover", "cellout", "cellclick"); |
|
|
|
function legend(svg) { |
|
|
|
var type = helper.d3_calcType(scale, ascending, cells, labels, labelFormat, labelDelimiter), |
|
legendG = svg.selectAll('g').data([scale]); |
|
|
|
if (cellFilter) { |
|
helper.d3_filterCells(type, cellFilter); |
|
} |
|
|
|
legendG.enter().append('g').attr('class', classPrefix + 'legendCells'); |
|
|
|
var cell = svg.select('.' + classPrefix + 'legendCells').selectAll("." + classPrefix + "cell").data(type.data); |
|
var cellEnter = cell.enter().append("g").attr("class", classPrefix + "cell"); |
|
cellEnter.append(shape).attr("class", classPrefix + "swatch"); |
|
|
|
var shapes = svg.selectAll("g." + classPrefix + "cell " + shape); |
|
|
|
//add event handlers |
|
helper.d3_addEvents(cellEnter, legendDispatcher); |
|
|
|
//remove old shapes |
|
cell.exit().transition().style("opacity", 0).remove(); |
|
|
|
helper.d3_drawShapes(shape, shapes, shapeHeight, shapeWidth, shapeRadius, type.feature); |
|
helper.d3_addText(svg, cellEnter, type.labels, classPrefix, labelWrap); |
|
|
|
// we need to merge the selection, otherwise changes in the legend (e.g. change of orientation) are applied only to the new cells and not the existing ones. |
|
cell = cellEnter.merge(cell); |
|
|
|
// sets placement |
|
var text = cell.selectAll("text"), |
|
textSize = text.nodes().map(function (d) { |
|
return d.getBBox(); |
|
}), |
|
shapeSize = shapes.nodes().map(function (d) { |
|
return d.getBBox(); |
|
}); |
|
|
|
var maxH = d3Array.max(shapeSize, function (d) { |
|
return d.height; |
|
}), |
|
maxW = d3Array.max(shapeSize, function (d) { |
|
return d.width; |
|
}); |
|
|
|
var cellTrans = void 0, |
|
textTrans = void 0, |
|
textAlign = labelAlign == "start" ? 0 : labelAlign == "middle" ? 0.5 : 1; |
|
|
|
//positions cells and text |
|
if (orient === "vertical") { |
|
(function () { |
|
var cellSize = textSize.map(function (d, i) { |
|
return Math.max(maxH, d.height); |
|
}); |
|
|
|
cellTrans = function cellTrans(d, i) { |
|
var height = d3Array.sum(cellSize.slice(0, i)); |
|
return 'translate(0, ' + (height + i * shapePadding) + ' )'; |
|
}; |
|
textTrans = function textTrans(d, i) { |
|
return 'translate( ' + (maxW + labelOffset) + ',\n ' + (shapeSize[i].y + shapeSize[i].height / 2 + 5) + ')'; |
|
}; |
|
})(); |
|
} else if (orient === "horizontal") { |
|
cellTrans = function cellTrans(d, i) { |
|
return 'translate( ' + i * (maxW + shapePadding) + ',0)'; |
|
}; |
|
textTrans = function textTrans(d, i) { |
|
return 'translate( ' + (shapeSize[i].width * textAlign + shapeSize[i].x) + ',\n ' + (maxH + labelOffset) + ')'; |
|
}; |
|
} |
|
|
|
helper.d3_placement(orient, cell, cellTrans, text, textTrans, labelAlign); |
|
helper.d3_title(svg, title, classPrefix, titleWidth); |
|
cell.transition().style("opacity", 1); |
|
} |
|
|
|
legend.scale = function (_) { |
|
if (!arguments.length) return scale; |
|
scale = _; |
|
return legend; |
|
}; |
|
|
|
legend.cells = function (_) { |
|
if (!arguments.length) return cells; |
|
if (_.length > 1 || _ >= 2) { |
|
cells = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.cellFilter = function (_) { |
|
if (!arguments.length) return cellFilter; |
|
cellFilter = _; |
|
return legend; |
|
}; |
|
|
|
legend.shapePadding = function (_) { |
|
if (!arguments.length) return shapePadding; |
|
shapePadding = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labels = function (_) { |
|
if (!arguments.length) return labels; |
|
labels = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelAlign = function (_) { |
|
if (!arguments.length) return labelAlign; |
|
if (_ == "start" || _ == "end" || _ == "middle") { |
|
labelAlign = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.labelFormat = function (_) { |
|
if (!arguments.length) return labelFormat; |
|
labelFormat = typeof _ === 'string' ? d3Format.format(_) : _; |
|
return legend; |
|
}; |
|
|
|
legend.labelOffset = function (_) { |
|
if (!arguments.length) return labelOffset; |
|
labelOffset = +_; |
|
return legend; |
|
}; |
|
|
|
legend.labelDelimiter = function (_) { |
|
if (!arguments.length) return labelDelimiter; |
|
labelDelimiter = _; |
|
return legend; |
|
}; |
|
|
|
legend.labelWrap = function (_) { |
|
if (!arguments.length) return labelWrap; |
|
labelWrap = _; |
|
return legend; |
|
}; |
|
|
|
legend.orient = function (_) { |
|
if (!arguments.length) return orient; |
|
_ = _.toLowerCase(); |
|
if (_ == "horizontal" || _ == "vertical") { |
|
orient = _; |
|
} |
|
return legend; |
|
}; |
|
|
|
legend.ascending = function (_) { |
|
if (!arguments.length) return ascending; |
|
ascending = !!_; |
|
return legend; |
|
}; |
|
|
|
legend.classPrefix = function (_) { |
|
if (!arguments.length) return classPrefix; |
|
classPrefix = _; |
|
return legend; |
|
}; |
|
|
|
legend.title = function (_) { |
|
if (!arguments.length) return title; |
|
title = _; |
|
return legend; |
|
}; |
|
|
|
legend.titleWidth = function (_) { |
|
if (!arguments.length) return titleWidth; |
|
titleWidth = _; |
|
return legend; |
|
}; |
|
|
|
legend.on = function () { |
|
var value = legendDispatcher.on.apply(legendDispatcher, arguments); |
|
return value === legendDispatcher ? legend : value; |
|
}; |
|
|
|
return legend; |
|
} |
|
|
|
var thresholdLabels = function thresholdLabels(_ref) { |
|
var i = _ref.i, |
|
genLength = _ref.genLength, |
|
generatedLabels = _ref.generatedLabels; |
|
|
|
|
|
if (i === 0) { |
|
return generatedLabels[i].replace('NaN to', 'Less than'); |
|
} else if (i === genLength - 1) { |
|
return 'More than ' + generatedLabels[genLength - 1].replace(' to NaN', ''); |
|
} |
|
return generatedLabels[i]; |
|
}; |
|
|
|
var legendHelpers = { |
|
thresholdLabels: thresholdLabels |
|
}; |
|
|
|
var index = { |
|
legendColor: color, |
|
legendSize: size, |
|
legendSymbol: symbol, |
|
legendHelpers: legendHelpers |
|
}; |
|
|
|
exports.legendColor = color; |
|
exports.legendSize = size; |
|
exports.legendSymbol = symbol; |
|
exports.legendHelpers = legendHelpers; |
|
exports['default'] = index; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
}))); |
|
|
|
|
|
},{"d3-array":6,"d3-dispatch":7,"d3-format":8,"d3-scale":9,"d3-selection":10}],6:[function(require,module,exports){ |
|
// https://d3js.org/d3-array/ Version 1.0.1. Copyright 2016 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}))); |
|
}(this, function (exports) { 'use strict'; |
|
|
|
function ascending(a, b) { |
|
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; |
|
} |
|
|
|
function bisector(compare) { |
|
if (compare.length === 1) compare = ascendingComparator(compare); |
|
return { |
|
left: function(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(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); |
|
}; |
|
} |
|
|
|
var ascendingBisect = bisector(ascending); |
|
var bisectRight = ascendingBisect.right; |
|
var bisectLeft = ascendingBisect.left; |
|
|
|
function descending(a, b) { |
|
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; |
|
} |
|
|
|
function number(x) { |
|
return x === null ? NaN : +x; |
|
} |
|
|
|
function variance(array, f) { |
|
var n = array.length, |
|
m = 0, |
|
a, |
|
d, |
|
s = 0, |
|
i = -1, |
|
j = 0; |
|
|
|
if (f == null) { |
|
while (++i < n) { |
|
if (!isNaN(a = number(array[i]))) { |
|
d = a - m; |
|
m += d / ++j; |
|
s += d * (a - m); |
|
} |
|
} |
|
} |
|
|
|
else { |
|
while (++i < n) { |
|
if (!isNaN(a = number(f(array[i], i, array)))) { |
|
d = a - m; |
|
m += d / ++j; |
|
s += d * (a - m); |
|
} |
|
} |
|
} |
|
|
|
if (j > 1) return s / (j - 1); |
|
} |
|
|
|
function deviation(array, f) { |
|
var v = variance(array, f); |
|
return v ? Math.sqrt(v) : v; |
|
} |
|
|
|
function extent(array, f) { |
|
var i = -1, |
|
n = array.length, |
|
a, |
|
b, |
|
c; |
|
|
|
if (f == null) { |
|
while (++i < n) if ((b = array[i]) != null && b >= b) { a = c = b; break; } |
|
while (++i < n) if ((b = array[i]) != null) { |
|
if (a > b) a = b; |
|
if (c < b) c = b; |
|
} |
|
} |
|
|
|
else { |
|
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = c = b; break; } |
|
while (++i < n) if ((b = f(array[i], i, array)) != null) { |
|
if (a > b) a = b; |
|
if (c < b) c = b; |
|
} |
|
} |
|
|
|
return [a, c]; |
|
} |
|
|
|
var array = Array.prototype; |
|
|
|
var slice = array.slice; |
|
var map = array.map; |
|
|
|
function constant(x) { |
|
return function() { |
|
return x; |
|
}; |
|
} |
|
|
|
function identity(x) { |
|
return x; |
|
} |
|
|
|
function range(start, stop, step) { |
|
start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; |
|
|
|
var i = -1, |
|
n = Math.max(0, Math.ceil((stop - start) / step)) | 0, |
|
range = new Array(n); |
|
|
|
while (++i < n) { |
|
range[i] = start + i * step; |
|
} |
|
|
|
return range; |
|
} |
|
|
|
var e10 = Math.sqrt(50); |
|
var e5 = Math.sqrt(10); |
|
var e2 = Math.sqrt(2); |
|
function ticks(start, stop, count) { |
|
var step = tickStep(start, stop, count); |
|
return range( |
|
Math.ceil(start / step) * step, |
|
Math.floor(stop / step) * step + step / 2, // inclusive |
|
step |
|
); |
|
} |
|
|
|
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; |
|
} |
|
|
|
function sturges(values) { |
|
return Math.ceil(Math.log(values.length) / Math.LN2) + 1; |
|
} |
|
|
|
function histogram() { |
|
var value = identity, |
|
domain = extent, |
|
threshold = sturges; |
|
|
|
function histogram(data) { |
|
var i, |
|
n = data.length, |
|
x, |
|
values = new Array(n); |
|
|
|
for (i = 0; i < n; ++i) { |
|
values[i] = value(data[i], i, data); |
|
} |
|
|
|
var xz = domain(values), |
|
x0 = xz[0], |
|
x1 = xz[1], |
|
tz = threshold(values, x0, x1); |
|
|
|
// Convert number of thresholds into uniform thresholds. |
|
if (!Array.isArray(tz)) tz = ticks(x0, x1, tz); |
|
|
|
// Remove any thresholds outside the domain. |
|
var m = tz.length; |
|
while (tz[0] <= x0) tz.shift(), --m; |
|
while (tz[m - 1] >= x1) tz.pop(), --m; |
|
|
|
var bins = new Array(m + 1), |
|
bin; |
|
|
|
// Initialize bins. |
|
for (i = 0; i <= m; ++i) { |
|
bin = bins[i] = []; |
|
bin.x0 = i > 0 ? tz[i - 1] : x0; |
|
bin.x1 = i < m ? tz[i] : x1; |
|
} |
|
|
|
// Assign data to bins by value, ignoring any outside the domain. |
|
for (i = 0; i < n; ++i) { |
|
x = values[i]; |
|
if (x0 <= x && x <= x1) { |
|
bins[bisectRight(tz, x, 0, m)].push(data[i]); |
|
} |
|
} |
|
|
|
return bins; |
|
} |
|
|
|
histogram.value = function(_) { |
|
return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value; |
|
}; |
|
|
|
histogram.domain = function(_) { |
|
return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain; |
|
}; |
|
|
|
histogram.thresholds = function(_) { |
|
return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold; |
|
}; |
|
|
|
return histogram; |
|
} |
|
|
|
function quantile(array, p, f) { |
|
if (f == null) f = number; |
|
if (!(n = array.length)) return; |
|
if ((p = +p) <= 0 || n < 2) return +f(array[0], 0, array); |
|
if (p >= 1) return +f(array[n - 1], n - 1, array); |
|
var n, |
|
h = (n - 1) * p, |
|
i = Math.floor(h), |
|
a = +f(array[i], i, array), |
|
b = +f(array[i + 1], i + 1, array); |
|
return a + (b - a) * (h - i); |
|
} |
|
|
|
function freedmanDiaconis(values, min, max) { |
|
values = map.call(values, number).sort(ascending); |
|
return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3))); |
|
} |
|
|
|
function scott(values, min, max) { |
|
return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3))); |
|
} |
|
|
|
function max(array, f) { |
|
var i = -1, |
|
n = array.length, |
|
a, |
|
b; |
|
|
|
if (f == null) { |
|
while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } |
|
while (++i < n) if ((b = array[i]) != null && b > a) a = b; |
|
} |
|
|
|
else { |
|
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; } |
|
while (++i < n) if ((b = f(array[i], i, array)) != null && b > a) a = b; |
|
} |
|
|
|
return a; |
|
} |
|
|
|
function mean(array, f) { |
|
var s = 0, |
|
n = array.length, |
|
a, |
|
i = -1, |
|
j = n; |
|
|
|
if (f == null) { |
|
while (++i < n) if (!isNaN(a = number(array[i]))) s += a; else --j; |
|
} |
|
|
|
else { |
|
while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) s += a; else --j; |
|
} |
|
|
|
if (j) return s / j; |
|
} |
|
|
|
function median(array, f) { |
|
var numbers = [], |
|
n = array.length, |
|
a, |
|
i = -1; |
|
|
|
if (f == null) { |
|
while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a); |
|
} |
|
|
|
else { |
|
while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a); |
|
} |
|
|
|
return quantile(numbers.sort(ascending), 0.5); |
|
} |
|
|
|
function merge(arrays) { |
|
var n = arrays.length, |
|
m, |
|
i = -1, |
|
j = 0, |
|
merged, |
|
array; |
|
|
|
while (++i < n) j += arrays[i].length; |
|
merged = new Array(j); |
|
|
|
while (--n >= 0) { |
|
array = arrays[n]; |
|
m = array.length; |
|
while (--m >= 0) { |
|
merged[--j] = array[m]; |
|
} |
|
} |
|
|
|
return merged; |
|
} |
|
|
|
function min(array, f) { |
|
var i = -1, |
|
n = array.length, |
|
a, |
|
b; |
|
|
|
if (f == null) { |
|
while (++i < n) if ((b = array[i]) != null && b >= b) { a = b; break; } |
|
while (++i < n) if ((b = array[i]) != null && a > b) a = b; |
|
} |
|
|
|
else { |
|
while (++i < n) if ((b = f(array[i], i, array)) != null && b >= b) { a = b; break; } |
|
while (++i < n) if ((b = f(array[i], i, array)) != null && a > b) a = b; |
|
} |
|
|
|
return a; |
|
} |
|
|
|
function pairs(array) { |
|
var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n); |
|
while (i < n) pairs[i] = [p, p = array[++i]]; |
|
return pairs; |
|
} |
|
|
|
function permute(array, indexes) { |
|
var i = indexes.length, permutes = new Array(i); |
|
while (i--) permutes[i] = array[indexes[i]]; |
|
return permutes; |
|
} |
|
|
|
function scan(array, compare) { |
|
if (!(n = array.length)) return; |
|
var i = 0, |
|
n, |
|
j = 0, |
|
xi, |
|
xj = array[j]; |
|
|
|
if (!compare) compare = ascending; |
|
|
|
while (++i < n) if (compare(xi = array[i], xj) < 0 || compare(xj, xj) !== 0) xj = xi, j = i; |
|
|
|
if (compare(xj, xj) === 0) return j; |
|
} |
|
|
|
function shuffle(array, i0, i1) { |
|
var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0), |
|
t, |
|
i; |
|
|
|
while (m) { |
|
i = Math.random() * m-- | 0; |
|
t = array[m + i0]; |
|
array[m + i0] = array[i + i0]; |
|
array[i + i0] = t; |
|
} |
|
|
|
return array; |
|
} |
|
|
|
function sum(array, f) { |
|
var s = 0, |
|
n = array.length, |
|
a, |
|
i = -1; |
|
|
|
if (f == null) { |
|
while (++i < n) if (a = +array[i]) s += a; // Note: zero and null are equivalent. |
|
} |
|
|
|
else { |
|
while (++i < n) if (a = +f(array[i], i, array)) s += a; |
|
} |
|
|
|
return s; |
|
} |
|
|
|
function transpose(matrix) { |
|
if (!(n = matrix.length)) return []; |
|
for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) { |
|
for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) { |
|
row[j] = matrix[j][i]; |
|
} |
|
} |
|
return transpose; |
|
} |
|
|
|
function length(d) { |
|
return d.length; |
|
} |
|
|
|
function zip() { |
|
return transpose(arguments); |
|
} |
|
|
|
exports.bisect = bisectRight; |
|
exports.bisectRight = bisectRight; |
|
exports.bisectLeft = bisectLeft; |
|
exports.ascending = ascending; |
|
exports.bisector = bisector; |
|
exports.descending = descending; |
|
exports.deviation = deviation; |
|
exports.extent = extent; |
|
exports.histogram = histogram; |
|
exports.thresholdFreedmanDiaconis = freedmanDiaconis; |
|
exports.thresholdScott = scott; |
|
exports.thresholdSturges = sturges; |
|
exports.max = max; |
|
exports.mean = mean; |
|
exports.median = median; |
|
exports.merge = merge; |
|
exports.min = min; |
|
exports.pairs = pairs; |
|
exports.permute = permute; |
|
exports.quantile = quantile; |
|
exports.range = range; |
|
exports.scan = scan; |
|
exports.shuffle = shuffle; |
|
exports.sum = sum; |
|
exports.ticks = ticks; |
|
exports.tickStep = tickStep; |
|
exports.transpose = transpose; |
|
exports.variance = variance; |
|
exports.zip = zip; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
})); |
|
},{}],7:[function(require,module,exports){ |
|
// https://d3js.org/d3-dispatch/ Version 1.0.1. Copyright 2016 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}))); |
|
}(this, function (exports) { 'use strict'; |
|
|
|
var noop = {value: function() {}}; |
|
|
|
function dispatch() { |
|
for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { |
|
if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); |
|
_[t] = []; |
|
} |
|
return new Dispatch(_); |
|
} |
|
|
|
function Dispatch(_) { |
|
this._ = _; |
|
} |
|
|
|
function parseTypenames(typenames, types) { |
|
return typenames.trim().split(/^|\s+/).map(function(t) { |
|
var name = "", i = t.indexOf("."); |
|
if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); |
|
if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); |
|
return {type: t, name: name}; |
|
}); |
|
} |
|
|
|
Dispatch.prototype = dispatch.prototype = { |
|
constructor: Dispatch, |
|
on: function(typename, callback) { |
|
var _ = this._, |
|
T = parseTypenames(typename + "", _), |
|
t, |
|
i = -1, |
|
n = T.length; |
|
|
|
// If no callback was specified, return the callback of the given type and name. |
|
if (arguments.length < 2) { |
|
while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; |
|
return; |
|
} |
|
|
|
// If a type was specified, set the callback for the given type and name. |
|
// Otherwise, if a null callback was specified, remove callbacks of the given name. |
|
if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); |
|
while (++i < n) { |
|
if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback); |
|
else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null); |
|
} |
|
|
|
return this; |
|
}, |
|
copy: function() { |
|
var copy = {}, _ = this._; |
|
for (var t in _) copy[t] = _[t].slice(); |
|
return new Dispatch(copy); |
|
}, |
|
call: function(type, that) { |
|
if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; |
|
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); |
|
for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); |
|
}, |
|
apply: function(type, that, args) { |
|
if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); |
|
for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); |
|
} |
|
}; |
|
|
|
function get(type, name) { |
|
for (var i = 0, n = type.length, c; i < n; ++i) { |
|
if ((c = type[i]).name === name) { |
|
return c.value; |
|
} |
|
} |
|
} |
|
|
|
function set(type, name, callback) { |
|
for (var i = 0, n = type.length; i < n; ++i) { |
|
if (type[i].name === name) { |
|
type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); |
|
break; |
|
} |
|
} |
|
if (callback != null) type.push({name: name, value: callback}); |
|
return type; |
|
} |
|
|
|
exports.dispatch = dispatch; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
})); |
|
},{}],8:[function(require,module,exports){ |
|
// https://d3js.org/d3-format/ Version 1.0.2. Copyright 2016 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : |
|
typeof define === 'function' && define.amd ? define(['exports'], factory) : |
|
(factory((global.d3 = global.d3 || {}))); |
|
}(this, function (exports) { 'use strict'; |
|
|
|
// 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 formatDefault(x, p) { |
|
x = x.toPrecision(p); |
|
|
|
out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { |
|
switch (x[i]) { |
|
case ".": i0 = i1 = i; break; |
|
case "0": if (i0 === 0) i0 = i; i1 = i; break; |
|
case "e": break out; |
|
default: if (i0 > 0) i0 = 0; break; |
|
} |
|
} |
|
|
|
return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; |
|
} |
|
|
|
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 = { |
|
"": formatDefault, |
|
"%": 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); } |
|
}; |
|
|
|
// [[fill]align][sign][symbol][0][width][,][.precision][type] |
|
var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; |
|
|
|
function formatSpecifier(specifier) { |
|
return new FormatSpecifier(specifier); |
|
} |
|
|
|
function FormatSpecifier(specifier) { |
|
if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); |
|
|
|
var match, |
|
fill = match[1] || " ", |
|
align = match[2] || ">", |
|
sign = match[3] || "-", |
|
symbol = match[4] || "", |
|
zero = !!match[5], |
|
width = match[6] && +match[6], |
|
comma = !!match[7], |
|
precision = match[8] && +match[8].slice(1), |
|
type = match[9] || ""; |
|
|
|
// The "n" type is an alias for ",g". |
|
if (type === "n") comma = true, type = "g"; |
|
|
|
// Map invalid types to the default format. |
|
else if (!formatTypes[type]) type = ""; |
|
|
|
// If zero fill is specified, padding goes after sign and before digits. |
|
if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; |
|
|
|
this.fill = fill; |
|
this.align = align; |
|
this.sign = sign; |
|
this.symbol = symbol; |
|
this.zero = zero; |
|
this.width = width; |
|
this.comma = comma; |
|
this.precision = precision; |
|
this.type = type; |
|
} |
|
|
|
FormatSpecifier.prototype.toString = function() { |
|
return this.fill |
|
+ this.align |
|
+ this.sign |
|
+ this.symbol |
|
+ (this.zero ? "0" : "") |
|
+ (this.width == null ? "" : Math.max(1, this.width | 0)) |
|
+ (this.comma ? "," : "") |
|
+ (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) |
|
+ this.type; |
|
}; |
|
|
|
var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; |
|
|
|
function identity(x) { |
|
return x; |
|
} |
|
|
|
function formatLocale(locale) { |
|
var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, |
|
currency = locale.currency, |
|
decimal = locale.decimal; |
|
|
|
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, |
|
type = specifier.type; |
|
|
|
// Compute the prefix and suffix. |
|
// For SI-prefix, the suffix is lazily computed. |
|
var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", |
|
suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; |
|
|
|
// What format function should we use? |
|
// Is this an integer type? |
|
// Can this type generate exponential notation? |
|
var formatType = formatTypes[type], |
|
maybeSuffix = !type || /[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 == null ? (type ? 6 : 12) |
|
: /[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; |
|
|
|
// Convert negative to positive, and compute the prefix. |
|
// Note that -0 is not less than 0, but 1 / -0 is! |
|
var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); |
|
|
|
// Perform the initial formatting. |
|
value = formatType(value, precision); |
|
|
|
// If the original value was negative, it may be rounded to zero during |
|
// formatting; treat this as (positive) zero. |
|
if (valueNegative) { |
|
i = -1, n = value.length; |
|
valueNegative = false; |
|
while (++i < n) { |
|
if (c = value.charCodeAt(i), (48 < c && c < 58) |
|
|| (type === "x" && 96 < c && c < 103) |
|
|| (type === "X" && 64 < c && c < 71)) { |
|
valueNegative = true; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
// Compute the prefix and suffix. |
|
valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; |
|
valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (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 "<": return valuePrefix + value + valueSuffix + padding; |
|
case "=": return valuePrefix + padding + value + valueSuffix; |
|
case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); |
|
} |
|
return padding + valuePrefix + value + valueSuffix; |
|
} |
|
|
|
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; |
|
defaultLocale({ |
|
decimal: ".", |
|
thousands: ",", |
|
grouping: [3], |
|
currency: ["$", ""] |
|
}); |
|
|
|
function defaultLocale(definition) { |
|
locale = formatLocale(definition); |
|
exports.format = locale.format; |
|
exports.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; |
|
} |
|
|
|
exports.formatDefaultLocale = defaultLocale; |
|
exports.formatLocale = formatLocale; |
|
exports.formatSpecifier = formatSpecifier; |
|
exports.precisionFixed = precisionFixed; |
|
exports.precisionPrefix = precisionPrefix; |
|
exports.precisionRound = precisionRound; |
|
|
|
Object.defineProperty(exports, '__esModule', { value: true }); |
|
|
|
})); |
|
},{}],9:[function(require,module,exports){ |
|
// https://d3js.org/d3-scale/ Version 1.0.3. Copyright 2016 Mike Bostock. |
|
(function (global, factory) { |
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-collection'), require('d3-interpolate'), require('d3-format'), require('d3-time'), require('d3-time-format'), require('d3-color')) : |
|
typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-collection', 'd3-interpolate', 'd3-format', 'd3-time', 'd3-time-format', 'd3-color'], factory) : |
|
(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3,global.d3,global.d3,global.d3,global.d3)); |
|
}(this, function (exports,d3Array,d3Collection,d3Interpolate,d3Format,d3Time,d3TimeFormat,d3Color) { 'use strict'; |
|
|
|
var array = Array.prototype; |
|
|
|
var map$1 = array.map; |
|
var slice = array.slice; |
|
|
|
var implicit = {name: "implicit"}; |
|
|
|
function ordinal(range) { |
|
var index = d3Collection.map(), |
|
domain = [], |
|
unknown = implicit; |
|
|
|
range = range == null ? [] : slice.call(range); |
|
|
|
function scale(d) { |
|
var key = d + "", i = index.get(key); |
|
if (!i) { |
|
if (unknown !== implicit) return unknown; |
|
index.set(key, i = domain.push(d)); |
|
} |
|
return range[(i - 1) % range.length]; |
|
} |
|
|
|
scale.domain = function(_) { |
|
if (!arguments.length) return domain.slice(); |
|
domain = [], index = d3Collection.map(); |
|
var i = -1, n = _.length, d, key; |
|
while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); |
|
return scale; |
|
}; |
|
|
|
scale.range = function(_) { |
|
return arguments.length ? (range = slice.call(_), scale) : range.slice(); |
|
}; |
|
|
|
scale.unknown = function(_) { |
|
return arguments.length ? (unknown = _, scale) : unknown; |
|
}; |
|
|
|
scale.copy = function() { |
|
return ordinal() |
|
.domain(domain) |
|
.range(range) |
|
.unknown(unknown); |
|
}; |
|
|
|
return scale; |
|
} |
|
|
|
function band() { |
|
var scale = ordinal().unknown(undefined), |
|
domain = scale.domain, |
|
ordinalRange = scale.range, |
|
range = [0, 1], |
|
step, |
|
bandwidth, |
|
round = false, |
|
paddingInner = 0, |
|
paddingOuter = 0, |
|
align = 0.5; |
|
|
|
delete scale.unknown; |
|
|
|
function rescale() { |
|
var n = domain().length, |
|
reverse = range[1] < range[0], |
|
start = range[reverse - 0], |
|
stop = range[1 - reverse]; |
|
step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2); |
|
if (round) step = Math.floor(step); |
|
start += (stop - start - step * (n - paddingInner)) * align; |
|
bandwidth = step * (1 - paddingInner); |
|
if (round) start = Math.round(start), bandwidth = Math.round(bandwidth); |
|
var values = d3Array.range(n).map(function(i) { return start + step * i; }); |
|
return ordinalRange(reverse ? values.reverse() : values); |
|
} |
|
|
|
scale.domain = function(_) { |
|
return arguments.length ? (domain(_), rescale()) : domain(); |
|
}; |
|
|
|
scale.range = function(_) { |
|
return arguments.length ? (range = [+_[0], +_[1]], rescale()) : range.slice(); |
|
}; |
|
|
|
scale.rangeRound = function(_) { |
|
return range = [+_[0], +_[1]], round = true, rescale(); |
|
}; |
|
|
|
scale.bandwidth = function() { |
|
return bandwidth; |
|
}; |
|
|
|