# D3实例3
# d3线段图加点展示
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据 界面 映射 刻度尺 绑定
let data=[[],[]]
function createdata(){
data=[[],[]];
for(let i=0;i<10;i++){
var a =parseInt(Math.random()*10)
var b =parseInt(Math.random()*10)
data[0].push(a)
data[1].push(b)
}
var tem =svg.selectAll("path.line").data(data)
tem.enter()
.append("path").merge(tem)
.transition().duration(1000)
.style("stroke",(d,i)=>colors(i)).attr("class","line").attr("d",(d,i)=>{
return line(d)
})
// svg.selectAll("circle.dot").remove()
for(let i=0;i<data.length;i++){
console.log(data[i])
var tem1 =svg.selectAll(`circle.dot${i}`)
var tem2=tem1.data(data[i]);
tem2.enter().append("circle").merge(tem2)
.transition().duration(1000)
.attr("class",`dot${i}`)
.style("fill",(d)=>{
return colors(i)
})
.attr("cx",(d,i)=>xscale(i))
.attr("cy",d=>yscale(d))
.attr("r",10)
}
}
console.log(data)
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var xscale = d3.scaleLinear().domain([0,10]).range([margin,width-margin])
var yscale =d3.scaleLinear().domain([0,10]).range([height-margin,margin])
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.selectAll("line.help").data([0,1,2,3,4,5,6,7,8,9,10]).enter().append("line")
.attr("class","help").attr("x1",xscale(0)).attr("y1",d=>yscale(d))
.attr("x2",xscale(10)).attr("y2",d=>yscale(d)).attr("stroke","#409EFF")
// yaxis(svg)
svg.append("g").attr("transform",`translate(0,${height-margin})`)
.classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`).call(yaxis)
.classed("axis",true)
var line=d3.line().x((d,i)=>xscale(i)).y(d=>yscale(d)).curve(d3.curveCardinal)
make()
function make(){
createdata()
}
</script>
<button onclick="make()">dianji</button>
</html>
# 总结
- 数据 界面 映射 刻度尺 绑定
- merge的使用需要注意
var tem =svg.selectAll("path.line").data(data)
tem.enter()
.append("path").merge(tem)
- path路径绘制出的曲线/折线/面积图是二维数组,而其中的circle(包括散点图)和pie则不需要是二维数组的数据
- 更新和新增 与合并
function render(data) { // <- B
var bars = d3.select("body").selectAll("div.h-bar") // <- C
.data(data); // Update <- D
// Enter
bars.enter() // <- E
.append("div") // <- F
.attr("class", "h-bar") // <- G
.merge(bars) // Enter + Update <- H
.style("width", function (d) {
return (d * 3) + "px"; // <- I
})
.text(function (d) {
return d; // <- J
});
// Exit
bars.exit() // <- K
.remove();
}
//方法二
function render(data){
console.log(data)
var bars = d3.select("body").selectAll("div.h-bar").data(data)
bars.text(function(d,i){
return d
}).style("width",(d,i)=>{
return (d * 3) + "px"
})
bars.enter().append("div").attr("class", "h-bar").text(function(d,i){
return d
}).style("width",(d,i)=>{
return (d * 3) + "px"
})
bars.exit().remove()
}
# 面积图
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据 界面 映射 刻度尺 绑定
let data=[[],[]]
function createdata(){
data=[[],[]];
for(let i=0;i<10;i++){
var a =parseInt(Math.random()*10)
var b =parseInt(Math.random()*10)
data[0].push(a)
data[1].push(b)
}
var tem =svg.selectAll("path.line").data(data)
tem.enter()
.append("path").merge(tem)
.transition().duration(1000)
.style("stroke",(d,i)=>colors(i)).attr("class","line").attr("d",(d,i)=>{
return line(d)
})
// svg.selectAll("circle.dot").remove()
var temarea =svg.selectAll("path.area").data(data)
temarea.enter()
.append("path").merge(temarea).classed("area",true)
.style("fill",(d,i)=>colors(i)).attr("opacity","0.8").attr("d",(d,i)=>{
return area(d)
})
for(let i=0;i<data.length;i++){
console.log(data[i])
var tem1 =svg.selectAll(`circle.dot${i}`)
var tem2=tem1.data(data[i]);
tem2.enter().append("circle").merge(tem2)
.transition().duration(1000)
.attr("class",`dot${i}`)
.style("fill",(d)=>{
return colors(i)
})
.attr("cx",(d,i)=>xscale(i))
.attr("cy",d=>yscale(d))
.attr("r",10)
}
}
console.log(data)
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var xscale = d3.scaleLinear().domain([0,10]).range([margin,width-margin])
var yscale =d3.scaleLinear().domain([0,10]).range([height-margin,margin])
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.selectAll("line.help").data([0,1,2,3,4,5,6,7,8,9,10]).enter()
.append("line").attr("class","help").attr("x1",xscale(0))
.attr("y1",d=>yscale(d)).attr("x2",xscale(10))
.attr("y2",d=>yscale(d)).attr("stroke","#409EFF")
// yaxis(svg)
svg.append("g").attr("transform",`translate(0,${height-margin})`)
.classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`).call(yaxis)
.classed("axis",true)
var line=d3.line().x((d,i)=>xscale(i)).y(d=>yscale(d))
.curve(d3.curveCardinal.tension(0.8))
var area=d3.area().x((d,i)=>xscale(i)).y0((d)=>yscale(0))
.y1(d=>yscale(d)).curve(d3.curveCardinal.tension(0.8))
make()
function make(){
createdata()
}
</script>
<button onclick="make()">dianji</button>
</html>
# d3散点图
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据 界面 映射 刻度尺 绑定
let data=[[],[],[],[]]
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
function createdata(){
data=[[],[],[],[]];
for(let i=0;i<10;i++){
var a =parseFloat(Math.random()*10)
var b =parseFloat(Math.random()*10)
var c =parseFloat(Math.random()*10)
var d =parseFloat(Math.random()*10)
var e =parseFloat(Math.random()*10)
var f =parseFloat(Math.random()*10)
var g =parseFloat(Math.random()*10)
var h =parseFloat(Math.random()*10)
data[0].push({x:a,y:b})
data[1].push({x:c,y:d})
data[2].push({x:e,y:f})
data[3].push({x:g,y:h})
}
console.log(data)
for(let i=0;i<data.length;i++){
var tem =svg.selectAll("path.dot"+i).data(data[i])
tem.enter()
.append("path").merge(tem).attr("class","dot"+i)
.transition().duration(1000)// <-C
.attr("transform", function(d){
console.log(d)
console.log(xscale(d.x))
return "translate(" // <-D
+ xscale(d.x)
+ ","
+ yscale(d.y)
+ ")";
})
.style("fill",(d)=>colors(i))
.attr("d", d3.symbol().type(_symbolTypes(i)))
}
}
console.log(data)
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var xscale = d3.scaleLinear().domain([0,10]).range([margin,width-margin])
var yscale =d3.scaleLinear().domain([0,10]).range([height-margin,margin])
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.append("g").attr("transform",`translate(0,${height-margin})`).classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`).call(yaxis).classed("axis",true)
var _symbolTypes = d3.scaleOrdinal() // <-A
.range([d3.symbolCircle,
d3.symbolCross,
d3.symbolDiamond,
d3.symbolSquare,
d3.symbolStar,
d3.symbolTriangle,
d3.symbolWye
]);
make()
function make(){
createdata()
}
</script>
<button onclick="make()">dianji</button>
</html>
# 总结
- 一维数组
- d属性画出的图形用d3.symbol().type(xxx)
- 位置需要用transform来绘制
- 绘制散点图可以d3提供很多内置的样式
- d3.symbolCircle,d3.symbolCross
- d3.symbolDiamond,d3.symbolSquare
- d3.symbolStar,d3.symbolTriangle,d3.symbolWye
- d属性注意是直接给出d3.symbol().type(xxx)而不是(d,i)=>再给出
# 气泡图
典型的用于展示三维数据的可视化控件
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据 界面 映射 刻度尺 绑定
let data=[]
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
function createdata(){
data=[];
for(let i=0;i<30;i++){
var a =parseFloat(Math.random()*10)
var b =parseFloat(Math.random()*10)
var c =parseInt(Math.random()*10)
data.push({x:a,y:b,r:c})
}
console.log(data)
var tem =svg.selectAll("circle.dot").data(data)
tem.enter().append("circle").merge(tem).attr("class","dot")
.transition().duration(1000)
.attr("fill",(d,i)=>colors(i))
.attr("cx",d=>xscale(d.x))
.attr("cy",d=>yscale(d.y))
.attr("r",d=>2*d.r)
}
console.log(data)
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var xscale = d3.scaleLinear().domain([0,10]).range([margin,width-margin])
var yscale =d3.scaleLinear().domain([0,10]).range([height-margin,margin])
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.append("g").attr("transform",`translate(0,${height-margin})`).classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`).call(yaxis).classed("axis",true)
make()
function make(){
createdata()
}
</script>
<button onclick="make()">dianji</button>
</html>
# 柱形图
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
//数据 界面 映射 刻度尺 绑定
let data=[]
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
function createdata(){
data=[];
for(let i=0;i<12;i++){
var a =parseInt(Math.random()*10+1)
data.push(a)
}
console.log(data)
var tem =svg.selectAll("rect.dot").data(data)
tem.enter().append("rect").merge(tem).attr("class","dot")
.transition().duration(1000)
.attr("fill",(d,i)=>colors(i))
.attr("x",(d,i)=>xscale(i))
.attr("y",d=>height-yscale(d)-margin)
.attr("height",d=>yscale(d))
.attr('width', xscale.bandwidth())
}
console.log(data)
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var yscale =d3.scaleLinear().domain([0,10]).range([height-margin,margin])
const xscale = d3.scaleBand().range([margin, width-margin])
.domain([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]).padding(0.2)
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.append("g").attr("transform",`translate(0,${height-margin})`).classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`).call(yaxis).classed("axis",true)
make()
function make(){
createdata()
}
</script>
<button onclick="make()">dianji</button>
</html>
# 总结
- 注意x轴,需要和数据绑定,要不然位置会出现问题
# 饼图
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
.line{
fill: none;
stroke: steelblue;
stroke-width: 2;
}
.axis path, .axis line {
stroke: #409EFF;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
data1=[];
for(let i=0;i<5;i++){
var math=parseInt( Math.random()*10)+1
data1.push(math)
}
endAngle = 2* Math.PI
var data = [ // <-B
{startAngle: 0, endAngle: 0.1 * endAngle},
{startAngle: 0.1 * endAngle, endAngle: 0.2 * endAngle},
{startAngle: 0.2 * endAngle, endAngle: 0.4 * endAngle},
{startAngle: 0.4 * endAngle, endAngle: 0.6 * endAngle},
{startAngle: 0.6 * endAngle, endAngle: 0.7 * endAngle},
{startAngle: 0.7 * endAngle, endAngle: 0.9 * endAngle},
{startAngle: 0.9 * endAngle, endAngle: endAngle}
];
var arc = d3.arc().outerRadius(100).innerRadius(20)
var pie= d3.pie().value(d=>{
console.log(d)
return d
})
var pieData= pie(data1)
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
svg.append("g").attr("transform",`translate(100,100)`)
.selectAll("path.arc").data(data).enter().append("path")
.attr("class","arc").attr("d",(d,i)=>arc(d)).attr("fill",(d,i)=>colors(i))
svg.append("g").attr("transform",`translate(100,300)`)
.selectAll("path.arc").data(pieData).enter().append("path")
.attr("class","arc").attr("d",(d,i)=>arc(d)).attr("fill",(d,i)=>colors(i))
svg.append("g").attr("transform",`translate(300,100)`)
.selectAll("path.arc2").data(pieData).enter().append("path").attr("class","arc2")
.transition().duration(3000).attrTween('d', function(d, i) {
console.log(d)
let interpolate = d3.interpolate(d.startAngle, d.endAngle);
return function(t) {
d.endAngle = interpolate(t);
return arc(d);
}
}).attr("fill",(d,i)=>colors(i))
svg.append("g").attr("transform",`translate(300,300)`)
.selectAll("path.arc2").data(pieData).enter().append("path").attr("class","arc2")
.transition().duration(3000).attrTween('d', function(d, i) {
// console.log(d)
var start ={startAngle:0,endAngle:0};
var interpolate =d3.interpolate(start,d)
// console.log(interpolate)
return function(t){
return arc(interpolate(t))
}
}).attr("fill",(d,i)=>colors(i))
</script>
</html>
# 总结
- 饼图如果不用d3.pie只使用d3.arc的话,需要精确好它的初始角度和结束角度
- d3.arc().outerRadius(x).innerRadius(y)控制圆的半径和圆是否空心
- pie = d3.pie().value()绑定原始数据,value中根据原始数据的某一项进行处理
- piedata = pie(data)
- 最后把这个piedata传给绘制的path
- 动画效果可以使用中间帧函数attrTween来实现
- 另外注意可以使用arc.centroid(d)来获取设置给饼图配置的文字位置
var arcs=svg.append("g").attr("transform",`translate(300,300)`)
.selectAll("path.arc2").data(pieData).enter()
arcs.append("path").attr("class","arc2").transition().duration(1000)
.attrTween('d', function(d, i) {
// console.log(d)
var start ={startAngle:0,endAngle:0};
var interpolate =d3.interpolate(start,d)
// console.log(interpolate)
return function(t){
return arc(interpolate(t))
}
}).attr("fill",(d,i)=>colors(i))
arcs
.append('text').transition().duration(3000)
.attr('transform', function(d) {
const x = arc.centroid(d)[0] * 1; // 文字的x坐标
const y = arc.centroid(d)[1] * 1;
return `translate(${x},${y})`;
})
.attr('text-anchor', 'middle')
.text((d,i) => {
return i
});
# 堆叠面积图
<html>
<body></body>
<style>
*{
margin:0;
padding:0;
}
</style>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
let data=[]
for(let i=0;i<11;i++){
var a =parseInt(Math.random()*10)+1
var b =parseInt(Math.random()*10)+1
var c =parseInt(Math.random()*10)+1
var d =parseInt(Math.random()*10)+1
data.push({x:a,y:b,z:c,f:d})
}
console.log(data)
var colors = d3.scaleOrdinal(d3.schemeCategory10);
var margin=30,
width =600,
height =500
var svg =d3.select("body").append("svg")
.attr("width",width).attr("height",height)
.style("border","1px solid deepskyblue")
var xscale = d3.scaleLinear().domain([0,10]).range([margin,width-margin])
var yscale =d3.scaleLinear().domain([0,40]).range([height-margin,margin])
var xaxis = d3.axisBottom().scale(xscale)
var yaxis = d3.axisLeft().scale(yscale)
svg.append("g").attr("transform",`translate(0,${height-margin})`)
.classed("axis",true).call(xaxis)
svg.append("g").attr("transform",`translate(30,0)`)
.call(yaxis).classed("axis",true)
var stack =d3.stack().keys(["x","y","z","f"]).offset(d3.stackOffsetNone)(data)
console.log(stack)
var area=d3.area().x((d,i) => xscale(i))
.y0(d =>{
return yscale(d[0])
})
.y1(d => yscale(d[1])).curve(d3.curveBasis)
svg.selectAll("path.area").data(stack).enter()
.append("path").attr("class","area")
.attr("d",(d,i)=>area(d)).attr("fill",(d,i)=>colors(i))
</script>
</html>
# 总结
- 利用d3.stack()把给的一维数组转化成二维,并且可以方便堆叠面积使用,里面的offset可以配置图形的形状
- 把转换后的数据填充到path中
- d3.stack需要绑定一个keys值
# treemap图
<!DOCTYPE html>
<style>
form{
font-family:"Helvetica Neue",Arical, sans-serif;
}
svg{
font: 10px sans-serif;
}
</style>
<svg width="1200" height="600"></svg>
<form>
</form>
<script src="http://d3js.org/d3.v5.min.js"></script>
<script>
var svg=d3.select("svg");
var width=1200,height=550;
var colors = d3.scaleOrdinal(d3.schemeCategory10)
var data={
"name":"gen",
"children":[
{
"name":"num1",
"children":[{"name":"num1-1","size":15},{"name":"num1-2","size":"5"}]
},
{
"name":"num2",
"children":[{"name":"num2-1","size":4},{"name":"num2-2","size":7},
{"name":"num2-3","size":2},{"name":"num2-4","size":5}
]
},
{
"name":"num3",
"size":10
},
{
"name":"num4",
"size":10
},
{
"name":"num5",
"size":10
}
]
};
var treemap=d3.treemap()
.tile(d3.treemapResquarify)//布局样式,默认 d3.treemapResquarify
.size([width,height])//宽高
.round(true)//启用或者禁止四舍五入默认false
.paddingInner(10)
var hi=d3.hierarchy(data)
.sum(function(d){ return d.size; })
treemap(hi);
var cell=svg.selectAll("g")
.data(hi.leaves())
.enter().append("g");
console.log(hi.leaves())
var arr=[]
cell.append("rect")
.attr("x",function(d){ return d.x0; })
.attr("y",function(d){ return d.y0; })
.attr("width",function(d){ return d.x1-d.x0; })
.attr("height",function(d){ return d.y1-d.y0; })
.attr("fill",function(d,i) {
return colors(d.parent.data.name)
})
cell.append("text")
.attr("x",function(d) {return d.x0;})
.attr("y",function(d) {return d.y0;})
.attr("dx","0.5em")
.attr("dy","1.5em")
.attr("fill","#FFF")
.attr("font-size",12)
.text(function(d){ return d.data.name+":"+d.data.size;
} );
</script>
# 总结
- d3.treemap()设置样式
- d3.hierarchy(data)设置参考
- treemap(hi)传递参数
- hi.leaves()根据这个绘制矩形
# tree
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CodePen - d3树图</title>
<script>
window.console = window.console || function(t) {};
</script>
<!-- <script>
if (document.location.search.match(/type=embed/gi)) {
window.parent.postMessage("resize", "*");
}
</script> -->
</head>
<body translate="no">
<svg width='1280' height="860"></svg>
<script src='https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script id="rendered-js">
var dataset = {
name: "中国",
children: [
{
name: "浙江",
children: [
{ name: "杭州", value: 100 },
{ name: "宁波", value: 100 },
{ name: "温州", value: 100 },
{ name: "绍兴", value: 100 }] },
{
name: "广西",
children: [
{
name: "桂林",
children: [
{ name: "秀峰区", value: 100 },
{ name: "叠彩区", value: 100 },
{ name: "象山区", value: 100 },
{ name: "七星区", value: 100 }] },
{ name: "南宁", value: 100 },
{ name: "柳州", value: 100 },
{ name: "防城港", value: 100 }] },
{
name: "黑龙江",
children: [
{ name: "哈尔滨", value: 100 },
{ name: "齐齐哈尔", value: 100 },
{ name: "牡丹江", value: 100 },
{ name: "大庆", value: 100 }] },
{
name: "新疆",
children:
[
{ name: "乌鲁木齐" },
{ name: "克拉玛依" },
{ name: "吐鲁番" },
{ name: "哈密" }] }] };
var marge = { top: 60, bottom: 0, left: 30, right: 0 };
var svg = d3.select("svg");
var width = svg.attr("width");
var height = svg.attr("height");
var g = svg.append("g").
attr("transform", "translate(" + marge.top + "," + marge.left + ")");
let hierarchyData = d3.hierarchy(dataset)
// .sum(function (d) {
// return d.name;
// });
let tree = d3.tree().
size([width - 100, height - 100])
.
separation(function (a, b) {
return a.parent == b.parent ? 1 : 2;
});
let treeData = tree(hierarchyData);
console.log(treeData)
let nodes = treeData.descendants().map(item => {
// item.show = false;
return item;
});
let links = treeData.links();
let beziler_generator = d3.linkHorizontal().
x(function (d,i) {
return d.x;
}).
y(function (d) {
return d.y;
});
// 边
g.append('g').
selectAll('path').
data(links).
enter().
append('path').
attr('d', function (d, i) {
var start = { x: d.source.x, y: d.source.y };
var end = { x: d.target.x, y: d.target.y };
return beziler_generator({ source: start, target: end });
}).
attr('fill', 'none').
attr('stroke', 'blue').
attr('stroke-width', '1');
let gs = g.append('g').
selectAll('g').
data(nodes).
enter().
append('g').
attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
}).
attr('cursor', 'pointer')
// .
// on('mouseover', function (d, i, context) {
// console.log(this);
// d3.select(this).select('.detail').style('display', 'block');
// }).
// on('mouseout', function () {
// d3.select(this).select('.detail').style('display', 'none');
// });
// gs.append('text').
// attr('x', function (d) {
// return 30 - d.data.name.length * 8;
// }).
// text(function (d) {
// return d.data.name;
// }).
// attr('class', 'detail').
// attr('style', function (d) {
// return d.show ? 'display:block' : 'display:none';
// });
gs.append('circle').
attr('r', 4).
attr('fill', 'white').
attr('stroke', 'blue').
attr('stroke-width', 1)
.attr('x', function (d) {
return d.x+100;
});
gs.append('text').
attr('x', function (d) {
return -d.data.name.length * 8;
}).
attr('y', function (d) {
return d.children ? -10 : 20;
}).
text(function (d) {
return d.data.name;
});
// let zoom = d3.zoom().scaleExtent([1, 5])
// .extent([[0, 0], [width, height]]).on('zoom', zoomed);
// zoom(svg);
//
// function zoomed(d, i, context) {
// g.attr('transform', d3.zoomTransform(this));
// // svg.call(zoom.transform, d3.zoomTransform(this))
// }
console.log(1, treeData, nodes, links);
</script>
</body>
</html>
# pack图
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/* circle {
fill: rgb(31, 119, 180);
fill-opacity: .25;
stroke: rgb(31, 119, 180);
stroke-width: 1px;
} */
/* .leaf circle {
fill: #ff7f0e;
fill-opacity: 1;
} */
text {
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<svg width="500" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var data={
"name":"gen",
"children":[
{
"name":"num1",
"children":[{"name":"num1-1","size":15},{"name":"num1-2","size":"5"}]
},
{
"name":"num2",
"children":[{"name":"num2-1","size":4},{"name":"num2-2","size":7},
{"name":"num2-3","size":2},{"name":"num2-4","size":5}
]
},
{
"name":"num3",
"size":10
},
{
"name":"num4",
"size":10
},
{
"name":"num5",
"size":10
}
]
};
// 定义一个svg画布
var svg = d3.select("svg"),
// 以svg画布的宽度来作为直径的长度
diameter = +svg.attr("width"),
// 定义一个组元素,并将其移动定位
g = svg.append("g").attr("transform", "translate(2,2)"),
// 定义一个格式化函数,该格式化函数将返回参数的整数部分
format = d3.format(",d");
var colors = d3.scaleOrdinal(d3.schemeCategory10)
// 创建一个包布局,返回包布局函数pack()
var pack = d3.pack()
// 设置包布局的宽、高尺寸
.size([diameter - 4, diameter - 4]);
// d3.hierarchy函数用来从层次型的数据构造根节点root及其递归的下属节点,计算并为每个节点添加
// depth,height,parent,value属性
var root = d3.hierarchy(data)
// 对每一个父节点来说,将其所有子节点的size属性的值相加,作为该父节点的value的值,
//叶子节点的size值作为其value值
.sum(function(d) { return d.size; })
// 对节点按照value属性值进行排序
.sort(function(a, b) { return b.value - a.value; });
// 定义节点元素
var node = g.selectAll(".node")
// pack(root)函数为root节点及其递归的下属节点计算并添加r,x,y属性,
//r用来确定节点半径的大小,x,y用来确定节点的位置
// desentdants()函数返回树形结构的数据中的所有节点组成的数组
// 此处为节点绑定数据
.data(pack(root).descendants())
.enter().append("g")
// 父节点和叶子节点的样式设定
.attr("class", function(d) { return d.children ? "node" : "leaf node"; })
// 根据节点的x,y来确定其摆放的位置
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
// 为节点添加title属性,即鼠标悬浮显示的信息
node.append("title")
.text(function(d) { return d.data.name + "\n" + format(d.value); });
// 根据节点的r属性值来绘制代表节点的圆
node.append("circle")
.attr("r", function(d) {
console.log(d)
return d.r;
}).attr("fill",(d)=>{
if(d.parent){
return colors(d.parent.data.name)
}else{
return colors("xxx")
}
}
)
// 若为叶子节点,则添加文字标签
node.filter(function(d) { return !d.children; }).append("text")
.attr("dy", "0.3em")
.text(function(d) { return d.data.name.substring(0, d.r / 3); });
</script>
# 总结
- d3.pack()创建打包图格式和大小
- d3.hierarchy() 层级
- pack(root).descendants()得出的数据结构如上图所示x、y、r参数
← d3实例2