2017-09-10 7 views
1

私はAxesを持つ棒グラフを描画しています.yScaleは、自分の追加した棒よりもyAxisの動作が異なります。yScaleが一貫して動作しないd3.js

y軸の範囲を(h - yPadding)に設定して、xAxisラベルの下部に余分なスペースを残すように設定しました。

   var yScale = d3.scale.linear() 
          .domain([0, d3.max(val)]) 
          .range([h - yPadding, 0]); 

- 範囲が逆さまです。そうでない場合は、yAxisのラベルは上下が逆です。

yScaleを使用してyAxisを呼び出すと、(h-yPadding)の開始点に従い、下部に部屋を残します。

しかし、私はyAxisのようにこれらの "rects"でyScaleを呼び出していても、グラフに追加しているすべての "rect"はhで始まり、h-yPaddingではなくhで始まります。

範囲を[h-yPadding、0]の代わりに[h、0]に変更すると、yAxisだけが変更に反応し、バーはまだhで開始します。

バーがyScaleを無視するのはなぜですか?

<script type="text/javascript"> 
     var xhr = new XMLHttpRequest(); 

     function makeRequest(){ 
      xhr.open("GET", "https://api.coinmarketcap.com/v1/ticker/", true); 
      xhr.send(); 
      xhr.onreadystatechange = processRequest; 
     } 

     function processRequest(){ 
      console.log("testing, state: ", xhr.readyState) 
      if(xhr.readyState == 4 && xhr.status == 200){ 
       dataset = []; 
       for(var i = 0; i < 10; i++){ 
        addingId = JSON.parse(xhr.responseText)[i]; 
        addingId.id = i; 
        dataset.push(addingId); 
       } 
       console.log("this is dataset: ", dataset); 
       makeChart(); 
      } 
     } 

     function makeChart(){ 
      var w = 1000; 
      var h = 600; 
      var padding = 40; 
      var yPadding = 80; 

      var val = []; 
      dataset.forEach(function(ele){ 
       val.push(parseInt(ele.market_cap_usd)); 
      }) 
      var max = d3.max(val) 

      var xAxisNames = [] 

      dataset.forEach(function(ele){ xAxisNames.push(ele.name); }) 
      // console.log(">>>>>>>>", xAxisNames) 

      var xScale = d3.scale.ordinal() 
          .domain(d3.range(dataset.length)) 
          .rangeRoundBands([padding, w - padding], 0.05) 

      var yScale = d3.scale.linear() 
          .domain([0, d3.max(val)]) 
          .range([h - yPadding, 0]); 

      var yAxis = d3.svg.axis() 
          .scale(yScale) 
          .orient("left") 
          .tickFormat(function(d){ 
           if(d > 0){ return d/1000000000 + " b"; } 
           return ""; 
          }) 

      var xAxis = d3.svg.axis() 
          .scale(xScale) 
          .orient("bottom") 
          .tickFormat(function(d, i){ 
           return xAxisNames[i] 
          }) 

      var svg = d3.select("body") 
         .append("svg") 
         .attr("width", w) 
         .attr("height", h); 

      svg.selectAll("rect") 
       .data(dataset) 
       .enter() 
       .append("rect") 
       .attr("x", function(d, i){ 
        return xScale(i); 
       }) 
       .attr("y", function(d){ 
        return yScale(d.market_cap_usd); 
       }) 
       .attr("width", xScale.rangeBand()) 
       .attr("height", function(d, i){ 
        return h - yScale(d.market_cap_usd) 
       }) 

      svg.append("g") 
       .attr("class", "y axis") 
       .attr("transform", "translate(" + padding + ", 0)") 
       .call(yAxis); 

      svg.append("g") 
       .attr("class", "x axis") 
       .attr("transform", "translate(0, " + (h - yPadding) + ")") 
       .call(xAxis) 
       .selectAll("text") 
       .attr("y", 15) 
       .attr("font-size", 12) 
       .attr("x", xScale.rangeBand()/2) 
       .attr("transform", "rotate(45)") 
     } 

     makeRequest(); 

    </script> 

答えて

1

スケールは、入力領域を出力範囲にマッピングするだけです。 SVG要素の位置と大きさをそれに応じて設定する必要があります。見てみましょう:

を今、あなたの規模を考えると、あなたはそれを自分のドメイン内の最小値を渡すときに返します。

h - yPadding 

あなたは、このようなバーはもちろん、ゼロピクセルの高さを有する欲しいです。

(h - yPadding) - yScale(minimumDomainValue) 

ドメイン内の最小値をゼロに与える:ゼロ方程式は単純であることを取得するには、その値から減算する必要があります。

.attr("height", function(d, i){ 
    return (h - yPadding) - yScale(d.market_cap_usd) 
}) 

PS

したがって、これは矩形の高さであるべきである方法によって、D3、スケールが決定少数のいずれかの状況でSVG要素の寸法であります軸ジェネレータによって生成されるパス/ライン。そのため、あなたの軸では違った振る舞いをしています。

+0

[OK]あなたは感謝の言葉を見ます!私は(h - yPadding)がバーのスケールを混乱させると思っていましたが、停止するバーのx/y座標を設定するだけです。素晴らしい作品です! – iggirex

関連する問題