2016-07-01 8 views
2

私は平行座標チャートを作成しています。各円は、特定のブランドで、すべてのブランドは、各列内の1つの円があります。ユーザーは、円の上に置いたときにD3 - DOM要素間のパスを描画する

enter image description here

を、私は他の3つの円にそのサークルを結ぶ経路を描画したいと思います同じブランド。問題は、円のX位置がランダムなので、円の変更されたCx値(データではなく)を使用して線を描く必要があることです。

便利なことに、私は自分のグラム要素にグループ化されたすべての4つのブランドの円を持っている:私は要素をつかむことができ、かつ双方向d3.lineのグループの座標は()好き

<g class="line-group"> 
    <circle r="5" cx="340.48700997553686" cy="0" data-brand="Brand X"></circle> 
    <circle r="5" cx="916.9181438059958" cy="59.347826086956466" data-brand="Brand X"></circle> 
    <circle r="5" cx="1589.2772695723352" cy="229.1306884480747" data-brand="Brand X"></circle> 
    <circle r="5" cx="2272.275506967826" cy="0" data-brand="Brand X"></circle> 
</g> 

が、それは1になりますすべての点を結ぶ線。

var line = d3.svg.line() 
       .interpolate('basis'); 

var circles = d3.selectAll('.line-group').selectAll('circle'), 
      circleCoords = []; 

     circles.forEach(function(d) { 
     console.log(circles); 
     for (i = 0; i < d.length; i++) { 
      var cx = d3.select(d[i]).attr('cx'), 
       cy = d3.select(d[i]).attr('cy'); 

      circleCoords.push([cx, cy]); 
     } 
     }); 

     lineGroup.append('path') 
      .attr({ 
       'd' : line(circleCoords) 
      }); 

どのように私はこれを構造化しますので、私は、各サークル・グループ(g.lineグループの内部同じブランドの4つの円)のCXとCYの値をつかむことができますか?

私はおそらく、カスタムD属性を作るために、このような何か(擬似コード)を持つ:

path.attr('d', function(d) { 
        return 'M ' + /* cx of circle 1 */ + ' ' + /* cy of circle 1 */ + 
        ' L ' + /* cx of circle 2 */ + ' ' + /* cy of circle 2 */ + 
        ' L ' + /* cx of circle 3 */ + ' ' + /* cy of circle 3 */ + 
        ' L ' + /* cx of circle 4 */ + ' ' + /* cy of circle 4 */ + ' Z'; 
       }) 

私はすべての作品があると信じて、私はちょうどそれをまとめるための方法を見つけるように見えることはできません正しく誰かが考えを持っているなら、大いに感謝します!

編集:行定義が追加されました。

答えて

2

あなたは間違った選択を(私はあなたのラインの定義を見ることができない、それを忘れないでください)があります。

var svg = d3.selectAll("svg") 
var circles = svg.selectAll('.line-group').selectAll("circle"), 
// or var circles = svg.selectAll('.line-group > circle'), 

      circleCoords = []; 

     circles.forEach(function(d) { 
     for (i = 0; i < d.length; i++) { 
      var cx = d3.select(d[i]).attr('cx'), 
       cy = d3.select(d[i]).attr('cy'); 

      circleCoords.push([cx, cy]); 
     } 
     console.log(circleCoords); 
     }); 

     var line = d3.svg.line() 

     svg.append('path') 
      .attr({ 
       'd' : line(circleCoords) 
      }); 

Here the working code

スタイルを忘れないでください。

: あなたがそうのように、複数の 『ブランド』を持っているあなたは、各「.LINE-グループ」を識別するために必要とするか、またはD3は、すべての「.LINE-グループ」クラスを選択します、あなたのケースでは

attribute.- IDを追加すること

<svg> 
<g class="line-group"> 
    <circle r="5" cx="10" cy="110" data-brand="Brand-X"></circle> 
    <circle r="5" cx="30" cy="120" data-brand="Brand-X"></circle> 
    <circle r="5" cx="150" cy="30" data-brand="Brand-X"></circle> 
    <circle r="5" cx="290" cy="40" data-brand="Brand-X"></circle> 
</g> 

<g class="line-group"> 
    <circle r="5" cx="10" cy="10" data-brand="Brand-Y"></circle> 
    <circle r="5" cx="30" cy="20" data-brand="Brand-Y"></circle> 
    <circle r="5" cx="150" cy="130" data-brand="Brand-Y"></circle> 
    <circle r="5" cx="290" cy="140" data-brand="Brand-Y"></circle> 
</g> 
</svg> 

あなたのコードをrefactoryする必要があります。

var svg = d3.selectAll("svg") 
var circles = svg.selectAll('.line-group').selectAll("circle"), 
      circleCoords = []; 
var line = d3.svg.line() 

// circles.length give you .line-group's count or brand's count: 

    for (j=0; j<circles.length; j++) { 
     circles[j].forEach(function(d) {  // forEach brand draw a line 
      var cx = d.getAttribute('cx'), 
       cy = d.getAttribute('cy'); 
      circleCoords.push([cx, cy]); 
     }) 
     svg.append('path') 
      .attr({ 'd' : line(circleCoords) }) 
      .attr("id","id_"+j); 
     circleCoords = []; 
    }; 

Here's the working code

+0

私は(ブランドYのための)第二のライングループを追加する場合、これが唯一のパスを作成します(すべてのCIRを結びますブランドXとブランドYのクリーム)。ブランドXとブランドYのそれぞれに独自の行があるように、どうすればいいですか? fiddle:https://jsfiddle.net/uobpp0La/7/ – BastionGamma

+0

Yeapを参照してください。それでも正しいシリーズを選択する必要があります。そのため、各シリーズにユニコードIDを定義する必要があります。データブランドの属性を使用することができます – Klaujesi

+0

どうすればよいでしょうか?私は次のようなものを試しています: 'var allBrandIDs = d3.set(studyData.map(function d){return d.brand_id;})).values();'そして 'allBrandIDs.forEach(function(d){ – BastionGamma

関連する問題