我正在使用ReactJS、d3JS 和 ES6创建组织结构图。 我可以创建图表并查看它。 但我想向图表添加缩放和拖动行为,所以我使用了d3.behavior.zoom 。 我可以看到放大的被调用的方法,但d3.event为空。
我尝试将缩放行为附加到div、svg 和 g,但没有任何帮助。 缩放行为被调用,但事件为空。
在我的 ASP.NET 项目中,我确保除了 systemJS 配置之外我没有任何对 d3.js 的引用,其中许多 stackoverflow 答案都提到了与为什么 d3.event 为空相关的问题。
我的代码与使用旧版本 ReactJS 的示例https://github.com/Swizec/candidate-bucket-chart/blob/169779e110c8825f4545c71ae5845ff7bad4f1f4/src/BubbleChart.jsx中的代码非常相似。
这是我的 systemJS 配置:
<script>
System.defaultJSExtensions = true;
System.config({
map: {
'rx': "https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js",
'react': 'https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react.js',
'react-dom': 'https://cdnjs.cloudflare.com/ajax/libs/react/15.0.1/react-dom.js',
'd3': 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.js'
}
});
System.import('../app/app.js');
</script>
import React, { Component } from 'react';
import * as Rx from 'rx';
import * as d3 from 'd3';
import Person from './person';
class OrgChart extends Component {
constructor(props) {
super(props);
this.state = { persons: [] };
}
componentWillMount() {
// Just read a JSON file
var source = Rx.Observable.fromPromise($.getJSON("/js/org-persons.json"));
source.subscribe(
function(chart) {
var tree = d3.layout.tree()
.nodeSize([110, 50])
.separation(function() {
return 1;
});
var nodes = tree.nodes(chart[0]).reverse();
var links = tree.links(nodes);
var p = [];
nodes.forEach(function(node) {
fs.push((<Person x={node.x} y={node.y}></Person>));
}.bind(this));
this.setState({ person: p });
}.bind(this)
);
}
componentDidMount() {
var rootX = document.body.clientWidth / 4;
var rootY = 300;
// A standard setup with d3 to use it's zoom/drag behavior
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", this.zoomed)
.translate([rootX, rootY]);
// Attach zoom behavior to the first group in the svg.
d3.select("#viewport")
.call(zoom);
}
// When I drag the svg, this function gets called but the event is null. d3 is a global object.
zoomed() {
d3.select("#viewport").attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
// renders an org chart
render() {
return (
<div id='treeContainer'><svg id='fullTree' width='100%'>
<g id='viewport'>
{ this.state.persons }
</g>
</svg></div>
);
}
}
export default OrgChart;
您引用的代码似乎是通用的 d3 javascript,并且该事件不会通过 React 的事件系统。 这看起来像一个 d3 问题,与 React 无关。 出于这个原因,我将关闭这个问题。
另一方面,您应该使用ref
来引用 DOM 节点,而不是通过 ID 进行选择。 使用d3.select("#viewport")
可能会导致与碰巧选择相同 ID 的其他组件的互操作性问题,并防止组件在同一页面上多次使用。 使用ref
将解决这些问题。
其他有这个问题的人肯定会在这里结束,所以这里有一种对我有用的方法:
> window.theD3versionHostingTheEvent = d3;
listener.apply(this, argumentz);
,然后选择Step into next function call,直到到达抛出错误的地方。window.theD3versionHostingTheEvent == d3
如果结果是false
,那么您肯定正在运行 d3 的两个实例。 就我而言,结果证明我使用的其中一个库中捆绑了 d3。
您很可能正在使用 Babel,它无法使用导入/导出语法从 d3 导入可变字段。
看到这个: https :
您需要使用以下内容更改导入 d3 的方式:
import * as d3 from 'd3';
import {event as currentEvent} from 'd3';
并用currentEvent
替换所有出现的d3.event
currentEvent
。
这解决了 d3.js v3 的问题。
最有用的评论
您很可能正在使用 Babel,它无法使用导入/导出语法从 d3 导入可变字段。
看到这个: https :
您需要使用以下内容更改导入 d3 的方式:
并用
currentEvent
替换所有出现的d3.event
currentEvent
。这解决了 d3.js v3 的问题。