D3.js从源码分析到精通(四)
d3.pointer
获取事件的鼠标指针的位置
let aaa=d3.select('.aaa');
aaa.on('click', function (e) {
// 我们发现这个是拿到鼠标在整个页面的坐标
console.log(e.pageX,e.pageY);
// 这个是拿到 鼠标在.aaa整个盒子的坐标
console.log(d3.pointer(e));
});
源码分析,关于SVG部分我就先放放,因为我是SVG菜鸡,等深入的话看能不能回顾下
export default function(event, node) {
// 如果没有传Dom就是拿到目标自身
if (node === undefined) node = event.currentTarget;
// 判断是否有这个属性
if (node.getBoundingClientRect) {
var rect = node.getBoundingClientRect();
// 把border的宽度算上
console.log(e.clientLeft);
node.clientLeft // undefined 没有宽度
return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
}
}
// 如果没有就应该是window,那么拿到的就是在窗口的鼠标位置
return [event.pageX, event.pageY];
}
这个拿到自身位置条件的函数还是挺牛逼的
getBoundingClientRect()
d3.pointers()
也是鼠标,手写笔,等效于上面d3.pointer()
,返回 的是一个二维数组
return Array.from(events, event => pointer(event, node));
pointer 是上面的d3.pointer 方法
具体怎么用处,暂时不清楚
selection.each
<div className={'aaa'}>
<div className="bbb"></div>
<div className="bbb"></div>
<div className="bbb"></div>
<div className="bbb"></div>
</div>
let aaa=d3.select('.aaa');
aaa.selectAll('.bbb').data([1,2,3,4]).each(function (d,i,group) {
console.log(this)// dom
console.log(d);// 1 数据
console.log(i);// 索引
console.log(group);//.bbb整个子元素
// 这个把dom重新包起来,在dom中填充数据
d3.select(this).text(v=>v)
});
eath 其实按照我的理解,可以继续分配给子元素进行操作
selection.call
可以提取公共部分进行某些操作
names(selection, first, last) {
selection.attr('first-name',first).attr('last_name',last)
}
let aaa=d3.select('.aaa');
aaa.selectAll('.bbb').call(this.names, 'xxxx', 'bbbb');
=====
或者这种方式
names(selection, first, last) {
selection.attr('first-name',first).attr('last_name',last)
}
componentDidMount() {
let that=this;
let aaa=d3.select('.aaa');
aaa.selectAll('.bbb').each(function(){
that.names(d3.select(this),'bbb','xxx')
})
}
selection.empty()
node() 非空判断
export default function() {
return !this.node();
}
样例
let aaa=d3.select('.aaa');
console.log(aaa.empty()); // 如果有 则是 false 没有这是true
selection.nodes
Array.from(this);
返回的是dom组合的数组
let aaa=d3.select('.aaa').selectAll('.bbb').nodes()
selection.node
获取dom节点
如果是selectAll
返回的第一个dom节点
selection.size
返回dom的总个数
源码
export default function() {
let size = 0;
for (const node of this) ++size; // eslint-disable-line no-unused-vars
return size;
}
实践
let aaa=d3.select('.aaa').selectAll('.bbb')
console.log(aaa.size());
内置迭代器
let selection=d3.select('.aaa').selectAll('.bbb')
const elements = [...selection];
for (const element of selection) {
console.log(element);
}
局部变量
d3.local
let a=d3.local() 相当于定义了一个局部变量
set(node)
let foo = d3.local()
d3.select('.aaa').selectAll('.bbb').data([1, 2, 3, 4]).each(function (d) {
// this 是dom
foo.set(this,d)
// 第二种方式 直接在当前dom自身设置
d3.select(this).property(foo,d)
})
get(node)
console.log(foo.get(document.querySelector('.bbb'))); // 查询数据
remove(node)
let foo = d3.local()
let aaa = d3.select('.aaa')
foo.set(aaa, 111)
console.log(foo.get(aaa));// 111
foo.remove(aaa)
console.log(foo.get(aaa)); // undefined
toString()
标识符
let foo = d3.local()
let aaa = d3.local()
console.log(foo.toString()); // @1
console.log(aaa.toString()); // @2
let foo = d3.local()
let aaa = d3.select('.aaa')
foo.set(aaa,2)
aaa.property(foo,333)
console.log(foo.get(aaa)); //设置自身 2
console.log(foo.get(aaa.node()));// 设置dom 333
console.log(aaa[foo]); //2
console.log(aaa.property(foo));
namespace
d3.namespace("svg:text"); // {space: "http://www.w3.org/2000/svg", local: "text"}
console.log(d3.namespaces);
//
{
svg: "http://www.w3.org/2000/svg",
xhtml: "http://www.w3.org/1999/xhtml",
xlink: "http://www.w3.org/1999/xlink",
xml: "http://www.w3.org/XML/1998/namespace",
xmlns: "http://www.w3.org/2000/xmlns/"
}
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