2013-09-27 101 views
8

使用D3的權力,我想創建一個X軸,看起來像:D3對數刻度標記爲10

image of desired log scale labels

我已經工作了怎麼辦軸線和蜱,但沒有標籤使用以下:

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); 

這裏還有一個jsFiddle與完整代碼。

回答

12

你可以使用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)); }; 

例如,formatTick(1e5)回報"10⁵"。例如在bl.ocks.org/6738109

axis

這種方法的缺點是,上標數字的垂直取向似乎不一致。所以使用後選擇(比如選擇文本元素併爲每個上標添加一個tspan元素)可能會更好。在bl.ocks.org/6738229又如:

axis

+1

對應的上標unicode爲\ u2070 \ u00B9 \ u00B2 \ u00B3 \ u2074 \ u2076 \ u2077 \ u2078 \ u2079 – Stefan

2

軸上有一個tickFormat功能可用。不幸的是,它期望一個字符串作爲返回值並將其放在軸上。如果你想顯示10^6,這會很好,但是當你想要使用上標符號時沒有那麼有用。

解決方法是創建2個軸:一個用於顯示10,另一個用於顯示指數。這裏是一個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); 

這不一定是最優雅的解決方案,但它的工作原理。

+0

肯定能行。在將此標記爲答案之前,我會持續一天左右的時間來看看是否有更優雅的解決方案。 –