2015-12-16 10 views
5

ドメインが数日から数十年まで変化する可能性があるd3でタイムラインの視覚化を構築しています。私はこのように、D3の時間スケールと軸を使用しています:ドメインがとても変数であるのでd3.js:タイムスケールからチックフォーマットを取得

var timeScale = d3.time.scale() 
    .domain([firstEvent, lastEvent]) 
    .range([leftPadding, w - rightPadding]); 
var timeAxis = d3.svg.axis() 
    .scale(timeScale) 
    .orient("bottom"); 
timeAxis.ticks(5); 

、自動的に目盛り形式を選択しますticks(x)を使用すると便利です。私の問題は、場合によっては年が表示されないことです。これは重要です。私の考えは、軸が作成された後にティック形式をチェックし、年が含まれていない場合は軸の横に手動で表示することでした。しかし、私はスケールのダンプフォーマットを取得できませんでした。 timeScale.tickFormat()を使用すると、関数が返されます。どうすればこの問題を解決できますか?

+0

引数なしで '.ticks()'を呼び出すと、ティックの位置を取得できます。 –

+0

@LarsKotthoffはい。しかし、 '.ticks()'はフォーマットされていない場所を返しますので、私が見る限り、その年のいずれかのラベルに表示されるかどうかはわかりません。 – speedymcs

答えて

3

単純な正規表現テストはどうですか?

var hasYear = false; 
var re = /^\d{4}$/; 
// get the ticks text  
d3.selectAll('.x>.tick>text').each(function(d){ 
    // does the text look like a year? 
    var txt = this.textContent; 
    if (re.test(txt)){ 
    hasYear = true; 
    } 
}); 
console.log(hasYear); 

このサンプルコードを使用し、様々な範囲で遊ん:目盛りに表示される日付のいずれかがオンになっているかどうかを

<!DOCTYPE html> 
 
<meta charset="utf-8"> 
 
<style> 
 

 
.axis text { 
 
    font: 10px sans-serif; 
 
} 
 

 
.axis line, 
 
.axis path { 
 
    fill: none; 
 
    stroke: #000; 
 
    shape-rendering: crispEdges; 
 
} 
 

 
</style> 
 
<body> 
 
<script src="//d3js.org/d3.v3.min.js"></script> 
 
<script> 
 

 
var margin = {top: 250, right: 40, bottom: 250, left: 40}, 
 
    width = 960 - margin.left - margin.right, 
 
    height = 500 - margin.top - margin.bottom; 
 

 
var x = d3.time.scale() 
 
    .domain([new Date(2013, 12, 2), new Date(2013, 12, 6)]) 
 
    .range([0, width]); 
 

 
var xAxis = d3.svg.axis() 
 
    .scale(x) 
 
    .ticks(5); 
 

 
var svg = d3.select("body").append("svg") 
 
    .attr("width", width + margin.left + margin.right) 
 
    .attr("height", height + margin.top + margin.bottom) 
 
    .append("g") 
 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
svg.append("g") 
 
    .attr("class", "x axis") 
 
    .attr("transform", "translate(0," + height + ")") 
 
    .call(xAxis); 
 
    
 
xAxis.ticks().some(function(d){ 
 
    return /^\d{4}$/.exec("3434") 
 
}) 
 

 
var hasYear = false; 
 
var re = /^\d{4}$/; 
 
d3.selectAll('.x>.tick>text').each(function(d){ 
 
    var txt = this.textContent; 
 
    if (re.test(txt)){ 
 
    hasYear = true; 
 
    } 
 
}); 
 
console.log(hasYear); 
 

 

 
</script>

+0

うまくいくように思えます - ありがとう!選択についてもっと学ぶ必要があります... – speedymcs

1

D3の時間軸の書式設定を確認真夜中、1月の初めにその年だけを表示する。あなたは通年ではダニを取得し、この状態を確認することで表示されるかどうかを確認することができます。

function isYear(t) { 
    return +t == +(new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0)); 
} 
var ticks = timeScale.ticks(); 
var willDisplayYear = ticks.some(isYear); 

に完全なデモを両方のケースhereため。

+0

あなたの答え、Larsに感謝します。時間軸が年を表示するかどうかを決定する方法のソースがありますか?それは私にはほとんど起こりそうにない、私は軸の範囲に依存すると思う。コードは私にエラーを与えます - 't.getFullYear'は関数ではありません。どうやらそれはDateオブジェクトから呼び出される必要があります。最初に作成したのは: var date = new Date(t); 新しい日付(+ t)==新しい日付(date.getFullYear()、0、0、0、0、0、0); コードは、ティックに年があっても 'false'を返します。私はマークの答えをどちらかというともっと頑強な解決策に見えるようにマークしました。 – speedymcs

+0

ああ、あなたが正しいです - これのスケールを使用する必要があります。私は答えを修正します。 –

+0

目盛りのラベルに満月があっても 'false'を返します。タイムゾーンと関係があります。 – speedymcs

関連する問題