我想为地图上的每个点绘制一个饼图,而不是圆圈。 地图和点显示良好,但饼图未显示在地图点上。也没有错误。我也可以在地图中看到添加的饼图代码。
以下是代码段。
var w = 600;
var h = 600;
var bounds = [[78,30], [87, 8]]; // rough extents of India
var proj = d3.geo.mercator()
.scale(800)
.translate([w/2,h/2])
.rotate([(bounds[0][0] + bounds[1][0]) / -2,
(bounds[0][1] + bounds[1][1]) / -2]); // rotate the project to bring India into view.
var path = d3.geo.path().projection(proj);
var map = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
var india = map.append("svg:g")
.attr("id", "india");
var gDataPoints = map.append("g"); // appended second
d3.json("data/states.json", function(json) {
india.selectAll("path")
.data(json.features)
.enter().append("path")
.attr("d", path);
});
d3.csv("data/water.csv", function(csv) {
console.log(JSON.stringify(csv))
gDataPoints.selectAll("circle")
.data(csv)
.enter()
.append("circle")
.attr("id", function (d,i) {
return "chart"+i;
})
.attr("cx", function (d) {
return proj([d.lon, d.lat])[0];
})
.attr("cy", function (d) {
return proj([d.lon, d.lat])[1];
})
.attr("r", function (d) {
return 3;
})
.each(function (d,i) {
barchart("chart"+i);
})
.style("fill", "red")
//.style("opacity", 1);
});
function barchart(id){
var data=[15,30,35,20];
var radius=30;
var color=d3.scale.category10()
var svg1=d3.select("#"+id)
.append("svg").attr('width',100).attr('height',100);
var group=svg1.append('g').attr("transform","translate(" + radius + "," + radius + ")");
var arc=d3.svg.arc()
.innerRadius('0')
.outerRadius(radius);
var pie=d3.layout.pie()
.value(function(d){
return d;
});
var arcs=group.selectAll(".arc")
.data(pie(data))
.enter()
.append('g')
.attr('class','arc')
arcs.append('path')
.attr('d',arc)
.attr("fill",function(d,i){
return color(d.data);
//return colors[i]
});
}
water.csv:
lon,lat,quality,complaints
80.06,20.07,4,17
72.822,18.968,2,62
77.216,28.613,5,49
92.79,87.208,4,3
87.208,21.813,1,12
77.589,12.987,2,54
16.320,75.724,4,7
答案 0 :(得分:2)
在测试代码时,我根本无法看到饼图渲染。但是,我相信我仍然有一个解决方案。
您不需要单独的饼图功能来调用每个点。我确信对此有各种各样的意见,但是关于Stack Overflow的d3问题通常会调用额外的功能来延长代码,同时充分利用d3的优势和内置功能。</ p>
为什么我会在这种情况下有这种感觉?很难保留绑定到svg对象的数据与饼图函数之间的链接,这就是为什么你必须将点的id传递给你的函数。如果您想在csv中拥有饼图数据,这将更加复杂。
使用d3的数据绑定和选择,您可以使用更简单的代码完成所需的一切。我花了一些时间来了解如何做到这一点,但它确实让你的生活变得更轻松。
注意:我道歉,我移植了您发布到d3v4的代码,但我已经包含了下面d3v3代码的链接,以及d3v4,尽管在片段中只有明显的变化可能是从颜色(i)到颜色[i]
在这种情况下,我们可以添加一个circle
元素,然后将元素直接附加到每个selection.each()
,而不是调用函数将饼图附加到每个g
元素。 {1}}选择。
另外,为了让生活更轻松,如果我们最初为每个g
元素添加一个变换,我们可以使用相对测量来在每个g
中放置项目,而不是找出我们的绝对svg坐标否则就需要了。
g
现在,如果我们想要显示每个饼图的csv数据,并且可能添加标签,该怎么办?现在很容易做到这一点。在csv中,如果有一个标记为 d3.csv("water.csv", function(error, water) {
// Append one g element for each row in the csv and bind data to it:
var points = gDataPoints.selectAll("g")
.data(water)
.enter()
.append("g")
.attr("transform",function(d) { return "translate("+projection([d.lon,d.lat])+")" })
.attr("id", function (d,i) { return "chart"+i; })
.append("g").attr("class","pies");
// Add a circle to it if needed
points.append("circle")
.attr("r", 3)
.style("fill", "red");
// Select each g element we created, and fill it with pie chart:
var pies = points.selectAll(".pies")
.data(pie([0,15,30,35,20]))
.enter()
.append('g')
.attr('class','arc');
pies.append("path")
.attr('d',arc)
.attr("fill",function(d,i){
return color[i];
});
});
的列,其中的值由短划线和名为data
的列分隔,我们可以轻松调整代码以显示此新数据:
label
我们想要显示的数据已经绑定到我们为csv中的每一行创建的初始d3.csv("water.csv", function(error, water) {
var points = gDataPoints.selectAll("g")
.data(water)
.enter()
.append("g")
.attr("transform",function(d) { return "translate("+projection([d.lon,d.lat])+")" })
.attr("class","pies")
points.append("text")
.attr("y", -radius - 5)
.text(function(d) { return d.label })
.style('text-anchor','middle');
var pies = points.selectAll(".pies")
.data(function(d) { return pie(d.data.split(['-'])); })
.enter()
.append('g')
.attr('class','arc');
pies.append("path")
.attr('d',arc)
.attr("fill",function(d,i){
return color[i];
});
});
。现在我们要做的就是附加我们想要显示的元素,并选择我们想要显示的绑定数据的属性。
这种情况下的结果如下:
我在v3和v4中发布了一些示例,以显示遵循上述饼图方法的潜在实现: