5

私のデータは次のようになります...

var data = [{name:'a', value : 97},
          {name:'b', value : 24},
          {name:'c', value : 10}];

このように作成された序数スケールがあります...

var y = d3.scale.ordinal().rangeBands([0, 30 * data.length]);

そして私はそれを使ってこのような基本的なグラフを作成しています...

    chart.selectAll("rect")
        .data(data)
        .enter().append("svg:rect")
        .attr("y", function(d,i){ return y(d.name);})
        .attr("width", function(d,i){ return x(d.value);})
        .attr("height", y.rangeBand());

d3のドキュメント(ここ)によると、順序尺度のドメインを指定する必要はなく、使用しようとすると入力されます。ただし、私の状況では、ドメイン配列がスケールオブジェクト内に入力されているように見えても、y(d.name)は常に0を返し、y.rangeBand()は例外を発生させます。

だから、私は自分のドメインを事前に定義することでこれを回避しました...

.domain(data.map(function (d){ return d.name;}))

ただし、このドメインに動的に追加できるようにしたいと思います。追加した場合、作成時に設定された元の値を超えて拡張されることはありません。これも可能ですか?

私はd3に非常に慣れていないので、ここで重要な何かを見逃している可能性があります。

4

3 に答える 3

12

rangeBandsとrangePointsを使用すると、範囲にアクセスするためにドメインを定義する必要があります。ドメインは、表示するバンドまたはポイントの数を順序スケールに指示します。ただし、後で(を呼び出すことによって)ドメインscale.domain(newDomain)変更すると、範囲が更新されます。以前は見えなかった値をスケールに渡すことによって、それを暗黙的に行うことはできません。とにかく順序スケールでドメインを定義することは一般的に良い考えです。そうすれば、常に決定論的な振る舞いを得ることができます。

于 2012-04-17T04:28:34.730 に答える
2

ドメイン内の要素は、文字列に強制変換されるときに一意である必要があるため、オブジェクトの配列をドメインに渡す場合、予期しない結果が生じる可能性があります。たとえば、各オブジェクトの文字列表現が「[object Object]」のように見える場合、d3はオブジェクトをすべて同じと見なす可能性があります。私は以前にこの問題に遭遇しました、そして私がそれを回避した方法は次のようなことをすることです

d3.scale.ordinal(d3.range(0,myData.length)).rangeBands([0,myRangeBound])

これは、各データ要素を一意の配列インデックスにマップします。この場合、スケールを設定する前に、必要に応じてデータを並べ替える必要があり、データが変更されるたびにドメインをリセットする必要があることに注意してください。一般に、レンダリングメソッドなどを定義して、新しいデータが入ったときにスケールをリセットしてすべてを再描画し、可能な場合はいつでもドメインを明示的に設定することをお勧めします。

于 2012-06-29T02:45:42.037 に答える
1

私はd3グーグルグループで私の答えを見つけました。どうやら、rangeBands()またはrangePoints()を使用する場合は、ドメインをすでに定義している必要があります。

http://groups.google.com/group/d3-js/browse_thread/thread/10387d8ecf7ee412

于 2012-04-16T19:50:07.850 に答える