如何在d3js中使用path属性创建条形图?

时间:2018-07-11 01:24:08

标签: d3.js svg

下面是我如何在D3中使用rect s创建条形图。但是,我将如何修改它以在d3js中获得带有path属性的条形图?

我有一个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>

我搜索了许多站点。我没办法

1 个答案:

答案 0 :(得分:2)

您不能为矩形分配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";

}

请记住,最大y值可能等于绘图高度,因此您无需计算该值

这会将光标移动到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";

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>

但是,在大多数情况下,这并不是真正的首选。当然,它比矩形要复杂。 矩形应该是可取的,除非您当然要尝试对矩形无法执行的路径进行某种处理。可能投影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";

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>