3

gs.csv (データ 1):

id, name, x_value, y_value
1, fruits, 60, 60
2, vegetables, 70, 70
...

circles.csv (データ 2):

id, name, value, cx_value, cy_value
1, fruits, apple, 10, 10
2, fruits, pear, 20, 20
3, fruits, strawberry, 30, 30
4, vegetables, carrot, 40, 40
5, vegetables, celery, 50, 50
...

上記のように2つのデータファイルがあります。gs.csv (data1) には g 要素に関するデータのみが含まれ、 circles.csv (data2) には円に関するデータのみが含まれており、それらを結合して以下を作成する適切な方法が必要です。



    <g class="groups" id="fruits" transform="translate(60,90)">
      <circle class="some" id="apple" cx="10" cy="10"/>
      <circle class="some" id="pear" cx="20" cy="20"/>
      <circle class="some" id="strawberry" cx="30" cy="30"/>
      ...
    </g>
    <g class="groups" id="vegetables" transform="translate(70,70)">
      <circle class="some" id="carrot" cx="40" cy="40">
      <circle class="some" id="celery" cx="50" cy="50">
      ...
    </g>

ファイルが複雑なため結合できません。コードは次のようなものにする必要があると思います。



    d3.csv("gs.csv", function(data1) {
     d3.csv("circles.csv", function(data2) {
       var svg = ...
       var groups = svg.selectAll(".groups")
                  .data(data1)
                  .enter().append("g")
                  .attr("class", "groups")
                  .attr("id", function(d) { return d.name; })
                  .attr("transform", function(d){return "translate(" + d.x_value + "," + d.y_value + ")"});

        groups.selectAll(".some")
        .data(data2, function(d) { return d.id; })
        .enter().append("circle")
        .attr("class", "some")
        .attr("id", function(d) { return d.value; })
        .attr("cx", function(d) { return d.cx_value; })
        .attr("cy", function(d) { return d.cy_value; });
    })
  });

2 つの解決策が頭に浮かびますが、常に問題があります。まず、2 番目の .data() で data2 から行をフィルタリングしようとしましたが、実際のグループの属性にアクセスして、同じ名前の値。次に、キー d.name で data2 を d3.nest してグループに入れようとしましたが、元の __ data_ を上書きしますそこで、各グループの _ data__ にキーと値を追加しようとしましたが、成功しませんでした。

4

3 に答える 3

6

これを行う最も簡単な方法は、次のように、データ グループをリストに入れてから操作することです。

groupData = [data1, data2];

groups = svg.selectAll('g')
    .data(groupData)
    .append('g')

これで 2 つのグループができました。それぞれのグループには、グループ内で必要なデータが追加されています。グループ内のデータに基づいて円を追加する関数を作成し、グループごとに呼び出すことができます。

function makeCircles(d){
    d3.select(this).selectAll('circle')
        .data(d)
        .append('circle')
        .attr('rx',function(D){return D.circleRadius})

groups.each(makeCircles);

これにより、各グループに関連するサークルが表示されます。内でselectAll作成した は、特定の円に関連付けられたデータを参照することに注意してください。代わりにを使用することもできますが、グループ データと円データの間の変数の混同を避けるのが最善です。このようにして、円の属性を定義する任意の関数で両方を使用することもできます。makeCirclesDddD

最初のデータに 2 番目のデータを含める場合は、同じ関数を使用できますが、D 自体を置き換える d に基づくフィルターを使用します。コードは次のようになります。

var root = d3.select('body').append('svg'),

    data1 = [{'name':'foo','value':10},{'name':'foo','value':3},{'name':'foo','value':8},{'name':'bar','value':10},{'name':'bar','value':1},{'name':'bar','value':15}],

    data2 = [{'name':'foo','color':'green','x':10},{'name':'bar','color':'blue','x':70}];

console.log('foo')

var groups = root.selectAll('g')
    .data(data2)
    .enter()
    .append('g')
    .attr('transform',function(d){return 'translate(' + d.x + ',10)'})
    .each(addCircles);

function addCircles(d){
    d3.select(this).selectAll('circle')
        .data(data1.filter(function(D){return D.name == d.name }))
        .enter()
        .append('circle')
        .attr('r',5)
        .attr('cx', 0)
        .attr('cy', function(D){return D.value * 30})
        .style('fill',d.color)
}

ここでフィドルを作りました

于 2013-07-23T20:14:04.957 に答える