Using D3 I want to create an X Axis that looks like:
I've worked out how to do the axis and ticks, but not the labels using the following:
var svgWidth = 500;
var svgHeight = 500;
var svgAxisPadding = 20;
var xScale = d3.scale.log()
.domain([Math.pow(10, 5), Math.pow(10, 7)])
.range([svgAxisPadding, svgWidth - svgAxisPadding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0, "e");
var svg = d3.select('#diagram')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight);
svg.append('g')
.attr("class", "axis")
.call(xAxis);
And here's a jsFiddle with the plete code.
Using D3 I want to create an X Axis that looks like:
I've worked out how to do the axis and ticks, but not the labels using the following:
var svgWidth = 500;
var svgHeight = 500;
var svgAxisPadding = 20;
var xScale = d3.scale.log()
.domain([Math.pow(10, 5), Math.pow(10, 7)])
.range([svgAxisPadding, svgWidth - svgAxisPadding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0, "e");
var svg = d3.select('#diagram')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight);
svg.append('g')
.attr("class", "axis")
.call(xAxis);
And here's a jsFiddle with the plete code.
Share Improve this question edited Sep 27, 2013 at 16:26 Mike Ward asked Sep 27, 2013 at 16:09 Mike WardMike Ward 3,3211 gold badge31 silver badges44 bronze badges2 Answers
Reset to default 16You could use unicode:
var superscript = "⁰¹²³⁴⁵⁶⁷⁸⁹",
formatPower = function(d) { return (d + "").split("").map(function(c) { return superscript[c]; }).join(""); },
formatTick = function(d) { return 10 + formatPower(Math.round(Math.log(d) / Math.LN10)); };
For example, formatTick(1e5)
returns "10⁵"
. Example at bl.ocks/6738109:
The downside of this approach is that the vertical alignment of the superscript numerals seems inconsistent. So using post-selection (say, selecting the text elements and adding a tspan element for the superscript to each) might be better. Another example at bl.ocks/6738229:
There's a tickFormat
function available on the axis. Unfortunately, it expects a String as a return value and plops that on the axis. This would be great if you wanted to display 10^6, but not as helpful when you want to use the superscript notation.
A workaround is to create 2 axes: one for displaying the 10 and another for displaying the exponent. Here's an example:
var svgWidth = 500;
var svgHeight = 500;
var svgAxisPadding = 20;
var xScale = d3.scale.log()
.domain([Math.pow(10, 5), Math.pow(10, 7)])
.range([svgAxisPadding, svgWidth - svgAxisPadding]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0, "e")
.tickFormat(function (d) {
var log = Math.log(d) / Math.LN10;
return Math.abs(Math.round(log) - log) < 1e-6 ? 10 : '';
});
var xAxis2 = d3.svg.axis()
.scale(xScale)
.orient('bottom')
.ticks(0, "e")
.tickFormat(function (d) {
var log = Math.log(d) / Math.LN10;
return Math.abs(Math.round(log) - log) < 1e-6 ? Math.round(log) : '';
});
var svg = d3.select('#diagram')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight);
svg.append('g')
.attr("class", "axis")
.call(xAxis);
svg.append('g')
.attr("class", "axis")
.attr("transform", "translate(12, -5)") //shifted up and to the right
.style("font-size", "12px")
.call(xAxis2);
It's not necessarily the most elegant solution, but it works.