【问题标题】:How to create bar chart with path property in d3js?如何在 d3js 中创建具有路径属性的条形图?
【发布时间】:2018-07-11 01:24:08
【问题描述】:

下面是我在 D3 中使用rects 创建条形图的方法。但是,我将如何修改它以在 d3js 中获取具有路径属性的条形图?

我有一个 json 文件,其中包含要读取的数据,并试图在 d3js 中创建一个带有路径而不是矩形的条形图。

json:

[
  {
    "name": "sam",
    "age": 24
  },
  {
    "name": "baby",
    "age": 23
  },
  {
    "name": "adu",
    "age": 21
  },
  {
    "name": "ja",
    "age": 23
  },
  {
    "name": "mack",
    "age": 34
  }
]

代码:

   <script>
        d3.json("mydata.json", function (data) {

           var canvas = d3.select('body').append('svg')
               .attr('width', 500)
               .attr('height', 500);

           canvas.selectAll('rect')
               .data(data)
               .enter()
                   .append('rect')
                   .attr('width',function (d) { return d.age * 10; })
                   .attr('height', 48)
                   .attr('y', function (d, i) { return i * 50; })
                   .attr('fill', 'blue');

           canvas.selectAll('text')
               .data(data)
               .enter()
                    .append('text')
                    .attr('fill','white')
                    .attr('y', function (d, i) {
                        return i* 50 + 24;
                    })
               .text(function (d) {
                   return d.name;
               })
        });
    </script>

我搜索了很多网站。我无法得到虽然

【问题讨论】:

    标签: d3.js svg


    【解决方案1】:

    您不能将d 属性分配给矩形,但您可以使用路径而不是矩形来制作条形图。您需要做的就是知道矩形角的坐标。你真的只需要对面的两个角。如果您有左上角和右下角坐标(分别为 [x0,y0] 和 [x1,y1]),您可以执行以下操作:

    function drawRect(x0,y0,x1,y1) {
      var p1 = x0 + " " + y0;
      var p2 = x0 + " " + y1;
      var p3 = x1 + " " + y1;
      var p4 = x1 + " " + y0;
    
      var l = "L";  // cause I'm lazy.
      return "M"+p1+l+p2+l+p3+l+p4+"Z";
    
    }
    

    这会将光标移动到 p1,然后绘制从 p1 到 p2 到 p3 到 p4 的连接线,然后返回以Z 开头。

    使用缩放值,无论是传递缩放参数还是缩放路径生成函数中的值(如下所示),都会变得有点冗长。

    这可能看起来像(路径淡入,因此您可以看到它们与矩形匹配):

    var data = [1,2,3,5,8,3];
    var width = 500;
    var height = 300;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width",width)
      .attr("height",height);
      
    var x = d3.scaleBand()
      .domain(d3.range(data.length))
      .range([0,width]);
      
    var y = d3.scaleLinear()
      .domain([0,d3.max(data)])
      .range([height,0]);
      
    svg.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("width", x.bandwidth())
      .attr("height", function(d) { return height-y(d); })
      .attr("x", function(d,i) { return x(i); })
      .attr("y", function(d) { return y(d); })
      
    svg.selectAll("path")
      .data(data)
      .enter()
      .append("path")
      .attr("d", makeRect)
      .attr("fill","orange")
      .style("opacity",0)
      .transition()
      .style("opacity",1)
      .duration(1500);
      
      
    function makeRect(d,i) {
      var x0 = x(i);
      var y0 = y(d);
      var x1 = x(i) + x.bandwidth();
      var y1 = height;
    
      var p1 = x0 + " " + y0;
      var p2 = x0 + " " + y1;
      var p3 = x1 + " " + y1;
      var p4 = x1 + " " + y0;
      var l = "L";
      
      return "M"+p1+l+p2+l+p3+l+p4+"Z";
    
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"&gt;&lt;/script&gt;

    但是,在大多数情况下,这并不是一个真正的首选选项。它肯定比矩形更复杂。 矩形应该更可取,当然,除非您尝试对路径进行某种无法使用矩形进行的操作,或者您可能想要rounded edges。也许您正在投影path on a globe 或者您想要进行一些路径转换(我已经在矩形路径中添加了额外的顶点以平滑转换,在大多数情况下,理想情况下,转换的开始和结束路径具有相同的编号顶点):

    var data = [1,2,3,5,8,3];
    var width = 500;
    var height = 200;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width",width)
      .attr("height",height);
      
    var x = d3.scaleBand()
      .domain(d3.range(data.length))
      .range([0,width]);
      
    var y = d3.scaleLinear()
      .domain([0,d3.max(data)])
      .range([height,0]);
      
      
      
    svg.selectAll("path")
      .data(data)
      .enter()
      .append("path")
      .attr('d', d3.symbol().type( d3.symbols[1]).size(function(d){ return  d*100; }) )
      .attr("transform","translate(0,"+height/2+")")
      .transition()
      .attr("transform",function(d,i) { return "translate("+(x(i)+x.bandwidth()/2) + "," + height/2 + ")" })
      .attr("fill","steelblue")
      .duration(1500)
      .transition()
      .attr("d", makeRect)
      .attr("fill","orange")
      .attr("transform","translate(0,0)")
      .duration(1500);
      //*/
      
    function makeRect(d,i) {
      var x0 = x(i);
      var y0 = y(d);
      var x1 = x(i) + x.bandwidth();
      var y1 = height;
      
      var p1 = x0 + " " + y0;
      var p2 = x0 + " " + y1;
      var p3 = x1 + " " + y1;
      var p4 = x1 + " " + y0;
      var l = "L";
      
      return "M"+p1+l+p1+l+p1+l+p4+l+p4+l+p4+l+p3+l+p3+l+p3+l+p2+l+p2+l+p2+"Z";
    
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"&gt;&lt;/script&gt;

    【讨论】:

      猜你喜欢
      • 2015-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多