前言
d3js的事件绑定也是非常重要的。他可以像咱们给dom绑定事件一样方便。
常用的events如下
- click
- dblclick
- mouseover
- mouseout
- mousemove
- mouseleave
- mousedown
- mouseup
- contextmenu
先用小demo绘制一些图形
绘制几个基础的小方块, 看不懂的翻前面几节文章 效果图如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#container {
width: 500px;
margin: 50px auto 0;
}
</style>
</head>
<body>
<div id="container">
</div>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
const svg = d3.select('#container')
.append('svg')
.attr('width', 500)
.attr('height', 500);
const data = [
{ id: 1, fill: 'black', x: 10, y: 10 },
{ id: 2, fill: 'black', x: 50, y: 50 },
{ id: 3, fill: 'black', x: 100, y: 70 },
{ id: 4, fill: 'black', x: 20, y: 100 }
];
draw(); // 绘制
function draw() {
const update = svg.selectAll('rect')
.data(data, d => d.id);
//修改层
update.attr('x', (d, idx) => d.x)
.attr('y', (d, idx) => d.y)
.attr('fill', (d) => d.fill)
//渲染层
const enter = update.enter();
//删除层
const exit = update.exit();
enter.append('rect')
.attr('width', 20)
.attr('height', 20)
.attr('id', d => d.id)
.attr('x', (d, idx) => d.x)
.attr('y', (d, idx) => d.y)
.attr('fill', (d) => d.fill)
.attr('stroke', 'blue')
.attr('strokeWidth', 1)
exit.remove()
}
</script>
使用d3js绑定事件
咱们先用
click绑定给咱们的小方块
code
bindEvent();
function bindEvent() {
svg.selectAll('rect') // 获取所有得rect
.on('click', (d, i) => { // 使用on 关键函数绑定, 后面回调函数参数d 当前数据 i 索引
console.log(d, i, 'data'); // 输出的是前面绑定的每一项 也就是点击到得数据{}
})
.on('mousemove', (d) => { }) // 同上
.on('mouseleave', (d) => { });// 同上
}
不难看出来我们绑定事件还是蛮方便得使用关键字
on即可
点击到得小方框变个颜色
前面给
rect都绑定了一个click事件了,下面咱们改变点击到方块得颜色(如果已经改变过得再被点击就更改回原来得)
code
const selected = [];
bindEvent();
function bindEvent() {
svg.selectAll('rect') // 获取所有得rect
.on('click', (d, i) => { // 使用on 关键函数绑定, 后面回调函数参数d 当前数据 i 索引
console.log(d, i, 'data'); // 输出的是前面绑定的每一项 也就是点击到得数据{}
undateSelect(d.id);
updateColor();
})
.on('mousemove', (d) => { }) // 同上
.on('mouseleave', (d) => { });// 同上
}
function undateSelect(id) { // 更新selected
const index = selected.findIndex(item => item === id);
if (index !== -1) { // 有的话就删除、没有得话添加
selected.splice(index, 1);
} else {
selected.push(id);
}
}
function updateColor() {
data.forEach((item) => {
if (selected.includes(item.id)) { //根据selected 改变颜色
item.fill = 'red';
} else {
item.fill = 'black';
}
});
draw(); // 数据绑定函数 会根据数据更改做更新, 不懂得可以翻下前面几章
};
效果图如下:
实现点击画布空白处事件
实现点击画布空白处所有方块恢复原来得颜色, 关键点怎么判断是不是点到了画布空白?看下面代码
code
function clearColor() { // 清空颜色函数
selected = [];
updateColor();
}
function bindEvent() {
svg.selectAll('rect')
.on('click', (d, i) => {
console.log(d, i, 'data');
undateSelect(d.id);
updateColor();
})
.on('mousemove', (d) => { })
.on('mouseleave', (d) => { });
svg.on('click', () => { // 给画布绑定click
const { event } = d3;
const target = event.srcElement; // 当前点击到得元素
const info = d3.select(target).datum(); // 获取到当前点击到图形得绑定数据
if (info?.id) return; //用数据判断是不是点击到了小方块
clearColor();
d3.event.preventDefault(); // 阻止事件向后传递
});
}
效果图如下:
源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#container {
width: 500px;
margin: 50px auto 0;
}
</style>
</head>
<body>
<div id="container">
</div>
</body>
</html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
let selected = [];
const svg = d3.select('#container')
.append('svg')
.attr('width', 500)
.attr('height', 500);
const data = [
{ id: 1, fill: 'black', x: 10, y: 10 },
{ id: 2, fill: 'black', x: 50, y: 50 },
{ id: 3, fill: 'black', x: 100, y: 70 },
{ id: 4, fill: 'black', x: 20, y: 100 }
];
draw(); // 绘制
bindEvent(); // 绑定event
function draw() {
const update = svg.selectAll('rect')
.data(data, d => d.id);
//修改层
update.attr('x', (d, idx) => d.x)
.attr('y', (d, idx) => d.y)
.attr('fill', (d) => d.fill)
//渲染层
const enter = update.enter();
//删除层
const exit = update.exit();
enter.append('rect')
.attr('width', 20)
.attr('height', 20)
.attr('id', d => d.id)
.attr('x', (d, idx) => d.x)
.attr('y', (d, idx) => d.y)
.attr('fill', (d) => d.fill)
.attr('stroke', 'blue')
.attr('strokeWidth', 1)
exit.remove()
}
function bindEvent() {
svg.selectAll('rect')
.on('click', (d, i) => {
console.log(d, i, 'data');
undateSelect(d.id);
updateColor();
})
.on('mousemove', (d) => { })
.on('mouseleave', (d) => { });
svg.on('click', () => {
const { event } = d3;
const target = event.srcElement; // 当前点击到得元素
const info = d3.select(target).datum(); // 获取到当前点击到图形得绑定数据
if (info?.id) return; //用数据判断是不是点击到了小方块
clearColor();
d3.event.preventDefault(); // 阻止事件向后传递
});
}
function undateSelect(id) {
const index = selected.findIndex(item => item === id);
if (index !== -1) {
selected.splice(index, 1);
} else {
selected.push(id);
}
}
function updateColor() {
data.forEach((item) => {
if (selected.includes(item.id)) {
item.fill = 'red';
} else {
item.fill = 'black';
}
});
draw();
};
function clearColor() {
selected = [];
updateColor();
}
</script>
往期推荐
- 当用d3js绘制数据量过大,reload过慢!!!重写d3js数据绑定算法
- 【d3js】用d3js带你实现一个简易柱形图🎈
- 【d3js】手把手教你绘制一个折线图
- 【d3js】d3js实现一个围绕圆运动的动画效果
- 【看了必懂D3JS(一)】d3js select、selectAll、attr、style、append
- 【看了必懂D3JS(二)】d3js data、datum 实现一个数据驱动绘制的方法
- 【d3js(五)】d3.transtion() 过渡动画篇
结束语
事件绑定就到这里了 相信大家对事件绑定有了一个新得认识
- 大家好 我是三原,多谢您的观看,我会更加努力(๑•̀ㅂ•́)و✧多多总结。
- 每个方法都是敲出来验证过通过的,有需要可以放心复制。
- 如果您给帮点个赞👍就更好了 谢谢您~~~~~
- 期待您的关注