React: d3.event 在 ReactJS + d3JS 组件中为 null

创建于 2016-04-28  ·  3评论  ·  资料来源: facebook/react

我正在使用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;

最有用的评论

您很可能正在使用 Babel,它无法使用导入/导出语法从 d3 导入可变字段。

看到这个: https :

您需要使用以下内容更改导入 d3 的方式:

import * as d3 from 'd3';
import {event as currentEvent} from 'd3';

并用currentEvent替换所有出现的d3.event currentEvent

这解决了 d3.js v3 的问题。

所有3条评论

您引用的代码似乎是通用的 d3 javascript,并且该事件不会通过 React 的事件系统。 这看起来像一个 d3 问题,与 React 无关。 出于这个原因,我将关闭这个问题。

另一方面,您应该使用ref来引用 DOM 节点,而不是通过 ID 进行选择。 使用d3.select("#viewport")可能会导致与碰巧选择相同 ID 的其他组件的互操作性问题,并防止组件在同一页面上多次使用。 使用ref将解决这些问题。

其他有这个问题的人肯定会在这里结束,所以这里有一种对我有用的方法:

  1. 打开 (chrome) 调试器的源窗格
  2. 为导致问题的事件设置事件侦听器断点
  3. 重新创建问题
  4. 执行应该中断到调试。 继续前进,直到您进入 d3(特别是 d3_selection_onListener(listener, argumentz))。
  5. 进入控制台并保存对 d3 对象的全局引用:

> window.theD3versionHostingTheEvent = d3;

  1. 前进直到listener.apply(this, argumentz); ,然后选择Step into next function call,直到到达抛出错误的地方。
  2. 再次进入控制台,然后执行: 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 的问题。

此页面是否有帮助?
0 / 5 - 0 等级