已被阅读 896 次 | 文章分类:javascript | 2022-05-04 01:19
d3.js的最大特征是所有图表元素都是一个单独对象,可以组合使用;有很高的自由度,比如增删改查等等
1 延时动画
初始化图表的时候,让图表有个延迟和缓冲的动画效果;
这里使用delay()函数和duration()函数;
实现效果如下:
如图有两部分,矩形和文字两种类型;原理就是让每个矩形和文字依次延迟出现;核心代码如下:
// 添加文字元素
var texts = svg
.selectAll('.MyText')
.data(dataset)
.enter()
.append('text')
.attr('class', 'MyText')
.attr(
'transform',
'translate(' + padding.left + ',' + padding.top + ')'
)
.attr('x', function (d, i) {
return xScale(i) + rectPadding / 2;
})
.attr('dx', function () {
return (xScale.rangeBand() - rectPadding) / 2;
})
.attr('dy', function (d) {
return 20;
})
.text(function (d) {
return d;
})
.attr('y', function (d) {
var min = yScale.domain()[0];
return yScale(min);
})
.transition()
.delay(function (d, i) {
return i * 200;
})
.duration(1000)
.ease('bounce')
.attr('y', function (d) {
return yScale(d);
});
2 鼠标悬浮交互
鼠标悬浮更改图表某些属性,比如尺寸或者颜色等;
通过on函数注册对应的事件即可;
这里演示鼠标悬浮事件更改颜色的效果
代码如下:
// 添加矩形元素
var rects = svg
.selectAll('.MyRect')
.data(dataset)
.enter()
.append('rect')
.attr('class', 'MyRect')
.attr(
'transform',
'translate(' + padding.left + ',' + padding.top + ')'
)
.attr('x', function (d, i) {
return xScale(i) + rectPadding / 2;
})
.attr('y', function (d) {
return yScale(d);
})
.attr('width', xScale.rangeBand() - rectPadding)
.attr('height', function (d) {
return height - padding.top - padding.bottom - yScale(d);
})
.attr('fill', 'steelblue') //填充颜色不要写在CSS里
.on('mouseover', function (d, i) {
d3.select(this).attr('fill', 'yellow');
})
.on('mouseout', function (d, i) {
d3.select(this).transition().duration(500).attr('fill', 'steelblue');
});
3 拖拽交互(力导向图)
力导向图绘制的关键是节点和连线之间的关系;不过D3为我们提供了对应的api;这个不需要我们去关心;只需要组织好数据结构,将数据传进去即可;实现下面一个效果:
节点和连线的关系用下面两个数组:
var nodes = [
{ name: '桂林' },
{ name: '广州' },
{ name: '厦门' },
{ name: '杭州' },
{ name: '上海' },
{ name: '青岛' },
{ name: '天津' },
];
var edges = [
{ source: 0, target: 1 },
{ source: 0, target: 2 },
{ source: 0, target: 3 },
{ source: 1, target: 4 },
{ source: 1, target: 5 },
{ source: 1, target: 6 },
];
这里我们使用d3.layout()方法绘制力导向图;
首先创建一个力导向图的元素布局;
var width = 500;
var height = 500;
var svg = d3
.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
var force = d3.layout
.force()
.nodes(nodes) //指定节点数组
.links(edges) //指定连线数组
.size([width, height]) //指定范围
.linkDistance(150) //指定连线长度
.charge(-400); //相互之间的作用力
force.start(); //开始作用
console.log(nodes);
console.log(edges);
// 添加连线
var svg_edges = svg
.selectAll('line')
.data(edges)
.enter()
.append('line')
.style('stroke', '#ccc')
.style('stroke-width', 1);
var color = d3.scale.category20();
// 添加节点
var svg_nodes = svg
.selectAll('circle')
.data(nodes)
.enter()
.append('circle')
.attr('r', 20)
.style('fill', function (d, i) {
return color(i);
})
.call(force.drag); //使得节点能够拖动
// 添加描述节点的文字
var svg_texts = svg
.selectAll('text')
.data(nodes)
.enter()
.append('text')
.style('fill', 'black')
.attr('dx', 20)
.attr('dy', 8)
.text(function (d) {
return d.name;
});
其次在鼠标拖拽的时候,实现实时更新所有节点、文字、连线的位置;代码如下
force.on('tick', function () {
// 对于每一个时间间隔
// 更新连线坐标
svg_edges
.attr('x1', function (d) {
return d.source.x;
})
.attr('y1', function (d) {
return d.source.y;
})
.attr('x2', function (d) {
return d.target.x;
})
.attr('y2', function (d) {
return d.target.y;
});
// 更新节点坐标
svg_nodes
.attr('cx', function (d) {
return d.x;
})
.attr('cy', function (d) {
return d.y;
});
// 更新文字坐标
svg_texts
.attr('x', function (d) {
return d.x;
})
.attr('y', function (d) {
return d.y;
});
});
4 动态添加组合实体
将多个元素放到一个组,然后整体添加;
效果如下
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>创建组合元素</title>
<style>
.Main_tool{
margin-bottom: 10px;
}
.node{
cursor: pointer;
}
</style>
</head>
<body>
<div id="Main">
<div class="Main_tool" id="Tool">
<input id="labeltext_Entity" type="text" />
<input id="addEntity" type="button" value="添加实体" />
<br />
<input id="labeltext_Field" type="text" />
<input id="addField" type="button" value="添加字段" />
</div>
<div id="svgContent">
</div>
</div>
<script src="../d3/d3.v3.min.js"></script>
<script>
//初始化实体参数,创建一个svg对象,定义宽高、背景颜色
var w =1000,h = 500, x=50,y=50,radius=50,radius1=30;
var svg = d3.select("#svgContent").append("svg")
.attr("width",w)
.attr("height",h)
.style("background-color", "white")
.style("border","solid 1px green");
var circles = [];
var circles1 = [];
function drawEntites(_circleArr){
// 创建一个组
var elem = svg.selectAll("g")
.data(_circleArr)
console.log("3. elem",elem);
/* 拖曳实体函数 -start */ //拖曳有两种方式,都是获取鼠标的像素位置更新;一种更新x、y坐标;一种更新偏移量
var drag=d3.behavior.drag().on("drag",dragmove)
function dragmove(d) {
d3.select(this)
.attr("transform","translate("+d3.event.x+","+d3.event.y+")");
}
/* 拖曳实体函数 -end */
var elemEnter = elem.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d){return "translate("+d.cx+","+d.cy+")"}).call(drag);
/*创建圆*/
var circle = elemEnter.append("circle")
.attr("r", function(d){return d.r} )
.attr("stroke","black")
.attr("fill",function(d){
console.log("4.d",d);
var name=d.name;//文字颜色
console.log("5.name",name);
switch(name){
case "entity":
color="green";
break;
case "field":
color="orange";
break;
default:
color="red";
}
return color;
});
/* 创建文本*/
elemEnter.append("text")
.text(function(d){return d.label}) //text 显示标注
.attr("text-anchor", "middle") //text相对块居中
.attr("fill","white")
}
/* tool事件 -start */
document.getElementById('addEntity').addEventListener('click',function(){
circles.push( {cx:x, cy:y, r:radius,label:document.getElementById("labeltext_Entity").value.toString().trim(),name:"entity"});
drawEntites(circles);
});
document.getElementById('addField').addEventListener('click',function(){
circles1.push( {cx:x, cy:y, r:radius1,label:document.getElementById("labeltext_Field").value.toString().trim(),name:"field"});
drawEntites(circles1);
})
/* tool事件 -end */
</script>
</body>
</html>
QQ:3410192267 | 技术支持 微信:popstarqqsmall
Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号