d3
圓餅圖
利用 d3.js 製作簡易圓餅圖
2021/05/04 10:12:58
0
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);
});