Comparing version 0.0.3 to 0.1.0
@@ -1,1 +0,1 @@ | ||
var version = "0.0.3"; export * from "../index"; export {version}; | ||
var version = "0.1.0"; export * from "../index"; export {version}; |
@@ -101,9 +101,9 @@ (function (global, factory) { | ||
function arc(d, i) { | ||
function arc() { | ||
var buffer, | ||
r, | ||
r0 = +innerRadius(d, i), | ||
r1 = +outerRadius(d, i), | ||
a0 = startAngle(d, i) - piHalf, | ||
a1 = endAngle(d, i) - piHalf, | ||
r0 = +innerRadius.apply(this, arguments), | ||
r1 = +outerRadius.apply(this, arguments), | ||
a0 = startAngle.apply(this, arguments) - piHalf, | ||
a1 = endAngle.apply(this, arguments) - piHalf, | ||
da = Math.abs(a1 - a0), | ||
@@ -138,5 +138,5 @@ cw = a1 > a0; | ||
da1 = da, | ||
ap = padAngle(d, i) / 2, | ||
rp = (ap > 0) && (padRadius ? +padRadius(d, i) : Math.sqrt(r0 * r0 + r1 * r1)), | ||
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius(d, i)), | ||
ap = padAngle.apply(this, arguments) / 2, | ||
rp = (ap > 0) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)), | ||
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), | ||
rc0 = rc, | ||
@@ -236,5 +236,5 @@ rc1 = rc; | ||
arc.centroid = function(d, i) { | ||
var r = (+innerRadius(d, i) + +outerRadius(d, i)) / 2, | ||
a = (+startAngle(d, i) + +endAngle(d, i)) / 2 - Math.PI / 2; | ||
arc.centroid = function() { | ||
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, | ||
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; | ||
return [Math.cos(a) * r, Math.sin(a) * r]; | ||
@@ -278,2 +278,13 @@ }; | ||
var slice = Array.prototype.slice; | ||
function curveBind(interpolate, args) { | ||
args = slice.call(args); | ||
args[0] = null; | ||
return function(context) { | ||
args[0] = context; | ||
return interpolate.apply(null, args); | ||
}; | ||
}; | ||
function linear(context) { | ||
@@ -311,13 +322,2 @@ return new Linear(context); | ||
var slice = Array.prototype.slice; | ||
function curveCurry(interpolate, args) { | ||
args = slice.call(args); | ||
args[0] = null; | ||
return function(context) { | ||
args[0] = context; | ||
return interpolate.apply(null, args); | ||
}; | ||
}; | ||
function x(p) { | ||
@@ -355,3 +355,3 @@ return p[0]; | ||
for (i = 0; i <= n; ++i) { | ||
if (!(i < n && defined(d = data[i], i)) === defined0) { | ||
if (!(i < n && defined(d = data[i], i, data)) === defined0) { | ||
if (defined0 = !defined0) { | ||
@@ -372,4 +372,4 @@ j = i; | ||
if (defined0) { | ||
x0z[i] = +x0(d, i), y0z[i] = +y0(d, i); | ||
output.point(x1 ? +x1(d, i) : x0z[i], y1 ? +y1(d, i) : y0z[i]); | ||
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); | ||
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); | ||
} | ||
@@ -411,3 +411,3 @@ } | ||
var n = arguments.length; | ||
return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), area) : curve; | ||
return n ? (curve = n > 1 ? curveBind(_, arguments) : _, context != null && (output = curve(context)), area) : curve; | ||
}; | ||
@@ -561,4 +561,4 @@ | ||
function bundle(context, beta) { | ||
return beta == null || (beta = +beta) === 1 | ||
? basis(context) | ||
return beta == null ? new Bundle(context, 0.85) | ||
: (beta = +beta) === 1 ? basis(context) | ||
: new Bundle(context, beta); | ||
@@ -775,5 +775,5 @@ } | ||
function catmullRom(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinal(context, 0) | ||
: new CatmullRom(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRom(context, alpha) | ||
: cardinal(context, 0); | ||
} | ||
@@ -832,5 +832,5 @@ | ||
function catmullRomClosed(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinalClosed(context, 0) | ||
: new CatmullRomClosed(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRomClosed(context, alpha) | ||
: cardinalClosed(context, 0); | ||
} | ||
@@ -895,5 +895,5 @@ | ||
function catmullRomOpen(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinalOpen(context, 0) | ||
: new CatmullRomOpen(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRomOpen(context, alpha) | ||
: cardinalOpen(context, 0); | ||
} | ||
@@ -1029,7 +1029,7 @@ | ||
for (i = 0; i <= n; ++i) { | ||
if (!(i < n && defined(d = data[i], i)) === defined0) { | ||
if (!(i < n && defined(d = data[i], i, data)) === defined0) { | ||
if (defined0 = !defined0) output.lineStart(); | ||
else output.lineEnd(); | ||
} | ||
if (defined0) output.point(+x$$(d, i), +y$$(d, i)); | ||
if (defined0) output.point(+x$$(d, i, data), +y$$(d, i, data)); | ||
} | ||
@@ -1054,3 +1054,3 @@ | ||
var n = arguments.length; | ||
return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), line) : curve; | ||
return n ? (curve = n > 1 ? curveBind(_, arguments) : _, context != null && (output = curve(context)), line) : curve; | ||
}; | ||
@@ -1065,2 +1065,84 @@ | ||
function sign(x) { | ||
return x < 0 ? -1 : 1; | ||
} | ||
// Calculate the slopes of the tangents (Hermite-type interpolation) based on | ||
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic | ||
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. | ||
// NOV(II), P. 443, 1990. | ||
function slope3(that, x2, y2) { | ||
var h0 = that._x1 - that._x0, | ||
h1 = x2 - that._x1, | ||
s0 = (that._y1 - that._y0) / h0, | ||
s1 = (y2 - that._y1) / h1, | ||
p = (s0 * h1 + s1 * h0) / (h0 + h1); | ||
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; | ||
} | ||
// Calculate a one-sided slope. | ||
function slope2(that, t) { | ||
var h = that._x1 - that._x0; | ||
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; | ||
} | ||
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations | ||
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves | ||
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". | ||
function point$3(that, t0, t1) { | ||
var x0 = that._x0, | ||
y0 = that._y0, | ||
x1 = that._x1, | ||
y1 = that._y1, | ||
dx = (x1 - x0) / 3; | ||
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); | ||
} | ||
function monotone(context) { | ||
return new Monotone(context); | ||
} | ||
function Monotone(context) { | ||
this._context = context; | ||
} | ||
Monotone.prototype = { | ||
areaStart: function() { | ||
this._line = 0; | ||
}, | ||
areaEnd: function() { | ||
this._line = NaN; | ||
}, | ||
lineStart: function() { | ||
this._x0 = this._x1 = | ||
this._y0 = this._y1 = | ||
this._t0 = NaN; | ||
this._point = 0; | ||
}, | ||
lineEnd: function() { | ||
switch (this._point) { | ||
case 2: this._context.lineTo(this._x1, this._y1); break; | ||
case 3: point$3(this, this._t0, slope2(this, this._t0)); break; | ||
} | ||
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); | ||
this._line = 1 - this._line; | ||
}, | ||
point: function(x, y) { | ||
var t1 = NaN; | ||
x = +x, y = +y; | ||
if (x === this._x1 && y === this._y1) return; // Ignore coincident points. | ||
switch (this._point) { | ||
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; | ||
case 1: this._point = 2; break; | ||
case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break; | ||
default: point$3(this, this._t0, t1 = slope3(this, x, y)); break; | ||
} | ||
this._x0 = this._x1, this._x1 = x; | ||
this._y0 = this._y1, this._y1 = y; | ||
this._t0 = t1; | ||
} | ||
} | ||
function natural(context) { | ||
@@ -1132,2 +1214,82 @@ return new Natural(context); | ||
var tau$1 = 2 * Math.PI; | ||
function identity(d) { | ||
return d; | ||
} | ||
function descending(a, b) { | ||
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; | ||
} | ||
function pie() { | ||
var value = identity, | ||
sortValues = descending, | ||
sort = null, | ||
startAngle = constant(0), | ||
endAngle = constant(tau$1), | ||
padAngle = constant(0); | ||
function pie(data) { | ||
var n = data.length, | ||
sum = 0, | ||
index = new Array(n), | ||
arcs = new Array(n), | ||
a0 = +startAngle.apply(this, arguments), | ||
da = Math.min(tau$1, Math.max(-tau$1, endAngle.apply(this, arguments) - a0)), | ||
a1, | ||
p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)), | ||
pa = p * (da < 0 ? -1 : 1); | ||
for (var i = 0, v; i < n; ++i) { | ||
if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) { | ||
sum += v; | ||
} | ||
} | ||
// Optionally sort the arcs by previously-computed values or by data. | ||
if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); }); | ||
else if (sort !== null) index.sort(function(i, j) { return sort(data[i], data[j]); }); | ||
// Compute the arcs! They are stored in the original data's order. | ||
for (var i = 0, j, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) { | ||
j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = { | ||
data: data[j], | ||
value: v, | ||
startAngle: a0, | ||
endAngle: a1, | ||
padAngle: p | ||
}; | ||
} | ||
return arcs; | ||
} | ||
pie.value = function(_) { | ||
return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value; | ||
}; | ||
pie.sortValues = function(_) { | ||
return arguments.length ? (sortValues = _, sort = null, pie) : sortValues; | ||
}; | ||
pie.sort = function(_) { | ||
return arguments.length ? (sort = _, sortValues = null, pie) : sort; | ||
}; | ||
pie.startAngle = function(_) { | ||
return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle; | ||
}; | ||
pie.endAngle = function(_) { | ||
return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle; | ||
}; | ||
pie.padAngle = function(_) { | ||
return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle; | ||
}; | ||
return pie; | ||
}; | ||
var square = { | ||
@@ -1295,6 +1457,6 @@ draw: function(context, size) { | ||
function symbol(d, i) { | ||
function symbol() { | ||
var buffer; | ||
if (!context) context = buffer = d3Path.path(); | ||
type(d, i).draw(context, +size(d, i)); | ||
type.apply(this, arguments).draw(context, +size.apply(this, arguments)); | ||
if (buffer) return context = null, buffer + "" || null; | ||
@@ -1318,3 +1480,3 @@ } | ||
var version = "0.0.3"; | ||
var version = "0.1.0"; | ||
@@ -1340,3 +1502,5 @@ exports.version = version; | ||
exports.line = line; | ||
exports.monotone = monotone; | ||
exports.natural = natural; | ||
exports.pie = pie; | ||
exports.square = square; | ||
@@ -1343,0 +1507,0 @@ exports.stepAfter = stepAfter; |
@@ -1,1 +0,1 @@ | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("d3-path")):"function"==typeof define&&define.amd?define("d3-shape",["exports","d3-path"],i):i(t.d3_shape={},t.d3_path)}(this,function(t,i){"use strict";function n(t){return function(){return t}}function s(t){return t.innerRadius}function h(t){return t.outerRadius}function _(t){return t.startAngle}function e(t){return t.endAngle}function o(t){return t&&t.padAngle}function a(t){return t>=1?it:-1>=t?-it:Math.asin(t)}function l(t,i,n,s,h,_,e,o){var a=n-t,l=s-i,c=e-h,r=o-_,u=(c*(i-_)-r*(t-h))/(r*a-c*l);return[t+u*a,i+u*l]}function c(t,i,n,s,h,_,e){var o=t-n,a=i-s,l=(e?_:-_)/Math.sqrt(o*o+a*a),c=l*a,r=-l*o,u=t+c,x=i+r,f=n+c,y=s+r,p=(u+f)/2,d=(x+y)/2,v=f-u,T=y-x,m=v*v+T*T,g=h-_,M=u*y-f*x,b=(0>T?-1:1)*Math.sqrt(Math.max(0,g*g*m-M*M)),w=(M*T-v*b)/m,N=(-M*v-T*b)/m,k=(M*T+v*b)/m,E=(-M*v+T*b)/m,S=w-p,P=N-d,q=k-p,A=E-d;return S*S+P*P>q*q+A*A&&(w=k,N=E),{cx:w,cy:N,x01:-c,y01:-r,x11:w*(h/g-1),y11:N*(h/g-1)}}function r(){function t(t,n){var s,h,_=+r(t,n),e=+u(t,n),o=y(t,n)-it,T=p(t,n)-it,m=Math.abs(T-o),g=T>o;if(v||(v=s=i.path()),_>e&&(h=e,e=_,_=h),e>0)if(m>=nt)v.moveTo(e*Math.cos(o),e*Math.sin(o)),v.arc(0,0,e,o,T,!g),_>0&&(v.moveTo(_*Math.cos(T),_*Math.sin(T)),v.arc(0,0,_,T,o,g));else{var M=o,b=T,w=o,N=T,k=m,E=m,S=d(t,n)/2,P=S>0&&(f?+f(t,n):Math.sqrt(_*_+e*e)),q=Math.min(Math.abs(e-_)/2,+x(t,n)),A=q,R=q;if(P>0){var C=a(P/_*Math.sin(S)),z=a(P/e*Math.sin(S));(k-=2*C)>0?(C*=g?1:-1,w+=C,N-=C):(k=0,w=N=(o+T)/2),(E-=2*z)>0?(z*=g?1:-1,M+=z,b-=z):(E=0,M=b=(o+T)/2)}var I=e*Math.cos(M),O=e*Math.sin(M),j=_*Math.cos(N),B=_*Math.sin(N);if(q>0){var D=e*Math.cos(b),U=e*Math.sin(b),F=_*Math.cos(w),G=_*Math.sin(w);if(tt>m){var H=k>0?l(I,O,F,G,D,U,j,B):[j,B],J=I-H[0],K=O-H[1],L=D-H[0],Q=U-H[1],V=1/Math.sin(Math.acos((J*L+K*Q)/(Math.sqrt(J*J+K*K)*Math.sqrt(L*L+Q*Q)))/2),W=Math.sqrt(H[0]*H[0]+H[1]*H[1]);A=Math.min(q,(_-W)/(V-1)),R=Math.min(q,(e-W)/(V+1))}}if(E>0)if(R>0){var X=c(F,G,I,O,e,R,g),Y=c(D,U,j,B,e,R,g);v.moveTo(X.cx+X.x01,X.cy+X.y01),q>R?v.arc(X.cx,X.cy,R,Math.atan2(X.y01,X.x01),Math.atan2(Y.y01,Y.x01),!g):(v.arc(X.cx,X.cy,R,Math.atan2(X.y01,X.x01),Math.atan2(X.y11,X.x11),!g),v.arc(0,0,e,Math.atan2(X.cy+X.y11,X.cx+X.x11),Math.atan2(Y.cy+Y.y11,Y.cx+Y.x11),!g),v.arc(Y.cx,Y.cy,R,Math.atan2(Y.y11,Y.x11),Math.atan2(Y.y01,Y.x01),!g))}else v.moveTo(I,O),v.arc(0,0,e,M,b,!g);else v.moveTo(I,O);if(_>0&&k>0)if(A>0){var X=c(j,B,D,U,_,-A,g),Y=c(I,O,F,G,_,-A,g);v.lineTo(X.cx+X.x01,X.cy+X.y01),q>A?v.arc(X.cx,X.cy,A,Math.atan2(X.y01,X.x01),Math.atan2(Y.y01,Y.x01),!g):(v.arc(X.cx,X.cy,A,Math.atan2(X.y01,X.x01),Math.atan2(X.y11,X.x11),!g),v.arc(0,0,_,Math.atan2(X.cy+X.y11,X.cx+X.x11),Math.atan2(Y.cy+Y.y11,Y.cx+Y.x11),g),v.arc(Y.cx,Y.cy,A,Math.atan2(Y.y11,Y.x11),Math.atan2(Y.y01,Y.x01),!g))}else v.arc(0,0,_,N,w,g);else v.lineTo(j,B)}else v.moveTo(0,0);return v.closePath(),s?(v=null,s+""||null):void 0}var r=s,u=h,x=n(0),f=null,y=_,p=e,d=o,v=null,T=null;return t.centroid=function(t,i){var n=(+r(t,i)+ +u(t,i))/2,s=(+y(t,i)+ +p(t,i))/2-Math.PI/2;return[Math.cos(s)*n,Math.sin(s)*n]},t.innerRadius=function(i){return arguments.length?(r="function"==typeof i?i:n(+i),t):r},t.outerRadius=function(i){return arguments.length?(u="function"==typeof i?i:n(+i),t):u},t.cornerRadius=function(i){return arguments.length?(x="function"==typeof i?i:n(+i),t):x},t.padRadius=function(i){return arguments.length?(f=null==i?null:"function"==typeof i?i:n(+i),t):f},t.startAngle=function(i){return arguments.length?(y="function"==typeof i?i:n(+i),t):y},t.endAngle=function(i){return arguments.length?(p="function"==typeof i?i:n(+i),t):p},t.padAngle=function(i){return arguments.length?(d="function"==typeof i?i:n(+i),t):d},t.context=function(i){return arguments.length?(v=T=null==i?null:i,t):v},t}function u(t){return new x(t)}function x(t){this._context=t}function f(t,i){return i=st.call(i),i[0]=null,function(n){return i[0]=n,t.apply(null,i)}}function y(t){return t[0]}function p(t){return t[1]}function d(){function t(t){var n,r,u,x,f,y=t.length,p=!1,d=new Array(y),v=new Array(y);for(a||(c=l(f=i.path())),n=0;y>=n;++n){if(!(y>n&&o(x=t[n],n))===p)if(p=!p)r=n,c.areaStart(),c.lineStart();else{for(c.lineEnd(),c.lineStart(),u=n-1;u>=r;--u)c.point(d[u],v[u]);c.lineEnd(),c.areaEnd()}p&&(d[n]=+s(x,n),v[n]=+_(x,n),c.point(h?+h(x,n):d[n],e?+e(x,n):v[n]))}return f?(c=null,f+""||null):void 0}var s=y,h=null,_=n(0),e=p,o=n(!0),a=null,l=u,c=null;return t.x=function(i){return arguments.length?t.x0(i).x1(null):s},t.x0=function(i){return arguments.length?(s="function"==typeof i?i:n(+i),t):s},t.x1=function(i){return arguments.length?(h=null==i?null:"function"==typeof i?i:n(+i),t):h},t.y=function(i){return arguments.length?t.y0(i).y1(null):_},t.y0=function(i){return arguments.length?(_="function"==typeof i?i:n(+i),t):_},t.y1=function(i){return arguments.length?(e=null==i?null:"function"==typeof i?i:n(+i),t):e},t.defined=function(i){return arguments.length?(o="function"==typeof i?i:n(!!i),t):o},t.curve=function(i){var n=arguments.length;return n?(l=n>1?f(i,arguments):i,null!=a&&(c=l(a)),t):l},t.context=function(i){return arguments.length?(null==i?a=c=null:c=l(a=i),t):a},t}function v(t,i,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+i)/6,(t._y0+4*t._y1+n)/6)}function T(t){return new m(t)}function m(t){this._context=t}function g(t){return new M(t)}function M(t){this._context=t}function b(t){return new w(t)}function w(t){this._context=t}function N(t,i){return null==i||1===(i=+i)?T(t):new k(t,i)}function k(t,i){this._basis=T(t),this._beta=i}function E(t,i,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-i),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function S(t,i){return new P(t,(null==i?1:1-i)/6)}function P(t,i){this._context=t,this._k=i}function q(t,i){return new A(t,(null==i?1:1-i)/6)}function A(t,i){this._context=t,this._k=i}function R(t,i){return new C(t,(null==i?1:1-i)/6)}function C(t,i){this._context=t,this._k=i}function z(t,i,n){var s=t._x1,h=t._y1,_=t._x2,e=t._y2;if(t._l01_a>ht){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,a=3*t._l01_a*(t._l01_a+t._l12_a);s=(s*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/a,h=(h*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/a}if(t._l23_a>ht){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,c=3*t._l23_a*(t._l23_a+t._l12_a);_=(_*l+t._x1*t._l23_2a-i*t._l12_2a)/c,e=(e*l+t._y1*t._l23_2a-n*t._l12_2a)/c}t._context.bezierCurveTo(s,h,_,e,t._x2,t._y2)}function I(t,i){return null!=i&&(i=+i)?new O(t,i):S(t,0)}function O(t,i){this._context=t,this._alpha=i}function j(t,i){return null!=i&&(i=+i)?new B(t,i):q(t,0)}function B(t,i){this._context=t,this._alpha=i}function D(t,i){return null!=i&&(i=+i)?new U(t,i):R(t,0)}function U(t,i){this._context=t,this._alpha=i}function F(t){return new G(t)}function G(t){this._context=t}function H(){function t(t){var n,l,c,r=t.length,u=!1;for(e||(a=o(c=i.path())),n=0;r>=n;++n)!(r>n&&_(l=t[n],n))===u&&((u=!u)?a.lineStart():a.lineEnd()),u&&a.point(+s(l,n),+h(l,n));return c?(a=null,c+""||null):void 0}var s=y,h=p,_=n(!0),e=null,o=u,a=null;return t.x=function(i){return arguments.length?(s="function"==typeof i?i:n(+i),t):s},t.y=function(i){return arguments.length?(h="function"==typeof i?i:n(+i),t):h},t.defined=function(i){return arguments.length?(_="function"==typeof i?i:n(!!i),t):_},t.curve=function(i){var n=arguments.length;return n?(o=n>1?f(i,arguments):i,null!=e&&(a=o(e)),t):o},t.context=function(i){return arguments.length?(null==i?e=a=null:a=o(e=i),t):e},t}function J(t){return new K(t)}function K(t){this._context=t}function L(t){var i,n,s=t.length-1,h=new Array(s),_=new Array(s),e=new Array(s);for(h[0]=0,_[0]=2,e[0]=t[0]+2*t[1],i=1;s-1>i;++i)h[i]=1,_[i]=4,e[i]=4*t[i]+2*t[i+1];for(h[s-1]=2,_[s-1]=7,e[s-1]=8*t[s-1]+t[s],i=1;s>i;++i)n=h[i]/_[i-1],_[i]-=n,e[i]-=n*e[i-1];for(h[s-1]=e[s-1]/_[s-1],i=s-2;i>=0;--i)h[i]=(e[i]-h[i+1])/_[i];for(_[s-1]=(t[s]+h[s-1])/2,i=0;s-1>i;++i)_[i]=2*t[i+1]-h[i+1];return[h,_]}function Q(t){return new V(t)}function V(t){this._context=t}function W(t){return new X(t)}function X(t){this._context=t}function Y(t){return new Z(t)}function Z(t){this._context=t}function $(){function t(t,n){var e;return _||(_=e=i.path()),s(t,n).draw(_,+h(t,n)),e?(_=null,e+""||null):void 0}var s=n(_t),h=n(64),_=null;return t.type=function(i){return arguments.length?(s="function"==typeof i?i:n(i),t):s},t.size=function(i){return arguments.length?(h="function"==typeof i?i:n(+i),t):h},t.context=function(i){return arguments.length?(_=null==i?null:i,t):_},t}var tt=Math.PI,it=tt/2,nt=2*tt;x.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(t,i)}}};var st=Array.prototype.slice;m.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:v(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:v(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},M.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._x2=t,this._y2=i;break;case 1:this._point=2,this._x3=t,this._y3=i;break;case 2:this._point=3,this._x4=t,this._y4=i,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+i)/6);break;default:v(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},w.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,s=(this._y0+4*this._y1+i)/6;this._line?this._context.lineTo(n,s):this._context.moveTo(n,s);break;case 3:this._point=4;default:v(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},k.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,i=this._y,n=t.length-1;if(n>0)for(var s,h=t[0],_=i[0],e=t[n]-h,o=i[n]-_,a=-1;++a<=n;)s=a/n,this._basis.point(this._beta*t[a]+(1-this._beta)*(h+s*e),this._beta*i[a]+(1-this._beta)*(_+s*o));this._x=this._y=null,this._basis.lineEnd()},point:function(t,i){this._x.push(+t),this._y.push(+i)}},P.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:E(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2,this._x1=t,this._y1=i;break;case 2:this._point=3;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},A.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._x3=t,this._y3=i;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=i);break;case 2:this._point=3,this._x5=t,this._y5=i;break;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},C.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}};var ht=1e-6;O.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this,this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;break;case 2:this._point=3;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},B.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=i;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=i);break;case 2:this._point=3,this._x5=t,this._y5=i;break;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},U.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}};var _t={draw:function(t,i){var n=Math.sqrt(i/Math.PI);t.moveTo(n,0),t.arc(0,0,n,0,2*Math.PI)}},et={draw:function(t,i){var n=Math.sqrt(i/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-n,-3*n),t.lineTo(n,-3*n),t.lineTo(n,-n),t.lineTo(3*n,-n),t.lineTo(3*n,n),t.lineTo(n,n),t.lineTo(n,3*n),t.lineTo(-n,3*n),t.lineTo(-n,n),t.lineTo(-3*n,n),t.closePath()}},ot=Math.sqrt(1/3),at=2*ot,lt={draw:function(t,i){var n=Math.sqrt(i/at),s=n*ot;t.moveTo(0,-n),t.lineTo(s,0),t.lineTo(0,n),t.lineTo(-s,0),t.closePath()}};G.prototype={lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,i){t=+t,i=+i,this._point?this._context.lineTo(t,i):(this._point=1,this._context.moveTo(t,i))}},K.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,i=this._y,n=t.length;if(n)if(this._line?this._context.lineTo(t[0],i[0]):this._context.moveTo(t[0],i[0]),2===n)this._context.lineTo(t[1],i[1]);else for(var s=L(t),h=L(i),_=0,e=1;n>e;++_,++e)this._context.bezierCurveTo(s[0][_],h[0][_],s[1][_],h[1][_],t[e],i[e]);(this._line||0!==this._line&&1===n)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,i){this._x.push(+t),this._y.push(+i)}};var ct={draw:function(t,i){var n=Math.sqrt(i),s=-n/2;t.rect(s,s,n,n)}};V.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._y=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(t,this._y),this._context.lineTo(t,i)}this._y=i}},X.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(this._x,i),this._context.lineTo(t,i)}this._x=t}},Z.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:var n=(this._x+t)/2;this._context.lineTo(n,this._y),this._context.lineTo(n,i)}this._x=t,this._y=i}};var rt=Math.sqrt(3),ut={draw:function(t,i){var n=Math.sqrt(i/rt),s=n*rt/2;t.moveTo(0,s),t.lineTo(n,-s),t.lineTo(-n,-s),t.closePath()}},xt={draw:function(t,i){var n=Math.sqrt(i/rt),s=n*rt/2;t.moveTo(0,-s),t.lineTo(n,s),t.lineTo(-n,s),t.closePath()}},ft=[_t,et,lt,ct,ut,xt],yt="0.0.3";t.version=yt,t.arc=r,t.area=d,t.basisClosed=g,t.basisOpen=b,t.basis=T,t.bundle=N,t.cardinalClosed=q,t.cardinalOpen=R,t.cardinal=S,t.catmullRomClosed=j,t.catmullRomOpen=D,t.catmullRom=I,t.circle=_t,t.cross=et,t.diamond=lt,t.linearClosed=F,t.linear=u,t.line=H,t.natural=J,t.square=ct,t.stepAfter=Q,t.stepBefore=W,t.step=Y,t.symbol=$,t.symbols=ft,t.triangleDown=ut,t.triangleUp=xt}); | ||
!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports,require("d3-path")):"function"==typeof define&&define.amd?define("d3-shape",["exports","d3-path"],i):i(t.d3_shape={},t.d3_path)}(this,function(t,i){"use strict";function n(t){return function(){return t}}function s(t){return t.innerRadius}function h(t){return t.outerRadius}function e(t){return t.startAngle}function _(t){return t.endAngle}function o(t){return t&&t.padAngle}function a(t){return t>=1?rt:-1>=t?-rt:Math.asin(t)}function l(t,i,n,s,h,e,_,o){var a=n-t,l=s-i,r=_-h,c=o-e,u=(r*(i-e)-c*(t-h))/(c*a-r*l);return[t+u*a,i+u*l]}function r(t,i,n,s,h,e,_){var o=t-n,a=i-s,l=(_?e:-e)/Math.sqrt(o*o+a*a),r=l*a,c=-l*o,u=t+r,x=i+c,f=n+r,y=s+c,p=(u+f)/2,d=(x+y)/2,g=f-u,m=y-x,v=g*g+m*m,T=h-e,M=u*y-f*x,b=(0>m?-1:1)*Math.sqrt(Math.max(0,T*T*v-M*M)),w=(M*m-g*b)/v,N=(-M*g-m*b)/v,k=(M*m+g*b)/v,E=(-M*g+m*b)/v,S=w-p,P=N-d,A=k-p,q=E-d;return S*S+P*P>A*A+q*q&&(w=k,N=E),{cx:w,cy:N,x01:-r,y01:-c,x11:w*(h/T-1),y11:N*(h/T-1)}}function c(){function t(){var t,n,s=+c.apply(this,arguments),h=+u.apply(this,arguments),e=y.apply(this,arguments)-rt,_=p.apply(this,arguments)-rt,o=Math.abs(_-e),m=_>e;if(g||(g=t=i.path()),s>h&&(n=h,h=s,s=n),h>0)if(o>=ct)g.moveTo(h*Math.cos(e),h*Math.sin(e)),g.arc(0,0,h,e,_,!m),s>0&&(g.moveTo(s*Math.cos(_),s*Math.sin(_)),g.arc(0,0,s,_,e,m));else{var v=e,T=_,M=e,b=_,w=o,N=o,k=d.apply(this,arguments)/2,E=k>0&&(f?+f.apply(this,arguments):Math.sqrt(s*s+h*h)),S=Math.min(Math.abs(h-s)/2,+x.apply(this,arguments)),P=S,A=S;if(E>0){var q=a(E/s*Math.sin(k)),C=a(E/h*Math.sin(k));(w-=2*q)>0?(q*=m?1:-1,M+=q,b-=q):(w=0,M=b=(e+_)/2),(N-=2*C)>0?(C*=m?1:-1,v+=C,T-=C):(N=0,v=T=(e+_)/2)}var R=h*Math.cos(v),z=h*Math.sin(v),I=s*Math.cos(b),O=s*Math.sin(b);if(S>0){var j=h*Math.cos(T),B=h*Math.sin(T),D=s*Math.cos(M),U=s*Math.sin(M);if(lt>o){var V=w>0?l(R,z,D,U,j,B,I,O):[I,O],F=R-V[0],G=z-V[1],H=j-V[0],J=B-V[1],K=1/Math.sin(Math.acos((F*H+G*J)/(Math.sqrt(F*F+G*G)*Math.sqrt(H*H+J*J)))/2),L=Math.sqrt(V[0]*V[0]+V[1]*V[1]);P=Math.min(S,(s-L)/(K-1)),A=Math.min(S,(h-L)/(K+1))}}if(N>0)if(A>0){var Q=r(D,U,R,z,h,A,m),W=r(j,B,I,O,h,A,m);g.moveTo(Q.cx+Q.x01,Q.cy+Q.y01),S>A?g.arc(Q.cx,Q.cy,A,Math.atan2(Q.y01,Q.x01),Math.atan2(W.y01,W.x01),!m):(g.arc(Q.cx,Q.cy,A,Math.atan2(Q.y01,Q.x01),Math.atan2(Q.y11,Q.x11),!m),g.arc(0,0,h,Math.atan2(Q.cy+Q.y11,Q.cx+Q.x11),Math.atan2(W.cy+W.y11,W.cx+W.x11),!m),g.arc(W.cx,W.cy,A,Math.atan2(W.y11,W.x11),Math.atan2(W.y01,W.x01),!m))}else g.moveTo(R,z),g.arc(0,0,h,v,T,!m);else g.moveTo(R,z);if(s>0&&w>0)if(P>0){var Q=r(I,O,j,B,s,-P,m),W=r(R,z,D,U,s,-P,m);g.lineTo(Q.cx+Q.x01,Q.cy+Q.y01),S>P?g.arc(Q.cx,Q.cy,P,Math.atan2(Q.y01,Q.x01),Math.atan2(W.y01,W.x01),!m):(g.arc(Q.cx,Q.cy,P,Math.atan2(Q.y01,Q.x01),Math.atan2(Q.y11,Q.x11),!m),g.arc(0,0,s,Math.atan2(Q.cy+Q.y11,Q.cx+Q.x11),Math.atan2(W.cy+W.y11,W.cx+W.x11),m),g.arc(W.cx,W.cy,P,Math.atan2(W.y11,W.x11),Math.atan2(W.y01,W.x01),!m))}else g.arc(0,0,s,b,M,m);else g.lineTo(I,O)}else g.moveTo(0,0);return g.closePath(),t?(g=null,t+""||null):void 0}var c=s,u=h,x=n(0),f=null,y=e,p=_,d=o,g=null,m=null;return t.centroid=function(){var t=(+c.apply(this,arguments)+ +u.apply(this,arguments))/2,i=(+y.apply(this,arguments)+ +p.apply(this,arguments))/2-lt/2;return[Math.cos(i)*t,Math.sin(i)*t]},t.innerRadius=function(i){return arguments.length?(c="function"==typeof i?i:n(+i),t):c},t.outerRadius=function(i){return arguments.length?(u="function"==typeof i?i:n(+i),t):u},t.cornerRadius=function(i){return arguments.length?(x="function"==typeof i?i:n(+i),t):x},t.padRadius=function(i){return arguments.length?(f=null==i?null:"function"==typeof i?i:n(+i),t):f},t.startAngle=function(i){return arguments.length?(y="function"==typeof i?i:n(+i),t):y},t.endAngle=function(i){return arguments.length?(p="function"==typeof i?i:n(+i),t):p},t.padAngle=function(i){return arguments.length?(d="function"==typeof i?i:n(+i),t):d},t.context=function(i){return arguments.length?(g=m=null==i?null:i,t):g},t}function u(t,i){return i=ut.call(i),i[0]=null,function(n){return i[0]=n,t.apply(null,i)}}function x(t){return new f(t)}function f(t){this._context=t}function y(t){return t[0]}function p(t){return t[1]}function d(){function t(t){var n,c,u,x,f,y=t.length,p=!1,d=new Array(y),g=new Array(y);for(a||(r=l(f=i.path())),n=0;y>=n;++n){if(!(y>n&&o(x=t[n],n,t))===p)if(p=!p)c=n,r.areaStart(),r.lineStart();else{for(r.lineEnd(),r.lineStart(),u=n-1;u>=c;--u)r.point(d[u],g[u]);r.lineEnd(),r.areaEnd()}p&&(d[n]=+s(x,n,t),g[n]=+e(x,n,t),r.point(h?+h(x,n,t):d[n],_?+_(x,n,t):g[n]))}return f?(r=null,f+""||null):void 0}var s=y,h=null,e=n(0),_=p,o=n(!0),a=null,l=x,r=null;return t.x=function(i){return arguments.length?t.x0(i).x1(null):s},t.x0=function(i){return arguments.length?(s="function"==typeof i?i:n(+i),t):s},t.x1=function(i){return arguments.length?(h=null==i?null:"function"==typeof i?i:n(+i),t):h},t.y=function(i){return arguments.length?t.y0(i).y1(null):e},t.y0=function(i){return arguments.length?(e="function"==typeof i?i:n(+i),t):e},t.y1=function(i){return arguments.length?(_=null==i?null:"function"==typeof i?i:n(+i),t):_},t.defined=function(i){return arguments.length?(o="function"==typeof i?i:n(!!i),t):o},t.curve=function(i){var n=arguments.length;return n?(l=n>1?u(i,arguments):i,null!=a&&(r=l(a)),t):l},t.context=function(i){return arguments.length?(null==i?a=r=null:r=l(a=i),t):a},t}function g(t,i,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+i)/6,(t._y0+4*t._y1+n)/6)}function m(t){return new v(t)}function v(t){this._context=t}function T(t){return new M(t)}function M(t){this._context=t}function b(t){return new w(t)}function w(t){this._context=t}function N(t,i){return null==i?new k(t,.85):1===(i=+i)?m(t):new k(t,i)}function k(t,i){this._basis=m(t),this._beta=i}function E(t,i,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-i),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function S(t,i){return new P(t,(null==i?1:1-i)/6)}function P(t,i){this._context=t,this._k=i}function A(t,i){return new q(t,(null==i?1:1-i)/6)}function q(t,i){this._context=t,this._k=i}function C(t,i){return new R(t,(null==i?1:1-i)/6)}function R(t,i){this._context=t,this._k=i}function z(t,i,n){var s=t._x1,h=t._y1,e=t._x2,_=t._y2;if(t._l01_a>xt){var o=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,a=3*t._l01_a*(t._l01_a+t._l12_a);s=(s*o-t._x0*t._l12_2a+t._x2*t._l01_2a)/a,h=(h*o-t._y0*t._l12_2a+t._y2*t._l01_2a)/a}if(t._l23_a>xt){var l=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,r=3*t._l23_a*(t._l23_a+t._l12_a);e=(e*l+t._x1*t._l23_2a-i*t._l12_2a)/r,_=(_*l+t._y1*t._l23_2a-n*t._l12_2a)/r}t._context.bezierCurveTo(s,h,e,_,t._x2,t._y2)}function I(t,i){return(i=null==i?.5:+i)?new O(t,i):S(t,0)}function O(t,i){this._context=t,this._alpha=i}function j(t,i){return(i=null==i?.5:+i)?new B(t,i):A(t,0)}function B(t,i){this._context=t,this._alpha=i}function D(t,i){return(i=null==i?.5:+i)?new U(t,i):C(t,0)}function U(t,i){this._context=t,this._alpha=i}function V(t){return new F(t)}function F(t){this._context=t}function G(){function t(t){var n,l,r,c=t.length,u=!1;for(_||(a=o(r=i.path())),n=0;c>=n;++n)!(c>n&&e(l=t[n],n,t))===u&&((u=!u)?a.lineStart():a.lineEnd()),u&&a.point(+s(l,n,t),+h(l,n,t));return r?(a=null,r+""||null):void 0}var s=y,h=p,e=n(!0),_=null,o=x,a=null;return t.x=function(i){return arguments.length?(s="function"==typeof i?i:n(+i),t):s},t.y=function(i){return arguments.length?(h="function"==typeof i?i:n(+i),t):h},t.defined=function(i){return arguments.length?(e="function"==typeof i?i:n(!!i),t):e},t.curve=function(i){var n=arguments.length;return n?(o=n>1?u(i,arguments):i,null!=_&&(a=o(_)),t):o},t.context=function(i){return arguments.length?(null==i?_=a=null:a=o(_=i),t):_},t}function H(t){return 0>t?-1:1}function J(t,i,n){var s=t._x1-t._x0,h=i-t._x1,e=(t._y1-t._y0)/s,_=(n-t._y1)/h,o=(e*h+_*s)/(s+h);return(H(e)+H(_))*Math.min(Math.abs(e),Math.abs(_),.5*Math.abs(o))||0}function K(t,i){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-i)/2:i}function L(t,i,n){var s=t._x0,h=t._y0,e=t._x1,_=t._y1,o=(e-s)/3;t._context.bezierCurveTo(s+o,h+o*i,e-o,_-o*n,e,_)}function Q(t){return new W(t)}function W(t){this._context=t}function X(t){return new Y(t)}function Y(t){this._context=t}function Z(t){var i,n,s=t.length-1,h=new Array(s),e=new Array(s),_=new Array(s);for(h[0]=0,e[0]=2,_[0]=t[0]+2*t[1],i=1;s-1>i;++i)h[i]=1,e[i]=4,_[i]=4*t[i]+2*t[i+1];for(h[s-1]=2,e[s-1]=7,_[s-1]=8*t[s-1]+t[s],i=1;s>i;++i)n=h[i]/e[i-1],e[i]-=n,_[i]-=n*_[i-1];for(h[s-1]=_[s-1]/e[s-1],i=s-2;i>=0;--i)h[i]=(_[i]-h[i+1])/e[i];for(e[s-1]=(t[s]+h[s-1])/2,i=0;s-1>i;++i)e[i]=2*t[i+1]-h[i+1];return[h,e]}function $(t){return t}function tt(t,i){return t>i?-1:i>t?1:i>=t?0:NaN}function it(){function t(t){for(var n,a,l=t.length,r=0,c=new Array(l),u=new Array(l),x=+e.apply(this,arguments),f=Math.min(mt,Math.max(-mt,_.apply(this,arguments)-x)),y=Math.min(Math.abs(f)/l,o.apply(this,arguments)),p=y*(0>f?-1:1),d=0;l>d;++d)(a=u[c[d]=d]=+i(t[d],d,t))>0&&(r+=a);null!=s?c.sort(function(t,i){return s(u[t],u[i])}):null!==h&&c.sort(function(i,n){return h(t[i],t[n])});for(var g,d=0,m=r?(f-l*p)/r:0;l>d;++d,x=n)g=c[d],a=u[g],n=x+(a>0?a*m:0)+p,u[g]={data:t[g],value:a,startAngle:x,endAngle:n,padAngle:y};return u}var i=$,s=tt,h=null,e=n(0),_=n(mt),o=n(0);return t.value=function(s){return arguments.length?(i="function"==typeof s?s:n(+s),t):i},t.sortValues=function(i){return arguments.length?(s=i,h=null,t):s},t.sort=function(i){return arguments.length?(h=i,s=null,t):h},t.startAngle=function(i){return arguments.length?(e="function"==typeof i?i:n(+i),t):e},t.endAngle=function(i){return arguments.length?(_="function"==typeof i?i:n(+i),t):_},t.padAngle=function(i){return arguments.length?(o="function"==typeof i?i:n(+i),t):o},t}function nt(t){return new st(t)}function st(t){this._context=t}function ht(t){return new et(t)}function et(t){this._context=t}function _t(t){return new ot(t)}function ot(t){this._context=t}function at(){function t(){var t;return e||(e=t=i.path()),s.apply(this,arguments).draw(e,+h.apply(this,arguments)),t?(e=null,t+""||null):void 0}var s=n(ft),h=n(64),e=null;return t.type=function(i){return arguments.length?(s="function"==typeof i?i:n(i),t):s},t.size=function(i){return arguments.length?(h="function"==typeof i?i:n(+i),t):h},t.context=function(i){return arguments.length?(e=null==i?null:i,t):e},t}var lt=Math.PI,rt=lt/2,ct=2*lt,ut=Array.prototype.slice;f.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(t,i)}}},v.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:g(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:g(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},M.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._x2=t,this._y2=i;break;case 1:this._point=2,this._x3=t,this._y3=i;break;case 2:this._point=3,this._x4=t,this._y4=i,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+i)/6);break;default:g(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},w.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,s=(this._y0+4*this._y1+i)/6;this._line?this._context.lineTo(n,s):this._context.moveTo(n,s);break;case 3:this._point=4;default:g(this,t,i)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i}},k.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,i=this._y,n=t.length-1;if(n>0)for(var s,h=t[0],e=i[0],_=t[n]-h,o=i[n]-e,a=-1;++a<=n;)s=a/n,this._basis.point(this._beta*t[a]+(1-this._beta)*(h+s*_),this._beta*i[a]+(1-this._beta)*(e+s*o));this._x=this._y=null,this._basis.lineEnd()},point:function(t,i){this._x.push(+t),this._y.push(+i)}},P.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:E(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2,this._x1=t,this._y1=i;break;case 2:this._point=3;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},q.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._x3=t,this._y3=i;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=i);break;case 2:this._point=3,this._x5=t,this._y5=i;break;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},R.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:E(this,t,i)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}};var xt=1e-6;O.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this,this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;break;case 2:this._point=3;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},B.prototype={lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=i;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=i);break;case 2:this._point=3,this._x5=t,this._y5=i;break;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}},U.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){if(t=+t,i=+i,this._point){var n=this._x2-t,s=this._y2-i;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+s*s,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:z(this,t,i)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=i}};var ft={draw:function(t,i){var n=Math.sqrt(i/Math.PI);t.moveTo(n,0),t.arc(0,0,n,0,2*Math.PI)}},yt={draw:function(t,i){var n=Math.sqrt(i/5)/2;t.moveTo(-3*n,-n),t.lineTo(-n,-n),t.lineTo(-n,-3*n),t.lineTo(n,-3*n),t.lineTo(n,-n),t.lineTo(3*n,-n),t.lineTo(3*n,n),t.lineTo(n,n),t.lineTo(n,3*n),t.lineTo(-n,3*n),t.lineTo(-n,n),t.lineTo(-3*n,n),t.closePath()}},pt=Math.sqrt(1/3),dt=2*pt,gt={draw:function(t,i){var n=Math.sqrt(i/dt),s=n*pt;t.moveTo(0,-n),t.lineTo(s,0),t.lineTo(0,n),t.lineTo(-s,0),t.closePath()}};F.prototype={lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,i){t=+t,i=+i,this._point?this._context.lineTo(t,i):(this._point=1,this._context.moveTo(t,i))}},W.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:L(this,this._t0,K(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){var n=NaN;if(t=+t,i=+i,t!==this._x1||i!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;break;case 2:this._point=3,L(this,K(this,n=J(this,t,i)),n);break;default:L(this,this._t0,n=J(this,t,i))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=i,this._t0=n}}},Y.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,i=this._y,n=t.length;if(n)if(this._line?this._context.lineTo(t[0],i[0]):this._context.moveTo(t[0],i[0]),2===n)this._context.lineTo(t[1],i[1]);else for(var s=Z(t),h=Z(i),e=0,_=1;n>_;++e,++_)this._context.bezierCurveTo(s[0][e],h[0][e],s[1][e],h[1][e],t[_],i[_]);(this._line||0!==this._line&&1===n)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,i){this._x.push(+t),this._y.push(+i)}};var mt=2*Math.PI,vt={draw:function(t,i){var n=Math.sqrt(i),s=-n/2;t.rect(s,s,n,n)}};st.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._y=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(t,this._y),this._context.lineTo(t,i)}this._y=i}},et.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:this._context.lineTo(this._x,i),this._context.lineTo(t,i)}this._x=t}},ot.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,i){switch(t=+t,i=+i,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,i):this._context.moveTo(t,i);break;case 1:this._point=2;default:var n=(this._x+t)/2;this._context.lineTo(n,this._y),this._context.lineTo(n,i)}this._x=t,this._y=i}};var Tt=Math.sqrt(3),Mt={draw:function(t,i){var n=Math.sqrt(i/Tt),s=n*Tt/2;t.moveTo(0,s),t.lineTo(n,-s),t.lineTo(-n,-s),t.closePath()}},bt={draw:function(t,i){var n=Math.sqrt(i/Tt),s=n*Tt/2;t.moveTo(0,-s),t.lineTo(n,s),t.lineTo(-n,s),t.closePath()}},wt=[ft,yt,gt,vt,Mt,bt],Nt="0.1.0";t.version=Nt,t.arc=c,t.area=d,t.basisClosed=T,t.basisOpen=b,t.basis=m,t.bundle=N,t.cardinalClosed=A,t.cardinalOpen=C,t.cardinal=S,t.catmullRomClosed=j,t.catmullRomOpen=D,t.catmullRom=I,t.circle=ft,t.cross=yt,t.diamond=gt,t.linearClosed=V,t.linear=x,t.line=G,t.monotone=Q,t.natural=X,t.pie=it,t.square=vt,t.stepAfter=nt,t.stepBefore=ht,t.step=_t,t.symbol=at,t.symbols=wt,t.triangleDown=Mt,t.triangleUp=bt}); |
@@ -19,3 +19,5 @@ export {default as arc} from "./src/arc"; | ||
export {default as line} from "./src/line"; | ||
export {default as monotone} from "./src/curve/monotone"; | ||
export {default as natural} from "./src/curve/natural"; | ||
export {default as pie} from "./src/pie"; | ||
export {default as square} from "./src/symbol/square"; | ||
@@ -22,0 +24,0 @@ export {default as stepAfter} from "./src/curve/stepAfter"; |
{ | ||
"name": "d3-shape", | ||
"version": "0.0.3", | ||
"version": "0.1.0", | ||
"description": "Graphical primitives for visualization, such as lines and areas.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
621
README.md
# d3-shape | ||
… | ||
Visualizations typically consist of discrete graphical marks, such as [symbols](#symbols), [arcs](#arcs), [lines](#lines) and [areas](#areas). While the rectangles of a bar chart may be easy enough to generate directly using [SVG](http://www.w3.org/TR/SVG/paths.html#PathData) or [Canvas](http://www.w3.org/TR/2dcontext/#canvaspathmethods), other shapes are complex, such as rounded annular sectors and centripetal Catmull–Rom splines. This module provides a variety of shape generators for your convenience. | ||
As with other aspects of D3, these shapes are driven by data: each shape generator exposes accessors that control how the input data are mapped to a visual representation. For example, you might define a line generator for a time series by [linearly scaling](https://github.com/d3/d3-scale) the `date` and `value` fields of your data to fit the chart: | ||
```js | ||
var l = line() | ||
.x(function(d) { return x(d.date); }) | ||
.y(function(d) { return y(d.value); }) | ||
.curve(shape.catmullRom); | ||
``` | ||
The line generator can then be used to set the `d` attribute of an SVG path element: | ||
```js | ||
path.datum(data).attr("d", l); | ||
``` | ||
Or you can use it to render to a Canvas 2D context: | ||
```js | ||
l.context(context)(data); | ||
``` | ||
## Installing | ||
@@ -13,257 +34,647 @@ | ||
… | ||
[<img alt="Pie Chart" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/pie.png" width="295" height="295">](http://bl.ocks.org/mbostock/3887235)[<img alt="Donut Chart" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/donut.png" width="295" height="295">](http://bl.ocks.org/mbostock/3887193) | ||
The arc generator produces a [circular](https://en.wikipedia.org/wiki/Circular_sector) or [annular](https://en.wikipedia.org/wiki/Annulus_\(mathematics\)) sector, as in a pie or donut chart. If the difference between the [start](#arc_startAngle) and [end](#arc_endAngle) angles (the *angular span*) is greater than [τ](https://en.wikipedia.org/wiki/Turn_\(geometry\)#Tau_proposal), the arc generator will produce a complete circle or annulus. If it is less than τ, arcs may have [rounded corners](#arc_cornerRadius) and [angular padding](#arc_padAngle). Arcs are always centered at ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to move the arc to a different position. | ||
See also the [pie generator](#pies), which computes the necessary angles to represent an array of data as a pie or donut chart; these angles can then be passed to an arc generator. | ||
<a name="arc" href="#arc">#</a> <b>arc</b>() | ||
… | ||
Constructs a new arc generator with the default settings. | ||
<a name="_arc" href="#_arc">#</a> <i>arc</i>(<i>d</i>, <i>i</i>) | ||
<a name="_arc" href="#_arc">#</a> <i>arc</i>(<i>arguments…</i>) | ||
… | ||
Generates an arc for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the arc generator’s accessor functions along with the `this` object. For example, with the default settings, an object with radii and angles is expected: | ||
<a name="arc_centroid" href="#arc_centroid">#</a> <i>arc</i>.<b>centroid</b>(<i>d</i>, <i>i</i>) | ||
```js | ||
var a = arc(); | ||
… | ||
a({ | ||
innerRadius: 0, | ||
outerRadius: 100, | ||
startAngle: 0, | ||
endAngle: Math.PI / 2 | ||
}); // "M0,-100A100,100,0,0,1,100,0L0,0Z" | ||
``` | ||
Note: to be consistent with [*arc*](#_arc), the arc’s associated accessors must be deterministic. | ||
If the radii and angles are instead defined as constants, you can generate an arc without any arguments: | ||
<a name="arc_innerRadius" href="#arc_innerRadius">#</a> <i>arc</i>.<b>innerRadius</b>([<i>innerRadius</i>]) | ||
```js | ||
var a = arc() | ||
.innerRadius(0) | ||
.outerRadius(100) | ||
.startAngle(0) | ||
.endAngle(Math.PI / 2); | ||
… | ||
a(); // "M0,-100A100,100,0,0,1,100,0L0,0Z" | ||
``` | ||
<a name="arc_outerRadius" href="#arc_outerRadius">#</a> <i>arc</i>.<b>outerRadius</b>([<i>outerRadius</i>]) | ||
If the arc generator has a [context](#arc_context), then the arc is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned. | ||
… | ||
<a name="arc_centroid" href="#arc_centroid">#</a> <i>arc</i>.<b>centroid</b>(<i>arguments…</i>) | ||
<a name="arc_cornerRadius" href="#arc_cornerRadius">#</a> <i>arc</i>.<b>cornerRadius</b>([<i>cornerRadius</i>]) | ||
Computes the midpoint [*x*, *y*] of the center line of the arc that would be [generated](#_arc) by the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the arc generator’s accessor functions along with the `this` object. To be consistent with the generated arc, the accessors must be deterministic, *i.e.*, return the same value given the same arguments. The midpoint is defined as ([startAngle](#arc_startAngle) + [endAngle](#arc_endAngle)) / 2 and ([innerRadius](#arc_innerRadius) + [outerRadius](#arc_outerRadius)) / 2. For example: | ||
… | ||
<img alt="Circular Sector Centroids" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/centroid-circular-sector.png" width="250" height="250"><img alt="Annular Sector Centroids" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/centroid-annular-sector.png" width="250" height="250"> | ||
<a name="arc_padRadius" href="#arc_padRadius">#</a> <i>arc</i>.<b>padRadius</b>([<i>padRadius</i>]) | ||
Note that this is **not the geometric center** of the arc, which may be outside the arc; this method is merely a convenience for positioning labels. | ||
… | ||
<a name="arc_innerRadius" href="#arc_innerRadius">#</a> <i>arc</i>.<b>innerRadius</b>([<i>radius</i>]) | ||
<a name="arc_startAngle" href="#arc_startAngle">#</a> <i>arc</i>.<b>startAngle</b>([<i>startAngle</i>]) | ||
If *radius* is specified, sets the inner radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current inner radius accessor, which defaults to: | ||
… | ||
```js | ||
function innerRadius(d) { | ||
return d.innerRadius; | ||
} | ||
``` | ||
<a name="arc_endAngle" href="#arc_endAngle">#</a> <i>arc</i>.<b>endAngle</b>([<i>endAngle</i>]) | ||
Specifying the inner radius as a function is useful for constructing a stacked polar bar chart, often in conjunction with a [sqrt scale](https://github.com/d3/d3-scale#sqrt). More commonly, a constant inner radius is used for a donut or pie chart. If the outer radius is smaller than the inner radius, the inner and outer radii are swapped. A negative value is treated as zero. | ||
… | ||
<a name="arc_outerRadius" href="#arc_outerRadius">#</a> <i>arc</i>.<b>outerRadius</b>([<i>radius</i>]) | ||
<a name="arc_padAngle" href="#arc_padAngle">#</a> <i>arc</i>.<b>padAngle</b>([<i>padAngle</i>]) | ||
If *radius* is specified, sets the outer radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current outer radius accessor, which defaults to: | ||
… | ||
```js | ||
function outerRadius(d) { | ||
return d.outerRadius; | ||
} | ||
``` | ||
The recommended minimum inner radius when using padding is outerRadius * | ||
padAngle / sin(θ), where θ is the angle of the smallest arc (without padding). | ||
For example, if the outerRadius is 200 pixels and the padAngle is 0.02 radians, | ||
a reasonable θ is 0.04 radians, and a reasonable innerRadius is 100 pixels. | ||
Specifying the outer radius as a function is useful for constructing a coxcomb or polar bar chart, often in conjunction with a [sqrt scale](https://github.com/d3/d3-scale#sqrt). More commonly, a constant outer radius is used for a pie or donut chart. If the outer radius is smaller than the inner radius, the inner and outer radii are swapped. A negative value is treated as zero. | ||
See also *pie*.padAngle. (From which module?) | ||
<a name="arc_cornerRadius" href="#arc_cornerRadius">#</a> <i>arc</i>.<b>cornerRadius</b>([<i>radius</i>]) | ||
If *radius* is specified, sets the corner radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current corner radius accessor, which defaults to: | ||
```js | ||
function cornerRadius() { | ||
return 0; | ||
} | ||
``` | ||
If the corner radius is greater than zero, the corners of the arc are rounded using circles of the given radius. For a circular sector, the two outer corners are rounded; for an annular sector, all four corners are rounded. The corner circles are shown in this diagram: | ||
<img alt="Rounded Circular Sectors" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/rounded-circular-sector.png" width="250" height="250"><img alt="Rounded Annular Sectors" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/rounded-annular-sector.png" width="250" height="250"> | ||
The corner radius may not be larger than ([outerRadius](#arc_outerRadius) - [innerRadius](#arc_innerRadius)) / 2. In addition, for arcs whose angular span is less than π, the corner radius may be reduced as two adjacent rounded corners intersect. This is occurs more often with the inner corners. See the [arc corners animation](http://bl.ocks.org/mbostock/b7671cb38efdfa5da3af) for illustration. | ||
<a name="arc_startAngle" href="#arc_startAngle">#</a> <i>arc</i>.<b>startAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the start angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current start angle accessor, which defaults to: | ||
```js | ||
function startAngle(d) { | ||
return d.startAngle; | ||
} | ||
``` | ||
The *angle* is specified in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. If |endAngle - startAngle| ≥ τ, a complete circle or annulus is generated rather than a sector. | ||
<a name="arc_endAngle" href="#arc_endAngle">#</a> <i>arc</i>.<b>endAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the end angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current end angle accessor, which defaults to: | ||
```js | ||
function endAngle(d) { | ||
return d.endAngle; | ||
} | ||
``` | ||
The *angle* is specified in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. If |endAngle - startAngle| ≥ τ, a complete circle or annulus is generated rather than a sector. | ||
<a name="arc_padAngle" href="#arc_padAngle">#</a> <i>arc</i>.<b>padAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the pad angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current pad angle accessor, which defaults to: | ||
```js | ||
function padAngle() { | ||
return d && d.padAngle; | ||
} | ||
``` | ||
The pad angle is converted to a fixed linear distance separating adjacent arcs, defined as [padRadius](#arc_padRadius) * padAngle. This distance is subtracted equally from the [start](#arc_startAngle) and [end](#arc_endAngle) of the arc. If the arc forms a complete circle or annulus, as when |endAngle - startAngle| ≥ τ, the pad angle is ignored. | ||
If the [inner radius](#arc_innerRadius) or angular span is small relative to the pad angle, it may not be possible to maintain parallel edges between adjacent arcs. In this case, the inner edge of the arc may collapse to a point, similar to a circular sector. For this reason, padding is typically only applied to annular sectors (*i.e.*, when innerRadius is positive), as shown in this diagram: | ||
<img alt="Padded Circular Sectors" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/padded-circular-sector.png" width="250" height="250"><img alt="Padded Annular Sectors" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/padded-annular-sector.png" width="250" height="250"> | ||
The recommended minimum inner radius when using padding is outerRadius \* padAngle / sin(θ), where θ is the angular span of the smallest arc before padding. For example, if the outer radius is 200 pixels and the pad angle is 0.02 radians, a reasonable θ is 0.04 radians, and a reasonable inner radius is 100 pixels. See the [arc padding animation](http://bl.ocks.org/mbostock/053fcc2295a445afab07) for illustration. | ||
Often, the pad angle is not set directly on the arc generator, but is instead computed by the [pie generator](#pies) so as to ensure that the area of padded arcs is proportional to their value; see [*pie*.padAngle](#pie_padAngle). See the [pie padding animation](http://bl.ocks.org/mbostock/3e961b4c97a1b543fff2) for illustration. If you apply a constant pad angle to the arc generator directly, it tends to subtract disproportionately from smaller arcs, introducing distortion. | ||
<a name="arc_padRadius" href="#arc_padRadius">#</a> <i>arc</i>.<b>padRadius</b>([<i>radius</i>]) | ||
If *radius* is specified, sets the pad radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current pad radius accessor, which defaults to null, indicating that the pad radius should be automatically computed as sqrt([innerRadius](#arc_innerRadius) * innerRadius + [outerRadius](#arc_outerRadius) * outerRadius). The pad radius determines the fixed linear distance separating adjacent arcs, defined as padRadius * [padAngle](#arc_padAngle). | ||
<a name="arc_context" href="#arc_context">#</a> <i>arc</i>.<b>context</b>([<i>context</i>]) | ||
… | ||
If *context* is specified, sets the context and returns this arc generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated arc](#_arc) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated arc is returned. | ||
### Pies | ||
The pie generator does not produce a shape directly, but instead computes the necessary angles to represent a tabular dataset as a pie or donut chart; these angles can then be passed to an [arc generator](#arcs). | ||
<a name="pie" href="#pie">#</a> <b>pie</b>() | ||
Constructs a new pie generator with the default settings. | ||
<a name="_pie" href="#_pie">#</a> <i>pie</i>(<i>data</i>[, <i>arguments…</i>]) | ||
Generates a pie for the given array of *data*, returning an array of objects representing each datum’s arc angles. Any additional *arguments* are arbitrary; they are simply propagated to the pie generator’s accessor functions along with the `this` object. The length of the returned array is the same as *data*, and each element *i* in the returned array corresponds to the element *i* in the input data. Each object in the returned array has the following properties: | ||
* `data` - the input datum; the corresponding element in the input data array. | ||
* `value` - the numeric [value](#pie_value) of the arc. | ||
* `startAngle` - the [start angle](#pie_startAngle) of the arc. | ||
* `endAngle` - the [end angle](#pie_endAngle) of the arc. | ||
* `padAngle` - the [pad angle](#pie_padAngle) of the arc. | ||
This representation is designed to work with the arc generator’s default [startAngle](#arc_startAngle), [endAngle](#arc_endAngle) and [padAngle](#arc_padAngle) accessors. The angular units are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify angles in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. | ||
Given a small dataset of numbers, here is how to compute the arc angles to render this data as a pie chart: | ||
```js | ||
var data = [1, 1, 2, 3, 5, 8, 13, 21]; | ||
var arcs = pie()(data); | ||
``` | ||
The first pair of parens, `pie()`, [constructs](#pie) a default pie generator. The second, `pie()(data)`, [invokes](#_pie) this generator on the dataset, returning an array of objects: | ||
```json | ||
[ | ||
{"data": 1, "value": 1, "startAngle": 6.050474740247008, "endAngle": 6.166830023713296, "padAngle": 0}, | ||
{"data": 1, "value": 1, "startAngle": 6.166830023713296, "endAngle": 6.283185307179584, "padAngle": 0}, | ||
{"data": 2, "value": 2, "startAngle": 5.817764173314431, "endAngle": 6.050474740247008, "padAngle": 0}, | ||
{"data": 3, "value": 3, "startAngle": 5.468698322915565, "endAngle": 5.817764173314431, "padAngle": 0}, | ||
{"data": 5, "value": 5, "startAngle": 4.886921905584122, "endAngle": 5.468698322915565, "padAngle": 0}, | ||
{"data": 8, "value": 8, "startAngle": 3.956079637853813, "endAngle": 4.886921905584122, "padAngle": 0}, | ||
{"data": 13, "value": 13, "startAngle": 2.443460952792061, "endAngle": 3.956079637853813, "padAngle": 0}, | ||
{"data": 21, "value": 21, "startAngle": 0.000000000000000, "endAngle": 2.443460952792061, "padAngle": 0} | ||
] | ||
``` | ||
Note that the returned array is in the same order as the data, even though this pie chart is [sorted](#pie_sortValues) by descending value, starting with the arc for the last datum (value 21) at 12 o’clock. | ||
<a name="pie_value" href="#pie_value">#</a> <i>pie</i>.<b>value</b>([<i>value</i>]) | ||
If *value* is specified, sets the value accessor to the specified function or number and returns this pie generator. If *value* is not specified, returns the current value accessor, which defaults to: | ||
```js | ||
function value(d) { | ||
return d; | ||
} | ||
``` | ||
When a pie is [generated](#_pie), the value accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default value accessor assumes that the input data are numbers, or that they are coercible to numbers using [valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf). If your data are not simply numbers, then you should specify an accessor that returns the corresponding numeric value for a given datum. For example: | ||
```js | ||
var data = [ | ||
{"number": 4, "name": Locke}, | ||
{"number": 8, "name": Reyes}, | ||
{"number": 15, "name": Ford}, | ||
{"number": 16, "name": Jarrah}, | ||
{"number": 23, "name": Shephard}, | ||
{"number": 42, "name": Kwon} | ||
]; | ||
var arcs = pie() | ||
.value(function(d) { return d.number; }) | ||
(data); | ||
``` | ||
This is similar to [mapping](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) your data to values before invoking the pie generator: | ||
```js | ||
var arcs = pie()(data.map(function(d) { return d.number; })); | ||
``` | ||
The benefit of an accessor is that the input data remains associated with the returned objects, thereby making it easier to access other fields of the data, for example to set the color or to add text labels. | ||
<a name="pie_sort" href="#pie_sort">#</a> <i>pie</i>.<b>sort</b>([<i>compare</i>]) | ||
If *compare* is specified, sets the data comparator to the specified function and returns this pie generator. If *compare* is not specified, returns the current data comparator, which defaults to null. If both the data comparator and the value comparator are null, then arcs are positioned in the original input order. Otherwise, the data is sorted according to the data comparator, and the resulting order is used. Setting the data comparator implicitly sets the [value comparator](#pie_sortValues) to null. | ||
The *compare* function takes two arguments *a* and *b*, each elements from the input data array. If the arc for *a* should be before the arc for *b*, then the comparator must return a number less than zero; if the arc for *a* should be after the arc for *b*, then the comparator must return a number greater than zero; returning zero means that the relative order of *a* and *b* is unspecified. For example, to sort arcs by their associated name: | ||
```js | ||
pie.sort(function(a, b) { return a.name.localeCompare(b.name); }); | ||
``` | ||
Sorting does not affect the order of the [generated arc array](#_pie) which is always in the same order as the input data array; it merely affects the computed angles of each arc. The first arc starts at the [start angle](#pie_startAngle) and the last arc ends at the [end angle](#pie_endAngle). | ||
<a name="pie_sortValues" href="#pie_sortValues">#</a> <i>pie</i>.<b>sortValues</b>([<i>compare</i>]) | ||
If *compare* is specified, sets the value comparator to the specified function and returns this pie generator. If *compare* is not specified, returns the current value comparator, which defaults to descending value. The default value comparator is implemented as: | ||
```js | ||
function compare(a, b) { | ||
return b - a; | ||
} | ||
``` | ||
If both the data comparator and the value comparator are null, then arcs are positioned in the original input order. Otherwise, the data is sorted according to the data comparator, and the resulting order is used. Setting the value comparator implicitly sets the [data comparator](#pie_sort) to null. | ||
The value comparator is similar to the [data comparator](#pie_sort), except the two arguments *a* and *b* are values derived from the input data array using the [value accessor](#pie_value), not the data elements. If the arc for *a* should be before the arc for *b*, then the comparator must return a number less than zero; if the arc for *a* should be after the arc for *b*, then the comparator must return a number greater than zero; returning zero means that the relative order of *a* and *b* is unspecified. For example, to sort arcs by ascending value: | ||
```js | ||
pie.sortValues(function(a, b) { return a - b; }); | ||
``` | ||
Sorting does not affect the order of the [generated arc array](#_pie) which is always in the same order as the input data array; it merely affects the computed angles of each arc. The first arc starts at the [start angle](#pie_startAngle) and the last arc ends at the [end angle](#pie_endAngle). | ||
<a name="pie_startAngle" href="#pie_startAngle">#</a> <i>pie</i>.<b>startAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the overall start angle of the pie to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current start angle accessor, which defaults to: | ||
```js | ||
function startAngle() { | ||
return 0; | ||
} | ||
``` | ||
The start angle here means the *overall* start angle of the pie, *i.e.*, the start angle of the first arc. The start angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. | ||
<a name="pie_endAngle" href="#pie_endAngle">#</a> <i>pie</i>.<b>endAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the overall end angle of the pie to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current end angle accessor, which defaults to: | ||
```js | ||
function endAngle() { | ||
return 2 * Math.PI; | ||
} | ||
``` | ||
The end angle here means the *overall* end angle of the pie, *i.e.*, the end angle of the last arc. The end angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. | ||
The value of the end angle is constrained to [startAngle](#pie_startAngle) ± τ, such that |endAngle - startAngle| ≤ τ. | ||
<a name="pie_padAngle" href="#pie_padAngle">#</a> <i>pie</i>.<b>padAngle</b>([<i>angle</i>]) | ||
If *angle* is specified, sets the pad angle to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current pad angle accessor, which defaults to: | ||
```js | ||
function padAngle() { | ||
return 0; | ||
} | ||
``` | ||
The pad angle here means the angular separation between each adjacent arc. The total amount of padding reserved is the specified *angle* times the number of elements in the input data array, and at most |endAngle - startAngle|; the remaining space is then divided proportionally by [value](#pie_value) such that the relative area of each arc is preserved. See the [pie padding animation](http://bl.ocks.org/mbostock/3e961b4c97a1b543fff2) for illustration. The pad angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians. | ||
### Lines | ||
… | ||
[<img width="295" height="154" alt="Line Chart" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/line.png">](http://bl.ocks.org/mbostock/3883245)[<img width="295" height="154" alt="Multi-Line Chart" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/line-multi.png">](http://bl.ocks.org/mbostock/3884955)[<img width="295" height="154" alt="Line Gradient" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/line-gradient.png">](http://bl.ocks.org/mbostock/3969722) | ||
The line generator produces a [spline](https://en.wikipedia.org/wiki/Spline_\(mathematics\)) or [polyline](https://en.wikipedia.org/wiki/Polygonal_chain), as in a line chart. Lines also appear in many other visualization types, such as the links in [hierarchical edge bundling](http://bl.ocks.org/mbostock/7607999). | ||
<a name="line" href="#line">#</a> <b>line</b>() | ||
… | ||
Constructs a new line generator with the default settings. | ||
<a name="_line" href="#_line">#</a> <i>line</i>(<i>data</i>) | ||
… | ||
Generates a line for the given array of *data*. Depending on this line generator’s associated [curve](#line_curve), the given input *data* may need to be sorted by *x*-value before being passed to the line generator. If the line generator has a [context](#line_context), then the line is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned. | ||
<a name="line_x" href="#line_x">#</a> <i>line</i>.<b>x</b>([<i>x</i>]) | ||
… | ||
If *x* is specified, sets the x accessor to the specified function or number and returns this line generator. If *x* is not specified, returns the current x accessor, which defaults to: | ||
```js | ||
function x(d) { | ||
return d[0]; | ||
} | ||
``` | ||
When a line is [generated](#_line), the x accessor will be invoked for each [defined](#line_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default x accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering, then you should specify a custom accessor. For example, if `x` is a [time scale](https://github.com/d3/d3-scale#time-scales) and `y` is a [linear scale](https://github.com/d3/d3-scale#linear-scales): | ||
```js | ||
var data = [ | ||
{date: new Date(2007, 3, 24), value: 93.24}, | ||
{date: new Date(2007, 3, 25), value: 95.35}, | ||
{date: new Date(2007, 3, 26), value: 98.84}, | ||
{date: new Date(2007, 3, 27), value: 99.92}, | ||
{date: new Date(2007, 3, 30), value: 99.80}, | ||
{date: new Date(2007, 4, 1), value: 99.47}, | ||
… | ||
]; | ||
var l = line() | ||
.x(function(d) { return x(d.date); }) | ||
.y(function(d) { return y(d.value); }); | ||
``` | ||
This is similar to [mapping](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) your data to values before invoking the line generator: | ||
```js | ||
line()(data.map(function(d) { return [x(d.date), y(d.value)]; })); | ||
``` | ||
The benefit of an accessor is that the input data remains associated with the returned objects, thereby making it easier to access other fields of the data, for example to set the color or to add text labels. | ||
<a name="line_y" href="#line_y">#</a> <i>line</i>.<b>y</b>([<i>y</i>]) | ||
… | ||
If *y* is specified, sets the y accessor to the specified function or number and returns this line generator. If *y* is not specified, returns the current y accessor, which defaults to: | ||
```js | ||
function y(d) { | ||
return d[1]; | ||
} | ||
``` | ||
When a line is [generated](#_line), the y accessor will be invoked for each [defined](#line_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default y accessor assumes that the input data are two-element arrays of numbers. See [*line*.x](#line_x) for more information. | ||
<a name="line_defined" href="#line_defined">#</a> <i>line</i>.<b>defined</b>([<i>defined</i>]) | ||
… | ||
If *defined* is specified, sets the defined accessor to the specified function or boolean and returns this line generator. If *defined* is not specified, returns the current defined accessor, which defaults to: | ||
```js | ||
function defined() { | ||
return true; | ||
} | ||
``` | ||
The default accessor thus assumes that the input data is always defined. When a line is [generated](#_line), the defined accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. If the given element is defined (*i.e.*, if the defined accessor returns a truthy value for this element), the [x](#line_x) and [y](#line_y) accessors will subsequently be evaluated and the point will be added to the current line segment. Otherwise, the element will be skipped, the current line segment will be ended, and a new line segment will be generated for the next defined point. As a result, the generated line may have several discrete segments. For example: | ||
[<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/line-defined.png" width="480" height="250" alt="Line with Missing Data">](http://bl.ocks.org/mbostock/0533f44f2cfabecc5e3a) | ||
Note that if a line segment consists of only a single point, it may appear invisible unless rendered with rounded or square [line caps](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap). In addition, some curves such as [cardinalOpen](#cardinalOpen) only render a visible segment if it contains multiple points. | ||
<a name="line_curve" href="#line_curve">#</a> <i>line</i>.<b>curve</b>([<i>curve</i>[, <i>parameters…</i>]]) | ||
… | ||
If *curve* is specified, sets the [curve factory](#curves) and returns this line generator. Any optional *parameters*, if specified, will be bound to the specified *curve*. If *curve* is not specified, returns the current curve factory, which defaults to [linear](#linear). | ||
<a name="line_context" href="#line_context">#</a> <i>line</i>.<b>context</b>([<i>context</i>]) | ||
… | ||
If *context* is specified, sets the context and returns this line generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated line](#_line) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated line is returned. | ||
### Areas | ||
… | ||
[<img alt="Area Chart" width="295" height="154" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/area.png">](http://bl.ocks.org/mbostock/3883195)[<img alt="Stacked Area Chart" width="295" height="154" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/area-stacked.png">](http://bl.ocks.org/mbostock/3885211)[<img alt="Difference Chart" width="295" height="154" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/area-difference.png">](http://bl.ocks.org/mbostock/3894205) | ||
The area generator produces an area, as in an area chart. An area is defined by two bounding [lines](#lines), either splines or polylines. Typically, the two lines share the same [*x*-values](#area_x) ([x0](#area_x0) = [x1](#area_x1)), differing only in *y*-value ([y0](#area_y0) and [y1](#area_y1)); most commonly, y0 is defined as a constant representing [zero](http://www.vox.com/2015/11/19/9758062/y-axis-zero-chart). The first line (the <i>topline</i>) is defined by x1 and y1 and is rendered first; the second line (the <i>baseline</i>) is defined by x0 and y0 and is rendered second, with the points in reverse order. With a [linear](#linear) [curve](#area_curve), this produces a clockwise polygon. | ||
<a name="area" href="#area">#</a> <b>area</b>() | ||
… | ||
Constructs a new area generator with the default settings. | ||
<a name="_area" href="#_area">#</a> <i>area</i>(<i>data</i>) | ||
… | ||
Generates an area for the given array of *data*. Depending on this area generator’s associated [curve](#area_curve), the given input *data* may need to be sorted by *x*-value before being passed to the area generator. If the area generator has a [context](#line_context), then the area is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned. | ||
<a name="area_x" href="#area_x">#</a> <i>area</i>.<b>x</b>([<i>x</i>]) | ||
… | ||
If *x* is specified, sets [x0](#area_x0) to *x* and [x1](#area_x1) to null and returns this area generator. If *x* is not specified, returns the current x0 accessor. | ||
<a name="area_x0" href="#area_x0">#</a> <i>area</i>.<b>x0</b>([<i>x0</i>]) | ||
<a name="area_x0" href="#area_x0">#</a> <i>area</i>.<b>x0</b>([<i>x</i>]) | ||
… | ||
If *x* is specified, sets the x0 accessor to the specified function or number and returns this area generator. If *x* is not specified, returns the current x0 accessor, which defaults to: | ||
<a name="area_x1" href="#area_x1">#</a> <i>area</i>.<b>x1</b>([<i>x1</i>]) | ||
```js | ||
function x(d) { | ||
return d[0]; | ||
} | ||
``` | ||
… | ||
When an area is [generated](#_area), the x0 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default x0 accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering, then you should specify a custom accessor. For example, if `x` is a [time scale](https://github.com/d3/d3-scale#time-scales) and `y` is a [linear scale](https://github.com/d3/d3-scale#linear-scales): | ||
```js | ||
var data = [ | ||
{date: new Date(2007, 3, 24), value: 93.24}, | ||
{date: new Date(2007, 3, 25), value: 95.35}, | ||
{date: new Date(2007, 3, 26), value: 98.84}, | ||
{date: new Date(2007, 3, 27), value: 99.92}, | ||
{date: new Date(2007, 3, 30), value: 99.80}, | ||
{date: new Date(2007, 4, 1), value: 99.47}, | ||
… | ||
]; | ||
var a = area() | ||
.x(function(d) { return x(d.date); }) | ||
.y1(function(d) { return y(d.value); }) | ||
.y0(y(0)); | ||
``` | ||
<a name="area_x1" href="#area_x1">#</a> <i>area</i>.<b>x1</b>([<i>x</i>]) | ||
If *x* is specified, sets the x1 accessor to the specified function or number and returns this area generator. If *x* is not specified, returns the current x1 accessor, which defaults to null, indicating that the previously-computed [x0](#area_x0) value should be reused for the x1 value. | ||
When an area is [generated](#_area), the x1 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information. | ||
<a name="area_y" href="#area_y">#</a> <i>area</i>.<b>y</b>([<i>y</i>]) | ||
… | ||
If *y* is specified, sets [y0](#area_y0) to *y* and [y1](#area_y1) to null and returns this area generator. If *y* is not specified, returns the current y0 accessor. | ||
<a name="area_y0" href="#area_y0">#</a> <i>area</i>.<b>y0</b>([<i>y0</i>]) | ||
<a name="area_y0" href="#area_y0">#</a> <i>area</i>.<b>y0</b>([<i>y</i>]) | ||
… | ||
If *y* is specified, sets the y0 accessor to the specified function or number and returns this area generator. If *y* is not specified, returns the current y0 accessor, which defaults to: | ||
<a name="area_y1" href="#area_y1">#</a> <i>area</i>.<b>y1</b>([<i>y1</i>]) | ||
```js | ||
function y() { | ||
return 0; | ||
} | ||
``` | ||
… | ||
When an area is [generated](#_area), the y0 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information. | ||
<a name="area_y1" href="#area_y1">#</a> <i>area</i>.<b>y1</b>([<i>y</i>]) | ||
If *y* is specified, sets the y1 accessor to the specified function or number and returns this area generator. If *y* is not specified, returns the current y1 accessor, which defaults to: | ||
```js | ||
function y(d) { | ||
return d[1]; | ||
} | ||
``` | ||
A null accessor is also allowed, indicating that the previously-computed [y0](#area_y0) value should be reused for the y1 value. When an area is [generated](#_area), the y1 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information. | ||
<a name="area_defined" href="#area_defined">#</a> <i>area</i>.<b>defined</b>([<i>defined</i>]) | ||
… | ||
If *defined* is specified, sets the defined accessor to the specified function or boolean and returns this area generator. If *defined* is not specified, returns the current defined accessor, which defaults to: | ||
```js | ||
function defined() { | ||
return true; | ||
} | ||
``` | ||
The default accessor thus assumes that the input data is always defined. When an area is [generated](#_area), the defined accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. If the given element is defined (*i.e.*, if the defined accessor returns a truthy value for this element), the [x0](#area_x0), [x1](#area_x1), [y0](#area_y0) and [y1](#area_y1) accessors will subsequently be evaluated and the point will be added to the current area segment. Otherwise, the element will be skipped, the current area segment will be ended, and a new area segment will be generated for the next defined point. As a result, the generated area may have several discrete segments. For example: | ||
[<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/area-defined.png" width="480" height="250" alt="Area with Missing Data">](http://bl.ocks.org/mbostock/3035090) | ||
Note that if an area segment consists of only a single point, it may appear invisible unless rendered with rounded or square [line caps](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap). In addition, some curves such as [cardinalOpen](#cardinalOpen) only render a visible segment if it contains multiple points. | ||
<a name="area_curve" href="#area_curve">#</a> <i>area</i>.<b>curve</b>([<i>curve</i>[, <i>parameters…</i>]]) | ||
… | ||
If *curve* is specified, sets the [curve factory](#curves) and returns this area generator. Any optional *parameters*, if specified, will be bound to the specified *curve*. If *curve* is not specified, returns the current curve factory, which defaults to [linear](#linear). | ||
Unlike [*line*.curve](#line_curve), this method **requires** that the curve implement [*curve*.areaStart](#curve_areaStart) and [*curve*.areaEnd](#curve_areaEnd); you cannot use closed curves such as [cardinalClosed](#cardinalClosed) with an area generator. Instead, a closed shape is produced by first rendering the topline and then rendering the baseline. | ||
<a name="area_context" href="#area_context">#</a> <i>area</i>.<b>context</b>([<i>context</i>]) | ||
… | ||
If *context* is specified, sets the context and returns this area generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated area](#_area) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated area is returned. | ||
### Curves | ||
Curves are typically not used directly, instead implementing paths for [lines](#lines) and [areas](#areas); they are passed to [*line*.curve](#line_curve) and [*area*.curve](#area_curve). | ||
While [lines](#lines) are defined as a sequence of two-dimensional [*x*, *y*] points, and [areas](#areas) are similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape: *i.e.*, how to interpolate between the points. A variety of curves are provided for this purpose. | ||
… | ||
Curves are typically not constructed or used directly, instead being passed to [*line*.curve](#line_curve) and [*area*.curve](#area_curve). | ||
<a name="basis" href="#basis">#</a> <b>basis</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/basis.png" width="888" height="240" alt="basis"> | ||
Produces a cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. The first and last points are triplicated such that the spline starts at the first point and ends at the last point, and is tangent to the line between the first and second points, and to the line between the penultimate and last points. | ||
<a name="basisClosed" href="#basisClosed">#</a> <b>basisClosed</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/basisClosed.png" width="888" height="240" alt="basisClosed"> | ||
Produces a closed cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. When a line segment ends, the first three control points are repeated, producing a closed loop with C2 continuity. | ||
<a name="basisOpen" href="#basisOpen">#</a> <b>basisOpen</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/basisOpen.png" width="888" height="240" alt="basisOpen"> | ||
Produces a cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. Unlike [basis](#basis), the first and last points are not repeated, and thus the curve typically does not intersect these points. | ||
<a name="bundle" href="#bundle">#</a> <b>bundle</b>(<i>context</i>[, <i>beta</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/bundle.png" width="888" height="240" alt="bundle"> | ||
Produces a straighted cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points, with the spline straightened according to the specified parameter *beta* in the range [0, 1]. If *beta* equals zero, a straight line between the first and last point is produced; if *beta* equals one, a standard [basis](#basis) spline is produced. If *beta* is not specified, it defaults to 0.85. This curve is typically used in [hierarchical edge bundling](http://bl.ocks.org/mbostock/7607999) to disambiguate connections, as proposed by [Danny Holten](https://www.win.tue.nl/vis1/home/dholten/) in [Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data](https://www.win.tue.nl/vis1/home/dholten/papers/bundles_infovis.pdf); *beta* represents the bundle strength. | ||
<a name="cardinal" href="#cardinal">#</a> <b>cardinal</b>(<i>context</i>[, <i>tension</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/cardinal.png" width="888" height="240" alt="cardinal"> | ||
Produces a cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points, with one-sided differences used for the first and last piece. The *tension* parameter in the range [0, 1] determines the length of the tangents: a *tension* of one yields all zero tangents, equivalent to [linear](#linear); a *tension* of zero produces a uniform [Catmull–Rom](#catmullRom) spline. If *tension* is not specified, it defaults to zero. | ||
<a name="cardinalClosed" href="#cardinalClosed">#</a> <b>cardinalClosed</b>(<i>context</i>[, <i>tension</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/cardinalClosed.png" width="888" height="240" alt="cardinalClosed"> | ||
Produces a closed cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points. When a line segment ends, the first three control points are repeated, producing a closed loop. The *tension* parameter in the range [0, 1] determines the length of the tangents: a *tension* of one yields all zero tangents, equivalent to [linearClosed](#linearClosed); a *tension* of zero produces a closed uniform [Catmull–Rom](#catmullRomClosed) spline. | ||
<a name="cardinalOpen" href="#cardinalOpen">#</a> <b>cardinalOpen</b>(<i>context</i>[, <i>tension</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/cardinalOpen.png" width="888" height="240" alt="cardinalOpen"> | ||
Produces a cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points. Unlike [cardinal](#cardinal), one-sided differences are not used for the first and last piece, and thus the curve starts at the second point and ends at the penultimate point. | ||
<a name="catmullRom" href="#catmullRom">#</a> <b>catmullRom</b>(<i>context</i>[, <i>alpha</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRom.png" width="888" height="240" alt="catmullRom"> | ||
Produces a cubic Catmull–Rom spline using the specified control points and the parameter *alpha*, as proposed by Yuksel et al. in [On the Parameterization of Catmull–Rom Curves](http://www.cemyuksel.com/research/catmullrom_param/), with one-sided differences used for the first and last piece. If *alpha* is zero, produces a uniform spline, equivalent to [cardinal](#cardinal) with a tension of zero; if *alpha* is one, produces a chordal spline; if *alpha* is 0.5, produces a [centripetal spline](https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline). If *alpha* is not specified, it defaults to 0.5. Centripetal splines are recommended to avoid self-intersections and overshoot. | ||
<a name="catmullRomClosed" href="#catmullRomClosed">#</a> <b>catmullRomClosed</b>(<i>context</i>[, <i>alpha</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRomClosed.png" width="888" height="330" alt="catmullRomClosed"> | ||
Produces a closed cubic Catmull–Rom spline using the specified control points and the parameter *alpha*, as proposed by Yuksel et al. When a line segment ends, the first three control points are repeated, producing a closed loop. If *alpha* is zero, produces a uniform spline, equivalent to [cardinalClosed](#cardinalClosed) with a tension of zero; if *alpha* is one, produces a chordal spline; if *alpha* is 0.5, produces a [centripetal spline](https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline). If *alpha* is not specified, it defaults to 0.5. Centripetal splines are recommended to avoid self-intersections and overshoot. | ||
<a name="catmullRomOpen" href="#catmullRomOpen">#</a> <b>catmullRomOpen</b>(<i>context</i>[, <i>alpha</i>]) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/catmullRomOpen.png" width="888" height="240" alt="catmullRomOpen"> | ||
Produces a cubic Catmull–Rom spline using the specified control points and the parameter *alpha*, as proposed by Yuksel et al. Unlike [catmullRom](#catmullRom), one-sided differences are not used for the first and last piece, and thus the curve starts at the second point and ends at the penultimate point. If *alpha* is zero, produces a uniform spline, equivalent to [cardinalOpen](#cardinalOpen) with a tension of zero; if *alpha* is one, produces a chordal spline; if *alpha* is 0.5, produces a [centripetal spline](https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline). If *alpha* is not specified, it defaults to 0.5. Centripetal splines are recommended to avoid self-intersections and overshoot. | ||
<a name="linear" href="#linear">#</a> <b>linear</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/linear.png" width="888" height="240" alt="linear"> | ||
Produces a polyline through the specified points. | ||
<a name="linearClosed" href="#linearClosed">#</a> <b>linearClosed</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/linearClosed.png" width="888" height="240" alt="linearClosed"> | ||
Produces a closed polyline through the specified points by repeating the first point when the line segment ends. | ||
<a name="monotone" href="#monotone">#</a> <b>monotone</b>(<i>context</i>) | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/monotone.png" width="888" height="240" alt="monotone"> | ||
Produces a cubic spline that [preserves monotonicity](https://en.wikipedia.org/wiki/Monotone_cubic_interpolation) in *y*, as proposed by Steffen in [A simple method for monotonic interpolation in one dimension](http://adsabs.harvard.edu/full/1990A%26A...239..443S): “a smooth curve with continuous first-order derivatives that passes through any given set of data points without spurious oscillations. Local extrema can occur only at grid points where they are given by the data, but not in between two adjacent grid points.” Assumes that the input data is monotonic in *x*. | ||
<a name="natural" href="#natural">#</a> <b>natural</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/natural.png" width="888" height="240" alt="natural"> | ||
Produces a [natural](https://en.wikipedia.org/wiki/Spline_interpolation) [cubic spline](http://mathworld.wolfram.com/CubicSpline.html) with the second derivative of the spline set to zero at the endpoints. | ||
<a name="step" href="#step">#</a> <b>step</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/step.png" width="888" height="240" alt="step"> | ||
Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes at the midpoint of each pair of adjacent *x*-values. | ||
<a name="stepAfter" href="#stepAfter">#</a> <b>stepAfter</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/stepAfter.png" width="888" height="240" alt="stepAfter"> | ||
Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes after the *x*-value. | ||
<a name="stepBefore" href="#stepBefore">#</a> <b>stepBefore</b>(<i>context</i>) | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/stepBefore.png" width="888" height="240" alt="stepBefore"> | ||
Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes before the *x*-value. | ||
### Custom Curves | ||
Curves are typically not used directly, instead being passed to [*line*.curve](#line_curve) and [*area*.curve](#area_curve). However, you can define your own curve implementation should none of the built-in curves satisfy your needs using the following interface. You can also use this low-level interface with a built-in curve type as an alternative to the line and area generators. | ||
<a name="curve_areaStart" href="#curve_areaStart">#</a> <i>curve</i>.<b>areaStart</b>() | ||
… | ||
Indicates the start of a new area segment. Each area segment consists of exactly two [line segments](#curve_lineStart): the topline, followed by the baseline, with the baseline points in reverse order. Note: this method need not be implemented by closed curves, such as <a href="#linearClosed">linearClosed</a>. | ||
Note: not implemented by closed curves, such as <a href="#linearClosed">linearClosed</a>. | ||
<a name="curve_areaEnd" href="#curve_areaEnd">#</a> <i>curve</i>.<b>areaEnd</b>() | ||
… | ||
Indicates the end of the current area segment. Note: this method need not be implemented by closed curves, such as <a href="#linearClosed">linearClosed</a>. | ||
Note: not implemented by closed curves, such as <a href="#linearClosed">linearClosed</a>. | ||
<a name="curve_lineStart" href="#curve_lineStart">#</a> <i>curve</i>.<b>lineStart</b>() | ||
… | ||
Indicates the start of a new line segment. Zero or more [points](#curve_point) will follow. | ||
<a name="curve_lineEnd" href="#curve_lineEnd">#</a> <i>curve</i>.<b>lineEnd</b>() | ||
… | ||
Indicates the end of the current line segment. | ||
<a name="curve_point" href="#curve_point">#</a> <i>curve</i>.<b>point</b>(<i>x</i>, <i>y</i>) | ||
… | ||
Indicates a new point in the current line segment with the given *x*- and *y*-values. | ||
### Symbols | ||
… | ||
Symbols provide a categorical shape encoding as is commonly used in scatterplots. Symbols are always centered at ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to move the arc to a different position. | ||
<a name="symbol" href="#symbol">#</a> <b>symbol</b>() | ||
… | ||
Constructs a new symbol generator with the default settings. | ||
<a name="_symbol" href="#_symbol">#</a> <i>symbol</i>(<i>arguments</i>…) | ||
Generates a symbol for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the symbol generator’s accessor functions along with the `this` object. For example, with the default settings, no arguments are needed to produce a circle with area 64 square pixels. If the symbol generator has a [context](#symbol_context), then the symbol is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned. | ||
<a name="symbol_type" href="#symbol_type">#</a> <i>symbol</i>.<b>type</b>([<i>type</i>]) | ||
… | ||
If *type* is specified, sets the symbol type and returns this line generator. If *type* is not specified, returns the current symbol type, which defaults to [circle](#circle). See [symbols](#symbols) for the set of built-in symbol types. | ||
<a name="symbol_size" href="#symbol_size">#</a> <i>symbol</i>.<b>size</b>([<i>size</i>]) | ||
… | ||
If *size* is specified, sets the size to the specified function or number and returns this symbol generator. If *size* is not specified, returns the current size accessor, which defaults to: | ||
<a name="symbol_context" href="#symbol_context">#</a> <i>symbol</i>.<b>context</b>([<i>context</i>]) | ||
```js | ||
function size() { | ||
return 64; | ||
} | ||
``` | ||
… | ||
Specifying the size as a function is useful for constructing a scatterplot with a size encoding. If you wish to scale the symbol to fit a given bounding box, rather than by area, try [SVG’s getBBox](http://bl.ocks.org/mbostock/3dd515e692504c92ab65). | ||
### Symbol Types | ||
<a name="symbol_context" href="#symbol_context">#</a> <i>symbol</i>.<b>context</b>([<i>context</i>]) | ||
Symbol types are typically not used directly, instead implementing paths for [symbols](#symbols); they are passed to [*symbol*.type](#symbol_type). | ||
If *context* is specified, sets the context and returns this symbol generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated symbol](#_symbol) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated symbol is returned. | ||
… | ||
<a name="symbols" href="#symbols">#</a> <b>symbols</b> | ||
@@ -275,27 +686,43 @@ | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/circle.png" width="100" height="100"> | ||
A circle. | ||
<a name="cross" href="#cross">#</a> <b>cross</b> | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/cross.png" width="100" height="100"> | ||
A Greek cross with arms of equal length. | ||
<a name="diamond" href="#diamond">#</a> <b>diamond</b> | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/diamond.png" width="100" height="100"> | ||
A rhombus. | ||
<a name="square" href="#square">#</a> <b>square</b> | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/square.png" width="100" height="100"> | ||
A square. | ||
<a name="triangleDown" href="#triangleDown">#</a> <b>triangleDown</b> | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/triangleDown.png" width="100" height="100"> | ||
A down-pointing triangle. | ||
<a name="triangleUp" href="#triangleUp">#</a> <b>triangleUp</b> | ||
… | ||
<img src="https://raw.githubusercontent.com/d3/d3-shape/master/img/triangleUp.png" width="100" height="100"> | ||
An up-pointing triangle. | ||
### Custom Symbol Types | ||
Symbol types are typically not used directly, instead being passed to [*symbol*.type](#symbol_type). However, you can define your own sumbol type implementation should none of the built-in types satisfy your needs using the following interface. You can also use this low-level interface with a built-in symbol type as an alternative to the symbol generator. | ||
<a name="symbolType_draw" href="#symbolType_draw">#</a> <i>symbolType</i>.<b>draw</b>(<i>context</i>, <i>size</i>) | ||
… | ||
Renders this symbol type to the specified *context* with the specified *size* in square pixels. The *context* implements the [CanvasPathMethods](http://www.w3.org/TR/2dcontext/#canvaspathmethods) interface. (Note that this is a subset of the CanvasRenderingContext2D interface!) | ||
@@ -306,3 +733,3 @@ ## Changes from D3 3.x: | ||
* The interpretation of the [cardinal](#cardinal) spline tension parameter has been fixed. The default tension is now 0 (corresponding to a uniform Catmull–Rom spline), not 0.7. Due to a bug in 3.x, the tension parameter was previously only valid in the range [2/3, 1]; this corresponds to the new corrected range of [0, 1]. Thus, the new default value of 0 is equivalent to the old value of 2/3, and the default behavior is only slightly changed. | ||
* The interpretation of the [cardinal](#cardinal) spline tension parameter has been fixed. The default cardinal tension is now 0 (corresponding to a uniform Catmull–Rom spline), not 0.7. Due to a bug in 3.x, the tension parameter was previously only valid in the range [2/3, 1]; this corresponds to the new corrected range of [0, 1]. Thus, the new default value of 0 is equivalent to the old value of 2/3, and the default behavior is only slightly changed. | ||
@@ -309,0 +736,0 @@ * To specify a [cardinal](#cardinal) spline tension of *t*, use `line.curve(cardinal, t)` instead of `line.interpolate("cardinal").tension(t)`. |
@@ -93,9 +93,9 @@ import {path} from "d3-path"; | ||
function arc(d, i) { | ||
function arc() { | ||
var buffer, | ||
r, | ||
r0 = +innerRadius(d, i), | ||
r1 = +outerRadius(d, i), | ||
a0 = startAngle(d, i) - piHalf, | ||
a1 = endAngle(d, i) - piHalf, | ||
r0 = +innerRadius.apply(this, arguments), | ||
r1 = +outerRadius.apply(this, arguments), | ||
a0 = startAngle.apply(this, arguments) - piHalf, | ||
a1 = endAngle.apply(this, arguments) - piHalf, | ||
da = Math.abs(a1 - a0), | ||
@@ -130,5 +130,5 @@ cw = a1 > a0; | ||
da1 = da, | ||
ap = padAngle(d, i) / 2, | ||
rp = (ap > 0) && (padRadius ? +padRadius(d, i) : Math.sqrt(r0 * r0 + r1 * r1)), | ||
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius(d, i)), | ||
ap = padAngle.apply(this, arguments) / 2, | ||
rp = (ap > 0) && (padRadius ? +padRadius.apply(this, arguments) : Math.sqrt(r0 * r0 + r1 * r1)), | ||
rc = Math.min(Math.abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), | ||
rc0 = rc, | ||
@@ -228,5 +228,5 @@ rc1 = rc; | ||
arc.centroid = function(d, i) { | ||
var r = (+innerRadius(d, i) + +outerRadius(d, i)) / 2, | ||
a = (+startAngle(d, i) + +endAngle(d, i)) / 2 - Math.PI / 2; | ||
arc.centroid = function() { | ||
var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, | ||
a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2; | ||
return [Math.cos(a) * r, Math.sin(a) * r]; | ||
@@ -233,0 +233,0 @@ }; |
import {path} from "d3-path"; | ||
import constant from "./constant"; | ||
import curveBind from "./curve/bind"; | ||
import curveLinear from "./curve/linear"; | ||
import curveCurry from "./curve/curry"; | ||
import {x as pointX, y as pointY} from "./point"; | ||
@@ -31,3 +31,3 @@ | ||
for (i = 0; i <= n; ++i) { | ||
if (!(i < n && defined(d = data[i], i)) === defined0) { | ||
if (!(i < n && defined(d = data[i], i, data)) === defined0) { | ||
if (defined0 = !defined0) { | ||
@@ -48,4 +48,4 @@ j = i; | ||
if (defined0) { | ||
x0z[i] = +x0(d, i), y0z[i] = +y0(d, i); | ||
output.point(x1 ? +x1(d, i) : x0z[i], y1 ? +y1(d, i) : y0z[i]); | ||
x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); | ||
output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); | ||
} | ||
@@ -87,3 +87,3 @@ } | ||
var n = arguments.length; | ||
return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), area) : curve; | ||
return n ? (curve = n > 1 ? curveBind(_, arguments) : _, context != null && (output = curve(context)), area) : curve; | ||
}; | ||
@@ -90,0 +90,0 @@ |
import basis from "./basis"; | ||
function bundle(context, beta) { | ||
return beta == null || (beta = +beta) === 1 | ||
? basis(context) | ||
return beta == null ? new Bundle(context, 0.85) | ||
: (beta = +beta) === 1 ? basis(context) | ||
: new Bundle(context, beta); | ||
@@ -7,0 +7,0 @@ } |
@@ -29,5 +29,5 @@ import cardinal from "./cardinal"; | ||
function catmullRom(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinal(context, 0) | ||
: new CatmullRom(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRom(context, alpha) | ||
: cardinal(context, 0); | ||
} | ||
@@ -34,0 +34,0 @@ |
@@ -5,5 +5,5 @@ import cardinalClosed from "./cardinalClosed"; | ||
function catmullRomClosed(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinalClosed(context, 0) | ||
: new CatmullRomClosed(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRomClosed(context, alpha) | ||
: cardinalClosed(context, 0); | ||
} | ||
@@ -10,0 +10,0 @@ |
@@ -5,5 +5,5 @@ import cardinalOpen from "./cardinalOpen"; | ||
function catmullRomOpen(context, alpha) { | ||
return alpha == null || !(alpha = +alpha) | ||
? cardinalOpen(context, 0) | ||
: new CatmullRomOpen(context, alpha); | ||
return (alpha = alpha == null ? 0.5 : +alpha) | ||
? new CatmullRomOpen(context, alpha) | ||
: cardinalOpen(context, 0); | ||
} | ||
@@ -10,0 +10,0 @@ |
@@ -1,80 +0,83 @@ | ||
// Computes the slope from points p0 to p1. | ||
function slope(p0, p1) { | ||
return (p1[1] - p0[1]) / (p1[0] - p0[0]); | ||
function sign(x) { | ||
return x < 0 ? -1 : 1; | ||
} | ||
// Compute three-point differences for the given points. | ||
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference | ||
function finiteDifferences(points) { | ||
var i = 0, | ||
j = points.length - 1, | ||
m = [], | ||
p0 = points[0], | ||
p1 = points[1], | ||
d = m[0] = slope(p0, p1); | ||
while (++i < j) { | ||
m[i] = (d + (d = slope(p0 = p1, p1 = points[i + 1]))) / 2; | ||
} | ||
m[i] = d; | ||
return m; | ||
// Calculate the slopes of the tangents (Hermite-type interpolation) based on | ||
// the following paper: Steffen, M. 1990. A Simple Method for Monotonic | ||
// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. | ||
// NOV(II), P. 443, 1990. | ||
function slope3(that, x2, y2) { | ||
var h0 = that._x1 - that._x0, | ||
h1 = x2 - that._x1, | ||
s0 = (that._y1 - that._y0) / h0, | ||
s1 = (y2 - that._y1) / h1, | ||
p = (s0 * h1 + s1 * h0) / (h0 + h1); | ||
return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; | ||
} | ||
// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite | ||
// interpolation. Returns an array of tangent vectors. For details, see | ||
// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation | ||
function monotoneTangents(points) { | ||
var tangents = [], | ||
d, | ||
a, | ||
b, | ||
s, | ||
m = finiteDifferences(points), | ||
i = -1, | ||
j = points.length - 1; | ||
// Calculate a one-sided slope. | ||
function slope2(that, t) { | ||
var h = that._x1 - that._x0; | ||
return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; | ||
} | ||
// The first two steps are done by computing finite-differences: | ||
// 1. Compute the slopes of the secant lines between successive points. | ||
// 2. Initialize the tangents at every point as the average of the secants. | ||
// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations | ||
// "you can express cubic Hermite interpolation in terms of cubic Bézier curves | ||
// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". | ||
function point(that, t0, t1) { | ||
var x0 = that._x0, | ||
y0 = that._y0, | ||
x1 = that._x1, | ||
y1 = that._y1, | ||
dx = (x1 - x0) / 3; | ||
that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); | ||
} | ||
// Then, for each segment… | ||
while (++i < j) { | ||
d = slope(points[i], points[i + 1]); | ||
function monotone(context) { | ||
return new Monotone(context); | ||
} | ||
// 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set | ||
// mk = m{k + 1} = 0 as the spline connecting these points must be flat to | ||
// preserve monotonicity. Ignore step 4 and 5 for those k. | ||
function Monotone(context) { | ||
this._context = context; | ||
} | ||
if (abs(d) < ε) { | ||
m[i] = m[i + 1] = 0; | ||
} else { | ||
// 4. Let ak = mk / dk and bk = m{k + 1} / dk. | ||
a = m[i] / d; | ||
b = m[i + 1] / d; | ||
Monotone.prototype = { | ||
areaStart: function() { | ||
this._line = 0; | ||
}, | ||
areaEnd: function() { | ||
this._line = NaN; | ||
}, | ||
lineStart: function() { | ||
this._x0 = this._x1 = | ||
this._y0 = this._y1 = | ||
this._t0 = NaN; | ||
this._point = 0; | ||
}, | ||
lineEnd: function() { | ||
switch (this._point) { | ||
case 2: this._context.lineTo(this._x1, this._y1); break; | ||
case 3: point(this, this._t0, slope2(this, this._t0)); break; | ||
} | ||
if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); | ||
this._line = 1 - this._line; | ||
}, | ||
point: function(x, y) { | ||
var t1 = NaN; | ||
// 5. Prevent overshoot and ensure monotonicity by restricting the | ||
// magnitude of vector <ak, bk> to a circle of radius 3. | ||
s = a * a + b * b; | ||
if (s > 9) { | ||
s = d * 3 / Math.sqrt(s); | ||
m[i] = s * a; | ||
m[i + 1] = s * b; | ||
} | ||
x = +x, y = +y; | ||
if (x === this._x1 && y === this._y1) return; // Ignore coincident points. | ||
switch (this._point) { | ||
case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; | ||
case 1: this._point = 2; break; | ||
case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break; | ||
default: point(this, this._t0, t1 = slope3(this, x, y)); break; | ||
} | ||
} | ||
// Compute the normalized tangent vector from the slopes. Note that if x is | ||
// not monotonic, it's possible that the slope will be infinite, so we protect | ||
// against NaN by setting the coordinate to zero. | ||
i = -1; while (++i <= j) { | ||
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); | ||
tangents.push([s || 0, m[i] * s || 0]); | ||
this._x0 = this._x1, this._x1 = x; | ||
this._y0 = this._y1, this._y1 = y; | ||
this._t0 = t1; | ||
} | ||
return tangents; | ||
} | ||
export function interpolateMonotone(points) { | ||
return points.length < 3 | ||
? interpolateLinear(points) | ||
: points[0] + interpolateHermite(points, monotoneTangents(points)); | ||
}; | ||
export default monotone; |
import {path} from "d3-path"; | ||
import constant from "./constant"; | ||
import curveBind from "./curve/bind"; | ||
import curveLinear from "./curve/linear"; | ||
import curveCurry from "./curve/curry"; | ||
import {x as pointX, y as pointY} from "./point"; | ||
@@ -25,7 +25,7 @@ | ||
for (i = 0; i <= n; ++i) { | ||
if (!(i < n && defined(d = data[i], i)) === defined0) { | ||
if (!(i < n && defined(d = data[i], i, data)) === defined0) { | ||
if (defined0 = !defined0) output.lineStart(); | ||
else output.lineEnd(); | ||
} | ||
if (defined0) output.point(+x(d, i), +y(d, i)); | ||
if (defined0) output.point(+x(d, i, data), +y(d, i, data)); | ||
} | ||
@@ -50,3 +50,3 @@ | ||
var n = arguments.length; | ||
return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), line) : curve; | ||
return n ? (curve = n > 1 ? curveBind(_, arguments) : _, context != null && (output = curve(context)), line) : curve; | ||
}; | ||
@@ -53,0 +53,0 @@ |
@@ -23,6 +23,6 @@ import {path} from "d3-path"; | ||
function symbol(d, i) { | ||
function symbol() { | ||
var buffer; | ||
if (!context) context = buffer = path(); | ||
type(d, i).draw(context, +size(d, i)); | ||
type.apply(this, arguments).draw(context, +size.apply(this, arguments)); | ||
if (buffer) return context = null, buffer + "" || null; | ||
@@ -29,0 +29,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
938753
77
2652
744
0