如何将圆环图划分为固定部分

时间:2016-02-24 16:47:02

标签: d3.js donut-chart

我试图搜索但找不到解决方案。

我的数据如下:

var data =  [
        {   "hour":"10",    
            "percentage":"50"
        },
        {   "hour":"11",    
            "percentage":"20"
        },
        {   "hour":"3", 
        "percentage":"90"
        },
        {   "hour":"55",    
            "percentage":"40"
        },
        {   "hour":"6", 
            "percentage":"70"
        },
        {   "hour":"8", 
            "percentage":"40"
        }
    ];

我根据这些数据绘制圆环图。我需要:

  1. 将图表划分为12个相等的部分,如时钟。

  2. 我有颜色范围来描述百分比,但如果我的小时属性中没有数据怎么办?

  3. 我是D3JS的新手,我无法弄清楚逻辑。下面是我的圆环图。

    先谢谢。

    
    
        var data =	[
            	{	"hour":"10",	
            		"percentage":"50"
            	},
            	{	"hour":"11",	
            		"percentage":"20"
            	},
            	{	"hour":"3",	
        		"percentage":"90"
            	},
            	{	"hour":"55",	
            		"percentage":"40"
            	},
            	{	"hour":"6",	
            		"percentage":"70"
            	},
            	{	"hour":"8",	
            		"percentage":"40"
            	}
            ];
    
    
    
        var can =     d3.select("body").append("svg").attr("height",1000).attr("width",1000);
                    //var svg = d3.select(can[0]);
                    var r =100;
                    var p = Math.PI*2;
                    var color = d3.scale.linear()
                                .domain([0,100])
                                .range(["white","red"]);
                     var group = can.append("g")
                                .attr("transform","translate(100,100)");
    
                    var arc = d3.svg.arc()
                            .innerRadius(r - 30)
                            .outerRadius(r)
                            //.startAngle(0)
                            .endAngle(p-1);
    
    
                    var pie = d3.layout.pie()
                            .sort(null)
                            .value(function (d){return d.percentage;});
    
                     var arcs = group.selectAll(".arc")
                                .data(pie(data))
                                .enter().append("g")
                                .attr("class", "arc")
                                .attr('fill',function(d){return     color(d.data.percentage)})
                                .on("mouseover", function(d){
                                    div.style("display", "inline")
                                     .text(d.data.percentage + ", " + d.data.hour)
                                    .style("left", (d3.event.pageX - 34) + "px")
                                    .style("top", (d3.event.pageY - 12) + "px");
                                         })
                                 .on("mouseout", mouseout);
    
    
                    arcs.append("path")
                                    .attr("d", arc)
                                    .style("fill", function (d) {
                                    return color(d.data.percentage);
                    });
    
                    var div = d3.select("body").append("div")
                                                    .attr("class", "tooltip")
                                                    .style("display", "none");
    
    
                     function mouseout() {
                                     div.style("display", "none");
                            }
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
    &#13;
    &#13;
    &#13;

1 个答案:

答案 0 :(得分:2)

如果你想要它们的等份,你的使用百分比怎么来pie.value()

Pie.value()是你如何分割饼图。

所以我要做的是创建一个虚拟值来创建相等的部分:

for(i=0;i<data.length;i++){
   data[i].value = 1;
}

现在将值传递给pie.value()而不是百分比:

var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.value
    //return d.percentage
  });

你的图表没有全面展开的原因是因为这一行:

.endAngle(p-1);

Math.PI以弧度为单位,因此您将其设置为角度:

p = 6.28319 radians;

p-1 = 5.28319 radians;

因此

p-1 = 302.7044894 degrees;

取走-1,你有一个完整的圆圈。

以下是当前数据:

var data = [{
  "hour": "10",
  "percentage": "50"
}, {
  "hour": "11",
  "percentage": "20"
}, {
  "hour": "3",
  "percentage": "90"
}, {
  "hour": "55",
  "percentage": "40"
}, {
  "hour": "6",
  "percentage": "70"
}, {
  "hour": "8",
  "percentage": "40"
}];

for (i = 0; i < data.length; i++) {
  data[i].value = 1;
}


var can = d3.select("body").append("svg").attr("height", 1000).attr("width", 1000);
//var svg = d3.select(can[0]);
var r = 100;
var p = Math.PI * 2;
var color = d3.scale.linear()
  .domain([0, 100])
  .range(["white", "red"]);
var group = can.append("g")
  .attr("transform", "translate(100,100)");

