使用d3连接和文本定位进行SVG操作

时间:2014-01-14 23:36:15

标签: svg d3.js

我一直试图用d3制作图表,我只是得到一张代表我所追求的图表,这是一些相对缩放的甜甜圈图表。

这是一个小提琴http://jsfiddle.net/Qxhzd/1/

我的代码:

function jsonToPieSlices(jsonScores) {
data = [];
var total_scores = 0;
for (var i in jsonScores){
   total_scores += parseInt(jsonScores[i].score, 10);
}
var factor = 100/total_scores;
var previous_angle = 0;

for (var i in jsonScores) {
  current_angle = ((jsonScores[i].score*factor)+previous_angle);
  data.push([previous_angle, current_angle, jsonScores[i].color]);
  previous_angle = current_angle;
}
return data;
}

function multi_nut() {

 var jsonScores = [{'topic': 'Credit Card Processing', 'total_scores': 35, 'scale': 1, 'position': '150,200', 'scores':[
                    {"color": '#522275', "name": 'site1.com', "score": 7},
                    {"color": '#5C6BD6', "name": 'site2.com', "score": 18},
                    {"color": '#FF7D33', "name": 'site3.com', "score": 3},
                    {"color": '#FFC433', "name": 'site4.com', "score": 2},
                    {"color": '#41B224', "name": 'site5.com', "score": 2},
                    {"color": '#36835D', "name": 'site6.com', "score": 3}]},

                    {'topic': 'Credit Card Reader', 'total_scores': 38, 'scale': 0.409090909, 'position': '650,250', 'scores':[
                    {"color": '#522275', "name": 'site1.com', "score": 7},
                    {"color": '#5C6BD6', "name": 'site2.com', "score": 8},
                    {"color": '#FF7D33', "name": 'site3.com', "score": 8},
                    {"color": '#FFC433', "name": 'site4.com', "score": 5},
                    {"color": '#41B224', "name": 'site5.com', "score": 7},
                    {"color": '#36835D', "name": 'site6.com', "score": 3}]},

                    {'topic': 'Mobile Payments', 'total_scores': 10, 'scale': 0.318181818, 'position': '900,560', 'scores':[
                    {"color": '#522275', "name": 'site1.com', "score": 4},
                    {"color": '#5C6BD6', "name": 'site2.com', "score": 3},
                    {"color": '#FF7D33', "name": 'site3.com', "score": 1},
                    {"color": '#FFC433', "name": 'site4.com', "score": 0 },
                    {"color": '#41B224', "name": 'site5.com', "score": 0},
                    {"color": '#36835D', "name": 'site6.com', "score": 2}]},

                    {'topic': 'Android Readers', 'total_scores': 9, 'scale': 0.136363636, 'position': '1950,1700', 'scores':[
                    {"color": '#522275', "name": 'site1.com', "score": 3},
                    {"color": '#5C6BD6', "name": 'site2.com', "score": 0},
                    {"color": '#FF7D33', "name": 'site3.com', "score": 3},
                    {"color": '#FFC433', "name": 'site4.com', "score": 0},
                    {"color": '#41B224', "name": 'site5.com', "score": 3},
                    {"color": '#36835D', "name": 'site6.com', "score": 0}]},

                    {'topic': 'Iphone Readers', 'total_scores': 22, 'scale': 0.318181818, 'position': '950,850', 'scores':[
                    {"color": '#522275', "name": 'site1.com', "score": 7},
                    {"color": '#5C6BD6', "name": 'site2.com', "score": 3},
                    {"color": '#FF7D33', "name": 'site3.com', "score": 5},
                    {"color": '#FFC433', "name": 'site4.com', "score": 0},
                    {"color": '#41B224', "name": 'site5.com', "score": 7},
                    {"color": '#36835D', "name": 'site6.com', "score": 0}]},
];




var cScale = d3.scale.linear().domain([0, 100]).range([0, 2 * Math.PI]);
var vis = d3.select("#svg_donut");

for (var i in jsonScores) {
data = jsonToPieSlices(jsonScores[i].scores);

var translation = "scale("+jsonScores[i].scale+") translate("+jsonScores[i].position+")"
// if (i==2) alert(translation);

var arc = d3.svg.arc()
.innerRadius(50)
.outerRadius(100)
.startAngle(function(d){return cScale(d[0]);})
.endAngle(function(d){return cScale(d[1]);});


vis.append('g')
.attr('id', "group-"+i)
.attr('class', "node")
.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("d", arc)
.style("fill", function(d){return d[2];})


.attr("transform", translation)
 .transition().delay(function(d, i) { return i * 500; }).duration(500)
  .attrTween('d', function(d) {
       var i = d3.interpolate(d.startAngle+0.1, d.endAngle);
       return function(t) {
           d.endAngle = i(t);
         return arc(d);
       }
  })

}



multi_nut();

我的问题是2折: 作为快速修复,我需要将图表的编号(当前为i + 1)放入每个图表的中心。我的所有尝试都会导致文本相对于文档而不是包含每个图表的组。

在更大的图片中,我非常确定我应该能够使用数据(可能需要重新格式化)来完成这项工作,而不会出现我所添加的可怕循环,并且没有我添加的明确定位 - 通过使用某种泡沫布局。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

您需要将<g>分组元素保存在变量中,以便稍后可以访问它们以添加文本。

var g = vis.append('g')
  .attr('id', "group-"+i)
  .attr('class', "node")
  .attr("transform", translation);  
  //translate the entire group, not individual paths

g.selectAll("path")
  .data(data)
  .enter()
  .append("path")
  .attr("d", arc)
  .style("fill", function(d){return d[2];})

g.append("text")  //add a single text element to each group
  .text(i+1); 

但是,请再看一下多饼图示例,并阅读this tutorial on nested selections以了解如何在没有for循环的情况下一次绘制所有饼图。您的文本元素将自动从其父组继承数据,因此如果使用嵌套选择,您可以使用.text(function(d,i) {return i+1;})访问图表索引。