web-dev-qa-db-ja.com

d3.jsで時間と分のカスタム軸フォーマッターを作成するにはどうすればよいですか?

D3.jsでグラフ化しているデータセットがあります。 x軸は時間(分単位)を表します。この軸をhh:mm形式で表示したいのですが、d3内でこれをきれいに行う方法が見つかりません。

私の軸コードは次のようになります:

svg.append('g')
   .attr('class', 'x axis')
   .attr('transform', 'translate(0,' + height + ')')
   .call(d3.svg.axis()
     .scale(x)
     .orient('bottom'));

[100, 115, 130, 140]などのようなラベルを数分で生成します。

私の現在の解決策は、生成された後にtext要素を選択し、それらを関数でオーバーライドすることです。

   svg.selectAll('.x.axis text')
   .text(function(d) { 
       d = d.toFixed();
       var hours = Math.floor(d / 60);
       var minutes = pad((d % 60), 2);
       return hours + ":" + minutes;
   });

[1:40, 1:55, 2:10]などの軸ティックを出力します。

しかし、これはぎこちなく感じ、d3.formatの使用を避けます。これらのラベルを作成するためのより良い方法はありますか?

17
matthewsteele

絶対時間がある場合は、xデータをJavaScriptに変換することをお勧めします 日付オブジェクト 単純な数値ではなく、 d3.time.scale および d3.time.format を使用します。軸の「hh:mm」形式の例は次のとおりです。

d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .tickFormat(d3.time.format("%H:%M"));

実際には、ティック形式を指定する必要はまったくありません。スケールの定義域とティック数によっては、 デフォルトのタイムスケール形式 で十分な場合があります。または、完全に制御したい場合は、目盛りの目盛り間隔を指定することもできます。たとえば、15分ごとのティックの場合、次のように言うことができます。

d3.svg.axis()
    .scale(x)
    .orient("bottom")
    .ticks(d3.time.minutes, 15)
    .tickFormat(d3.time.format("%H:%M"));

相対時間ie期間がある場合(したがって、絶対日付ではなく分を表す数値があります)、任意のエポックを選択してオンザフライで変換することにより、これらを日付としてフォーマットできます。そうすれば、データ自体を数値のままにすることができます。例えば:

var formatTime = d3.time.format("%H:%M"),
    formatMinutes = function(d) { return formatTime(new Date(2012, 0, 1, 0, d)); };

分と時間のみが表示されるため、どのエポックを選択してもかまいません。この手法を使用して期間の分布をフォーマットする例を次に示します。

53
mbostock