var arc = d3.svg.arc()
  .innerRadius(r - 30)
  .outerRadius(r)
  //.startAngle(0)
  .endAngle(p );


var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.value
      //return d.percentage
  });

var arcs = group.selectAll(".arc")
  .data(pie(data))
  .enter().append("g")
  .attr("class", "arc")
  .attr('fill', function(d) {
    //console.log(d)
    return color(d.data.percentage)
  })
  .on("mouseover", function(d) {
    div.style("display", "inline")
      .text(d.data.percentage + ", " + d.data.hour)
      .style("left", (d3.event.pageX - 34) + "px")
      .style("top", (d3.event.pageY - 12) + "px");
  })
  .on("mouseout", mouseout);


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

var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("display", "none");


function mouseout() {
  div.style("display", "none");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

现在你遇到的问题在12个相等的部分。我想你需要扩展你想要的东西。你想要显示缺失的部分吗?用不同的颜色显示?你想要什么 ?

要解决这些问题,您必须创建数据并将其添加到现有数据中,如下所示:

var newData = [];
for (i = 1; i <= 12; i++) { //go through numbers 1-12 like a clock
  var thisData;
  var inData = false; //bool to check if data exists already
  for (j = 0; j < data.length; j++) { //go through existing data
    if (data[j].hour == i) { //check if data exists
      inData = true; //data exists
      thisData = {
        "hour": data[j].hour, //add data at [i]
        "percentage": data[j].percentage, //add data at [i]
        "value": data[j].value //add data at [i]
      }
      newData.push(thisData) //push into new array
    }
  }
  if (!inData) { //if data doesnt exist
    thisData = {
      "hour": i, //set hour to i
      "percentage": 0, 
      "value": 1
    }
    newData.push(thisData) //push into new data
  }
}
console.log(newData)

这是带有新数据的饼图,仍然值为1,因此您获得相等的段。它们是白色的,因为它们没有百分比,我已经添加了一个笔划,所以你可以分辨哪个是哪个:)

var data = [{
  "hour": "10",
  "percentage": "50"
}, {
  "hour": "11",
  "percentage": "20"
}, {
  "hour": "3",
  "percentage": "90"
}, {
  "hour": "5",
  "percentage": "40"
}, {
  "hour": "6",
  "percentage": "70"
}, {
  "hour": "8",
  "percentage": "40"
}];

for (i = 0; i < data.length; i++) {
  data[i].value = 1;
}

var newData = [];
for (i = 1; i <= 12; i++) { //go through numbers 1-12 like a clock
  var thisData;
  var inData = false; //bool to check if data exists already
  for (j = 0; j < data.length; j++) { //go through existing data
    if (data[j].hour == i) { //check if data exists
      inData = true; //data exists
      thisData = {
        "hour": data[j].hour, //add data at [i]
        "percentage": data[j].percentage, //add data at [i]
        "value": data[j].value //add data at [i]
      }
      newData.push(thisData) //push into new array
    }
  }
  if (!inData) { //if data doesnt exist
    thisData = {
      "hour": i, //set hour to i
      "percentage": 0, 
      "value": 1
    }
    newData.push(thisData) //push into new data
  }
}
console.log(newData)


var can = d3.select("body").append("svg").attr("height", 1000).attr("width", 1000);
//var svg = d3.select(can[0]);
var r = 100;
var p = Math.PI * 2;
var color = d3.scale.linear()
  .domain([0, 100])
  .range(["white", "red"]);

var group = can.append("g")
  .attr("transform", "translate(100,100)");

var arc = d3.svg.arc()
  .innerRadius(r - 30)
  .outerRadius(r)
  //.startAngle(0)
  .endAngle(p);


var pie = d3.layout.pie()
  .sort(null)
  .value(function(d) {
    return d.value
      //return d.percentage
  });

var arcs = group.selectAll(".arc")
  .data(pie(newData))
  .enter().append("g")
  .attr("class", "arc")
  .attr('fill', function(d) {
    //console.log(d)
    return color(d.data.percentage)
  })
  .style('stroke','black')
  .on("mouseover", function(d) {
    div.style("display", "inline")
      .text(d.data.percentage + ", " + d.data.hour)
      .style("left", (d3.event.pageX - 34) + "px")
      .style("top", (d3.event.pageY - 12) + "px");
  })
  .on("mouseout", mouseout);


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

var div = d3.select("body").append("div")
  .attr("class", "tooltip")
  .style("display", "none");


function mouseout() {
  div.style("display", "none");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>