1

d3 のシンボル メカニズムを使用して、データ セットごとに一意のシンボルを指定するのに問題があります。データは次のようになります: [[{x: 1, y:1},{x: 2, y:2},{x: 3, y:3}], [{x: 1, y:1},{ x:2、y:4}、{x:3、y:9}]など]

シンボルを書き出すコードの部分は次のようになります。点のベクトルごとに系列グループを作成します。それで:

series.selectAll("g.points") 
//this selects all <g> elements with class points (there aren't any yet)
.data(Object) //drill down into the nested Data
.enter() 
.append("g") //create groups then move them to the data location
.attr("transform", function(d, i) {
return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")";
        })
.append("path")
.attr("d", function(d,i,j){
        return (d3.svg.symbol().type(d3.svg.symbolTypes[j]));
    }
 );

または、少なくともそれが私がそれを機能させたい方法です。問題は、関数 d3.svg.symbol() を他の関数から返すことができないことです。関数を「タイプ」引数に入れようとすると、データは j が何であるか (シリーズのインデックス) を知るために正しくスコープされなくなります。

正しいですが、各データポイントに一意のシンボルは必要ありません。各シリーズに一意のシンボルが必要です。データは複数の配列 (シリーズ) で構成され、各配列は任意の数の点 (x,y) を持つことができます。配列ごとに異なるシンボルが欲しいのですが、それは j が私に与えるべきものです。データ (この例では 2 つの配列が示されているため、i は 0 の次に 1 です) を系列の選択に関連付けます。次に、データ オブジェクトをポイント選択に関連付けます。つまり、i は各配列内のポイントのインデックスになり、j は元の配列/一連のデータのインデックスになります。私は実際にこの構文を別の場所からコピーしましたが、他のインスタンス (グループ化された棒グラフの一連の棒の色付けなど) では問題なく機能しますが、なぜ機能するのか正確にはわかりませんでした...

任意のガイダンスをいただければ幸いです。ありがとう!

4

2 に答える 2

6

質問は正確には何ですか?あなたが与えるコードはあなたの質問に答えます。私の悪い、jはシリーズへの参照を返します。より簡単な例。

   var data = [
        {id: 1, pts: [{x:50, y:10},{x:50, y:30},{x:50, y:20},{x:50, y:30},{x:50, y:40}]},
        {id: 2, pts: [{x:10, y:10},{x:10, y:30},{x:40, y:20},{x:30, y:30},{x:10, y:30}]}
    ];
    var vis = d3.select("svg");
    var series = vis.selectAll("g.series") 
        .data(data, function(d, i) { return d.id; })
        .enter() 
        .append("svg:g")
        .classed("series", true);

    series.selectAll("g.point")
        .data(function(d, i) { return d.pts })
        .enter()
        .append("svg:path")
        .attr("transform", function(d, i) { return "translate(" + d.x + "," + d.y + ")"; })
        .attr("d", function(d,i, j) { return d3.svg.symbol().type(d3.svg.symbolTypes[j])(); })

唯一の違いは、d3.svg.symbol()。type(currentType)()の後に括弧を追加して、関数ではなく値を返すことです。D3jsは、チェーン、jqueryスタイルを使用します。これにより、symbol()。type('circle')を使用して値を設定し、symbol()。type()を使用して値を取得できます。アクセサーが使用されるときはいつでも、返されるのはメソッドと属性を持つ関数への参照です。Javascriptでは、関数はファーストクラスオブジェクトであることに注意してください- 「ファーストクラスオブジェクト」とはどういう意味ですか?。そのアプローチを使用するライブラリでは、多くの場合、意味のあるデータを取得するための明らかなゲッターがあります。symbolでは、symbol()()を使用する必要があります。

シンボル機能以外のコードは、 https://github.com/mbostock/d3/blob/master/src/svg/symbol.jsで確認できます。

d3.svg.symbol = function() {
  var type = d3_svg_symbolType,
      size = d3_svg_symbolSize;

  function symbol(d, i) {
    return (d3_svg_symbols.get(type.call(this, d, i))
        || d3_svg_symbolCircle)
        (size.call(this, d, i));
  }

  ...

  symbol.type = function(x) {
    if (!arguments.length) return type;
    type = d3_functor(x);
    return symbol;
  };


  return symbol;
};
于 2013-03-14T01:10:01.257 に答える
0

お持ちでない場合に備えて。やってみました?

.append("svg:path")
.attr("d", d3.svg.symbol()) 

https://github.com/mbostock/d3/wiki/SVG-Shapesに従って。

于 2013-03-13T08:59:45.647 に答える