如何从json数据绘制饼图?

时间:2018-08-31 12:45:18

标签: javascript d3.js

我使用d3 libray version5。

我尝试绘制饼图。我的数据存储在json对象中。请帮我。现场演示is here.

我的JavaScript代码:

const data = [
    {id: 0, label: 'qqqqq', percent: 50},
  {id: 1, label: 'wwww', percent: 30},
  {id: 2, label: 'eeeee', percent: 20}
];

const svg = d3.select("#segmentsGraph"),
      width = 250,
      height = 250,
      radius = Math.min(width, height) / 2,
      g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

const color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

const pie = d3.pie()
.sort(null)
.value(function(d) { return d.label; });

const path = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);

const label = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);

data.forEach((d) => {
    console.log(d);

  const arc = g.selectAll(".arc")
  .data(pie(data))
  .enter().append("g")
  .attr("class", "arc");          

  arc.append("path")
    .attr("d", path)
    .attr("fill", function(d) { return color(d.percent); });

  arc.append("text")
    .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
    .attr("dy", "0.35em")
    .text(function(d) { return d.percent; });  
});

我搜索了文档,发现以下example。但是这个例子在jsfiddle中不起作用...

2 个答案:

答案 0 :(得分:2)

使用最新的d3进行工作。

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<!DOCTYPE html>
<html>
  <head>    
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Testing Pie Chart</title>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?2.1.3"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.geom.js?2.1.3"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.layout.js?2.1.3"></script>

    <style type="text/css">
        .slice text {
            font-size: 16pt;
            font-family: Arial;
        }   
    </style>
  </head>
  <body>
    <script type="text/javascript">

    var w = 300,                     
    h = 300,                           
    r = 100,                          
    color = d3.scale.category20c();    

    data = [{"label":"one", "value":20}, 
            {"label":"two", "value":50}, 
            {"label":"three", "value":30}];
    
    var vis = d3.select("body")
        .append("svg:svg")       
        .data([data])                 
            .attr("width", w)       
            .attr("height", h)
        .append("svg:g")             
            .attr("transform", "translate(" + r + "," + r + ")")  

    var arc = d3.svg.arc()        
        .outerRadius(r);

    var pie = d3.layout.pie()      
        .value(function(d) { return d.value; });   

    var arcs = vis.selectAll("g.slice")   
        .data(pie)                        
        .enter()                          
            .append("svg:g")           
                .attr("class", "slice");  

        arcs.append("svg:path")
                .attr("fill", function(d, i) { return color(i); } ) 
                .attr("d", arc);        
        arcs.append("svg:text")            
                .attr("transform", function(d) {                  
                d.innerRadius = 0;
                d.outerRadius = r;
                return "translate(" + arc.centroid(d) + ")";   
            })
            .attr("text-anchor", "middle")           
            .text(function(d, i) { return data[i].label; });       
    </script>
  </body>
</html>

答案 1 :(得分:1)

我有changed your code来画馅饼:

bg-light
const data = [
        {id: 0, label: 'qqqqq', percent: 50},
    {id: 1, label: 'wwww', percent: 30},
    {id: 2, label: 'eeeee', percent: 20}
    ];

    const svg = d3.select("#segmentsGraph"),
        width = 250,
        height = 250,
        radius = Math.min(width, height) / 2,
        g = svg.attr("height", height).attr("width", width).append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    const color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
    
    const pie = d3.pie()
    .sort(null)
    .value(function(d) { return d.percent; });

    const path = d3.arc()
    .outerRadius(radius - 10)
    .innerRadius(0);

    const label = d3.arc()
    .outerRadius(radius - 40)
    .innerRadius(radius - 40);

    
    const arc = g.selectAll(".arc")
    .data(pie(data))
    .enter().append("g")
    .attr("class", "arc");          

    arc.append("path")
        .attr("d", path)
        .attr("fill", function(d) { return color(d.data.id); });

    arc.append("text")
        .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; })
        .attr("dy", "0.35em")
        .text(function(d) {  return d.data.percent; });

您应该在d3.pie()。value()方法中使用数字值。它将创建一个新的数据集,将d.value的比例以及所有d.value的和映射到角度。建议您运行console.log(arc.data())以便对新数据集有更好的了解。

您不需要使用forEach遍历数据,因为data()。enter()会为您完成它。