d3.js之饼状图
懒得改了,在动画这卡了好长时间。柱状图和散点图只要把比例尺那块搞懂了,基本上就没问题了,利用比例尺生成的数据,直接在svg上画rect 或 circle就行(最简单的)。
折线图出现了线段生成器,饼状图出现弧生成器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="https://d3js.org/d3.v5.js"></script>
<title>Document</title>
<style>
body {
box-sizing: border-box;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: #666666;
}
.box {
box-sizing: border-box;
width: 1200px;
height: 800px;
background-color: #fff;
padding: 30px;
margin: 50px auto;
}
h1 {
text-align: center;
}
.rectt {
fill: #33adff;
opacity: .9;
}
.rectt:hover {
opacity: .2;
}
#sbx {
position: relative;
}
.tooltip {
position: absolute;
text-align: center;
width: 150px;
height: 50px;
padding: 2px;
font: 12px;
background: lightsteelblue;
box-shadow: 1px 1px 10px;
border-radius: 2px;
pointer-events: none;
}
</style>
</head>
<body>
<div class="box">
<h1>United States GDP</h1>
<div id="sbx"></div>
</div>
<script>
let width = 900,
height = 600;
let ssvgdom = d3.select("#sbx").append("svg")
.attr("width", width)
.attr("height", height)
var dataset = [
["小米", 60.8],
["三星", 58.4],
["联想", 47.3],
["苹果", 46.6],
["华为", 41.3],
["酷派", 40.1],
["其他", 111.5]
];
// 创建饼状图布局
//二者皆可返回不同
let piee = d3.pie().value((d) => d[1])(dataset)
let pieee = d3.pie()(dataset.map((d) => d[1]))
//外半径和内半径
let waibj = width / 4
let libj = 50
// 创建弧生成器
let arc = d3.arc()
.innerRadius(libj).outerRadius(waibj)
let animarc = d3.arc() //这个是动画的,当鼠标移上去,用这个生成器。
.innerRadius(libj+30).outerRadius(waibj + 20)
//颜色生成器,返回的是数组[],一到十
let color = d3.schemeCategory10
let arcss = ssvgdom.selectAll("g").data(pieee)
.enter().append("g").attr("transform", `translate(${width/2} ${height/2})`)
arcss.append("path").attr("fill", (d, i) => color[i])
.attr("d", (d) => {
console.log(arc(d))
return arc(d)
})
arcss.append("text").attr("transform", (d) => {
//arc.centroid(arguments…) 找到区域的中心点
let x = arc.centroid(d)[0] * 1.5
let y = arc.centroid(d)[1] * 1.5
return `translate(${x} ${y})`
}).attr("text-anchor", "middle")
.text((d) => {
// console.log(d.value)
// console.log(d)
var percent = Number(d.value) /
d3.sum(dataset, function (d) {
return d[1];
}) * 100;
//保留1位小数点,末尾加一个百分号返回
return percent.toFixed(1) + "%";
})
// 在Echarts看到这种动画,好喜欢啊
arcss.on("mouseover", function (d) {
//过渡对象不能选择g元素,g没用,改变路径选path,不知道原因,
//开始选g,控制台都看到d的值改变了,就是不动,查到一段话
//<g>元素经过过渡后最终变为<g x="50">。没有任何意义,<g>的子元素
//<rect>和<text>的x属性并没有变。
let domm = d3.select(this).select("path")
domm.attr("d", arc(d))
.transition().duration(200)
.attr("d", animarc(d))
// console.log(dpa)
// console.log(domm.attr("fill","red"))
// console.log(this)
}).on("mouseout", function (d) {
let domm = d3.select(this).select("path")
domm.attr("d", animarc(d))
.transition().duration(200)
.attr("d", arc(d))
})
</script>
</body>
</html>
这是创建饼状图布局那两个在控制台打印的结果