import {clipExtent} from "../clip/extent"; import identity from "../identity"; import {transformer} from "../transform"; import {fitExtent, fitSize} from "./fit"; function scaleTranslate(kx, ky, tx, ty) { return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity : transformer({ point: function(x, y) { this.stream.point(x * kx + tx, y * ky + ty); } }); } export default function() { var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity, // scale, translate and reflect x0 = null, y0, x1, y1, clip = identity, // clip extent cache, cacheStream, projection; function reset() { cache = cacheStream = null; return projection; } return projection = { stream: function(stream) { return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream)); }, clipExtent: function(_) { return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; }, scale: function(_) { return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k; }, translate: function(_) { return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty]; }, reflectX: function(_) { return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0; }, reflectY: function(_) { return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0; }, fitExtent: function(extent, object) { return fitExtent(projection, extent, object); }, fitSize: function(size, object) { return fitSize(projection, size, object); } }; }