【问题标题】:D3.js - rotate text to verticalD3.js - 将文本旋转到垂直
【发布时间】:2015-10-31 17:57:46
【问题描述】:

问题:

我是 D3.js 的新手,我创建了一个从数组中获取数据的条形图。我将文本放在条形图的顶部,文本比条形图本身更宽。我想垂直旋转它,以便文本穿过栏的中间。

我知道.attr("transform", "rotate(180)") 不起作用,因为它会将我的文本旋转到屏幕外。我从 Mike Bostock here 那里找到了答案,但它似乎对我不起作用,我不知道我做错了什么。他说我需要改变旋转原点,但我不能让它工作。

感谢您的帮助,您可以在下面找到代码:

var label = svg.selectAll("text")
              .data(data)
              .enter()
              .append("text")
              .text(function(d){
                return d;
              })
              .attr("x", function(d, i){
                xText = i*(w/data.length);
                return xText;
              })
              .attr("y", function(d){
                yText = h - yScale(d);
                return yText;
              })
              .attr("transform", "translate(" + xText + "," + yText + ") rotate(90)")
              .attr("fill", "black")
              .attr("font-family", "sans-serif")
              .attr("font-size", "11px");

谢谢!

【问题讨论】:

    标签: javascript d3.js rotation


    【解决方案1】:

    您正在设置xy 属性并翻译文本。随着旋转,你只想使用translate

    .attr("transform", function(d,i){
      var xText = i * (w / data.length);
      var yText = h - yScale(d.v);
      return "translate(" + xText + "," + yText + ") rotate(90)";
    })
    

    另外,我发现您的示例代码令人困惑,我假设您的数据是一个字符串数组,因为您这样做了:

    .text(function(d) {
      return d;
    })
    

    但这会使 yScale(d) 返回 NaN。

    这是一个很好的例子:

    <html>
    
    <head>
      <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
    </head>
    
    <body>
      <script>
        var w = 300,
          h = 300,
          data = [{
              t: "Now",
              v: 50
            },{
              t: "is",
              v: 25
            },{
              t: "the",
              v: 10
            },{
              t: "winter",
              v: 30
            }];
    
        var svg = d3.select('body')
          .append('svg')
          .attr('width', w)
          .attr('height', h);
    
        var yScale = d3.scale.linear()
          .range([0, h])
          .domain([60, 0]);
    
        var label = svg.selectAll("text")
          .data(data)
          .enter()
          .append("text")
          .text(function(d) {
            return d.t;
          })
          .attr("transform", function(d,i){
            var xText = i * (w / data.length);
            var yText = h - yScale(d.v);
            return "translate(" + xText + "," + yText + ") rotate(90)";
          })
          .attr("fill", "black")
          .attr("font-family", "sans-serif")
          .attr("font-size", "11px");
      </script>
    </body>
    
    </html>

    【讨论】:

    • 嗨,马克,谢谢。那行得通,我没有意识到我必须删除 x 和 y 属性,现在这很有意义。感谢您的帮助我的数据是一个整数数组,如下所示: var data = [ 100, 200, 300, 400, 500, etc ];
    【解决方案2】:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
      .bar {
        fill: steelblue;
      }
      .bar:hover {
        fill: brown;
      }
      .axis {
        font: 10px sans-serif;
      }
      .axis path,
      .axis line {
        fill: none;
        stroke: #000;
        shape-rendering: crispEdges;
      }
      .x.axis path {
        display: none;
      }
    </style>
    
    <body>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
      <script>
        var data = [{
          "letter": "A",
          "frequency": 0.08167
        }, {
          "letter": "B",
          "frequency": 0.01492
        }, {
          "letter": "C",
          "frequency": 0.02782
        }, {
          "letter": "D",
          "frequency": 0.04253
        }, {
          "letter": "E",
          "frequency": 0.12702
        }];
    
        var margin = {
            top: 20,
            right: 20,
            bottom: 30,
            left: 40
          },
          width = 500 - margin.left - margin.right,
          height = 200 - margin.top - margin.bottom;
    
        var x = d3.scale.ordinal()
          .rangeRoundBands([0, width], .1);
    
        var y = d3.scale.linear()
          .range([height, 0]);
    
        var xAxis = d3.svg.axis()
          .scale(x)
          .orient("bottom");
    
        var yAxis = d3.svg.axis()
          .scale(y)
          .orient("left")
          .ticks(10, "%");
    
        var svg = d3.select("body").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 + ")");
    
    
    
        x.domain(data.map(function(d) {
          return d.letter;
        }));
        y.domain([0, d3.max(data, function(d) {
          return d.frequency;
        })]);
    
        svg.append("g")
          .attr("class", "x axis")
          .attr("transform", "translate(0," + height + ")")
          .call(xAxis);
    
        svg.append("g")
          .attr("class", "y axis")
          .call(yAxis)
          .append("text")
          .attr("transform", "rotate(-90)")
          .attr("y", 6)
          .attr("dy", ".71em")
          .style("text-anchor", "end")
          .text("Frequency");
    
        svg.selectAll(".bar")
          .data(data)
          .enter().append("rect")
          .attr("class", "bar")
          .attr("x", function(d) {
            return x(d.letter);
          })
          .attr("width", x.rangeBand())
          .attr("y", function(d) {
            return y(d.frequency);
          })
          .attr("height", function(d) {
            return height - y(d.frequency);
          });
    
    
    
        function type(d) {
          d.frequency = +d.frequency;
          return d;
        }
    
        var text = svg.selectAll(".text").data(data);
        text.enter()
          .append("text")
          .attr("class", "text")
          .attr("x", function(d, i) {
            return x(d.letter);
          })
          .attr("y", function(d) {
            return y(d.frequency);
          })
          .text(function(d) {
            return d.letter;
          })
    
        .attr("transform", function(d) {
          return "rotate(90 " + x(d.letter) + "," + (y(d.frequency) - d.letter.length) + ")"
        });
      </script>

    您可以尝试一下,作为基础,您可以根据需要对其进行修改。希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      • 2012-03-15
      • 1970-01-01
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多