如何从D3 Selection中获取D3实例?
如何从D3 Selection中获取D3实例(无需额外传入)
这个问题问得好!其实不需要自定义getD3()方法,就能从Selection里拿到D3实例——根据你的需求,有几种靠谱的方式:
1. 只是需要创建新的Selection(比如d3.select(element))
这种情况甚至不需要拿到完整的D3实例。因为任何D3 Selection的constructor就是d3.selection,你可以直接用它来创建新的选择集:
function foo(selection) { const element = document.createElement('div'); // 效果等价于 d3.select(element) const newSelection = selection.constructor(element); // 如果你更习惯显式的select写法,也可以这样: const newSelection = selection.constructor().select(element); }
这是因为selection.constructor指向的就是你所用D3实例中的d3.selection函数,用DOM元素调用它就能创建对应元素的选择集,和d3.select()的作用完全一样。
2. 需要完整的D3实例(比如使用比例尺、颜色工具等)
如果你需要用到D3的其他功能(比如d3.scaleLinear()或者d3.color()),那就要看你的使用环境了:
全局引入D3(通过script标签)
如果是用script标签加载D3(此时D3挂载在window上),直接引用window.d3就行:
function foo(selection) { const d3 = window.d3; const linearScale = d3.scaleLinear(); // ... 你的其他代码 }
模块化引入D3(ES模块/npm)
在模块化环境下,D3不会挂载到全局window上,所以没法直接用上面的方法。可惜的是,D3的Selection在公开API里并没有直接暴露对父D3实例的引用。最稳妥的方案还是把D3实例显式传入函数,但如果你实在不想传,也可以用个小技巧:
function foo(selection) { // 获取d3.selection构造函数 const d3SelectionConstructor = selection.constructor; // 在模块化环境中,你可以本地导入D3并验证是否为同一个实例 import * as d3 from 'd3'; if (d3.selection === d3SelectionConstructor) { // 使用导入的d3实例 const color = d3.color('steelblue'); } }
注意这个技巧的前提是你能在foo函数的作用域内导入D3。如果做不到的话,就没有可靠的方法能仅通过Selection获取完整的D3实例了——因为D3的Selection本身并没有在公开API里存储对父实例的引用。
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

