下面是我如何在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>
我搜索了许多站点。我没办法
答案 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>