【问题标题】:D3.js Barchart, split textD3.js 条形图,分割文本
【发布时间】:2016-02-09 05:10:49
【问题描述】:

我有 D3.js 条形图,我想在上面显示数组中的数字。每个条形都有自己的数字数组,例如[12, 34, 65]。我能够在每个栏的顶部仅将数组显示为文本,但我想拆分每个数组并从上到下显示每个数字,因此对于[12, 34, 65] 栏,底部是12,然后是@987654324 @ 在中间,65 在顶部。这个怎么做?到目前为止,我有这样的代码,它只在每个栏的顶部显示数组:

        g.selectAll("text")
           .data(dataset)
           .enter()
           .append("text")
           .text(function(d) {
                return d;
           })
           .attr("font-family", "sans-serif")
           .attr("font-size", "11px")
           .attr("fill", "white")
           .attr("text-anchor", "middle")
           .attr("x", function(d, i) {
                return ...;
           })          
           .attr("y", function(d) {
                return ...;
           });

其中dataset 是一个数组数组。然后d 将对应于[12, 34, 65]。我需要一种将其拆分为单个数字并为每个数字指定y 的方法。同时x 显然对于每个条都应该保持不变。还希望通过绘制黑白数字线或通过更改与数字对应的每个段的颜色来将每个条分成与每个数字对应的部分。

【问题讨论】:

    标签: javascript arrays d3.js


    【解决方案1】:

    要解决您的问题,您需要处理nested data with d3,即您需要先为每个堆叠条创建一个组:

    var stacks = root.selectAll("g.stack")
    .data(dataset)
    .enter()
    .append("g").attr("class","stack")
    

    然后使用从父数据中提取嵌套数组的新 data 函数为每个堆栈创建一个新的选择,其中嵌套数组作为数据。

    var bars = stacks.selectAll("g.bar")
    .data(function(d, i) { return d; })
    .enter().append(...)
    

    对于堆栈中的每个条形,您可以使用不同的颜色,例如,使用d3.scale.category10

    这里是完整的例子:

    var root = d3.selectAll("svg>g#root")
    var dataset = [[10,20,50],[70,40,10],[20,40,10]]
    var color = d3.scale.category10()
    
    dataset.forEach( function(d) {
        d.sort( function(a,b)  { return b-a; } )
    })
    
    var stacks = root.selectAll("g.stack")
    .data(dataset)
    .enter()
    .append("g").attr("class","stack")
    .attr("transform", function(d,i) {
        return "translate(0,"+ (i * 30) +")"
    })
    
    var bars = stacks.selectAll("g.bar")
    .data(function(d, i) { return d; })
    .enter()
    .append("g").attr("class","bar")
    
    var barWidth = function(d,i) { return d * 2 }
    var barColor = function(d,i) { return color(i) }
    
    bars.append("rect")
    .attr("height", "20")
    .attr("x",      "0")
    .attr("y",      "0")
    .attr("width",  barWidth )
    .style("fill",  barColor )
    
    bars.append("text")
    .text( function(d) { return d } )
    .attr("x", barWidth )
    .attr("y", 9)
    .attr("transform", "translate(-10,0)" )
    svg { border: solid 1px gray }
    
    svg text {
        font-family: sans-serif;
        font-size:   11px;
        fill:        white;
        text-anchor: middle;
    }
    
    svg rect {
        fill:   gray;
        stroke: black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    <svg width=200 height=100 id="container" 
         style="border: solid 1px gray">
        <g id="root" transform="translate(10,10)"></g>
    </svg>

    请注意,为简洁起见,该示例不使用任何d3.scale 将数据空间转换为几何空间。详情请参考d3 wiki

    该示例当前假定数组中的值是绝对值,即所有条形都从 x="0" 开始。如果您需要真正堆叠相对值,我建议首先通过汇总排序嵌套数组的先前值,为每个条形图预先计算 x 的对应值:

    var sum = function(a,b) { return a+b }
    var derivedData = dataset.map( function(d,i) {
        d.sort( function(a,b)  { return b-a; } )
        return d.map( function(v,i) {
            // `value` determines the width or height of a bar
            // `sum`   determines the position of the bar
            return { value: v, sum: d.slice(0,i+1).reduce(sum) }
        })
    })
    

    【讨论】:

      【解决方案2】:

      好的,我有一个数据集,其中我有数组形式的标签,正如你所说的,每个条都有自己的带有数字的数组,比如[12, 34, 65]

      {
          "letter": "B",
              "frequency": 0.03492,
          label: [10, 20, 30]//this is the array which will be displayed on bar's top middle bottom
      } 
      

      要在栏上附加标签,请这样做

      var rects = svg.selectAll(".bar")
          .data(data)
          .enter().append("g");
      //make the bars
      rects.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);
      });
      //text @ the top
      rects.append("text")
          .attr("x", function (d) {
          return x(d.letter) + x.rangeBand() / 2;
      })
          .attr("y", function (d) {
          return y(d.frequency) + 10;
      }).attr("font-family", "sans-serif")
          .attr("font-size", "11px")
          .attr("fill", "white")
          .attr("text-anchor", "middle")
          .attr("dy", ".35em")
          .text(function (d) {
          return d.label[0];
      });
      //text @ the middle
      rects.append("text")
          .attr("x", function (d) {
          return x(d.letter) + x.rangeBand() / 2;
      })
          .attr("y", function (d) {
          return (height + y(d.frequency))/2;
      }).attr("font-family", "sans-serif")
          .attr("font-size", "11px")
          .attr("fill", "white")
          .attr("text-anchor", "middle")
          .attr("dy", ".35em")
          .text(function (d) {
          return d.label[1];
      });
      //text @ the bottom
      rects.append("text")
          .attr("x", function (d) {
          return x(d.letter) + x.rangeBand() / 2;
      })
          .attr("y", function (d) {
          return height - 10;
      }).attr("font-family", "sans-serif")
          .attr("font-size", "11px")
          .attr("fill", "white")
          .attr("text-anchor", "middle")
          .attr("dy", ".35em")
          .text(function (d) {
          return d.label[2];
      });
      

      工作代码here

      希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-08
        • 1970-01-01
        相关资源
        最近更新 更多