diff --git a/README.md b/README.md index 48159f9..db7ae75 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ If you use NPM, `npm install d3-shape`. Otherwise, download the [latest release] … -# line.interpolate([interpolate[, t]]) +# line.curve([curve[, parameters…]]) … @@ -80,7 +80,7 @@ If you use NPM, `npm install d3-shape`. Otherwise, download the [latest release] … -# area.interpolate([interpolate[, t]]) +# area.curve([curve[, parameters…]]) … @@ -88,31 +88,97 @@ If you use NPM, `npm install d3-shape`. Otherwise, download the [latest release] … -### Interpolators +### 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). + +… + +# curveBasis(context) + +… + +# curveBasisClosed(context) + +… + +# curveBasisOpen(context) + +… + +# curveBundle(context[, beta]) + +… + +# curveCardinal(context[, tension]) + +… + +# curveCardinalClosed(context[, tension]) + +… + +# curveCardinalOpen(context[, tension]) + +… + +# curveCatmullRom(context[, alpha]) + +… + +# curveCatmullRomClosed(context[, alpha]) + +… + +# curveCatmullRomOpen(context[, alpha]) + +… + +# curveLinear(context) + +… + +# curveLinearClosed(context) + +… + +# curveNatural(context) + +… + +# curveStep(context) + +… + +# curveStepAfter(context) … -# interpolate(context) +# curveStepBefore(context) … -# interpolator.areaStart() +# curve.areaStart() … -# interpolator.areaEnd() +Note: not implemented by closed curves, such as curveLinearClosed. + +# curve.areaEnd() … -# interpolator.lineStart() +Note: not implemented by closed curves, such as curveLinearClosed. + +# curve.lineStart() … -# interpolator.lineEnd() +# curve.lineEnd() … -# interpolator.point(x, y) +# curve.point(x, y) … @@ -136,30 +202,57 @@ If you use NPM, `npm install d3-shape`. Otherwise, download the [latest release] … +### Symbol Types + +Symbol types are typically not used directly, instead implementing paths for [symbols](#symbols); they are passed to [*symbol*.type](#symbol_type). + +… + # symbolTypes -An array containing the set of supported [symbol types](#symbol_type): +An array containing the set of all built-in symbol types: [circle](#symbolCircle), [cross](#symbolCross), [diamond](#symbolDiamond), [square](#symbolSquare), [downwards triangle](#symbolTriangleDown), and [upwards triangle](#symbolTriangleUp). Useful for constructing the range of an [ordinal scale](https://github.com/d3/d3-scale#ordinal-scales) should you wish to use a shape encoding for categorical data. + +# symbolCircle + +… + +# symbolCross + +… + +# symbolDiamond + +… + +# symbolSquare + +… + +# symbolTriangleDown + +… + +# symbolTriangleUp -* `circle` -* `cross` -* `diamond` -* `square` -* `triangle-down` -* `triangle-up` +… + +# symbolType.draw(context, size) + +… ## Changes from D3 3.x: -* You can now render shapes to Canvas by specifying a context (e.g., [*line*.context](#line_context))! +* You can now render shapes to Canvas by specifying a context (e.g., [*line*.context](#line_context))! See [d3-path](https://github.com/d3/d3-path) for how it works. -* The interpretation of the 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 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. -* To specify a Cardinal interpolation tension of *t*, use `line.interpolate("cardinal", t)` instead of `line.interpolate("cardinal").tension(t)`. +* To specify a [cardinal](#curveCardinal) spline tension of *t*, use `line.curve(curveCardinal, t)` instead of `line.interpolate("cardinal").tension(t)`. -* The custom interpolator API has changed. +* To specify a custom line or area interpolator, implement a [curve](#curves). -* Added “natural” cubic spline interpolation. +* Added [natural](#curveNatural) cubic splines. -* Added “catmull-rom” spline interpolation, parameterized by alpha. If α = 0, produces a uniform Catmull–Rom spline equivalent to a Cardinal spline with zero tension; if α = 0.5, produces a centripetal spline; if α = 1.0, produces a chordal spline. +* Added [Catmull–Rom](#curveCatmullRom) splines, parameterized by alpha. If α = 0, produces a uniform Catmull–Rom spline equivalent to a Cardinal spline with zero tension; if α = 0.5, produces a centripetal spline; if α = 1.0, produces a chordal spline. * By setting [*area*.x1](#area_x1) or [*area*.y1](#area_y1) to null, you can reuse the [*area*.x0](#area_x0) or [*area*.y0](#area_y0) value, rather than computing it twice. This is useful for nondeterministic values (e.g., jitter). diff --git a/index.js b/index.js index 0b1d71d..e94d740 100644 --- a/index.js +++ b/index.js @@ -1,3 +1,27 @@ export {default as area} from "./src/area"; export {default as line} from "./src/line"; + +export {default as curveBasisClosed} from "./src/curve/basis-closed"; +export {default as curveBasisOpen} from "./src/curve/basis-open"; +export {default as curveBasis} from "./src/curve/basis"; +export {default as curveBundle} from "./src/curve/bundle"; +export {default as curveCardinalClosed} from "./src/curve/cardinal-closed"; +export {default as curveCardinalOpen} from "./src/curve/cardinal-open"; +export {default as curveCardinal} from "./src/curve/cardinal"; +export {default as curveCatmullRomClosed} from "./src/curve/catmull-rom-closed"; +export {default as curveCatmullRomOpen} from "./src/curve/catmull-rom-open"; +export {default as curveCatmullRom} from "./src/curve/catmull-rom"; +export {default as curveLinearClosed} from "./src/curve/linear-closed"; +export {default as curveLinear} from "./src/curve/linear"; +export {default as curveNatural} from "./src/curve/natural"; +export {default as curveStepAfter} from "./src/curve/step-after"; +export {default as curveStepBefore} from "./src/curve/step-before"; +export {default as curveStep} from "./src/curve/step"; + export {default as symbol, symbolTypes} from "./src/symbol"; + +export {default as symbolCircle} from "./src/symbol/circle"; +export {default as symbolCross} from "./src/symbol/cross"; +export {default as symbolDiamond} from "./src/symbol/diamond"; +export {default as symbolSquare} from "./src/symbol/square"; +export {triangleDown as symbolTriangleDown, triangleUp as symbolTriangleUp} from "./src/symbol/triangle"; diff --git a/src/area.js b/src/area.js index 83b7713..c3bed04 100644 --- a/src/area.js +++ b/src/area.js @@ -1,27 +1,18 @@ import {path} from "d3-path"; -import basis from "./interpolate/basis"; -import basisOpen from "./interpolate/basis-open"; -import cardinal from "./interpolate/cardinal"; -import cardinalOpen from "./interpolate/cardinal-open"; -import catmullRom from "./interpolate/catmull-rom"; -import catmullRomOpen from "./interpolate/catmull-rom-open"; -import constant, {constantTrue, constantZero} from "./constant"; -import linear from "./interpolate/linear"; -import natural from "./interpolate/natural"; -import step from "./interpolate/step"; -import stepAfter from "./interpolate/step-after"; -import stepBefore from "./interpolate/step-before"; +import constant from "./constant"; +import curveLinear from "./curve/linear"; +import curveCurry from "./curve/curry"; import {x as pointX, y as pointY} from "./point"; export default function() { var x0 = pointX, x1 = null, - y0 = constantZero, + y0 = constant(0), y1 = pointY, - defined = constantTrue, + defined = constant(true), context = null, - interpolate = linear, - interpolator = null; + curve = curveLinear, + output = null; function area(data) { var i, @@ -34,31 +25,31 @@ export default function() { x0z = new Array(n), y0z = new Array(n); - if (!context) interpolator = interpolate(buffer = path()); + if (!context) output = curve(buffer = path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i)) === defined0) { if (defined0 = !defined0) { j = i; - interpolator.areaStart(); - interpolator.lineStart(); + output.areaStart(); + output.lineStart(); } else { - interpolator.lineEnd(); - interpolator.lineStart(); + output.lineEnd(); + output.lineStart(); for (k = i - 1; k >= j; --k) { - interpolator.point(x0z[k], y0z[k]); + output.point(x0z[k], y0z[k]); } - interpolator.lineEnd(); - interpolator.areaEnd(); + output.lineEnd(); + output.areaEnd(); } } if (defined0) { x0z[i] = +x0(d, i), y0z[i] = +y0(d, i); - interpolator.point(x1 ? +x1(d, i) : x0z[i], y1 ? +y1(d, i) : y0z[i]); + output.point(x1 ? +x1(d, i) : x0z[i], y1 ? +y1(d, i) : y0z[i]); } } - if (buffer) return interpolator = null, buffer + "" || null; + if (buffer) return output = null, buffer + "" || null; } area.x = function(_) { @@ -89,28 +80,13 @@ export default function() { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined; }; - area.interpolate = function(_, a) { - if (!arguments.length) return interpolate; - if (typeof _ === "function") interpolate = _; - else switch (_ + "") { - case "step": interpolate = step; break; - case "step-before": interpolate = stepBefore; break; - case "step-after": interpolate = stepAfter; break; - case "basis": interpolate = basis; break; - case "basis-open": interpolate = basisOpen; break; - case "cardinal": interpolate = cardinal(a); break; - case "cardinal-open": interpolate = cardinalOpen(a); break; - case "catmull-rom": interpolate = catmullRom(a); break; - case "catmull-rom-open": interpolate = catmullRomOpen(a); break; - case "natural": interpolate = natural; break; - default: interpolate = linear; break; - } - if (context != null) interpolator = interpolate(context); - return area; + area.curve = function(_) { + var n = arguments.length; + return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), area) : curve; }; area.context = function(_) { - return arguments.length ? (_ == null ? context = interpolator = null : interpolator = interpolate(context = _), area) : context; + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; }; return area; diff --git a/src/constant.js b/src/constant.js index ef00a83..df6c780 100644 --- a/src/constant.js +++ b/src/constant.js @@ -3,11 +3,3 @@ export default function(x) { return x; }; }; - -export function constantTrue() { - return true; -}; - -export function constantZero() { - return 0; -}; diff --git a/src/interpolate/basis-closed.js b/src/curve/basis-closed.js similarity index 100% rename from src/interpolate/basis-closed.js rename to src/curve/basis-closed.js diff --git a/src/interpolate/basis-open.js b/src/curve/basis-open.js similarity index 100% rename from src/interpolate/basis-open.js rename to src/curve/basis-open.js diff --git a/src/interpolate/basis.js b/src/curve/basis.js similarity index 100% rename from src/interpolate/basis.js rename to src/curve/basis.js diff --git a/src/interpolate/bundle.js b/src/curve/bundle.js similarity index 83% rename from src/interpolate/bundle.js rename to src/curve/bundle.js index 62fcc73..a4212e9 100644 --- a/src/interpolate/bundle.js +++ b/src/curve/bundle.js @@ -1,9 +1,9 @@ import basis from "./basis"; -import linear from "./linear"; -function bundle(beta) { - return beta == null || (beta = +beta) === 1 ? basis - : function(context) { return new Bundle(context, beta); }; +function bundle(context, beta) { + return beta == null || (beta = +beta) === 1 + ? basis(context) + : new Bundle(context, beta); } function Bundle(context, beta) { diff --git a/src/interpolate/cardinal-closed.js b/src/curve/cardinal-closed.js similarity index 88% rename from src/interpolate/cardinal-closed.js rename to src/curve/cardinal-closed.js index 4a984a7..d6d9cdd 100644 --- a/src/interpolate/cardinal-closed.js +++ b/src/curve/cardinal-closed.js @@ -1,10 +1,7 @@ import {point} from "./cardinal"; -function cardinalClosed(tension) { - var k = (tension == null ? 1 : 1 - tension) / 6; - return function(context) { - return new CardinalClosed(context, k); - }; +function cardinalClosed(context, tension) { + return new CardinalClosed(context, (tension == null ? 1 : 1 - tension) / 6); } function CardinalClosed(context, k) { diff --git a/src/interpolate/cardinal-open.js b/src/curve/cardinal-open.js similarity index 86% rename from src/interpolate/cardinal-open.js rename to src/curve/cardinal-open.js index baba122..4558c95 100644 --- a/src/interpolate/cardinal-open.js +++ b/src/curve/cardinal-open.js @@ -1,10 +1,7 @@ import {point} from "./cardinal"; -function cardinalOpen(tension) { - var k = (tension == null ? 1 : 1 - tension) / 6; - return function(context) { - return new CardinalOpen(context, k); - }; +function cardinalOpen(context, tension) { + return new CardinalOpen(context, (tension == null ? 1 : 1 - tension) / 6); } function CardinalOpen(context, k) { diff --git a/src/interpolate/cardinal.js b/src/curve/cardinal.js similarity index 90% rename from src/interpolate/cardinal.js rename to src/curve/cardinal.js index b51e215..58bfdfd 100644 --- a/src/interpolate/cardinal.js +++ b/src/curve/cardinal.js @@ -9,11 +9,8 @@ export function point(that, x, y) { ); }; -function cardinal(tension) { - var k = (tension == null ? 1 : 1 - tension) / 6; - return function(context) { - return new Cardinal(context, k); - }; +function cardinal(context, tension) { + return new Cardinal(context, (tension == null ? 1 : 1 - tension) / 6); } function Cardinal(context, k) { diff --git a/src/interpolate/catmull-rom-closed.js b/src/curve/catmull-rom-closed.js similarity index 91% rename from src/interpolate/catmull-rom-closed.js rename to src/curve/catmull-rom-closed.js index 7e938e3..fe299af 100644 --- a/src/interpolate/catmull-rom-closed.js +++ b/src/curve/catmull-rom-closed.js @@ -1,10 +1,10 @@ import cardinalClosed from "./cardinal-closed"; import {point} from "./catmull-rom"; -function catmullRomClosed(alpha) { - return alpha == null || !(alpha = +alpha) ? cardinalClosed(0) : function(context) { - return new CatmullRomClosed(context, alpha); - }; +function catmullRomClosed(context, alpha) { + return alpha == null || !(alpha = +alpha) + ? cardinalClosed(context, 0) + : new CatmullRomClosed(context, alpha); } function CatmullRomClosed(context, alpha) { diff --git a/src/interpolate/catmull-rom-open.js b/src/curve/catmull-rom-open.js similarity index 90% rename from src/interpolate/catmull-rom-open.js rename to src/curve/catmull-rom-open.js index 394a0ac..74e3643 100644 --- a/src/interpolate/catmull-rom-open.js +++ b/src/curve/catmull-rom-open.js @@ -1,10 +1,10 @@ import cardinalOpen from "./cardinal-open"; import {point} from "./catmull-rom"; -function catmullRomOpen(alpha) { - return alpha == null || !(alpha = +alpha) ? cardinalOpen(0) : function(context) { - return new CatmullRomOpen(context, alpha); - }; +function catmullRomOpen(context, alpha) { + return alpha == null || !(alpha = +alpha) + ? cardinalOpen(context, 0) + : new CatmullRomOpen(context, alpha); } function CatmullRomOpen(context, alpha) { diff --git a/src/interpolate/catmull-rom.js b/src/curve/catmull-rom.js similarity index 93% rename from src/interpolate/catmull-rom.js rename to src/curve/catmull-rom.js index 932cf32..bd4b1d5 100644 --- a/src/interpolate/catmull-rom.js +++ b/src/curve/catmull-rom.js @@ -25,10 +25,10 @@ export function point(that, x, y) { that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); }; -function catmullRom(alpha) { - return alpha == null || !(alpha = +alpha) ? cardinal(0) : function(context) { - return new CatmullRom(context, alpha); - }; +function catmullRom(context, alpha) { + return alpha == null || !(alpha = +alpha) + ? cardinal(context, 0) + : new CatmullRom(context, alpha); } function CatmullRom(context, alpha) { diff --git a/src/curve/curry.js b/src/curve/curry.js new file mode 100644 index 0000000..a343371 --- /dev/null +++ b/src/curve/curry.js @@ -0,0 +1,10 @@ +var slice = Array.prototype.slice; + +export default function(interpolate, args) { + args = slice.call(args); + args[0] = null; + return function(context) { + args[0] = context; + return interpolate.apply(null, args); + }; +}; diff --git a/src/interpolate/linear-closed.js b/src/curve/linear-closed.js similarity index 100% rename from src/interpolate/linear-closed.js rename to src/curve/linear-closed.js diff --git a/src/interpolate/linear.js b/src/curve/linear.js similarity index 100% rename from src/interpolate/linear.js rename to src/curve/linear.js diff --git a/src/interpolate/monotone.js b/src/curve/monotone.js similarity index 100% rename from src/interpolate/monotone.js rename to src/curve/monotone.js diff --git a/src/interpolate/natural.js b/src/curve/natural.js similarity index 100% rename from src/interpolate/natural.js rename to src/curve/natural.js diff --git a/src/interpolate/step-after.js b/src/curve/step-after.js similarity index 100% rename from src/interpolate/step-after.js rename to src/curve/step-after.js diff --git a/src/interpolate/step-before.js b/src/curve/step-before.js similarity index 100% rename from src/interpolate/step-before.js rename to src/curve/step-before.js diff --git a/src/interpolate/step.js b/src/curve/step.js similarity index 100% rename from src/interpolate/step.js rename to src/curve/step.js diff --git a/src/line.js b/src/line.js index 45dcc5d..409b51b 100644 --- a/src/line.js +++ b/src/line.js @@ -1,30 +1,16 @@ import {path} from "d3-path"; -import basis from "./interpolate/basis"; -import basisClosed from "./interpolate/basis-closed"; -import basisOpen from "./interpolate/basis-open"; -import bundle from "./interpolate/bundle"; -import cardinal from "./interpolate/cardinal"; -import cardinalClosed from "./interpolate/cardinal-closed"; -import cardinalOpen from "./interpolate/cardinal-open"; -import catmullRom from "./interpolate/catmull-rom"; -import catmullRomClosed from "./interpolate/catmull-rom-closed"; -import catmullRomOpen from "./interpolate/catmull-rom-open"; -import constant, {constantTrue} from "./constant"; -import linear from "./interpolate/linear"; -import linearClosed from "./interpolate/linear-closed"; -import natural from "./interpolate/natural"; -import step from "./interpolate/step"; -import stepAfter from "./interpolate/step-after"; -import stepBefore from "./interpolate/step-before"; +import constant from "./constant"; +import curveLinear from "./curve/linear"; +import curveCurry from "./curve/curry"; import {x as pointX, y as pointY} from "./point"; export default function() { var x = pointX, y = pointY, - defined = constantTrue, + defined = constant(true), context = null, - interpolate = linear, - interpolator = null; + curve = curveLinear, + output = null; function line(data) { var i, @@ -33,17 +19,17 @@ export default function() { defined0 = false, buffer; - if (!context) interpolator = interpolate(buffer = path()); + if (!context) output = curve(buffer = path()); for (i = 0; i <= n; ++i) { if (!(i < n && defined(d = data[i], i)) === defined0) { - if (defined0 = !defined0) interpolator.lineStart(); - else interpolator.lineEnd(); + if (defined0 = !defined0) output.lineStart(); + else output.lineEnd(); } - if (defined0) interpolator.point(+x(d, i), +y(d, i)); + if (defined0) output.point(+x(d, i), +y(d, i)); } - if (buffer) return interpolator = null, buffer + "" || null; + if (buffer) return output = null, buffer + "" || null; } line.x = function(_) { @@ -58,33 +44,13 @@ export default function() { return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined; }; - line.interpolate = function(_, a) { - if (!arguments.length) return interpolate; - if (typeof _ === "function") interpolate = _; - else switch (_ + "") { - case "linear-closed": interpolate = linearClosed; break; - case "step": interpolate = step; break; - case "step-before": interpolate = stepBefore; break; - case "step-after": interpolate = stepAfter; break; - case "basis": interpolate = basis; break; - case "basis-open": interpolate = basisOpen; break; - case "basis-closed": interpolate = basisClosed; break; - case "bundle": interpolate = bundle(a); break; - case "cardinal": interpolate = cardinal(a); break; - case "cardinal-open": interpolate = cardinalOpen(a); break; - case "cardinal-closed": interpolate = cardinalClosed(a); break; - case "catmull-rom": interpolate = catmullRom(a); break; - case "catmull-rom-open": interpolate = catmullRomOpen(a); break; - case "catmull-rom-closed": interpolate = catmullRomClosed(a); break; - case "natural": interpolate = natural; break; - default: interpolate = linear; break; - } - if (context != null) interpolator = interpolate(context); - return line; + line.curve = function(_) { + var n = arguments.length; + return n ? (curve = n > 1 ? curveCurry(_, arguments) : _, context != null && (output = curve(context)), line) : curve; }; line.context = function(_) { - return arguments.length ? (_ == null ? context = interpolator = null : interpolator = interpolate(context = _), line) : context; + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; }; return line; diff --git a/src/symbol.js b/src/symbol.js index f5eee68..cf228d4 100644 --- a/src/symbol.js +++ b/src/symbol.js @@ -6,46 +6,29 @@ import square from "./symbol/square"; import {triangleDown, triangleUp} from "./symbol/triangle"; import constant from "./constant"; -function constantSixtyFour() { - return 64; -} - -function constantCircle() { - return "circle"; -} - export var symbolTypes = [ - "circle", - "cross", - "diamond", - "square", - "triangle-down", - "triangle-up" + circle, + cross, + diamond, + square, + triangleDown, + triangleUp ]; export default function() { - var type = constantCircle, - size = constantSixtyFour, + var type = constant(circle), + size = constant(64), context = null; function symbol(d, i) { var buffer; if (!context) context = buffer = path(); - var t; - switch (type(d, i) + "") { - case "cross": t = cross; break; - case "diamond": t = diamond; break; - case "square": t = square; break; - case "triangle-down": t = triangleDown; break; - case "triangle-up": t = triangleUp; break; - default: t = circle; break; - } - t(context, +size(d, i)); + type(d, i).draw(context, +size(d, i)); if (buffer) return context = null, buffer + "" || null; } symbol.type = function(_) { - return arguments.length ? (type = typeof _ === "function" ? _ : constant(_ + ""), symbol) : type; + return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type; }; symbol.size = function(_) { diff --git a/src/symbol/circle.js b/src/symbol/circle.js index 0c32775..c9168fa 100644 --- a/src/symbol/circle.js +++ b/src/symbol/circle.js @@ -1,5 +1,7 @@ -export default function(context, size) { - var r = Math.sqrt(size / Math.PI); - context.moveTo(r, 0); - context.arc(0, 0, r, 0, 2 * Math.PI); +export default { + draw: function(context, size) { + var r = Math.sqrt(size / Math.PI); + context.moveTo(r, 0); + context.arc(0, 0, r, 0, 2 * Math.PI); + } }; diff --git a/src/symbol/cross.js b/src/symbol/cross.js index b1b1e2f..a282f80 100644 --- a/src/symbol/cross.js +++ b/src/symbol/cross.js @@ -1,16 +1,18 @@ -export default function(context, size) { - var r = Math.sqrt(size / 5) / 2; - context.moveTo(-3 * r, -r); - context.lineTo(-r, -r); - context.lineTo(-r, -3 * r); - context.lineTo(r, -3 * r); - context.lineTo(r, -r); - context.lineTo(3 * r, -r); - context.lineTo(3 * r, r); - context.lineTo(r, r); - context.lineTo(r, 3 * r); - context.lineTo(-r, 3 * r); - context.lineTo(-r, r); - context.lineTo(-3 * r, r); - context.closePath(); +export default { + draw: function(context, size) { + var r = Math.sqrt(size / 5) / 2; + context.moveTo(-3 * r, -r); + context.lineTo(-r, -r); + context.lineTo(-r, -3 * r); + context.lineTo(r, -3 * r); + context.lineTo(r, -r); + context.lineTo(3 * r, -r); + context.lineTo(3 * r, r); + context.lineTo(r, r); + context.lineTo(r, 3 * r); + context.lineTo(-r, 3 * r); + context.lineTo(-r, r); + context.lineTo(-3 * r, r); + context.closePath(); + } }; diff --git a/src/symbol/diamond.js b/src/symbol/diamond.js index 43abfa3..9f4ff1a 100644 --- a/src/symbol/diamond.js +++ b/src/symbol/diamond.js @@ -1,12 +1,14 @@ var tan30 = Math.sqrt(1 / 3), tan30_2 = tan30 * 2; -export default function(context, size) { - var y = Math.sqrt(size / tan30_2), - x = y * tan30; - context.moveTo(0, -y); - context.lineTo(x, 0); - context.lineTo(0, y); - context.lineTo(-x, 0); - context.closePath(); +export default { + draw: function(context, size) { + var y = Math.sqrt(size / tan30_2), + x = y * tan30; + context.moveTo(0, -y); + context.lineTo(x, 0); + context.lineTo(0, y); + context.lineTo(-x, 0); + context.closePath(); + } }; diff --git a/src/symbol/square.js b/src/symbol/square.js index 9e7dbf0..10beccd 100644 --- a/src/symbol/square.js +++ b/src/symbol/square.js @@ -1,5 +1,7 @@ -export default function(context, size) { - var w = Math.sqrt(size), - x = -w / 2; - context.rect(x, x, w, w); +export default { + draw: function(context, size) { + var w = Math.sqrt(size), + x = -w / 2; + context.rect(x, x, w, w); + } }; diff --git a/src/symbol/triangle.js b/src/symbol/triangle.js index 155f33f..30f946c 100644 --- a/src/symbol/triangle.js +++ b/src/symbol/triangle.js @@ -1,19 +1,23 @@ var sqrt3 = Math.sqrt(3); -export function triangleDown(context, size) { - var x = Math.sqrt(size / sqrt3), - y = x * sqrt3 / 2; - context.moveTo(0, y); - context.lineTo(x, -y); - context.lineTo(-x, -y); - context.closePath(); +export var triangleDown = { + draw: function(context, size) { + var x = Math.sqrt(size / sqrt3), + y = x * sqrt3 / 2; + context.moveTo(0, y); + context.lineTo(x, -y); + context.lineTo(-x, -y); + context.closePath(); + } }; -export function triangleUp(context, size) { - var x = Math.sqrt(size / sqrt3), - y = x * sqrt3 / 2; - context.moveTo(0, -y); - context.lineTo(x, y); - context.lineTo(-x, y); - context.closePath(); +export var triangleUp = { + draw: function(context, size) { + var x = Math.sqrt(size / sqrt3), + y = x * sqrt3 / 2; + context.moveTo(0, -y); + context.lineTo(x, y); + context.lineTo(-x, y); + context.closePath(); + } }; diff --git a/test/area-test.js b/test/area-test.js index 8c6b40c..f837fbf 100644 --- a/test/area-test.js +++ b/test/area-test.js @@ -8,6 +8,7 @@ tape("area() returns a default area shape", function(test) { test.equal(a.y0()([42, 34]), 0); test.equal(a.y1()([42, 34]), 34); test.equal(a.defined()([42, 34]), true); + test.equal(a.curve(), shape.curveLinear); test.equal(a.context(), null); test.equal(a([[0, 1], [2, 3], [4, 5]]), "M0,1L2,3L4,5L4,0L2,0L0,0Z"); test.end(); @@ -52,8 +53,8 @@ tape("area.y(y)(data) observes the specified constant", function(test) { test.end(); }); -tape("area.interpolate(\"linear\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("linear"); +tape("area.curve(curveLinear)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveLinear); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [2, 3]]), "M0,1L2,3L2,0L0,0Z"); @@ -61,8 +62,8 @@ tape("area.interpolate(\"linear\")(data) generates the expected path", function( test.end(); }); -tape("area.interpolate(\"basis\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("basis"); +tape("area.curve(curveBasis)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveBasis); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [1, 3]]), "M0,1L1,3L1,0L0,0Z"); @@ -70,8 +71,8 @@ tape("area.interpolate(\"basis\")(data) generates the expected path", function(t test.end(); }); -tape("area.interpolate(\"basis-open\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("basis-open"); +tape("area.curve(curveBasisOpen)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveBasisOpen); test.equal(a([]), null); test.equal(a([[0, 1]]), null); test.equal(a([[0, 1], [1, 3]]), null); @@ -81,8 +82,8 @@ tape("area.interpolate(\"basis-open\")(data) generates the expected path", funct test.end(); }); -tape("area.interpolate(\"cardinal\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("cardinal"); +tape("area.curve(curveCardinal)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveCardinal); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [1, 3]]), "M0,1L1,3L1,0L0,0Z"); @@ -91,8 +92,8 @@ tape("area.interpolate(\"cardinal\")(data) generates the expected path", functio test.end(); }); -tape("area.interpolate(\"cardinal-open\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("cardinal-open"); +tape("area.curve(curveCardinalOpen)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveCardinalOpen); test.equal(a([]), null); test.equal(a([[0, 1]]), null); test.equal(a([[0, 1], [1, 3]]), null); @@ -101,8 +102,8 @@ tape("area.interpolate(\"cardinal-open\")(data) generates the expected path", fu test.end(); }); -tape("area.interpolate(\"catmull-rom\", 0.5)(data) generates the expected path", function(test) { - var a = shape.area().interpolate("catmull-rom", 0.5); +tape("area.curve(curveCatmullRom, 0.5)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveCatmullRom, 0.5); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [1, 3]]), "M0,1L1,3L1,0L0,0Z"); @@ -111,8 +112,8 @@ tape("area.interpolate(\"catmull-rom\", 0.5)(data) generates the expected path", test.end(); }); -tape("area.interpolate(\"catmull-rom-open\", 0.5)(data) generates the expected path", function(test) { - var a = shape.area().interpolate("catmull-rom-open", 0.5); +tape("area.curve(curveCatmullRomOpen, 0.5)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveCatmullRomOpen, 0.5); test.equal(a([]), null); test.equal(a([[0, 1]]), null); test.equal(a([[0, 1], [1, 3]]), null); @@ -121,8 +122,8 @@ tape("area.interpolate(\"catmull-rom-open\", 0.5)(data) generates the expected p test.end(); }); -tape("area.interpolate(\"step\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("step"); +tape("area.curve(curveStep)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveStep); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [2, 3]]), "M0,1L1,1L1,3L2,3L2,0L1,0L1,0L0,0Z"); @@ -130,8 +131,8 @@ tape("area.interpolate(\"step\")(data) generates the expected path", function(te test.end(); }); -tape("area.interpolate(\"step-before\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("step-before"); +tape("area.curve(curveStepBefore)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveStepBefore); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [2, 3]]), "M0,1L0,3L2,3L2,0L2,0L0,0Z"); @@ -139,8 +140,8 @@ tape("area.interpolate(\"step-before\")(data) generates the expected path", func test.end(); }); -tape("area.interpolate(\"step-after\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("step-after"); +tape("area.curve(curveStepAfter)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveStepAfter); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [2, 3]]), "M0,1L2,1L2,3L2,0L0,0L0,0Z"); @@ -148,8 +149,8 @@ tape("area.interpolate(\"step-after\")(data) generates the expected path", funct test.end(); }); -tape("area.interpolate(\"natural\")(data) generates the expected path", function(test) { - var a = shape.area().interpolate("natural"); +tape("area.curve(curveNatural)(data) generates the expected path", function(test) { + var a = shape.area().curve(shape.curveNatural); test.equal(a([]), null); test.equal(a([[0, 1]]), "M0,1L0,0Z"); test.equal(a([[0, 1], [1, 3]]), "M0,1L1,3L1,0L0,0Z"); @@ -157,3 +158,35 @@ tape("area.interpolate(\"natural\")(data) generates the expected path", function test.equal(a([[0, 1], [1, 3], [2, 1], [3, 3]]), "M0,1C0.33333333333333326,2.111111111111111,0.6666666666666665,3.2222222222222223,1,3C1.3333333333333335,2.7777777777777777,1.666666666666667,1.2222222222222223,2,1C2.333333333333333,0.7777777777777778,2.6666666666666665,1.8888888888888888,3,3L3,0C2.666666666666667,0,2.3333333333333335,0,2,0C1.6666666666666665,0,1.3333333333333333,0,1,0C0.6666666666666667,0,0.33333333333333337,0,0,0Z"); test.end(); }); + +tape("area.curve(curveCardinal) uses a default tension of zero", function(test) { + var a = shape.area().curve(shape.curveCardinal, 0); + test.equal(shape.area().curve(shape.curveCardinal)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCardinal, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCardinal, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("area.curve(curveCardinalOpen) uses a default tension of zero", function(test) { + var a = shape.area().curve(shape.curveCardinalOpen, 0); + test.equal(shape.area().curve(shape.curveCardinalOpen)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCardinalOpen, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCardinalOpen, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("area.curve(curveCatmullRom) uses a default alpha of zero", function(test) { + var a = shape.area().curve(shape.curveCatmullRom, 0); + test.equal(shape.area().curve(shape.curveCatmullRom)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCatmullRom, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCatmullRom, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("area.curve(curveCatmullRomOpen) uses a default alpha of zero", function(test) { + var a = shape.area().curve(shape.curveCatmullRomOpen, 0); + test.equal(shape.area().curve(shape.curveCatmullRomOpen)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCatmullRomOpen, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.area().curve(shape.curveCatmullRomOpen, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), a([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); diff --git a/test/line-test.js b/test/line-test.js index d9f0ac1..c858662 100644 --- a/test/line-test.js +++ b/test/line-test.js @@ -6,6 +6,7 @@ tape("line() returns a default line shape", function(test) { test.equal(l.x()([42, 34]), 42); test.equal(l.y()([42, 34]), 34); test.equal(l.defined()([42, 34]), true); + test.equal(l.curve(), shape.curveLinear); test.equal(l.context(), null); test.equal(l([[0, 1], [2, 3], [4, 5]]), "M0,1L2,3L4,5"); test.end(); @@ -35,15 +36,15 @@ tape("line.y(y)(data) observes the specified constant", function(test) { test.end(); }); -tape("line.interpolate(name) sets the interpolation method", function(test) { - var l = shape.line().interpolate("linear-closed"); +tape("line.curve(curve) sets the curve method", function(test) { + var l = shape.line().curve(shape.curveLinearClosed); test.equal(l([]), null); test.equal(l([[0, 1], [2, 3]]), "M0,1L2,3Z"); test.end(); }); -tape("line.interpolate(\"cardinal\", tension) sets the cardinal interpolation tension", function(test) { - var l = shape.line().interpolate("cardinal", 0.1); +tape("line.curve(curveCardinal, tension) sets the cardinal spline tension", function(test) { + var l = shape.line().curve(shape.curveCardinal, 0.1); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -52,8 +53,8 @@ tape("line.interpolate(\"cardinal\", tension) sets the cardinal interpolation te test.end(); }); -tape("line.interpolate(\"cardinal\", tension) coerces the specified tension to a number", function(test) { - var l = shape.line().interpolate("cardinal", "0.1"); +tape("line.curve(curveCardinal, tension) coerces the specified tension to a number", function(test) { + var l = shape.line().curve(shape.curveCardinal, "0.1"); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -62,50 +63,8 @@ tape("line.interpolate(\"cardinal\", tension) coerces the specified tension to a test.end(); }); -tape("line.interpolate(\"cardinal\") implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal"), - l1 = shape.line().interpolate("cardinal", 0); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"cardinal\", null) implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal"), - l1 = shape.line().interpolate("cardinal", null); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"cardinal\", undefined) implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal"), - l1 = shape.line().interpolate("cardinal", undefined); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"cardinal-open\") implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal-open"), - l1 = shape.line().interpolate("cardinal-open", 0); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"cardinal-open\", null) implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal-open"), - l1 = shape.line().interpolate("cardinal-open", null); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"cardinal-open\", undefined) implicitly uses a tension of zero", function(test) { - var l0 = shape.line().interpolate("cardinal-open"), - l1 = shape.line().interpolate("cardinal-open", undefined); - test.equal(l1([[0, 1], [1, 3], [2, 1], [3, 3]]), l0([[0, 1], [1, 3], [2, 1], [3, 3]])); - test.end(); -}); - -tape("line.interpolate(\"linear\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("linear"); +tape("line.curve(curveLinear)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveLinear); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [2, 3]]), "M0,1L2,3"); @@ -113,8 +72,8 @@ tape("line.interpolate(\"linear\")(data) generates the expected path", function( test.end(); }); -tape("line.interpolate(\"linear-closed\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("linear-closed"); +tape("line.curve(curveLinearClosed)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveLinearClosed); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [2, 3]]), "M0,1L2,3Z"); @@ -122,8 +81,8 @@ tape("line.interpolate(\"linear-closed\")(data) generates the expected path", fu test.end(); }); -tape("line.interpolate(\"step\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("step"); +tape("line.curve(curveStep)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveStep); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [2, 3]]), "M0,1L1,1L1,3L2,3"); @@ -131,8 +90,8 @@ tape("line.interpolate(\"step\")(data) generates the expected path", function(te test.end(); }); -tape("line.interpolate(\"step-before\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("step-before"); +tape("line.curve(curveStepBefore)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveStepBefore); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [2, 3]]), "M0,1L0,3L2,3"); @@ -140,8 +99,8 @@ tape("line.interpolate(\"step-before\")(data) generates the expected path", func test.end(); }); -tape("line.interpolate(\"step-after\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("step-after"); +tape("line.curve(curveStepAfter)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveStepAfter); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [2, 3]]), "M0,1L2,1L2,3"); @@ -149,8 +108,8 @@ tape("line.interpolate(\"step-after\")(data) generates the expected path", funct test.end(); }); -tape("line.interpolate(\"basis\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("basis"); +tape("line.curve(curveBasis)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveBasis); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -158,8 +117,8 @@ tape("line.interpolate(\"basis\")(data) generates the expected path", function(t test.end(); }); -tape("line.interpolate(\"basis-open\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("basis-open"); +tape("line.curve(curveBasisOpen)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveBasisOpen); test.equal(l([]), null); test.equal(l([[0, 0]]), null); test.equal(l([[0, 0], [0, 10]]), null); @@ -169,8 +128,8 @@ tape("line.interpolate(\"basis-open\")(data) generates the expected path", funct test.end(); }); -tape("line.interpolate(\"basis-closed\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("basis-closed"); +tape("line.curve(curveBasisClosed)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveBasisClosed); test.equal(l([]), null); test.equal(l([[0, 0]]), "M0,0Z"); test.equal(l([[0, 0], [0, 10]]), "M0,6.666666666666667L0,3.3333333333333335Z"); @@ -180,8 +139,8 @@ tape("line.interpolate(\"basis-closed\")(data) generates the expected path", fun test.end(); }); -tape("line.interpolate(\"cardinal\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("cardinal"); +tape("line.curve(curveCardinal)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCardinal); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -190,8 +149,8 @@ tape("line.interpolate(\"cardinal\")(data) generates the expected path", functio test.end(); }); -tape("line.interpolate(\"cardinal-open\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("cardinal-open"); +tape("line.curve(curveCardinalOpen)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCardinalOpen); test.equal(l([]), null); test.equal(l([[0, 1]]), null); test.equal(l([[0, 1], [1, 3]]), null); @@ -200,8 +159,8 @@ tape("line.interpolate(\"cardinal-open\")(data) generates the expected path", fu test.end(); }); -tape("line.interpolate(\"cardinal-closed\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("cardinal-closed"); +tape("line.curve(curveCardinalClosed)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCardinalClosed); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M1,3L0,1Z"); @@ -210,8 +169,8 @@ tape("line.interpolate(\"cardinal-closed\")(data) generates the expected path", test.end(); }); -tape("line.interpolate(\"catmull-rom\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom"); +tape("line.curve(curveCatmullRom)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRom); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -220,8 +179,8 @@ tape("line.interpolate(\"catmull-rom\")(data) generates the expected path", func test.end(); }); -tape("line.interpolate(\"catmull-rom-open\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom-open"); +tape("line.curve(curveCatmullRomOpen)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRomOpen); test.equal(l([]), null); test.equal(l([[0, 1]]), null); test.equal(l([[0, 1], [1, 3]]), null); @@ -230,8 +189,8 @@ tape("line.interpolate(\"catmull-rom-open\")(data) generates the expected path", test.end(); }); -tape("line.interpolate(\"catmull-rom-closed\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom-closed"); +tape("line.curve(curveCatmullRomClosed)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRomClosed); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M1,3L0,1Z"); @@ -240,8 +199,8 @@ tape("line.interpolate(\"catmull-rom-closed\")(data) generates the expected path test.end(); }); -tape("line.interpolate(\"catmull-rom\", 1)(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom", 1); +tape("line.curve(curveCatmullRom, 1)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRom, 1); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -250,8 +209,8 @@ tape("line.interpolate(\"catmull-rom\", 1)(data) generates the expected path", f test.end(); }); -tape("line.interpolate(\"catmull-rom-open\", 1)(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom-open", 1); +tape("line.curve(curveCatmullRomOpen, 1)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRomOpen, 1); test.equal(l([]), null); test.equal(l([[0, 1]]), null); test.equal(l([[0, 1], [1, 3]]), null); @@ -260,8 +219,8 @@ tape("line.interpolate(\"catmull-rom-open\", 1)(data) generates the expected pat test.end(); }); -tape("line.interpolate(\"catmull-rom-closed\", 1)(data) generates the expected path", function(test) { - var l = shape.line().interpolate("catmull-rom-closed", 1); +tape("line.curve(curveCatmullRomClosed, 1)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveCatmullRomClosed, 1); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M1,3L0,1Z"); @@ -270,8 +229,8 @@ tape("line.interpolate(\"catmull-rom-closed\", 1)(data) generates the expected p test.end(); }); -tape("line.interpolate(\"natural\")(data) generates the expected path", function(test) { - var l = shape.line().interpolate("natural"); +tape("line.curve(curveNatural)(data) generates the expected path", function(test) { + var l = shape.line().curve(shape.curveNatural); test.equal(l([]), null); test.equal(l([[0, 1]]), "M0,1Z"); test.equal(l([[0, 1], [1, 3]]), "M0,1L1,3"); @@ -279,3 +238,59 @@ tape("line.interpolate(\"natural\")(data) generates the expected path", function test.equal(l([[0, 1], [1, 3], [2, 1], [3, 3]]), "M0,1C0.33333333333333326,2.111111111111111,0.6666666666666665,3.2222222222222223,1,3C1.3333333333333335,2.7777777777777777,1.666666666666667,1.2222222222222223,2,1C2.333333333333333,0.7777777777777778,2.6666666666666665,1.8888888888888888,3,3"); test.end(); }); + +tape("line.curve(curveCardinal) uses a default tension of zero", function(test) { + var l = shape.line().curve(shape.curveCardinal, 0); + test.equal(shape.line().curve(shape.curveCardinal)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinal, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinal, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveCardinalOpen) uses a default tension of zero", function(test) { + var l = shape.line().curve(shape.curveCardinalOpen, 0); + test.equal(shape.line().curve(shape.curveCardinalOpen)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinalOpen, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinalOpen, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveCardinalClosed) uses a default tension of zero", function(test) { + var l = shape.line().curve(shape.curveCardinalClosed, 0); + test.equal(shape.line().curve(shape.curveCardinalClosed)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinalClosed, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCardinalClosed, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveCatmullRom) uses a default alpha of zero", function(test) { + var l = shape.line().curve(shape.curveCatmullRom, 0); + test.equal(shape.line().curve(shape.curveCatmullRom)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRom, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRom, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveCatmullRomOpen) uses a default alpha of zero", function(test) { + var l = shape.line().curve(shape.curveCatmullRomOpen, 0); + test.equal(shape.line().curve(shape.curveCatmullRomOpen)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRomOpen, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRomOpen, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveCatmullRomClosed) uses a default alpha of zero", function(test) { + var l = shape.line().curve(shape.curveCatmullRomClosed, 0); + test.equal(shape.line().curve(shape.curveCatmullRomClosed)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRomClosed, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveCatmullRomClosed, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); + +tape("line.curve(curveBundle) uses a default beta of one", function(test) { + var l = shape.line().curve(shape.curveBundle, 1); + test.equal(shape.line().curve(shape.curveBundle)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveBundle, null)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.equal(shape.line().curve(shape.curveBundle, undefined)([[0, 1], [1, 3], [2, 1], [3, 3]]), l([[0, 1], [1, 3], [2, 1], [3, 3]])); + test.end(); +}); diff --git a/test/symbol-test.js b/test/symbol-test.js index 45dffa9..2a8ff6b 100644 --- a/test/symbol-test.js +++ b/test/symbol-test.js @@ -3,7 +3,7 @@ var tape = require("tape"), tape("symbol() returns a default symbol shape", function(test) { var s = shape.symbol(); - test.equal(s.type()(), "circle"); + test.equal(s.type()(), shape.symbolCircle); test.equal(s.size()(), 64); test.equal(s.context(), null); test.equal(s(), "M4.51351666838205,0A4.51351666838205,4.51351666838205,0,1,1,-4.51351666838205,0A4.51351666838205,4.51351666838205,0,1,1,4.51351666838205,0"); @@ -31,44 +31,38 @@ tape("symbol.size(size) observes the specified size constant", function(test) { test.end(); }); -tape("symbol.type(\"cross\") generates the expected path", function(test) { - var s = shape.symbol().type("cross").size(function(d) { return d; }); +tape("symbol.type(symbolCross) generates the expected path", function(test) { + var s = shape.symbol().type(shape.symbolCross).size(function(d) { return d; }); test.equal(s(0), "M0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0L0,0Z"); test.equal(s(20), "M-3,-1L-1,-1L-1,-3L1,-3L1,-1L3,-1L3,1L1,1L1,3L-1,3L-1,1L-3,1Z"); test.end(); }); -tape("symbol.type(\"diamond\") generates the expected path", function(test) { - var s = shape.symbol().type("diamond").size(function(d) { return d; }); +tape("symbol.type(symbolDiamond) generates the expected path", function(test) { + var s = shape.symbol().type(shape.symbolDiamond).size(function(d) { return d; }); test.equal(s(0), "M0,0L0,0L0,0L0,0Z"); test.equal(s(10), "M0,-2.942830956382712L1.6990442448471226,0L0,2.942830956382712L-1.6990442448471226,0Z"); test.end(); }); -tape("symbol.type(\"square\") generates the expected path", function(test) { - var s = shape.symbol().type("square").size(function(d) { return d; }); +tape("symbol.type(symbolSquare) generates the expected path", function(test) { + var s = shape.symbol().type(shape.symbolSquare).size(function(d) { return d; }); test.equal(s(0), "M0,0h0v0h0Z"); test.equal(s(4), "M-1,-1h2v2h-2Z"); test.equal(s(16), "M-2,-2h4v4h-4Z"); test.end(); }); -tape("symbol.type(\"triangle-up\") generates the expected path", function(test) { - var s = shape.symbol().type("triangle-down").size(function(d) { return d; }); +tape("symbol.type(symbolTriangleUp) generates the expected path", function(test) { + var s = shape.symbol().type(shape.symbolTriangleDown).size(function(d) { return d; }); test.equal(s(0), "M0,0L0,0L0,0Z"); test.equal(s(10), "M0,2.0808957251439084L2.4028114141347543,-2.0808957251439084L-2.4028114141347543,-2.0808957251439084Z"); test.end(); }); -tape("symbol.type(\"triangle-down\") generates the expected path", function(test) { - var s = shape.symbol().type("triangle-up").size(function(d) { return d; }); +tape("symbol.type(symbolTriangleDown) generates the expected path", function(test) { + var s = shape.symbol().type(shape.symbolTriangleUp).size(function(d) { return d; }); test.equal(s(0), "M0,0L0,0L0,0Z"); test.equal(s(10), "M0,-2.0808957251439084L2.4028114141347543,2.0808957251439084L-2.4028114141347543,2.0808957251439084Z"); test.end(); }); - -tape("symbol.type(invalid) defaults to circle", function(test) { - var s = shape.symbol().type("__proto__"); - test.equal(s(), "M4.51351666838205,0A4.51351666838205,4.51351666838205,0,1,1,-4.51351666838205,0A4.51351666838205,4.51351666838205,0,1,1,4.51351666838205,0"); - test.end(); -}); diff --git a/test/symbolTypes-test.js b/test/symbolTypes-test.js index c322369..c29c5c1 100644 --- a/test/symbolTypes-test.js +++ b/test/symbolTypes-test.js @@ -3,12 +3,12 @@ var tape = require("tape"), tape("symbolTypes is the array of symbol types", function(test) { test.deepEqual(shape.symbolTypes, [ - "circle", - "cross", - "diamond", - "square", - "triangle-down", - "triangle-up" + shape.symbolCircle, + shape.symbolCross, + shape.symbolDiamond, + shape.symbolSquare, + shape.symbolTriangleDown, + shape.symbolTriangleUp ]); test.end(); });