为什么我的旋转刻度值没有完全显示d3js?

时间:2017-01-29 22:38:51

标签: javascript html css d3.js

我正在制作一个图表,其中整个svg对象和刻度值应该在给定的高度限制内。我想知道为什么我的旋转刻度值没有完全显示。高度是100px,我希望我的图表和刻度值在100里面。我试过了  .attr("transform", "scale(1,1.4)")

功能但没有用。到目前为止,这是代码!

数据是这样的,渲染图表的代码低于它。

 { 
  "Height" : 100,
  "Width" : 250,
"margins" : {
    "top": 10,
    "left": 20,
    "right": 10,
    "bottom": 20
  },

  "data":[
          {
             "fruit" : "apple",
             "initialsale" : 40,
             "totalsale": 600
           },
           {
              "fruit" : "orange",
              "initialsale" : 40,
              "totalsale": 60
            },
          {
            "fruit" : "mango",
            "initialsale" : 1420,
            "totalsale": 6000
          }
        ]
}



function stackChart(){

  
  
 data =  { 
      "Height" : 100,
      "Width" : 250,
    "margins" : {
        "top": 10,
        "left": 20,
        "right": 10,
        "bottom": 20
      },

      "data":[
              {
                 "fruit" : "apple",
                 "initialsale" : 40,
                 "totalsale": 600
               },
               {
                  "fruit" : "orange",
                  "initialsale" : 40,
                  "totalsale": 60
                },
              {
                "fruit" : "mango",
                "initialsale" : 1420,
                "totalsale": 6000
              }
            ]
    };

var margin = data.margins;

var top = margin.top,
    bottom = margin.bottom,
    left = margin.left,
    right = margin.right,
    Width = data.Width,
    Height = data.Height,
    data = data.data;

var width = Width -left -right,
    height = Height -top - bottom;


var svg = d3.select("#stackChart")
  .append("svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


// Divider functionality
var div = 0;
if(Width>50&&Width<=100){
  div = 1.2
}
else if(Width>100&&Width<=200)
{
  div = 1.5
}
else if(Width>200&&Width<=300){
  div = 2.0
}
else if(Width>300&&Width<=400){
  div = 2.2
}
else if(Width>400&&Width<=500){
  div = 2.4
}
else if(Width>500&&Width<=600){
  div = 2.6
}
else if(Width>600&&Width<=800){
  div = 2.8
}
else if(Width>800){
  div = 3.0
}


var par = Width/div;

// var scale_parameter = Width/par;



var dataset = [];
var arr1 = [];
var arr2 = [];
data.forEach(function(d) {
                var currentObj = {}
                currentObj["os"] = d.os;
                currentObj["value"] = d.total;
                currentObj["percent"] = (d.initial/d.total)*100;
                arr1.push(currentObj);
                currentObj = {}
                currentObj["os"] = d.os;
                currentObj["value"] = d.total;
                currentObj["percent"] = ((d.total - d.initial)/d.total)*100;
                arr2.push(currentObj);
              }
            );
dataset = [{
    data: arr1,
    name: 'initial'
},{
   data: arr2,
  name: 'remaining'
}];

var series = dataset.map(function (d) {
    return d.name;
}),
dataset = dataset.map(function (d) {
    return d.data.map(function (o, i) {
        // Structure it so that your numeric
        // axis (the stacked amount) is y
        return {
            y: o.percent,
            x: o.os,
            v: o.value
        };
    });
}),
stack = d3.layout.stack(); //.layout in v3

stack(dataset);


var h1= Width * 0.7;
// Set x, y and colors
var x = d3.scale.ordinal()
  .domain(dataset[0].map(function(d) { return d.x; }))
  .rangeRoundBands([0, width], 0.15);

var y = d3.scale.linear()
  .domain([0, d3.max(dataset, function(d) {  return d3.max(d, function(d) { return d.y0+d.y; });  })])
  .range([height, 0]);

var colors = ["#14a900", "#cccccc"];


// Define and draw axes
var yAxis = d3.svg.axis()
  .scale(y)
  .orient("left")
  .ticks(5)
  .tickSize(1)
  .tickFormat( function(d) { return d } )


var xAxis = d3.svg.axis()
  .scale(x)
  .orient("bottom")

// Create groups for each series, rects for each segment

var groups = svg.selectAll("g.cost")
  .data(dataset)
  .enter().append("g")
  .attr("class", "cost")
  .style("fill", function(d, i) { return colors[i]; });


  // Height Calculation of the stack bars
  // y0 will be the base, y is the stacked up bar on y0

var crucial = 0;
var cr = 0;
var heightsof = [];
var rects = groups.selectAll("rect")
  .data(function(d) { return d; })
  .enter()
  .append("rect")
  // .attr("transform","scale(1,1.4)")
  .attr("x", function(d) { return x(d.x); })
  .attr("y", function(d) {
    crucial = y(d.y0 + d.y);
    return  crucial;
  })
  .attr("height", function(d) {
     return height - y(d.y);
   })
  .attr("width", x.rangeBand())

// Getting the length of the total bar
// For tilt angle

var calh=0;
  for(i=0;i<data.length+1;i++){
    var j = data.length;
    if(i==j){
      calh = heightsof[j]+heightsof[0];
    }
  }

  console.log(calh);
  var rect_width = Math.round($("rect").outerWidth());

  svg.append("g")
    .attr("class", "y axis")
    .call(yAxis)
    // .attr("transform","scale(1,)")


  var bool = [],
      counter = 0,
      y = [],
      x = 0,
      z = 0; // max value of y[]

  svg.append("g")
    .attr("class", "x axis")
    .attr("transform", function(){
      return "translate(0,"+(h1)+")";
    })
    .call(xAxis)
    .selectAll("text")
            .style("fill","black")
            .each(function(d,i) {
                    var thisWidth = this.getComputedTextLength();
                    var x = Math.round(thisWidth);
                    y.push(x);
                    if(rect_width>x){
                      bool.push(true);
                    }
                    else{
                      bool.push(false);
                      counter++;
                    }
                    z = Math.max.apply(Math, y);
                  })
                  .style("text-anchor",function(d,i){
                    if(rect_width<=20){
                      return "end";
                    }
                    else {
                      return "middle";
                    }
                  })
                  .attr("transform", function(d,i) {      // Rotation Code
                    if(rect_width<=20) {
                      x = -90;
                      return "translate(-13,8) rotate("+x+")"; //  Minimum width rotation
                    }
                    else if (rect_width>z) {
                      return "rotate(0)";
                    }
                    else if(rect_width>20&&rect_width<z) {
                      var tilt = data.length;
                      var angle = Math.cos(z/rect_width)
                      console.log(angle);
                      if(angle>0&&bool[i]==false){
                        return "translate(-10,"+((y[i]/3)+12)+") rotate(-45)";// -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment
                      }
                      if(angle>0&&bool[i]==true){
                        return "translate(-10,"+((y[i]/3)+8)+") rotate(-45)"//"+ -(90-angle*100) +")"; // Rotating based on the maximum angle for proper alignment
                      }
                      else{
                        return "translate(-10,"+((y[i]/3)+12)+") rotate("+ -(90+angle*10) +")"; // Rotating based on the maximum angle for proper alignment
                      }
                        }
                  });

   
}
&#13;
<div id="stackChart">
  </div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script>
  stackChart();
  </script>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:2)

您需要做的是将第二个height(图例一)的<svg>值从100更改为120。我不太了解d3.js或您的脚本,以便在您的脚本内部实现它。在生成javascript之后,我可以写一个<svg>代码段来动态执行,但它会是hack - ish。 我想通过这些信息以及您对自己脚本的了解,您可以从该图例的来源得到修复。

由Gerardo Furtado提供,您需要做的就是让legend svg有足够的空间(高度)来正确显示标签:

  

在D3中,轴生成器始终在SVG的原点(0,0)处创建。然后,它被转换为用户想要的任何位置,并在轴下方创建刻度线。目前,OP正在翻译"translate(0,"+(height)+")",高度为Height -top - bottom;。因此,解决方案只是增加data.margins.bottom的值。为了不扭曲条形,请告诉人们需要相应地增加data.height

如果必须使您的图例符合100px高度,则需要将此CSS规则应用于此:

transform: scale(factor);
transform-origin:left; /* keep it aligned on left side */

,其中factor低于1以便缩小。如果您不关心按比例缩放,则可以将比例因子限制为仅Y轴。 (使用scaleY代替scale)但这会扭曲您的图例svg中的所有内容,包括文字。