簡體   English   中英

D3.JS Y軸標簽問題

[英]D3.JS Y-axis label issue

首先,我是D3.Js的新手。 過去一周左右,我一直在研究D3.JS問題,尤其是制作帶有Y軸標簽的圖形。 但是,我無法獲得所需的圖形。 快到了,但是倒掛了,或者我的數據出了錯。 現在,在顯示所有代碼之前,我將簡要展示一些代碼和主要問題的圖像。 我花了很多時間看其他有類似問題的Stack Overflow帖子,我做了這些帖子上的內容,但仍然有同樣的問題。

例如,我認為該帖子將提供解決方案: Y軸反轉D3

數據如下:

[0,20,3,8](實際上是一個對象數組,但是我認為這可能就是所需要的。

因此,首先,當yScale如下所示時:

  var yScale = d3.scaleLinear() 
             .domain([0, maxPound]) //Value of maxpound is 20
             .range([0, 350]);

條形圖如下所示: 圖1

可以看到,Y圖表的頂部從零開始,底部從20開始,起初我認為這是將域中的值翻轉到此的簡單解決方案:

     var yScale = d3.scaleLinear() 
             .domain([0, maxPound]) //Value of maxpound is 20
             .range([0, 350]);

我得到這張圖片:

在此處輸入圖片說明

在第二個圖像中,y軸是右20,位於頂部。 但是圖表是錯誤的。 現在,0將返回350像素的值,即SVG元素的高度。 那就是20應該返回的值! 如果嘗試切換圖像范圍值,則會遇到同樣的問題!

現在的代碼:

  var w = 350;
  var h = 350;
  var barPadding = 1;
  var margin = {top: 5, right: 200, bottom: 70, left: 25}

  var maxPound = d3.max(poundDataArray, 
     function(d) {return parseInt(d.Pounds)}
  );

  //Y-Axis Code
  var yScale = d3.scaleLinear()
                 .domain([maxPound, 0])
                 .range([0, h]);

  var yAxis = d3.axisLeft()
                .scale(yScale)
                .ticks(5);


  //Creating SVG element 
  var svg = d3.select(".pounds")
              .append('svg')
              .attr("width", w)
              .attr('height', h)
              .append("g")
                 .attr("transform", "translate(" + margin.left + "," + 
     margin.top + ")");

    svg.selectAll("rect")
       .data(poundDataArray)
       .enter()
       .append("rect")
       .attr('x',  function(d, i){
            return i * (w / poundDataArray.length);
         })
       .attr('y', function(d) {
            return 350 - yScale(d.Pounds);
        })
       .attr('width', (w / 4) - 25)
       .attr('height', function(d){
           return yScale(d.Pounds);
        })
       .attr('fill', 'steelblue');



   //Create Y axis
   svg.append("g")
      .attr("class", "axis")
      .call(yAxis);

感謝您的任何幫助! 我認為錯誤可能出在y或height值上,並花了很多時間在那里弄亂了結果。

這不是一個D3的問題,而是一個SVG功能:在SVG,原點(0,0)是在左上角 ,而不是左下角,作為普通的笛卡爾平面。 這就是為什么使用[0, h]作為范圍會使軸看起來像是反轉的 ...實際上,它不是反轉的:這是SVG中正確的方向。 順便說一句,HTML5 Canvas具有相同的坐標系,並且使用Canvas也會遇到相同的問題。

因此,您必須翻轉range而不是domain:

var yScale = d3.scaleLinear()
    .domain([0, maxPound])
    .range([h, 0]);//the range goes from the bottom to the top now

或者,在您的情況下,使用邊距:

var yScale = d3.scaleLinear()
    .domain([0, maxPound])
    .range([h - margin.bottom, margin.top]);

除此之外,y位置和高度的數學運算是錯誤的。 它應該是:

.attr('y', function(d) {
    return yScale(d.Pounds);
})
.attr('height', function(d) {
    return h - margin.bottom - yScale(d.Pounds);
})

另外,請注意,請勿硬編碼x的位置和寬度。 請改用帶刻度。

這是您所做的更改的代碼:

 var poundDataArray = [{ Pounds: 10 }, { Pounds: 20 }, { Pounds: 5 }, { Pounds: 8 }, { Pounds: 14 }, { Pounds: 1 }, { Pounds: 12 }]; var w = 350; var h = 350; var barPadding = 1; var margin = { top: 5, right: 20, bottom: 70, left: 25 } var maxPound = d3.max(poundDataArray, function(d) { return parseInt(d.Pounds) } ); //Y-Axis Code var yScale = d3.scaleLinear() .domain([0, maxPound]) .range([h - margin.bottom, margin.top]); var xScale = d3.scaleBand() .domain(d3.range(poundDataArray.length)) .range([margin.left, w - margin.right]) .padding(.2); var yAxis = d3.axisLeft() .scale(yScale) .ticks(5); //Creating SVG element var svg = d3.select("body") .append('svg') .attr("width", w) .attr('height', h) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); svg.selectAll("rect") .data(poundDataArray) .enter() .append("rect") .attr('x', function(d, i) { return xScale(i); }) .attr('y', function(d) { return yScale(d.Pounds); }) .attr('width', xScale.bandwidth()) .attr('height', function(d) { return h - margin.bottom - yScale(d.Pounds); }) .attr('fill', 'steelblue'); //Create Y axis svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + margin.left + ",0)") .call(yAxis); 
 <script src="https://d3js.org/d3.v4.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM