diff -r efd9c589177a -r c0b4a8b5a012 toolkit/javascript/d3/test/svg/axis-test.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/toolkit/javascript/d3/test/svg/axis-test.js Thu Apr 10 14:20:23 2014 +0200 @@ -0,0 +1,347 @@ +require("../env"); +require("../../d3"); + +var vows = require("vows"), + assert = require("assert"); + +var suite = vows.describe("d3.svg.axis"); + +suite.addBatch({ + "axis": { + topic: function() { + return d3.svg.axis; + }, + + "scale": { + "defaults to a linear scale": function(axis) { + var a = axis(), x = a.scale(); + assert.deepEqual(x.domain(), [0, 1]); + assert.deepEqual(x.range(), [0, 1]); + assert.equal(x(0.5), 0.5); + }, + "can be defined as a scale object": function(axis) { + var x = d3.scale.linear(), a = axis().scale(x); + assert.equal(a.scale(), x); + }, + "can be a polylinear scale": function(axis) { + var a = axis().scale(d3.scale.linear().domain([0, 1, 10]).range([2, 20, 200])), + g = d3.select("body").html("").append("svg:g").call(a), + path = g.selectAll("path"); + assert.equal(path.attr("d"), "M2,6V0H200V6"); + } + }, + + "orient": { + "defaults to bottom": function(axis) { + var a = axis(); + assert.equal(a.orient(), "bottom"); + }, + "supports top orientation": function(axis) { + var a = axis().orient("top"), + g = d3.select("body").html("").append("svg:g").call(a), + tick = g.select("g:nth-child(3)"), + text = tick.select("text"), + line = tick.select("line"), + path = g.select("path.domain"); + assert.equal(tick.attr("transform"), "translate(0.2,0)"); + assert.equal(text.attr("y"), -9) + assert.equal(text.attr("dy"), "0em"); + assert.equal(text.attr("text-anchor"), "middle"); + assert.equal(text.text(), "0.2"); + assert.equal(line.attr("y2"), -6); + assert.equal(path.attr("d"), "M0,-6V0H1V-6"); + }, + "supports right orientation": function(axis) { + var a = axis().orient("right"), + g = d3.select("body").html("").append("svg:g").call(a), + tick = g.select("g:nth-child(3)"), + text = tick.select("text"), + line = tick.select("line"), + path = g.select("path.domain"); + assert.equal(tick.attr("transform"), "translate(0,0.2)"); + assert.equal(text.attr("x"), 9) + assert.equal(text.attr("dy"), ".32em"); + assert.equal(text.attr("text-anchor"), "start"); + assert.equal(text.text(), "0.2"); + assert.equal(line.attr("x2"), 6); + assert.equal(path.attr("d"), "M6,0H0V1H6"); + }, + "supports bottom orientation": function(axis) { + var a = axis().orient("bottom"), + g = d3.select("body").html("").append("svg:g").call(a), + tick = g.select("g:nth-child(3)"), + text = tick.select("text"), + line = tick.select("line"), + path = g.select("path.domain"); + assert.equal(tick.attr("transform"), "translate(0.2,0)"); + assert.equal(text.attr("y"), 9) + assert.equal(text.attr("dy"), ".71em"); + assert.equal(text.attr("text-anchor"), "middle"); + assert.equal(text.text(), "0.2"); + assert.equal(line.attr("y2"), 6); + assert.equal(path.attr("d"), "M0,6V0H1V6"); + }, + "supports left orientation": function(axis) { + var a = axis().orient("left"), + g = d3.select("body").html("").append("svg:g").call(a), + tick = g.select("g:nth-child(3)"), + text = tick.select("text"), + line = tick.select("line"), + path = g.select("path.domain"); + assert.equal(tick.attr("transform"), "translate(0,0.2)"); + assert.equal(text.attr("x"), -9) + assert.equal(text.attr("dy"), ".32em"); + assert.equal(text.attr("text-anchor"), "end"); + assert.equal(text.text(), "0.2"); + assert.equal(line.attr("x2"), -6); + assert.equal(path.attr("d"), "M-6,0H0V1H-6"); + } + }, + + "tickSize": { + "defaults to six pixels": function(axis) { + var a = axis(); + assert.equal(a.tickSize(), 6); + }, + "can be defined as a number": function(axis) { + var a = axis().tickSize(3); + assert.equal(a.tickSize(), 3); + }, + "coerces input value to a number": function(axis) { + var a = axis().tickSize("3"); + assert.strictEqual(a.tickSize(), 3); + }, + "affects the generated domain path": function(axis) { + var a = axis().tickSize(3), + g = d3.select("body").html("").append("svg:g").call(a), + path = g.select("path.domain"); + assert.equal(path.attr("d"), "M0,3V0H1V3"); + }, + "affects the generated tick lines": function(axis) { + var a = axis().tickSize(3), + g = d3.select("body").html("").append("svg:g").call(a), + line = g.selectAll("g line"); + line.each(function() { + assert.equal(d3.select(this).attr("y2"), 3); + }); + }, + "if negative, labels are placed on the opposite end": function(axis) { + var a = axis().tickSize(-80), + g = d3.select("body").html("").append("svg:g").call(a), + line = g.selectAll("g line"), + text = g.selectAll("g text"); + line.each(function() { + assert.equal(d3.select(this).attr("y2"), -80); + }); + text.each(function() { + assert.equal(d3.select(this).attr("y"), 3); + }); + }, + "with two arguments, specifies end tick size": function(axis) { + var a = axis().tickSize(6, 3), + g = d3.select("body").html("").append("svg:g").call(a), + path = g.selectAll("path"); + assert.equal(path.attr("d"), "M0,3V0H1V3"); + }, + "with three arguments, specifies end and minor tick sizes": function(axis) { + var a = axis().tickSubdivide(3).tickSize(6, 3, 9), + g = d3.select("body").html("").append("svg:g").call(a), + path = g.selectAll("path"), + line = g.select(".minor"); + assert.equal(path.attr("d"), "M0,9V0H1V9"); + assert.equal(line.attr("y2"), "3"); + } + }, + + "tickPadding": { + "defaults to three pixels": function(axis) { + var a = axis(); + assert.equal(a.tickPadding(), 3); + }, + "can be defined as a number": function(axis) { + var a = axis().tickPadding(6); + assert.equal(a.tickPadding(), 6); + }, + "coerces input value to a number": function(axis) { + var a = axis().tickPadding("6"); + assert.strictEqual(a.tickPadding(), 6); + }, + "affects the generated tick labels": function(axis) { + var a = axis().tickSize(2).tickPadding(7), + g = d3.select("body").html("").append("svg:g").call(a), + text = g.selectAll("g text"); + text.each(function() { + assert.equal(d3.select(this).attr("y"), 9); + }); + } + }, + + "ticks": { + "defaults to 10": function(axis) { + var a = axis(); + assert.deepEqual(a.ticks(), [10]); + }, + "can be defined as any arguments": function(axis) { + var b = {}, a = axis().ticks(b, 42), t = a.ticks(); + assert.equal(t[0], b); + assert.equal(t[1], 42); + assert.equal(t.length, 2); + }, + "passes any arguments to the scale's ticks function": function(axis) { + var x = d3.scale.linear(), b = {}, a = axis().ticks(b, 42).scale(x), aa = [], + g = d3.select("body").html("").append("svg:g"); + x.ticks = function() { aa.push(arguments); return [42]; }; + g.call(a); + assert.equal(aa.length, 1); + assert.equal(aa[0].length, 2); + assert.equal(aa[0][0], b); + assert.equal(aa[0][1], 42); + }, + "passes any arguments to the scale's tickFormat function": function(axis) { + var b = {}, + x = d3.scale.linear(), + a = axis().scale(x).ticks(b, 42), + g = d3.select("body").html("").append("svg:g"), + aa = []; + + x.tickFormat = function() { + aa.push(arguments); + return String; + }; + + g.call(a); + assert.equal(aa.length, 1); + assert.equal(aa[0].length, 2); + assert.equal(aa[0][0], b); + assert.equal(aa[0][1], 42); + }, + "affects the generated ticks": function(axis) { + var a = axis().ticks(20), + g = d3.select("body").html("").append("svg:g").call(a), + t = g.selectAll("g"); + assert.equal(t[0].length, 21); + } + }, + + "tickSubdivide": { + "defaults to zero": function(axis) { + var a = axis(); + assert.equal(a.tickSubdivide(), 0); + }, + "coerces input value to a number": function(axis) { + var a = axis().tickSubdivide(true); + assert.strictEqual(a.tickSubdivide(), 1); + }, + "does not generate minor ticks when zero": function(axis) { + var g = d3.select("body").html("").append("svg:g").call(axis()); + assert.isTrue(g.selectAll(".minor").empty()); + }, + "affects the generated minor ticks": function(axis) { + var a = axis().tickSubdivide(3), + g = d3.select("body").html("").append("svg:g").call(a), + t = g.selectAll("line.tick.minor"); + assert.equal(t[0].length, 30); + assert.equal(t[0][1].getAttribute("transform"), "translate(0.05,0)"); + } + }, + + "tickFormat": { + "defaults to null": function(axis) { + var a = axis(); + assert.isTrue(a.tickFormat() == null); + }, + "when null, uses the scale's tick format": function(axis) { + var x = d3.scale.linear(), a = axis().scale(x), + g = d3.select("body").html("").append("svg:g"); + + x.tickFormat = function() { + return function(d) { + return "foo-" + d; + }; + }; + + g.call(a); + var t = g.selectAll("g text"); + assert.equal(t.text(), "foo-0"); + }, + "affects the generated tick labels": function(axis) { + var a = axis().tickFormat(d3.format("+.2%")), + g = d3.select("body").html("").append("svg:g").call(a), + t = g.selectAll("g text"); + assert.equal(t.text(), "+0.00%"); + }, + "can be set to a constant": function(axis) { + var a = axis().tickFormat("I'm a tick!"), + g = d3.select("body").html("").append("svg:g").call(a), + t = g.selectAll("g text"); + assert.equal(t.text(), "I'm a tick!"); + }, + "can be set to a falsey constant": function(axis) { + var a = axis().tickFormat(""), + g = d3.select("body").html("").append("svg:g").call(a), + t = g.selectAll("g text"); + assert.equal(t.text(), ""); + } + }, + + "enter": { + "generates a new domain path": function(axis) { + var a = axis(), + g = d3.select("body").html("").append("svg:g").call(a), + path = g.selectAll("path.domain"); + assert.equal(path[0].length, 1); + assert.equal(path.attr("d"), "M0,6V0H1V6"); + assert.isNull(path.node().nextSibling); + }, + "generates new tick marks with labels": function(axis) { + var a = axis(), + g = d3.select("body").html("").append("svg:g").call(a), + x = d3.scale.linear(), + tick = g.selectAll("g"), + ticks = x.ticks(10), + tickFormat = x.tickFormat(10); + assert.equal(tick[0].length, ticks.length); + tick.each(function(d, i) { + var t = d3.select(this); + assert.isFalse(t.select("line").empty()); + assert.isFalse(t.select("text").empty()); + assert.equal(t.select("text").text(), tickFormat(ticks[i])); + }); + } + }, + + "update": { + "updates the domain path": function(axis) { + var a = axis(), + g = d3.select("body").html("").append("svg:g").call(a); + a.scale().domain([0, 2]).range([1, 2]); + a.tickSize(3); + g.call(a); + var path = g.selectAll("path.domain"); + assert.equal(path[0].length, 1); + assert.equal(path.attr("d"), "M1,3V0H2V3"); + assert.domEqual(path.node().nextSibling, null); + }, + "enters, exits and updates tick marks": function(axis) { + var a = axis(), + g = d3.select("body").html("").append("svg:g").call(a), + x = d3.scale.linear().domain([1, 1.5]); + a.scale().domain(x.domain()); + a.tickSize(3).tickPadding(9); + g.call(a); + var tick = g.selectAll("g"), + ticks = x.ticks(10), + tickFormat = x.tickFormat(10); + assert.equal(tick[0].length, ticks.length); + tick.each(function(d, i) { + var t = d3.select(this); + assert.isFalse(t.select("line").empty()); + assert.isFalse(t.select("text").empty()); + assert.equal(t.select("text").text(), tickFormat(ticks[i])); + }); + } + } + } +}); + +suite.export(module);