2017-12-13 20 views
0

データに(y軸上の)ギャップがあるので、リニアスケールを使用していますが、序数量—に移動する必要があります。穴が見えません。d3カスタマイズtick線(nextSiblingに基づいて)

しかし、別のティックマーカーを使用してデータが連続していないことを視覚的に示す必要があります。ここでの考え方は、next value - current valueが1であるかどうかをチェックし、そうでない場合は別のティックラインを描くことです。

this exampleを使用しました。this.parentNode.nextSibling —を使用しましたが、必要な値が得られていません。

これを行うにはどうすればよいですか?

下記のサンプルコード。私は別のダニに2、図5、図8のショーのためにラインアップしたいです(たとえばstroke-dasharray: "10,2"または異なる色であってもよい)

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <meta charset="utf-8"> 
 
    <title>Ticks problem</title> 
 
    </head> 
 
    <body> 
 

 
    <svg width="500" height="300"></svg> 
 

 
    <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> 
 
    <script type="text/javascript"> 
 
     var svg = d3.select("svg"), 
 
     margin = {top: 20, right: 0, bottom: 20, left: 0}, 
 
     width = +svg.attr("width") - margin.left - margin.right, 
 
     height = +svg.attr("height") - margin.top - margin.bottom, 
 
     g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
     var data = [5, 15, 7, 10, 4, 12, 14]; 
 

 
     var yDomain = [1, 2, 4, 5, 8, 10, 11]; 
 
     var yRange = Array(data.length+1).fill().map((d,i)=>(i+1)*35); 
 
     var yScale = d3.scaleOrdinal() 
 
      .domain(yDomain) 
 
      .range(yRange); 
 

 
     var yAxis = d3.axisRight(yScale) 
 
     .ticks(data.length+1) 
 
     .tickSize(width); 
 

 
     function customYAxis(g) { 
 
     g.call(yAxis); 
 
     g.attr("id", "y-axis"); 
 
     g.select(".domain").remove(); 
 
     //g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2"); 
 
     g.selectAll(".tick line") 
 
     .attr("stroke", "#777") 
 
     .attr("stroke-dasharray", (d,i)=>{ 
 
      //let n = d3.select(this.parentNode.nextSibling).datum(); // not working 
 
      //console.log(i + " " + d+" "+n); 
 
      // return "10,2" if n-d > 1 
 
      return "2,2"; // return some default for now 
 
     }) 
 
     g.selectAll(".tick text").attr("x", 4).attr("dy", -4); 
 
     } 
 

 
     g.append('g').call(customYAxis); 
 
    </script> 
 

 
    </body> 
 
</html>

答えて

2

selection.attr()3を提供すると呼ばれますことを、覚えておいてください引数:

は、現在の原点(D)、現在のインデックス(私を渡されます)、および現在のDOM要素としてこのと現在のグループ(ノード)、(ノード[I]

あなたの基準にアクセスするための第三の引数を利用することができ次の要素。 iは現在の要素のインデックスなので、node[i+1]は次の要素を指します。その次の要素を簡単に選択し、.datum()を使用してバインドされたデータを取得することができます。

d3.select(nodes[i+1]).datum() 

残された唯一の事はnodes配列の最後の要素を過ぎて読んでいないために安全装置を採用することです。

i < nodes.length - 1 && d3.select(nodes[i+1]).datum() 

これが直接あなたの.attr()セッターで使用することができます

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <meta charset="utf-8"> 
 
    <title>Ticks problem</title> 
 
    </head> 
 
    <body> 
 

 
    <svg width="500" height="300"></svg> 
 

 
    <script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script> 
 
    <script type="text/javascript"> 
 
     var svg = d3.select("svg"), 
 
     margin = {top: 20, right: 0, bottom: 20, left: 0}, 
 
     width = +svg.attr("width") - margin.left - margin.right, 
 
     height = +svg.attr("height") - margin.top - margin.bottom, 
 
     g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
     var data = [5, 15, 7, 10, 4, 12, 14]; 
 

 
     var yDomain = [1, 2, 4, 5, 8, 10, 11]; 
 
     var yRange = Array(data.length+1).fill().map((d,i)=>(i+1)*35); 
 
     var yScale = d3.scaleOrdinal() 
 
      .domain(yDomain) 
 
      .range(yRange); 
 

 
     var yAxis = d3.axisRight(yScale) 
 
     .ticks(data.length+1) 
 
     .tickSize(width); 
 

 
     function customYAxis(g) { 
 
     g.call(yAxis); 
 
     g.attr("id", "y-axis"); 
 
     g.select(".domain").remove(); 
 
     //g.selectAll(".tick line").attr("stroke", "#777").attr("stroke-dasharray", "2,2"); 
 
     g.selectAll(".tick line") 
 
     .attr("stroke", "#777") 
 
     .attr("stroke-dasharray", (d, i, nodes) => { 
 
      return i < nodes.length - 1 && d3.select(nodes[i+1]).datum() - d > 1 ? "10,2" : "2,2"; 
 
     }) 
 
     g.selectAll(".tick text").attr("x", 4).attr("dy", -4); 
 
     } 
 

 
     svg.append('g').call(customYAxis); 
 
    </script> 
 

 
    </body> 
 
</html>

+0

ありがとう!これが手元にある問題を解決する一方で、 'this'キーワードについてもう少し詳しく知りたいし、それがd3のコンテキストで一般的にどのように使われているか(つまり' this.parentNode'を使って問題を解決できるか等?)。この点に関して私が指摘できるドキュメンテーション/リンクはありますか?再度、感謝します! – mrbrahman

+1

物事はもう少し複雑です:テキストラベルと一緒にティックの行は 'g'要素にラップされます。したがって、それは親要素です。あなたはそれを握るために内部を点検しなければならないでしょう。私が知っている限り、私が引用したもの以外に、「this」の使用に関する文書はありません。さらに、あなたのように矢印関数を使うときは、 'this'に注意する必要があります。すべてのことを考えれば、私は自分のアプローチを安全な選択肢だと考えていますが、ソースを深く掘り下げる必要があると感じたら、多くを学ぶべきです。 – altocumulus

関連する問題