radial-progress-chart
Version:
A customizable Radial Progress Chart written on the top of D3.js.
469 lines (396 loc) • 276 kB
JavaScript
this["radial-progress-chart"] =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
module.exports = __webpack_require__(1);
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var d3;
// RadialProgressChart object
function RadialProgressChart(query, options) {
// verify d3 is loaded
d3 = typeof window !== 'undefined' && window.d3 ? window.d3 : true ? __webpack_require__(2) : undefined;
if (!d3) throw new Error('d3 object is missing. D3.js library has to be loaded before.');
var self = this;
self.options = RadialProgressChart.normalizeOptions(options);
// internal variables
var series = self.options.series,
width = 15 + (self.options.diameter / 2 + self.options.stroke.width * self.options.series.length + (self.options.stroke.gap * self.options.series.length - 1)) * 2,
height = width,
dim = "0 0 " + height + " " + width,
τ = 2 * Math.PI,
inner = [],
outer = [];
function innerRadius(item) {
var radius = inner[item.index];
if (radius) return radius;
// first ring based on diameter and the rest based on the previous outer radius plus gap
radius = item.index === 0 ? self.options.diameter / 2 : outer[item.index - 1] + self.options.stroke.gap;
inner[item.index] = radius;
return radius;
}
function outerRadius(item) {
var radius = outer[item.index];
if (radius) return radius;
// based on the previous inner radius + stroke width
radius = inner[item.index] + self.options.stroke.width;
outer[item.index] = radius;
return radius;
}
self.progress = d3.svg.arc().startAngle(0).endAngle(function (item) {
return item.percentage / 100 * τ;
}).innerRadius(innerRadius).outerRadius(outerRadius).cornerRadius(function (d) {
// Workaround for d3 bug https://github.com/mbostock/d3/issues/2249
// Reduce corner radius when corners are close each other
var m = d.percentage >= 90 ? (100 - d.percentage) * 0.1 : 1;
return self.options.stroke.width / 2 * m;
});
var background = d3.svg.arc().startAngle(0).endAngle(τ).innerRadius(innerRadius).outerRadius(outerRadius);
// create svg
self.svg = d3.select(query).append("svg").attr("preserveAspectRatio", "xMinYMin meet").attr("viewBox", dim).append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// add gradients defs
var defs = self.svg.append("svg:defs");
series.forEach(function (item) {
if (item.color.linearGradient || item.color.radialGradient) {
var gradient = RadialProgressChart.Gradient.toSVGElement('gradient' + item.index, item.color);
defs.node().appendChild(gradient);
}
});
// add shadows defs
defs = self.svg.append("svg:defs");
var dropshadowId = "dropshadow-" + Math.random();
var filter = defs.append("filter").attr("id", dropshadowId);
if (self.options.shadow.width > 0) {
filter.append("feGaussianBlur").attr("in", "SourceAlpha").attr("stdDeviation", self.options.shadow.width).attr("result", "blur");
filter.append("feOffset").attr("in", "blur").attr("dx", 1).attr("dy", 1).attr("result", "offsetBlur");
}
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode").attr("in", "offsetBlur");
feMerge.append("feMergeNode").attr("in", "SourceGraphic");
// add inner text
if (self.options.center) {
self.svg.append("text").attr('class', 'rbc-center-text').attr("text-anchor", "middle").attr('x', self.options.center.x + 'px').attr('y', self.options.center.y + 'px').selectAll('tspan').data(self.options.center.content).enter().append('tspan').attr("dominant-baseline", function () {
// Single lines can easily centered in the middle using dominant-baseline, multiline need to use y
if (self.options.center.content.length === 1) {
return 'central';
}
}).attr('class', function (d, i) {
return 'rbc-center-text-line' + i;
}).attr('x', 0).attr('dy', function (d, i) {
if (i > 0) {
return '1.1em';
}
}).each(function (d) {
if (typeof d === 'function') {
this.callback = d;
}
}).text(function (d) {
if (typeof d === 'string') {
return d;
}
return '';
});
}
// add ring structure
self.field = self.svg.selectAll("g").data(series).enter().append("g");
self.field.append("path").attr("class", "progress").attr("filter", "url(#" + dropshadowId + ")");
self.field.append("path").attr("class", "bg").style("fill", function (item) {
return item.color.background;
}).style("opacity", 0.2).attr("d", background);
self.field.append("text").classed('rbc-label rbc-label-start', true).attr("dominant-baseline", "central").attr("x", "10").attr("y", function (item) {
return -(self.options.diameter / 2 + item.index * (self.options.stroke.gap + self.options.stroke.width) + self.options.stroke.width / 2);
}).text(function (item) {
return item.labelStart;
});
self.update();
}
/**
* Update data to be visualized in the chart.
*
* @param {Object|Array} data Optional data you'd like to set for the chart before it will update. If not specified the update method will use the data that is already configured with the chart.
* @example update([70, 10, 45])
* @example update({series: [{value: 70}, 10, 45]})
*
*/
RadialProgressChart.prototype.update = function (data) {
var self = this;
// parse new data
if (data) {
if (typeof data === 'number') {
data = [data];
}
var series;
if (Array.isArray(data)) {
series = data;
} else if (typeof data === 'object') {
series = data.series || [];
}
for (var i = 0; i < series.length; i++) {
this.options.series[i].previousValue = this.options.series[i].value;
var item = series[i];
if (typeof item === 'number') {
this.options.series[i].value = item;
} else if (typeof item === 'object') {
this.options.series[i].value = item.value;
}
}
}
// calculate from percentage and new percentage for the progress animation
self.options.series.forEach(function (item) {
item.fromPercentage = item.percentage ? item.percentage : 5;
item.percentage = (item.value - self.options.min) * 100 / (self.options.max - self.options.min);
});
var center = self.svg.select("text.rbc-center-text");
// progress
self.field.select("path.progress").interrupt().transition().duration(self.options.animation.duration).delay(function (d, i) {
// delay between each item
return i * self.options.animation.delay;
}).ease("elastic").attrTween("d", function (item) {
var interpolator = d3.interpolateNumber(item.fromPercentage, item.percentage);
return function (t) {
item.percentage = interpolator(t);
return self.progress(item);
};
}).tween("center", function (item) {
// Execute callbacks on each line
if (self.options.center) {
var interpolate = self.options.round ? d3.interpolateRound : d3.interpolateNumber;
var interpolator = interpolate(item.previousValue || 0, item.value);
return function (t) {
center.selectAll('tspan').each(function () {
if (this.callback) {
d3.select(this).text(this.callback(interpolator(t), item.index, item));
}
});
};
}
}).tween("interpolate-color", function (item) {
if (item.color.interpolate && item.color.interpolate.length == 2) {
var colorInterpolator = d3.interpolateHsl(item.color.interpolate[0], item.color.interpolate[1]);
return function (t) {
var color = colorInterpolator(item.percentage / 100);
d3.select(this).style('fill', color);
d3.select(this.parentNode).select('path.bg').style('fill', color);
};
}
}).style("fill", function (item) {
if (item.color.solid) {
return item.color.solid;
}
if (item.color.linearGradient || item.color.radialGradient) {
return "url(#gradient" + item.index + ')';
}
});
};
/**
* Remove svg and clean some references
*/
RadialProgressChart.prototype.destroy = function () {
this.svg.remove();
delete this.svg;
};
/**
* Detach and normalize user's options input.
*/
RadialProgressChart.normalizeOptions = function (options) {
if (!options || typeof options !== 'object') {
options = {};
}
var _options = {
diameter: options.diameter || 100,
stroke: {
width: options.stroke && options.stroke.width || 40,
gap: options.stroke && options.stroke.gap || 2
},
shadow: {
width: !options.shadow || options.shadow.width === null ? 4 : options.shadow.width
},
animation: {
duration: options.animation && options.animation.duration || 1750,
delay: options.animation && options.animation.delay || 200
},
min: options.min || 0,
max: options.max || 100,
round: options.round !== undefined ? !!options.round : true,
series: options.series || [],
center: RadialProgressChart.normalizeCenter(options.center)
};
var defaultColorsIterator = new RadialProgressChart.ColorsIterator();
for (var i = 0, length = _options.series.length; i < length; i++) {
var item = options.series[i];
// convert number to object
if (typeof item === 'number') {
item = { value: item };
}
_options.series[i] = {
index: i,
value: item.value,
labelStart: item.labelStart,
color: RadialProgressChart.normalizeColor(item.color, defaultColorsIterator)
};
}
return _options;
};
/**
* Normalize different notations of color property
*
* @param {String|Array|Object} color
* @example '#fe08b5'
* @example { solid: '#fe08b5', background: '#000000' }
* @example ['#000000', '#ff0000']
* @example {
linearGradient: { x1: '0%', y1: '100%', x2: '50%', y2: '0%'},
stops: [
{offset: '0%', 'stop-color': '#fe08b5', 'stop-opacity': 1},
{offset: '100%', 'stop-color': '#ff1410', 'stop-opacity': 1}
]
}
* @example {
radialGradient: {cx: '60', cy: '60', r: '50'},
stops: [
{offset: '0%', 'stop-color': '#fe08b5', 'stop-opacity': 1},
{offset: '100%', 'stop-color': '#ff1410', 'stop-opacity': 1}
]
}
*
*/
RadialProgressChart.normalizeColor = function (color, defaultColorsIterator) {
if (!color) {
color = { solid: defaultColorsIterator.next() };
} else if (typeof color === 'string') {
color = { solid: color };
} else if (Array.isArray(color)) {
color = { interpolate: color };
} else if (typeof color === 'object') {
if (!color.solid && !color.interpolate && !color.linearGradient && !color.radialGradient) {
color.solid = defaultColorsIterator.next();
}
}
// Validate interpolate syntax
if (color.interpolate) {
if (color.interpolate.length !== 2) {
throw new Error('interpolate array should contain two colors');
}
}
// Validate gradient syntax
if (color.linearGradient || color.radialGradient) {
if (!color.stops || !Array.isArray(color.stops) || color.stops.length !== 2) {
throw new Error('gradient syntax is malformed');
}
}
// Set background when is not provided
if (!color.background) {
if (color.solid) {
color.background = color.solid;
} else if (color.interpolate) {
color.background = color.interpolate[0];
} else if (color.linearGradient || color.radialGradient) {
color.background = color.stops[0]['stop-color'];
}
}
return color;
};
/**
* Normalize different notations of center property
*
* @param {String|Array|Function|Object} center
* @example 'foo bar'
* @example { content: 'foo bar', x: 10, y: 4 }
* @example function(value, index, item) {}
* @example ['foo bar', function(value, index, item) {}]
*/
RadialProgressChart.normalizeCenter = function (center) {
if (!center) return null;
// Convert to object notation
if (center.constructor !== Object) {
center = { content: center };
}
// Defaults
center.content = center.content || [];
center.x = center.x || 0;
center.y = center.y || 0;
// Convert content to array notation
if (!Array.isArray(center.content)) {
center.content = [center.content];
}
return center;
};
// Linear or Radial Gradient internal object
RadialProgressChart.Gradient = (function () {
function Gradient() {}
Gradient.toSVGElement = function (id, options) {
var gradientType = options.linearGradient ? 'linearGradient' : 'radialGradient';
var gradient = d3.select(document.createElementNS(d3.ns.prefix.svg, gradientType)).attr(options[gradientType]).attr('id', id);
options.stops.forEach(function (stopAttrs) {
gradient.append("svg:stop").attr(stopAttrs);
});
this.background = options.stops[0]['stop-color'];
return gradient.node();
};
return Gradient;
})();
// Default colors iterator
RadialProgressChart.ColorsIterator = (function () {
ColorsIterator.DEFAULT_COLORS = ["#1ad5de", "#a0ff03", "#e90b3a", '#ff9500', '#007aff', '#ffcc00', '#5856d6', '#8e8e93'];
function ColorsIterator() {
this.index = 0;
}
ColorsIterator.prototype.next = function () {
if (this.index === ColorsIterator.DEFAULT_COLORS.length) {
this.index = 0;
}
return ColorsIterator.DEFAULT_COLORS[this.index++];
};
return ColorsIterator;
})();
// Export RadialProgressChart object
if (true) module.exports = RadialProgressChart;
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict";!(function(){var d3={version:"3.5.17"};var d3_arraySlice=[].slice,d3_array=function d3_array(list){return d3_arraySlice.call(list);};var d3_document=this.document;function d3_documentElement(node){return node && (node.ownerDocument || node.document || node).documentElement;}function d3_window(node){return node && (node.ownerDocument && node.ownerDocument.defaultView || node.document && node || node.defaultView);}if(d3_document){try{d3_array(d3_document.documentElement.childNodes)[0].nodeType;}catch(e) {d3_array = function(list){var i=list.length,array=new Array(i);while(i--) array[i] = list[i];return array;};}}if(!Date.now)Date.now = function(){return +new Date();};if(d3_document){try{d3_document.createElement("DIV").style.setProperty("opacity",0,"");}catch(error) {var d3_element_prototype=this.Element.prototype,d3_element_setAttribute=d3_element_prototype.setAttribute,d3_element_setAttributeNS=d3_element_prototype.setAttributeNS,d3_style_prototype=this.CSSStyleDeclaration.prototype,d3_style_setProperty=d3_style_prototype.setProperty;d3_element_prototype.setAttribute = function(name,value){d3_element_setAttribute.call(this,name,value + "");};d3_element_prototype.setAttributeNS = function(space,local,value){d3_element_setAttributeNS.call(this,space,local,value + "");};d3_style_prototype.setProperty = function(name,value,priority){d3_style_setProperty.call(this,name,value + "",priority);};}}d3.ascending = d3_ascending;function d3_ascending(a,b){return a < b?-1:a > b?1:a >= b?0:NaN;}d3.descending = function(a,b){return b < a?-1:b > a?1:b >= a?0:NaN;};d3.min = function(array,f){var i=-1,n=array.length,a,b;if(arguments.length === 1){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.call(array,array[i],i)) != null && b >= b){a = b;break;}while(++i < n) if((b = f.call(array,array[i],i)) != null && a > b)a = b;}return a;};d3.max = function(array,f){var i=-1,n=array.length,a,b;if(arguments.length === 1){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.call(array,array[i],i)) != null && b >= b){a = b;break;}while(++i < n) if((b = f.call(array,array[i],i)) != null && b > a)a = b;}return a;};d3.extent = function(array,f){var i=-1,n=array.length,a,b,c;if(arguments.length === 1){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.call(array,array[i],i)) != null && b >= b){a = c = b;break;}while(++i < n) if((b = f.call(array,array[i],i)) != null){if(a > b)a = b;if(c < b)c = b;}}return [a,c];};function d3_number(x){return x === null?NaN:+x;}function d3_numeric(x){return !isNaN(x);}d3.sum = function(array,f){var s=0,n=array.length,a,i=-1;if(arguments.length === 1){while(++i < n) if(d3_numeric(a = +array[i]))s += a;}else {while(++i < n) if(d3_numeric(a = +f.call(array,array[i],i)))s += a;}return s;};d3.mean = function(array,f){var s=0,n=array.length,a,i=-1,j=n;if(arguments.length === 1){while(++i < n) if(d3_numeric(a = d3_number(array[i])))s += a;else --j;}else {while(++i < n) if(d3_numeric(a = d3_number(f.call(array,array[i],i))))s += a;else --j;}if(j)return s / j;};d3.quantile = function(values,p){var H=(values.length - 1) * p + 1,h=Math.floor(H),v=+values[h - 1],e=H - h;return e?v + e * (values[h] - v):v;};d3.median = function(array,f){var numbers=[],n=array.length,a,i=-1;if(arguments.length === 1){while(++i < n) if(d3_numeric(a = d3_number(array[i])))numbers.push(a);}else {while(++i < n) if(d3_numeric(a = d3_number(f.call(array,array[i],i))))numbers.push(a);}if(numbers.length)return d3.quantile(numbers.sort(d3_ascending),.5);};d3.variance = function(array,f){var n=array.length,m=0,a,d,s=0,i=-1,j=0;if(arguments.length === 1){while(++i < n) {if(d3_numeric(a = d3_number(array[i]))){d = a - m;m += d / ++j;s += d * (a - m);}}}else {while(++i < n) {if(d3_numeric(a = d3_number(f.call(array,array[i],i)))){d = a - m;m += d / ++j;s += d * (a - m);}}}if(j > 1)return s / (j - 1);};d3.deviation = function(){var v=d3.variance.apply(this,arguments);return v?Math.sqrt(v):v;};function d3_bisector(compare){return {left:function left(a,x,lo,hi){if(arguments.length < 3)lo = 0;if(arguments.length < 4)hi = a.length;while(lo < hi) {var mid=lo + hi >>> 1;if(compare(a[mid],x) < 0)lo = mid + 1;else hi = mid;}return lo;},right:function right(a,x,lo,hi){if(arguments.length < 3)lo = 0;if(arguments.length < 4)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;}};}var d3_bisect=d3_bisector(d3_ascending);d3.bisectLeft = d3_bisect.left;d3.bisect = d3.bisectRight = d3_bisect.right;d3.bisector = function(f){return d3_bisector(f.length === 1?function(d,x){return d3_ascending(f(d),x);}:f);};d3.shuffle = function(array,i0,i1){if((m = arguments.length) < 3){i1 = array.length;if(m < 2)i0 = 0;}var m=i1 - 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;};d3.permute = function(array,indexes){var i=indexes.length,permutes=new Array(i);while(i--) permutes[i] = array[indexes[i]];return permutes;};d3.pairs = function(array){var i=0,n=array.length - 1,p0,p1=array[0],pairs=new Array(n < 0?0:n);while(i < n) pairs[i] = [p0 = p1,p1 = array[++i]];return pairs;};d3.transpose = function(matrix){if(!(n = matrix.length))return [];for(var i=-1,m=d3.min(matrix,d3_transposeLength),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 d3_transposeLength(d){return d.length;}d3.zip = function(){return d3.transpose(arguments);};d3.keys = function(map){var keys=[];for(var key in map) keys.push(key);return keys;};d3.values = function(map){var values=[];for(var key in map) values.push(map[key]);return values;};d3.entries = function(map){var entries=[];for(var key in map) entries.push({key:key,value:map[key]});return entries;};d3.merge = function(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;};var abs=Math.abs;d3.range = function(start,stop,step){if(arguments.length < 3){step = 1;if(arguments.length < 2){stop = start;start = 0;}}if((stop - start) / step === Infinity)throw new Error("infinite range");var range=[],k=d3_range_integerScale(abs(step)),i=-1,j;start *= k,stop *= k,step *= k;if(step < 0)while((j = start + step * ++i) > stop) range.push(j / k);else while((j = start + step * ++i) < stop) range.push(j / k);return range;};function d3_range_integerScale(x){var k=1;while(x * k % 1) k *= 10;return k;}function d3_class(ctor,properties){for(var key in properties) {Object.defineProperty(ctor.prototype,key,{value:properties[key],enumerable:false});}}d3.map = function(object,f){var map=new d3_Map();if(object instanceof d3_Map){object.forEach(function(key,value){map.set(key,value);});}else if(Array.isArray(object)){var i=-1,n=object.length,o;if(arguments.length === 1)while(++i < n) map.set(i,object[i]);else while(++i < n) map.set(f.call(object,o = object[i],i),o);}else {for(var key in object) map.set(key,object[key]);}return map;};function d3_Map(){this._ = Object.create(null);}var d3_map_proto="__proto__",d3_map_zero="\x00";d3_class(d3_Map,{has:d3_map_has,get:function get(key){return this._[d3_map_escape(key)];},set:function set(key,value){return this._[d3_map_escape(key)] = value;},remove:d3_map_remove,keys:d3_map_keys,values:function values(){var values=[];for(var key in this._) values.push(this._[key]);return values;},entries:function entries(){var entries=[];for(var key in this._) entries.push({key:d3_map_unescape(key),value:this._[key]});return entries;},size:d3_map_size,empty:d3_map_empty,forEach:function forEach(f){for(var key in this._) f.call(this,d3_map_unescape(key),this._[key]);}});function d3_map_escape(key){return (key += "") === d3_map_proto || key[0] === d3_map_zero?d3_map_zero + key:key;}function d3_map_unescape(key){return (key += "")[0] === d3_map_zero?key.slice(1):key;}function d3_map_has(key){return d3_map_escape(key) in this._;}function d3_map_remove(key){return (key = d3_map_escape(key)) in this._ && delete this._[key];}function d3_map_keys(){var keys=[];for(var key in this._) keys.push(d3_map_unescape(key));return keys;}function d3_map_size(){var size=0;for(var key in this._) ++size;return size;}function d3_map_empty(){for(var key in this._) return false;return true;}d3.nest = function(){var nest={},keys=[],sortKeys=[],sortValues,rollup;function map(mapType,array,depth){if(depth >= keys.length)return rollup?rollup.call(nest,array):sortValues?array.sort(sortValues):array;var i=-1,n=array.length,key=keys[depth++],keyValue,object,setter,valuesByKey=new d3_Map(),values;while(++i < n) {if(values = valuesByKey.get(keyValue = key(object = array[i]))){values.push(object);}else {valuesByKey.set(keyValue,[object]);}}if(mapType){object = mapType();setter = function(keyValue,values){object.set(keyValue,map(mapType,values,depth));};}else {object = {};setter = function(keyValue,values){object[keyValue] = map(mapType,values,depth);};}valuesByKey.forEach(setter);return object;}function entries(map,depth){if(depth >= keys.length)return map;var array=[],sortKey=sortKeys[depth++];map.forEach(function(key,keyMap){array.push({key:key,values:entries(keyMap,depth)});});return sortKey?array.sort(function(a,b){return sortKey(a.key,b.key);}):array;}nest.map = function(array,mapType){return map(mapType,array,0);};nest.entries = function(array){return entries(map(d3.map,array,0),0);};nest.key = function(d){keys.push(d);return nest;};nest.sortKeys = function(order){sortKeys[keys.length - 1] = order;return nest;};nest.sortValues = function(order){sortValues = order;return nest;};nest.rollup = function(f){rollup = f;return nest;};return nest;};d3.set = function(array){var set=new d3_Set();if(array)for(var i=0,n=array.length;i < n;++i) set.add(array[i]);return set;};function d3_Set(){this._ = Object.create(null);}d3_class(d3_Set,{has:d3_map_has,add:function add(key){this._[d3_map_escape(key += "")] = true;return key;},remove:d3_map_remove,values:d3_map_keys,size:d3_map_size,empty:d3_map_empty,forEach:function forEach(f){for(var key in this._) f.call(this,d3_map_unescape(key));}});d3.behavior = {};function d3_identity(d){return d;}d3.rebind = function(target,source){var i=1,n=arguments.length,method;while(++i < n) target[method = arguments[i]] = d3_rebind(target,source,source[method]);return target;};function d3_rebind(target,source,method){return function(){var value=method.apply(source,arguments);return value === source?target:value;};}function d3_vendorSymbol(object,name){if(name in object)return name;name = name.charAt(0).toUpperCase() + name.slice(1);for(var i=0,n=d3_vendorPrefixes.length;i < n;++i) {var prefixName=d3_vendorPrefixes[i] + name;if(prefixName in object)return prefixName;}}var d3_vendorPrefixes=["webkit","ms","moz","Moz","o","O"];function d3_noop(){}d3.dispatch = function(){var dispatch=new d3_dispatch(),i=-1,n=arguments.length;while(++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);return dispatch;};function d3_dispatch(){}d3_dispatch.prototype.on = function(type,listener){var i=type.indexOf("."),name="";if(i >= 0){name = type.slice(i + 1);type = type.slice(0,i);}if(type)return arguments.length < 2?this[type].on(name):this[type].on(name,listener);if(arguments.length === 2){if(listener == null)for(type in this) {if(this.hasOwnProperty(type))this[type].on(name,null);}return this;}};function d3_dispatch_event(dispatch){var listeners=[],listenerByName=new d3_Map();function event(){var z=listeners,i=-1,n=z.length,l;while(++i < n) if(l = z[i].on)l.apply(this,arguments);return dispatch;}event.on = function(name,listener){var l=listenerByName.get(name),i;if(arguments.length < 2)return l && l.on;if(l){l.on = null;listeners = listeners.slice(0,i = listeners.indexOf(l)).concat(listeners.slice(i + 1));listenerByName.remove(name);}if(listener)listeners.push(listenerByName.set(name,{on:listener}));return dispatch;};return event;}d3.event = null;function d3_eventPreventDefault(){d3.event.preventDefault();}function d3_eventSource(){var e=d3.event,s;while(s = e.sourceEvent) e = s;return e;}function d3_eventDispatch(target){var dispatch=new d3_dispatch(),i=0,n=arguments.length;while(++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);dispatch.of = function(thiz,argumentz){return function(e1){try{var e0=e1.sourceEvent = d3.event;e1.target = target;d3.event = e1;dispatch[e1.type].apply(thiz,argumentz);}finally {d3.event = e0;}};};return dispatch;}d3.requote = function(s){return s.replace(d3_requote_re,"\\$&");};var d3_requote_re=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;var d3_subclass=({}).__proto__?function(object,prototype){object.__proto__ = prototype;}:function(object,prototype){for(var property in prototype) object[property] = prototype[property];};function d3_selection(groups){d3_subclass(groups,d3_selectionPrototype);return groups;}var d3_select=function d3_select(s,n){return n.querySelector(s);},d3_selectAll=function d3_selectAll(s,n){return n.querySelectorAll(s);},_d3_selectMatches=function d3_selectMatches(n,s){var d3_selectMatcher=n.matches || n[d3_vendorSymbol(n,"matchesSelector")];_d3_selectMatches = function(n,s){return d3_selectMatcher.call(n,s);};return _d3_selectMatches(n,s);};if(typeof Sizzle === "function"){d3_select = function(s,n){return Sizzle(s,n)[0] || null;};d3_selectAll = Sizzle;_d3_selectMatches = Sizzle.matchesSelector;}d3.selection = function(){return d3.select(d3_document.documentElement);};var d3_selectionPrototype=d3.selection.prototype = [];d3_selectionPrototype.select = function(selector){var subgroups=[],subgroup,subnode,group,node;selector = d3_selection_selector(selector);for(var j=-1,m=this.length;++j < m;) {subgroups.push(subgroup = []);subgroup.parentNode = (group = this[j]).parentNode;for(var i=-1,n=group.length;++i < n;) {if(node = group[i]){subgroup.push(subnode = selector.call(node,node.__data__,i,j));if(subnode && "__data__" in node)subnode.__data__ = node.__data__;}else {subgroup.push(null);}}}return d3_selection(subgroups);};function d3_selection_selector(selector){return typeof selector === "function"?selector:function(){return d3_select(selector,this);};}d3_selectionPrototype.selectAll = function(selector){var subgroups=[],subgroup,node;selector = d3_selection_selectorAll(selector);for(var j=-1,m=this.length;++j < m;) {for(var group=this[j],i=-1,n=group.length;++i < n;) {if(node = group[i]){subgroups.push(subgroup = d3_array(selector.call(node,node.__data__,i,j)));subgroup.parentNode = node;}}}return d3_selection(subgroups);};function d3_selection_selectorAll(selector){return typeof selector === "function"?selector:function(){return d3_selectAll(selector,this);};}var d3_nsXhtml="http://www.w3.org/1999/xhtml";var d3_nsPrefix={svg:"http://www.w3.org/2000/svg",xhtml:d3_nsXhtml,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns = {prefix:d3_nsPrefix,qualify:function qualify(name){var i=name.indexOf(":"),prefix=name;if(i >= 0 && (prefix = name.slice(0,i)) !== "xmlns")name = name.slice(i + 1);return d3_nsPrefix.hasOwnProperty(prefix)?{space:d3_nsPrefix[prefix],local:name}:name;}};d3_selectionPrototype.attr = function(name,value){if(arguments.length < 2){if(typeof name === "string"){var node=this.node();name = d3.ns.qualify(name);return name.local?node.getAttributeNS(name.space,name.local):node.getAttribute(name);}for(value in name) this.each(d3_selection_attr(value,name[value]));return this;}return this.each(d3_selection_attr(name,value));};function d3_selection_attr(name,value){name = d3.ns.qualify(name);function attrNull(){this.removeAttribute(name);}function attrNullNS(){this.removeAttributeNS(name.space,name.local);}function attrConstant(){this.setAttribute(name,value);}function attrConstantNS(){this.setAttributeNS(name.space,name.local,value);}function attrFunction(){var x=value.apply(this,arguments);if(x == null)this.removeAttribute(name);else this.setAttribute(name,x);}function attrFunctionNS(){var x=value.apply(this,arguments);if(x == null)this.removeAttributeNS(name.space,name.local);else this.setAttributeNS(name.space,name.local,x);}return value == null?name.local?attrNullNS:attrNull:typeof value === "function"?name.local?attrFunctionNS:attrFunction:name.local?attrConstantNS:attrConstant;}function d3_collapse(s){return s.trim().replace(/\s+/g," ");}d3_selectionPrototype.classed = function(name,value){if(arguments.length < 2){if(typeof name === "string"){var node=this.node(),n=(name = d3_selection_classes(name)).length,i=-1;if(value = node.classList){while(++i < n) if(!value.contains(name[i]))return false;}else {value = node.getAttribute("class");while(++i < n) if(!d3_selection_classedRe(name[i]).test(value))return false;}return true;}for(value in name) this.each(d3_selection_classed(value,name[value]));return this;}return this.each(d3_selection_classed(name,value));};function d3_selection_classedRe(name){return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)","g");}function d3_selection_classes(name){return (name + "").trim().split(/^|\s+/);}function d3_selection_classed(name,value){name = d3_selection_classes(name).map(d3_selection_classedName);var n=name.length;function classedConstant(){var i=-1;while(++i < n) name[i](this,value);}function classedFunction(){var i=-1,x=value.apply(this,arguments);while(++i < n) name[i](this,x);}return typeof value === "function"?classedFunction:classedConstant;}function d3_selection_classedName(name){var re=d3_selection_classedRe(name);return function(node,value){if(c = node.classList)return value?c.add(name):c.remove(name);var c=node.getAttribute("class") || "";if(value){re.lastIndex = 0;if(!re.test(c))node.setAttribute("class",d3_collapse(c + " " + name));}else {node.setAttribute("class",d3_collapse(c.replace(re," ")));}};}d3_selectionPrototype.style = function(name,value,priority){var n=arguments.length;if(n < 3){if(typeof name !== "string"){if(n < 2)value = "";for(priority in name) this.each(d3_selection_style(priority,name[priority],value));return this;}if(n < 2){var node=this.node();return d3_window(node).getComputedStyle(node,null).getPropertyValue(name);}priority = "";}return this.each(d3_selection_style(name,value,priority));};function d3_selection_style(name,value,priority){function styleNull(){this.style.removeProperty(name);}function styleConstant(){this.style.setProperty(name,value,priority);}function styleFunction(){var x=value.apply(this,arguments);if(x == null)this.style.removeProperty(name);else this.style.setProperty(name,x,priority);}return value == null?styleNull:typeof value === "function"?styleFunction:styleConstant;}d3_selectionPrototype.property = function(name,value){if(arguments.length < 2){if(typeof name === "string")return this.node()[name];for(value in name) this.each(d3_selection_property(value,name[value]));return this;}return this.each(d3_selection_property(name,value));};function d3_selection_property(name,value){function propertyNull(){delete this[name];}function propertyConstant(){this[name] = value;}function propertyFunction(){var x=value.apply(this,arguments);if(x == null)delete this[name];else this[name] = x;}return value == null?propertyNull:typeof value === "function"?propertyFunction:propertyConstant;}d3_selectionPrototype.text = function(value){return arguments.length?this.each(typeof value === "function"?function(){var v=value.apply(this,arguments);this.textContent = v == null?"":v;}:value == null?function(){this.textContent = "";}:function(){this.textContent = value;}):this.node().textContent;};d3_selectionPrototype.html = function(value){return arguments.length?this.each(typeof value === "function"?function(){var v=value.apply(this,arguments);this.innerHTML = v == null?"":v;}:value == null?function(){this.innerHTML = "";}:function(){this.innerHTML = value;}):this.node().innerHTML;};d3_selectionPrototype.append = function(name){name = d3_selection_creator(name);return this.select(function(){return this.appendChild(name.apply(this,arguments));});};function d3_selection_creator(name){function create(){var document=this.ownerDocument,namespace=this.namespaceURI;return namespace === d3_nsXhtml && document.documentElement.namespaceURI === d3_nsXhtml?document.createElement(name):document.createElementNS(namespace,name);}function createNS(){return this.ownerDocument.createElementNS(name.space,name.local);}return typeof name === "function"?name:(name = d3.ns.qualify(name)).local?createNS:create;}d3_selectionPrototype.insert = function(name,before){name = d3_selection_creator(name);before = d3_selection_selector(before);return this.select(function(){return this.insertBefore(name.apply(this,arguments),before.apply(this,arguments) || null);});};d3_selectionPrototype.remove = function(){return this.each(d3_selectionRemove);};function d3_selectionRemove(){var parent=this.parentNode;if(parent)parent.removeChild(this);}d3_selectionPrototype.data = function(value,key){var i=-1,n=this.length,group,node;if(!arguments.length){value = new Array(n = (group = this[0]).length);while(++i < n) {if(node = group[i]){value[i] = node.__data__;}}return value;}function bind(group,groupData){var i,n=group.length,m=groupData.length,n0=Math.min(n,m),updateNodes=new Array(m),enterNodes=new Array(m),exitNodes=new Array(n),node,nodeData;if(key){var nodeByKeyValue=new d3_Map(),keyValues=new Array(n),keyValue;for(i = -1;++i < n;) {if(node = group[i]){if(nodeByKeyValue.has(keyValue = key.call(node,node.__data__,i))){exitNodes[i] = node;}else {nodeByKeyValue.set(keyValue,node);}keyValues[i] = keyValue;}}for(i = -1;++i < m;) {if(!(node = nodeByKeyValue.get(keyValue = key.call(groupData,nodeData = groupData[i],i)))){enterNodes[i] = d3_selection_dataNode(nodeData);}else if(node !== true){updateNodes[i] = node;node.__data__ = nodeData;}nodeByKeyValue.set(keyValue,true);}for(i = -1;++i < n;) {if(i in keyValues && nodeByKeyValue.get(keyValues[i]) !== true){exitNodes[i] = group[i];}}}else {for(i = -1;++i < n0;) {node = group[i];nodeData = groupData[i];if(node){node.__data__ = nodeData;updateNodes[i] = node;}else {enterNodes[i] = d3_selection_dataNode(nodeData);}}for(;i < m;++i) {enterNodes[i] = d3_selection_dataNode(groupData[i]);}for(;i < n;++i) {exitNodes[i] = group[i];}}enterNodes.update = updateNodes;enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;enter.push(enterNodes);update.push(updateNodes);exit.push(exitNodes);}var enter=d3_selection_enter([]),update=d3_selection([]),exit=d3_selection([]);if(typeof value === "function"){while(++i < n) {bind(group = this[i],value.call(group,group.parentNode.__data__,i));}}else {while(++i < n) {bind(group = this[i],value);}}update.enter = function(){return enter;};update.exit = function(){return exit;};return update;};function d3_selection_dataNode(data){return {__data__:data};}d3_selectionPrototype.datum = function(value){return arguments.length?this.property("__data__",value):this.property("__data__");};d3_selectionPrototype.filter = function(filter){var subgroups=[],subgroup,group,node;if(typeof filter !== "function")filter = d3_selection_filter(filter);for(var j=0,m=this.length;j < m;j++) {subgroups.push(subgroup = []);subgroup.parentNode = (group = this[j]).parentNode;for(var i=0,n=group.length;i < n;i++) {if((node = group[i]) && filter.call(node,node.__data__,i,j)){subgroup.push(node);}}}return d3_selection(subgroups);};function d3_selection_filter(selector){return function(){return _d3_selectMatches(this,selector);};}d3_selectionPrototype.order = function(){for(var j=-1,m=this.length;++j < m;) {for(var group=this[j],i=group.length - 1,next=group[i],node;--i >= 0;) {if(node = group[i]){if(next && next !== node.nextSibling)next.parentNode.insertBefore(node,next);next = node;}}}return this;};d3_selectionPrototype.sort = function(comparator){comparator = d3_selection_sortComparator.apply(this,arguments);for(var j=-1,m=this.length;++j < m;) this[j].sort(comparator);return this.order();};function d3_selection_sortComparator(comparator){if(!arguments.length)comparator = d3_ascending;return function(a,b){return a && b?comparator(a.__data__,b.__data__):!a - !b;};}d3_selectionPrototype.each = function(callback){return d3_selection_each(this,function(node,i,j){callback.call(node,node.__data__,i,j);});};function d3_selection_each(groups,callback){for(var j=0,m=groups.length;j < m;j++) {for(var group=groups[j],i=0,n=group.length,node;i < n;i++) {if(node = group[i])callback(node,i,j);}}return groups;}d3_selectionPrototype.call = function(callback){var args=d3_array(arguments);callback.apply(args[0] = this,args);return this;};d3_selectionPrototype.empty = function(){return !this.node();};d3_selectionPrototype.node = function(){for(var j=0,m=this.length;j < m;j++) {for(var group=this[j],i=0,n=group.length;i < n;i++) {var node=group[i];if(node)return node;}}return null;};d3_selectionPrototype.size = function(){var n=0;d3_selection_each(this,function(){++n;});return n;};function d3_selection_enter(selection){d3_subclass(selection,d3_selection_enterPrototype);return selection;}var d3_selection_enterPrototype=[];d3.selection.enter = d3_selection_enter;d3.selection.enter.prototype = d3_selection_enterPrototype;d3_selection_enterPrototype.append = d3_selectionPrototype.append;d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;d3_selection_enterPrototype.node = d3_selectionPrototype.node;d3_selection_enterPrototype.call = d3_selectionPrototype.call;d3_selection_enterPrototype.size = d3_selectionPrototype.size;d3_selection_enterPrototype.select = function(selector){var subgroups=[],subgroup,subnode,upgroup,group,node;for(var j=-1,m=this.length;++j < m;) {upgroup = (group = this[j]).update;subgroups.push(subgroup = []);subgroup.parentNode = group.parentNode;for(var i=-1,n=group.length;++i < n;) {if(node = group[i]){subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode,node.__data__,i,j));subnode.__data__ = node.__data__;}else {subgroup.push(null);}}}return d3_selection(subgroups);};d3_selection_enterPrototype.insert = function(name,before){if(arguments.length < 2)before = d3_selection_enterInsertBefore(this);return d3_selectionPrototype.insert.call(this,name,before);};function d3_selection_enterInsertBefore(enter){var i0,j0;return function(d,i,j){var group=enter[j].update,n=group.length,node;if(j != j0)j0 = j,i0 = 0;if(i >= i0)i0 = i + 1;while(!(node = group[i0]) && ++i0 < n);return node;};}d3.select = function(node){var group;if(typeof node === "string"){group = [d3_select(node,d3_document)];group.parentNode = d3_document.documentElement;}else {group = [node];group.parentNode = d3_documentElement(node);}return d3_selection([group]);};d3.selectAll = function(nodes){var group;if(typeof nodes === "string"){group = d3_array(d3_selectAll(nodes,d3_document));group.parentNode = d3_document.documentElement;}else {group = d3_array(nodes);group.parentNode = null;}return d3_selection([group]);};d3_selectionPrototype.on = function(type,listener,capture){var n=arguments.length;if(n < 3){if(typeof type !== "string"){if(n < 2)listener = false;for(capture in type) this.each(d3_selection_on(capture,type[capture],listener));return this;}if(n < 2)return (n = this.node()["__on" + type]) && n._;capture = false;}return this.each(d3_selection_on(type,listener,capture));};function d3_selection_on(type,listener,capture){var name="__on" + type,i=type.indexOf("."),wrap=d3_selection_onListener;if(i > 0)type = type.slice(0,i);var filter=d3_selection_onFilters.get(type);if(filter)type = filter,wrap = d3_selection_onFilter;function onRemove(){var l=this[name];if(l){this.removeEventListener(type,l,l.$);delete this[name];}}function onAdd(){var l=wrap(listener,d3_array(arguments));onRemove.call(this);this.addEventListener(type,this[name] = l,l.$ = capture);l._ = listener;}function removeAll(){var re=new RegExp("^__on([^.]+)" + d3.requote(type) + "$"),match;for(var name in this) {if(match = name.match(re)){var l=this[name];this.removeEventListener(match[1],l,l.$);delete this[name];}}}return i?listener?onAdd:onRemove:listener?d3_noop:removeAll;}var d3_selection_onFilters=d3.map({mouseenter:"mouseover",mouseleave:"mouseout"});if(d3_document){d3_selection_onFilters.forEach(function(k){if("on" + k in d3_document)d3_selection_onFilters.remove(k);});}function d3_selection_onListener(listener,argumentz){return function(e){var o=d3.event;d3.event = e;argumentz[0] = this.__data__;try{listener.apply(this,argumentz);}finally {d3.event = o;}};}function d3_selection_onFilter(listener,argumentz){var l=d3_selection_onListener(listener,argumentz);return function(e){var target=this,related=e.relatedTarget;if(!related || related !== target && !(related.compareDocumentPosition(target) & 8)){l.call(target,e);}};}var d3_event_dragSelect,d3_event_dragId=0;function d3_event_dragSuppress(node){var name=".dragsuppress-" + ++d3_event_dragId,click="click" + name,w=d3.select(d3_window(node)).on("touchmove" + name,d3_eventPreventDefault).on("dragstart" + name,d3_eventPreventDefault).on("selectstart" + name,d3_eventPreventDefault);if(d3_event_dragSelect == null){d3_event_dragSelect = "onselectstart" in node?false:d3_vendorSymbol(node.style,"userSelect");}if(d3_event_dragSelect){var style=d3_documentElement(node).style,select=style[d3_event_dragSelect];style[d3_event_dragSelect] = "none";}return function(suppressClick){w.on(name,null);if(d3_event_dragSelect)style[d3_event_dragSelect] = select;if(suppressClick){var off=function off(){w.on(click,null);};w.on(click,function(){d3_eventPreventDefault();off();},true);setTimeout(off,0);}};}d3.mouse = function(container){return d3_mousePoint(container,d3_eventSource());};var d3_mouse_bug44083=this.navigator && /WebKit/.test(this.navigator.userAgent)?-1:0;function d3_mousePoint(container,e){if(e.changedTouches)e = e.changedTouches[0];var svg=container.ownerSVGElement || container;if(svg.createSVGPoint){var point=svg.createSVGPoint();if(d3_mouse_bug44083 < 0){var window=d3_window(container);if(window.scrollX || window.scrollY){svg = d3.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var ctm=svg[0][0].getScreenCTM();d3_mouse_bug44083 = !(ctm.f || ctm.e);svg.remove();}}if(d3_mouse_bug44083)point.x = e.pageX,point.y = e.pageY;else point.x = e.clientX,point.y = e.clientY;point = point.matrixTransform(container.getScreenCTM().inverse());return [point.x,point.y];}var rect=container.getBoundingClientRect();return [e.clientX - rect.left - container.clientLeft,e.clientY - rect.top - container.clientTop];}d3.touch = function(container,touches,identifier){if(arguments.length < 3)identifier = touches,touches = d3_eventSource().changedTouches;if(touches)for(var i=0,n=touches.length,touch;i < n;++i) {if((touch = touches[i]).identifier === identifier){return d3_mousePoint(container,touch);}}};d3.behavior.drag = function(){var event=d3_eventDispatch(drag,"drag","dragstart","dragend"),origin=null,mousedown=dragstart(d3_noop,d3.mouse,d3_window,"mousemove","mouseup"),touchstart=dragstart(d3_behavior_dragTouchId,d3.touch,d3_identity,"touchmove","touchend");function drag(){this.on("mousedown.drag",mousedown).on("touchstart.drag",touchstart);}function dragstart(id,position,subject,move,end){return function(){var that=this,target=d3.event.target.correspondingElement || d3.event.target,parent=that.parentNode,dispatch=event.of(that,arguments),dragged=0,dragId=id(),dragName=".drag" + (dragId == null?"":"-" + dragId),dragOffset,dragSubject=d3.select(subject(target)).on(move + dragName,moved).on(end + dragName,ended),dragRestore=d3_event_dragSuppress(target),position0=position(parent,dragId);if(origin){dragOffset = origin.apply(that,arguments);dragOffset = [dragOffset.x - position0[0],dragOffset.y - position0[1]];}else {dragOffset = [0,0];}dispatch({type:"dragstart"});function moved(){var position1=position(parent,dragId),dx,dy;if(!position1)return;dx = position1[0] - position0[0];dy = position1[1] - position0[1];dragged |= dx | dy;position0 = position1;dispatch({type:"drag",x:position1[0] + dragOffset[0],y:position1[1] + dragOffset[1],dx:dx,dy:dy});}function ended(){if(!position(parent,dragId))return;dragSubject.on(move + dragName,null).on(end + dragName,null);dragRestore(dragged);dispatch({type:"dragend"});}};}drag.origin = function(x){if(!arguments.length)return origin;origin = x;return drag;};return d3.rebind(drag,event,"on");};function d3_behavior_dragTouchId(){return d3.event.changedTouches[0].identifier;}d3.touches = function(container,touches){if(arguments.length < 2)touches = d3_eventSource().touches;return touches?d3_array(touches).map(function(touch){var point=d3_mousePoint(container,touch);point.identifier = touch.identifier;return point;}):[];};var ε=1e-6,ε2=ε * ε,π=Math.PI,τ=2 * π,τε=τ - ε,halfπ=π / 2,d3_radians=π / 180,d3_degrees=180 / π;function d3_sgn(x){return x > 0?1:x < 0?-1:0;}function d3_cross2d(a,b,c){return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);}function d3_acos(x){return x > 1?0:x < -1?π:Math.acos(x);}function d3_asin(x){return x > 1?halfπ:x < -1?-halfπ:Math.asin(x);}function d3_sinh(x){return ((x = Math.exp(x)) - 1 / x) / 2;}function d3_cosh(x){return ((x = Math.exp(x)) + 1 / x) / 2;}function d3_tanh(x){return ((x = Math.exp(2 * x)) - 1) / (x + 1);}function d3_haversin(x){return (x = Math.sin(x / 2)) * x;}var ρ=Math.SQRT2,ρ2=2,ρ4=4;d3.interpolateZoom = 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;if(d2 < ε2){S = Math.log(w1 / w0) / ρ;i = function(t){return [ux0 + t * dx,uy0 + t * dy,w0 * Math.exp(ρ * t * S)];};}else {var d1=Math.sqrt(d2),b0=(w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1),b1=(w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1),r0=Math.log(Math.sqrt(b0 * b0 + 1) - b0),r1=Math.log(Math.sqrt(b1 * b1 + 1) - b1);S = (r1 - r0) / ρ;i = function(t){var s=t * S,coshr0=d3_cosh(r0),u=w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));return [ux0 + u * dx,uy0 + u * dy,w0 * coshr0 / d3_cosh(ρ * s + r0)];};}i.duration = S * 1e3;return i