d3 圓餅圖

利用 d3.js 製作簡易圓餅圖

邱蘭婷 Nio Chiu 2021/05/04 10:12:58
2547

此篇包含簡易圓餅圖 + tooltip 用法

引用套件:https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js

 HTML 

主要設定設定一個外框包覆圓餅圖和tooltip。

tooltip則是在滑鼠覆蓋在圓餅圖上時才會呈現。

<div class="out">
  <div id="chart"></div>
  <div id="mainTooltip" class="hidden">
	  <p><span id="value"></span></p>
  </div>
</div>

 CSS 

主要設定 tooltip 的樣式。

.out{
  width:250px;
}

#mainTooltip {
    position: absolute;
    min-width :90px;
    height: 40px;
    padding: 0 10px 25px 10px;
    background-color: rgba(0,0,0,0.8);
    border-radius: 4px;
    box-shadow: 2px 2px 3px rgba(0, 0, 0, 1);
    pointer-events: none;
    fill: #fff;
    color: #fff;
    text-anchor: middle;
    text-align: center;
    font-weight: bold;
    z-index: 9999;
}
#mainTooltip:before {
    border: solid;
    border-color: rgba(0,0,0,0.6) transparent;
    border-width: 10px 10px 0 10px;
    top: 100%;
    content: "";
    left: 43%;
    position: absolute;
    z-index: 99;
}
#mainTooltip.hidden {
    display: none;
}

 JS 

主要設定圓餅圖 d3.js,並且把 tooltip 放進去

 

// 設定資料
var data = [
    {
        "str_lab": "HTML", // 項目命名
        "num": 100 // 比重數
    },
    {
        "str_lab": "CSS",
        "num": 100
    },
    {
        "str_lab": "JS",
        "num": 100
    }
];
var width = 250, // 畫布寬度
    height = 250, // 畫布高度
    radius = 100; // 畫布半徑
var divNode = d3.select("body").node(); // 設定畫布
var outerRadius = 100, // 外圈半徑
    innerRadius = 0; // 內圈半徑
var color = d3.scale.ordinal()
    .range(["#4BEFCF","#2c9af7","#F96262"]); // 設定顏色

var arc = d3.svg.arc() // 建立弧
    .outerRadius(outerRadius) // 建立外圈半徑
    .innerRadius(innerRadius);// 建立內圈半徑

var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) { return d.num; }); // 建立排序

d3.select("#chart").append("div") // 建立 id 和 class
    .attr("id","mainPie") 
    .attr("class","pieBox"); 

var svg = d3.select("#mainPie").append("svg") // 建立畫布
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var defs = svg.append("defs");
var filter = defs.append("filter") // 建立滑鼠事件
                .attr("id", "drop-shadow")
                .attr("height","130%");

filter.append("feGaussianBlur")// 建立監聽事件
        .attr("in","SourceAlpha")
        .attr("stdDeviation", 3)
        .attr("result", "blur");

filter.append("feOffset")// 建立陰影事件
    .attr("in", "blur")
    .attr("dx", 3)
    .attr("dy", 3)
    .attr("result", "offsetBlur");
    var feMerge = filter.append("feMerge");

feMerge.append("feMergeNode") // 建立滑鼠監聽事件
    .attr("in", "offsetBlur")
feMerge.append("feMergeNode")
    .attr("in", "SourceGraphic");

var g = svg.selectAll(".arc") // 建立內部資料
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path") // 建立內部資料與滑鼠事件浮動文字
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.str_lab); })
      .attr("stroke","#fff")
      .attr("stroke-width","1px")
      .on("mousemove", function(d) {
          d3.select(this)
              .attr("stroke","#fff")
              .attr("stroke-width","2px")
              .style("filter", "url(#drop-shadow)");
				  d3.select(this)
						.transition()
						.duration(500)
						.ease('elastic')
						.attr('transform',function(d){
							var dist = 1;
							d.midAngle = ((d.endAngle - d.startAngle)/2) + d.startAngle;
							var x = Math.sin(d.midAngle) * dist;
							var y = Math.cos(d.midAngle) * dist;
							return 'translate(' + x + ',' + y + ')';
						});
            var mousePos = d3.mouse(divNode);
            d3.select("#mainTooltip")
              .style("left", mousePos[0] - 40 + "px")
              .style("top", mousePos[1] - 70 + "px")
              .select("#value")
              .attr("text-anchor", "middle")
              .html(d.data.str_lab + "<br />" + d.data.num);

					d3.select("#mainTooltip").classed("hidden", false);
        })
      .on("mouseout", function(d){
          d3.select(this)
              .attr("stroke","none")
              .style("filter","none");
					d3.select(this)
						.transition()
						.duration(500)
						.ease('bounce')
						.attr('transform','translate(0,0)');

					d3.select("#mainTooltip").classed("hidden", true);
      });
邱蘭婷 Nio Chiu