d3-axes
Version:
D3 plugin to manage pairs of axes.
372 lines (314 loc) • 10.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-gup')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-gup'], factory) :
(factory((global.d3 = {}),global.d3,global.d3));
}(this, (function (exports,d3,d3Gup) { 'use strict';
function closestClassed(selection, className) {
var closest = selection;
while (!closest.classed(className)) {
closest = closest.node().parentElement;
if (!closest) { return; }
closest = d3.select(closest);
}
return closest;
}
function translate(context, v) {
var selection = context.selection ? context.selection() : context
, x = 0
, y = 0
;
var closest = closestClassed(selection, 'axis');
if (selection.classed('x')) {
y = +v;
} else if (selection.classed('y')) {
x = +v;
} else { return; }
context.attr('transform', ("translate(" + x + " " + y + ")"));
}
function positionStart(selection, axis) {
translate(selection, axis.scale().range()[0]);
}
function positionEnd(selection, axis) {
translate(selection, axis.scale().range()[1]);
}
function positionOrigin(selection, axis) {
translate(selection, axis.scale()(0));
}
function position(_) {
var n = +_;
if (isNaN(n))
{ return positionDefault; }
return function(selection, axis) {
translate(selection, axis.scale()(n));
};
}
function empty(scale) {
function axis(context) {
}
axis.scale = function(_) {
return arguments.length ? (scale = _, this) : scale;
};
return axis;
}
var positionDefault = positionOrigin;
var container = d3Gup.gup()
.enter(function ($, id) { return $.append("g")
.attr("id", id)
.attr("class", "axes"); })
.post(function ($, id, h, v) { return $
.attr("transform", ("translate(" + h + " " + v + ")")); }
)([null]);
var clipPath = d3Gup.gup()
.enter(function ($, id) { return $.append("clipPath")
.attr("id", (id + "-clip-path"))
.call(function ($) { return $.append("rect"); }); })
.post(function ($, id, h, v) { return $.select('rect')
.attr("width", h)
.attr("height", v); })([null]);
var axis = d3Gup.gup()
.enter(function ($, axis) { return $.append("g")
.attr("class", (axis + " axis")); })
.post(function ($, _, x, y) { return $.call(x, y); })([null]);
var count = 0;
function axes(x, y) {
var paddingTop = 20
, paddingRight = 20
, paddingBottom = 20
, paddingLeft = 20
, height = 0
, width = 0
, index = count++
, id = null
;
function axes(context) {
var selection = context.selection ? context.selection() : context
, v = height - paddingTop - paddingBottom
, h = width - paddingRight - paddingLeft
;
x.scale().range([0, h]);
y.scale().range([v, 0]);
var id = axes.id();
context.selectAll(("g#" + id))
.call(container, id, paddingLeft, paddingTop);
var g = context.select(("g#" + id));
g.selectAll(("#" + id + "-clip-path")).call(clipPath, id, h, v);
g.selectAll(".x.axis").call(axis, "x", x, y);
g.selectAll(".y.axis").call(axis, "y", y, x);
}
axes.x = function(_) {
return arguments.length ? (x = _, this) : x;
};
axes.y = function(_) {
return arguments.length ? (y = _, this) : y;
};
axes.padding = function(v, h, b, l) {
var assign, assign$1;
switch (arguments.length) {
case 0:
return {
"top": paddingTop,
"right": paddingRight,
"bottom": paddingBottom,
"left": paddingLeft
};
case 1:
h = b = l = v;
break;
case 2:
(assign = [ v, h ], b = assign[0], l = assign[1]);
break;
case 3:
l = h;
break;
}
(assign$1 = [ v, h, b, l ], paddingTop = assign$1[0], paddingRight = assign$1[1], paddingBottom = assign$1[2], paddingLeft = assign$1[3]);
return this;
};
axes.height = function(_) {
return arguments.length ? (height = _, this) : height;
};
axes.width = function(_) {
return arguments.length ? (width = _, this) : width;
};
axes.domain = function(_x, _y) {
if (!arguments.length)
{ return [x.scale().domain(), y.scale().domain()]; }
if (_x) { x.scale().domain(_x); }
if (_y) { y.scale().domain(_y); }
return this;
};
axes.id = function(_) {
return arguments.length ? (id = _, this) : (id || 'axes-' + index);
};
return axes;
}
function center(scale) {
var offset = scale.bandwidth() / 2;
if (scale.round()) { offset = Math.round(offset); }
return function(d) {
return scale(d) + offset;
};
}
function gridLine(x, y, size, pos, opacity, next) {
return function ($) { return $.attr("opacity", opacity)
.attr(x + "2", size)
.call(next ? function ($) { return $.each(function() { pos.set(this, next); }); } : function ($){ return $; })
.attr(y + "1", function(d) { return pos.get(this)(d) })
.attr(y + "2", function(d) { return pos.get(this)(d) }); }
}
function grid(basis) {
var position = d3.local();
var tickValues = null
, tickArguments = null
, line = d3Gup.gup()
.select(function ($) { return $.selectAll(".grid"); })
.pre(function ($) { return ($.selection ? $.selection() : $)
.order(); })
.exit(function ($, x, y, size, position, p) { return $
.call(gridLine(x, y, size, position, 0, p))
.remove(); })
.enter(function ($, x, y, size, position, p) { return $
.append("line")
.attr("class", "grid")
.call(gridLine(x, y, size, position, 0)); })
.post(function ($, x, y, size, position, p) { return $
.call(gridLine(x, y, size, position, 1, p)); })
;
function grid(context, axis) {
var selection = context.selection ? context.selection() : context
, scale = basis.scale()
, values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments || basis.tickArguments()) : scale.domain()) : tickValues
, range = axis.scale().range()
, size = range[1] - range[0];
var ref = closestClassed(selection, 'axis').classed("y")
? ["x", "y"]
: ["y", "x"];
var x = ref[0];
var y = ref[1];
range = basis.scale().range();
var p = scale.copy().range([range[0] + 0.5, range[1] + 0.5]);
if (scale.bandwidth) { p = center(p); }
if (!position.get(context.node())) {
position.set(context.node(), p);
}
context
.call(line(values, scale), x, y, size, position, p);
position.set(context.node(), p);
}
grid.ticks = function() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
return tickArguments = args, this;
};
grid.tickArguments = function(_) {
return arguments.length ? (tickArguments = _ == null ? [] : slice.call(_), this) : tickArguments.slice();
};
grid.tickValues = function(_) {
return arguments.length ? (tickValues = _ == null ? null : slice.call(_), this) : tickValues && tickValues.slice();
};
grid.gup = function(_) {
return arguments.length ? (line = _, this) : line;
};
return grid;
}
function compose(scale, accessor) {
if (accessor.scale) {
return accessor.scale(scale);
}
var f = function() {
var args = [], len = arguments.length;
while ( len-- ) args[ len ] = arguments[ len ];
return scale.call(this, accessor.apply(this, args));
};
f.scale = function(_) {
return arguments.length ? (scale = _, this) : scale;
};
return f;
}
var count$1 = 0;
var shapes = d3Gup.gup()
.select(function ($, id) { return $.select('.axes').selectAll(("g#" + id)); })
.enter(function ($, id) { return $.append('g')
.attr('id', id)
.attr('class', 'shapes'); })([null]);
function shape(path) {
var index = count$1++
, id = null
, call = d3Gup.gup()
.select(function ($) { return $.selectAll('path.shape'); })
.exit(function ($) { return $.remove(); })
.enter(function ($) { return $.append("path")
.attr("d", path)
.attr('class', 'shape'); })
.pre(function ($) { return $.attr("d", path); })
, data = call([])
;
function shape(context, axes) {
var ref;
var args = [], len = arguments.length - 2;
while ( len-- > 0 ) args[ len ] = arguments[ len + 2 ];
if (path.x) {
path.x(compose(axes.x().scale(), path.x()));
}
if (path.y) {
path.y(compose(axes.y().scale(), path.y()));
}
axes.apply(this, [context ].concat( args));
(ref = shapes(context, shape.id()))
.call.apply(ref, [ data ].concat( args ));
}
shape.path = function(_) {
return arguments.length ? (path = _, this) : path;
};
shape.data = function() {
var _ = [], len = arguments.length;
while ( len-- ) _[ len ] = arguments[ len ];
return arguments.length
? (data = call.apply(void 0, _), this)
: (data.data ? data.data() : data);
};
shape.id = function(_) {
return arguments.length ? (id = _, this) : (id || 'axes-shape-' + index);
};
shape.gup = function(_) {
return arguments.length ? (call = _, this) : call;
};
return shape;
}
function symbol(path) {
var x = function (d) { return d[0]; }
, y = function (d) { return d[1]; }
;
path.x = function(_) {
return arguments.length ? (x = _, this) : x;
};
path.y = function(_) {
return arguments.length ? (y = _, this) : y;
};
var $ = shape(path);
$.gup(
d3Gup.gupCompose(
d3Gup.gup()
.pre(translate)
.enter(translate)
, $.gup()
)
);
return $;
function translate($) {
return $.attr('transform', function (d) { return ("translate(" + (path.x()(d)) + " " + (path.y()(d)) + ")"); })
}
}
exports.axes = axes;
exports.axesPositionBottom = positionStart;
exports.axesPositionLeft = positionStart;
exports.axesPositionTop = positionEnd;
exports.axesPositionRight = positionEnd;
exports.axesPositionDefault = positionDefault;
exports.axesPosition = position;
exports.axesEmpty = empty;
exports.axesGrid = grid;
exports.axesShape = shape;
exports.axesSymbol = symbol;
Object.defineProperty(exports, '__esModule', { value: true });
})));