|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<title>Classical Scales</title> |
|
<script type="text/javascript" src="http://d3js.org/d3.v2.js"></script> |
|
<style type="text/css"> |
|
|
|
body { |
|
font: 10px sans-serif; |
|
} |
|
|
|
.error { |
|
fill: red; |
|
font-size: 200%; |
|
} |
|
|
|
line, path { |
|
fill: none; |
|
stroke: #000; |
|
shape-rendering: crispEdges; |
|
} |
|
|
|
/* |
|
.minor :not(.minor) { |
|
display: none; |
|
} |
|
*/ |
|
|
|
</style> |
|
</head> |
|
<body> |
|
<svg> |
|
<g> |
|
<filter id="glow"> |
|
<feColorMatrix type="matrix" |
|
values= |
|
"0 0 0 0.98 0 |
|
0 0 0 0.98 0 |
|
0 0 0 0.98 0 |
|
0 0 0 1 0" |
|
/> |
|
<feGaussianBlur stdDeviation="3.5" result="coloredBlur"/> |
|
<feMerge> |
|
<feMergeNode in="coloredBlur"/> |
|
<feMergeNode in="SourceGraphic"/> |
|
</feMerge> |
|
</filter> |
|
</g> |
|
</svg> |
|
<script type="text/javascript" src="http://gerhobbelt.github.com/bl.ocks.org-hack/fixit.js" ></script> |
|
|
|
<script type="text/javascript"> |
|
|
|
/* |
|
Correct bl.ocks.org IFRAME, Iff we're shown in an iframe! |
|
*/ |
|
d3.select(window.frameElement) |
|
.style("height", "1500px"); |
|
|
|
|
|
|
|
var margin = {top: 0, right: 20, bottom: 20, left: 20}, |
|
width = 960 - margin.right - margin.left, |
|
height = 1500 - margin.top - margin.bottom; |
|
hstep = Math.floor(height / 32); |
|
|
|
var x = d3.scale.linear() |
|
.domain([.05, .95]) |
|
.range([0, width]); |
|
|
|
var log_x = d3.scale.log() |
|
.domain([.05, 95]) |
|
.range([0, width]); |
|
|
|
var log_x_v2 = d3.scale.log() |
|
.domain([.05, 9500]) |
|
.range([0, width]); |
|
|
|
var log_x_v3 = d3.scale.log() |
|
.domain([.05, .95]) |
|
.range([0, width]); |
|
|
|
var pow_x_2 = d3.scale.pow() |
|
.exponent(2) |
|
.domain([.05, 9.5]) |
|
.range([0, width]); |
|
|
|
var pow_x_2_v2 = d3.scale.pow() |
|
.exponent(2) |
|
.domain([.05, 9500]) |
|
.range([0, width]); |
|
|
|
var pow_x_2_v3 = d3.scale.pow() |
|
.exponent(2) |
|
.domain([0, 2]) |
|
.range([0, width]); |
|
|
|
var pow_x_4 = d3.scale.pow() |
|
.exponent(2) |
|
.domain([0, 9.5]) |
|
.range([0, width]); |
|
|
|
var pow_x_f5 = d3.scale.pow() |
|
.exponent(1 / 5) |
|
.domain([0, 9.5]) |
|
.range([0, width]); |
|
|
|
var pow_x_m3 = d3.scale.pow() |
|
.exponent(-3) |
|
.domain([0, 9.5]) |
|
.range([0, width]); |
|
|
|
var sqrt_x = d3.scale.sqrt() |
|
.domain([0, 9.5]) |
|
.range([0, width]); |
|
|
|
var quantile_x = d3.scale.quantile() |
|
.domain([.05, .1, .11, .12, .13, .15, .2, .25, .4, .55, .7, 1, 2, 3, 4, 4.5, 4.6, 4.7, 4.8, 4.9, 5, 5.1, 6.3, 6.7, 6.8, 7, 8.4, 8.5, 8.6, 8.7, 9.5]) |
|
.range([0, width / 8, width / 4, width / 2, width * 3 / 4, width]); |
|
|
|
var quantize_x = d3.scale.quantize() |
|
.domain([.05, 9.5]) |
|
.range([0, width / 8, width / 4, width / 2, width * 3 / 4, width]); |
|
|
|
// d3.scale.threshold ASSUMPTION: domain.length == range.length - 1 |
|
var threshold_x = d3.scale.threshold() |
|
.domain([50, 140, 201, 605]) |
|
.range([0, width / 4, width / 2, width * 3 / 4, width]); |
|
|
|
var identity_x = d3.scale.identity() |
|
.domain([0, width]); |
|
|
|
var svg = d3.select("svg") |
|
.attr("width", width + margin.right + margin.left) |
|
.attr("height", height + margin.top + margin.bottom) |
|
.append("g") |
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
var axis_y = hstep; |
|
var descr = function(txt) { |
|
return function() { |
|
this.insert("text", "g") |
|
.text(txt) |
|
.attr("class", "description") |
|
.attr("x", width / 2) |
|
.attr("y", 0) |
|
.attr("dy", "-1em") |
|
.attr("text-anchor", "middle"); |
|
}; |
|
}; |
|
|
|
svg.append("g") |
|
.attr("class", "x axis") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x)) |
|
.call(descr("regular, linear axis (range = [0.05 - 0.95])")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(false)) |
|
.call(descr("regular, with .tickSubdivide(false)")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(true)) |
|
.call(descr("regular, with .tickSubdivide(true)")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(9)) |
|
.call(descr("regular, with 10 subticks per tick")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide("9")) |
|
.call(descr('regular, with 10 subticks per tick, using non-numeric .tickSubdivide("9")')); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(9).tickSize(6, 3, 10)) |
|
.call(descr("regular, with 10 (smaller) subticks and longer start/end ticks")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(9).tickSize(8, |
|
3 |
|
, -10)) |
|
.call(descr("classical, with 10 (smaller) subticks, emphasis on the fifth, and longer start/end ticks, inverted")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(x).tickSubdivide(16 - 1).tickSize(10, |
|
2 |
|
, -4)) |
|
.call(descr("classical, with 16 subticks, emphasis on the even and half-way ticks a la classical inches scale, start/end ticks inverted")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical log_x") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(log_x).tickSubdivide(9).tickSize(8, |
|
3 |
|
, -10)) |
|
.call(descr("classical logarithmic, with 10 (smaller) subticks, emphasis on the fifth, and longer start/end ticks, inverted")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// returns function suitable for axis.tickSubdivision(): |
|
function example_subdiv_A(scale) { |
|
return 10 - 1; |
|
} |
|
|
|
function b0rk_prevention(svg, f) { |
|
var s; |
|
try { |
|
s = f(); |
|
} catch (e) { |
|
s = svg.append("g") |
|
.attr("class", "b0rk") |
|
.attr("transform", "translate(0," + axis_y + ")"); |
|
|
|
s.append("text") |
|
.text("B0rk B0rk B0rk!") |
|
.attr("class", "error") |
|
.attr("style", "stroke: white; stroke-width: 10;") |
|
.attr("x", 40) |
|
.attr("y", 10) |
|
.attr("text-anchor", "left"); |
|
|
|
s.append("text") |
|
.text("B0rk B0rk B0rk!") |
|
.attr("class", "error") |
|
.attr("style", "filter: url(#glow);") |
|
.attr("x", 40) |
|
.attr("y", 10) |
|
.attr("text-anchor", "left"); |
|
} |
|
return s; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical log_x") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(log_x).tickSubdivide(example_subdiv_A(log_x)) |
|
.tickSize(12, |
|
4 |
|
, -10)) |
|
.call(descr("classical logarithmic, with output-dependent # of subticks, emphasis on the 2nd and other even (but only when we have 10+ subticks!) and .5 subdiv, and longer start/end ticks")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical log_x_v2") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(log_x_v2).tickSubdivide(example_subdiv_A(log_x_v2)) |
|
.tickSize(12, |
|
4 |
|
, -10)) |
|
.call(descr("classical logarithmic as above, but for a much larger range")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical log_x_v2") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(log_x_v3).tickSubdivide(example_subdiv_A(log_x_v3)) |
|
.tickSize(12, |
|
4 |
|
, -10)) |
|
.call(descr("classical logarithmic as above, but for a much smaller range")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, with 10 (smaller) subticks, emphasis on the even (for modulo >= 10) and fifth, and longer start/end ticks, inverted")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2).tickSubdivide(example_subdiv_A(pow_x_2)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2_v2).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, with 10 (smaller) subticks, etc., for larger range")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2_v2).tickSubdivide(example_subdiv_A(pow_x_2_v2)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2_v3).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, with 10 (smaller) subticks, etc., for smaller range")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_2_v3).tickSubdivide(example_subdiv_A(pow_x_2_v3)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square power, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_4).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(4), with 10 (smaller) subticks, emphasis on the even (for modulo >= 10) and fifth, and longer start/end ticks, inverted")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_4).tickSubdivide(example_subdiv_A(pow_x_4)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(4), adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_f5).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(1/5), with 10 (smaller) subticks, emphasis on the even (for modulo >= 10) and fifth, and longer start/end ticks, inverted")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_f5).tickSubdivide(example_subdiv_A(pow_x_f5)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(1/5), adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_m3).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(-3), with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(pow_x_m3).tickSubdivide(example_subdiv_A(pow_x_m3)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical power(-3), adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(sqrt_x).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square root, with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(sqrt_x).tickSubdivide(example_subdiv_A(sqrt_x)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
.call(descr("classical square root, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(quantile_x).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical quantile, with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(quantile_x).tickSubdivide(example_subdiv_A(quantile_x)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical quantile, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(quantize_x).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical quantized, with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(quantize_x).tickSubdivide(example_subdiv_A(quantize_x)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical quantized, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(threshold_x).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical threshold, with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(threshold_x).tickSubdivide(example_subdiv_A(threshold_x)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical threshold, adaptive subticks, etc.")); |
|
|
|
|
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(identity_x).tickSubdivide(9) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical identity, with 10 (smaller) subticks, etc.")); |
|
|
|
axis_y += hstep; |
|
b0rk_prevention(svg, function() { |
|
svg.append("g") |
|
.attr("class", "x minor endticks classical") |
|
.attr("transform", "translate(0," + axis_y + ")") |
|
.call(d3.svg.axis().scale(identity_x).tickSubdivide(example_subdiv_A(identity_x)) |
|
.tickSize(10, |
|
4 |
|
, -10)) |
|
}).call(descr("classical identity, adaptive subticks, etc.")); |
|
|
|
</script> |
|
</body> |
|
</html> |