Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Radial lines and areas! #45

Merged
merged 8 commits into from
Dec 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 70 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,32 @@ If *curve* is specified, sets the [curve factory](#curves) and returns this line

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.

<a name="radialLine" href="#radialLine">#</a> <b>radialLine</b>()

<img alt="Radial Line" width="250" height="250" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/line-radial.png">

Constructs a new radial line generator with the default settings. A radial line generator is equivalent to the standard Cartesian [line generator](#line), except the [x](#line_x) and [y](#line_y) accessors are replaced with [radius](#radialLine_radius) and [angle](#radialLine_angle) accessors, respectively. Radial lines are always positioned relative to ⟨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 change the origin.

<a name="radialLine_radius" href="#radialLine_radius">#</a> <i>radialLine</i>.<b>radius</b>([<i>radius</i>])

Equivalent to [*line*.x](#line_x), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.

<a name="radialLine_angle" href="#radialLine_angle">#</a> <i>radialLine</i>.<b>angle</b>([<i>angle</i>])

Equivalent to [*line*.y](#line_y), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock).

<a name="radialLine_defined" href="#radialLine_defined">#</a> <i>radialLine</i>.<b>defined</b>([<i>defined</i>])

Equivalent to [*line*.defined](#line_defined).

<a name="radialLine_curve" href="#radialLine_curve">#</a> <i>radialLine</i>.<b>curve</b>([<i>curve</i>[, <i>parameters…</i>]])

Equivalent to [*line*.curve](#line_curve). Note that the [monotone](#monotone) curve is not recommended for radial lines because it assumes that the data is monotonic in *x*, which is typically untrue of radial lines.

<a name="radialLine_context" href="#radialLine_context">#</a> <i>radialLine</i>.<b>context</b>([<i>context</i>])

Equivalent to [*line*.context](#line_context).

### 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)
Expand Down Expand Up @@ -506,12 +532,52 @@ Note that if an area segment consists of only a single point, it may appear invi

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.

<a name="radialArea" href="#radialArea">#</a> <b>radialArea</b>()

<img alt="Radial Area" width="250" height="250" src="https://raw.githubusercontent.com/d3/d3-shape/master/img/area-radial.png">

Constructs a new radial area generator with the default settings. A radial area generator is equivalent to the standard Cartesian [area generator](#area), except the [x](#area_x) and [y](#area_y) accessors are replaced with [radius](#radialArea_radius) and [angle](#radialArea_angle) accessors, respectively. Radial areas are always positioned relative to ⟨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 change the origin.

<a name="radialArea_radius" href="#radialArea_radius">#</a> <i>radialArea</i>.<b>radius</b>([<i>radius</i>])

Equivalent to [*area*.x](#area_x), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.

<a name="radialArea_innerRadius" href="#radialArea_innerRadius">#</a> <i>radialArea</i>.<b>innerRadius</b>([<i>radius</i>])

Equivalent to [*area*.x0](#area_x0), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.

<a name="radialArea_outerRadius" href="#radialArea_outerRadius">#</a> <i>radialArea</i>.<b>outerRadius</b>([<i>radius</i>])

Equivalent to [*area*.x1](#area_x1), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.

<a name="radialArea_angle" href="#radialArea_angle">#</a> <i>radialArea</i>.<b>angle</b>([<i>angle</i>])

Equivalent to [*area*.y](#area_y), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock).

<a name="radialArea_startAngle" href="#radialArea_startAngle">#</a> <i>radialArea</i>.<b>startAngle</b>([<i>angle</i>])

Equivalent to [*area*.y0](#area_y0), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock). Note: typically [angle](#radialArea_angle) is used instead of setting separate start and end angles.

<a name="radialArea_endAngle" href="#radialArea_endAngle">#</a> <i>radialArea</i>.<b>endAngle</b>([<i>angle</i>])

Equivalent to [*area*.y1](#area_y1), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock). Note: typically [angle](#radialArea_angle) is used instead of setting separate start and end angles.

<a name="radialArea_defined" href="#radialArea_defined">#</a> <i>radialArea</i>.<b>defined</b>([<i>defined</i>])

Equivalent to [*area*.defined](#area_defined).

<a name="radialArea_curve" href="#radialArea_curve">#</a> <i>radialArea</i>.<b>curve</b>([<i>curve</i>[, <i>parameters…</i>]])

Equivalent to [*area*.curve](#area_curve). Note that the [monotone](#monotone) curve is not recommended for radial areas because it assumes that the data is monotonic in *x*, which is typically untrue of radial areas.

<a name="radialArea_context" href="#radialArea_context">#</a> <i>radialArea</i>.<b>context</b>([<i>context</i>])

Equivalent to [*line*.context](#line_context).

### Curves

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.
Expand Down Expand Up @@ -626,11 +692,11 @@ Curves are typically not used directly, instead being passed to [*line*.curve](#

<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>.
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.

<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>.
Indicates the end of the current area segment.

<a name="curve_lineStart" href="#curve_lineStart">#</a> <i>curve</i>.<b>lineStart</b>()

Expand Down
Binary file added img/area-radial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/line-radial.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ 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 radialArea} from "./src/radialArea";
export {default as radialLine} from "./src/radialLine";
export {default as square} from "./src/symbol/square";
export {default as stepAfter} from "./src/curve/stepAfter";
export {default as stepBefore} from "./src/curve/stepBefore";
Expand Down
11 changes: 4 additions & 7 deletions src/arc.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {path} from "d3-path";
import constant from "./constant";

var pi = Math.PI,
piHalf = pi / 2,
tau = 2 * pi;
import {pi, halfPi, tau} from "./math";

function arcInnerRadius(d) {
return d.innerRadius;
Expand All @@ -26,7 +23,7 @@ function arcPadAngle(d) {
}

function asin(x) {
return x >= 1 ? piHalf : x <= -1 ? -piHalf : Math.asin(x);
return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
}

function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
Expand Down Expand Up @@ -95,8 +92,8 @@ export default function() {
r,
r0 = +innerRadius.apply(this, arguments),
r1 = +outerRadius.apply(this, arguments),
a0 = startAngle.apply(this, arguments) - piHalf,
a1 = endAngle.apply(this, arguments) - piHalf,
a0 = startAngle.apply(this, arguments) - halfPi,
a1 = endAngle.apply(this, arguments) - halfPi,
da = Math.abs(a1 - a0),
cw = a1 > a0;

Expand Down
7 changes: 3 additions & 4 deletions src/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default function() {
}

area.x = function(_) {
return arguments.length ? area.x0(_).x1(null) : x0;
return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0;
};

area.x0 = function(_) {
Expand All @@ -65,7 +65,7 @@ export default function() {
};

area.y = function(_) {
return arguments.length ? area.y0(_).y1(null) : y0;
return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0;
};

area.y0 = function(_) {
Expand All @@ -81,8 +81,7 @@ export default function() {
};

area.curve = function(_) {
var n = arguments.length;
return n ? (curve = n > 1 ? curveBind(_, arguments) : _, context != null && (output = curve(context)), area) : curve;
return arguments.length ? (curve = curveBind(_, arguments), context != null && (output = curve(context)), area) : curve;
};

area.context = function(_) {
Expand Down
8 changes: 3 additions & 5 deletions src/curve/basis.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ export function point(that, x, y) {
);
};

function basis(context) {
return new Basis(context);
}

function Basis(context) {
this._context = context;
}
Expand Down Expand Up @@ -50,4 +46,6 @@ Basis.prototype = {
}
};

export default basis;
export default function(context) {
return new Basis(context);
};
11 changes: 6 additions & 5 deletions src/curve/basisClosed.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import noop from "../noop";
import {point} from "./basis";

function basisClosed(context) {
return new BasisClosed(context);
}

function BasisClosed(context) {
this._context = context;
}

BasisClosed.prototype = {
areaStart: noop,
areaEnd: noop,
lineStart: function() {
this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
Expand Down Expand Up @@ -48,4 +47,6 @@ BasisClosed.prototype = {
}
};

export default basisClosed;
export default function(context) {
return new BasisClosed(context);
};
8 changes: 3 additions & 5 deletions src/curve/basisOpen.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import {point} from "./basis";

function basisOpen(context) {
return new BasisOpen(context);
}

function BasisOpen(context) {
this._context = context;
}
Expand Down Expand Up @@ -38,4 +34,6 @@ BasisOpen.prototype = {
}
};

export default basisOpen;
export default function(context) {
return new BasisOpen(context);
};
5 changes: 3 additions & 2 deletions src/curve/bind.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
var slice = Array.prototype.slice;

export default function(interpolate, args) {
export default function(curve, args) {
if (args.length < 2) return curve;
args = slice.call(args);
args[0] = null;
return function(context) {
args[0] = context;
return interpolate.apply(null, args);
return curve.apply(null, args);
};
};
12 changes: 5 additions & 7 deletions src/curve/bundle.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import basis from "./basis";

function bundle(context, beta) {
return beta == null ? new Bundle(context, 0.85)
: (beta = +beta) === 1 ? basis(context)
: new Bundle(context, beta);
}

function Bundle(context, beta) {
this._basis = basis(context);
this._beta = beta;
Expand Down Expand Up @@ -48,4 +42,8 @@ Bundle.prototype = {
}
};

export default bundle;
export default function(context, beta) {
return beta == null ? new Bundle(context, 0.85)
: (beta = +beta) === 1 ? basis(context)
: new Bundle(context, beta);
};
8 changes: 3 additions & 5 deletions src/curve/cardinal.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ export function point(that, x, y) {
);
};

function cardinal(context, tension) {
return new Cardinal(context, (tension == null ? 1 : 1 - tension) / 6);
}

function Cardinal(context, k) {
this._context = context;
this._k = k;
Expand Down Expand Up @@ -51,4 +47,6 @@ Cardinal.prototype = {
}
};

export default cardinal;
export default function(context, tension) {
return new Cardinal(context, (tension == null ? 1 : 1 - tension) / 6);
};
11 changes: 6 additions & 5 deletions src/curve/cardinalClosed.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import noop from "../noop";
import {point} from "./cardinal";

function cardinalClosed(context, tension) {
return new CardinalClosed(context, (tension == null ? 1 : 1 - tension) / 6);
}

function CardinalClosed(context, k) {
this._context = context;
this._k = k;
}

CardinalClosed.prototype = {
areaStart: noop,
areaEnd: noop,
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;
Expand Down Expand Up @@ -48,4 +47,6 @@ CardinalClosed.prototype = {
}
};

export default cardinalClosed;
export default function(context, tension) {
return new CardinalClosed(context, (tension == null ? 1 : 1 - tension) / 6);
};
8 changes: 3 additions & 5 deletions src/curve/cardinalOpen.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import {point} from "./cardinal";

function cardinalOpen(context, tension) {
return new CardinalOpen(context, (tension == null ? 1 : 1 - tension) / 6);
}

function CardinalOpen(context, k) {
this._context = context;
this._k = k;
Expand Down Expand Up @@ -39,4 +35,6 @@ CardinalOpen.prototype = {
}
};

export default cardinalOpen;
export default function(context, tension) {
return new CardinalOpen(context, (tension == null ? 1 : 1 - tension) / 6);
};
12 changes: 5 additions & 7 deletions src/curve/catmullRom.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,6 @@ export function point(that, x, y) {
that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
};

function catmullRom(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRom(context, alpha)
: cardinal(context, 0);
}

function CatmullRom(context, alpha) {
this._context = context;
this._alpha = alpha;
Expand Down Expand Up @@ -81,4 +75,8 @@ CatmullRom.prototype = {
}
};

export default catmullRom;
export default function(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRom(context, alpha)
: cardinal(context, 0);
};
15 changes: 8 additions & 7 deletions src/curve/catmullRomClosed.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import cardinalClosed from "./cardinalClosed";
import noop from "../noop";
import {point} from "./catmullRom";

function catmullRomClosed(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRomClosed(context, alpha)
: cardinalClosed(context, 0);
}

function CatmullRomClosed(context, alpha) {
this._context = context;
this._alpha = alpha;
}

CatmullRomClosed.prototype = {
areaStart: noop,
areaEnd: noop,
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;
Expand Down Expand Up @@ -63,4 +60,8 @@ CatmullRomClosed.prototype = {
}
};

export default catmullRomClosed;
export default function(context, alpha) {
return (alpha = alpha == null ? 0.5 : +alpha)
? new CatmullRomClosed(context, alpha)
: cardinalClosed(context, 0);
};
Loading