React: ReactJS + d3JSコンポーネントでd3.eventがnull

作成日 2016年04月28日  ·  3コメント  ·  ソース: facebook/react

ReactJS、d3JS、ES6を使用して組織図を作成しています。 チャートを作成して見ることができます。 ただし、ズームとドラッグの動作をグラフに追加したいので、 d3.behavior.zoomを使用しズームされたメソッドが呼び出されていることがわかりますが、

ズーム動作をdiv、svg、gにアタッチしてみましたが、何も役に立ちません。 ズームされた動作が呼び出されますが、イベントはnullです。

私のASP.NETプロジェクトでは、d3.eventがnullである理由に関連する問題として多くのスタックオーバーフローの回答が言及されているsystemJS構成以外に、d3.jsへの参照がないことを確認しました。

私のコードは、古いバージョンの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から可変フィールドをインポートするのに問題があるBabelを使用している可能性が非常に高いです。

これを参照してください: https

次のようにd3をインポートする方法を変更する必要があります。

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

そして、 d3.eventすべての出現をcurrentEvent置き換えます。

これにより、d3.jsv3の問題が修正されます。

全てのコメント3件

参照するコードは一般的なd3javascriptのようであり、イベントはReactのイベントシステムを通過しません。 これは、Reactとは関係のないd3の質問のように見えます。 このため、この問題を解決します。

別の注意点として、IDで選択するのではなく、 refを使用してDOMノードを参照する必要があります。 d3.select("#viewport")ようなものを使用すると、同じIDを選択する他のコンポーネントとの相互運用性の問題が発生し、コンポーネントが同じページで複数回使用されるのを防ぐことができます。 refを使用すると、これらの問題が解決します。

この問題を抱えている他の人はきっとここで終わるでしょう、それでここに私のために働いたアプローチがあります:

  1. (クロム)デバッガーのソースペインを開きます
  2. 問題の原因となっているイベントのイベントリスナーブレークポイントを設定します
  3. 問題を再現する
  4. 実行はデバッグに割り込む必要があります。 d3(特に、d3_selection_onListener(listener、argumentz))に入るまで前に進みます。
  5. コンソールに入り、d3オブジェクトへのグローバル参照を保存します。

> window.theD3versionHostingTheEvent = d3;

  1. listener.apply(this, argumentz);まで前に進み、エラーをスローする場所に到達するまで[次の関数呼び出しにステップイン]を選択します。
  2. もう一度コンソールに侵入し、次の手順を実行します: window.theD3versionHostingTheEvent == d3

結果がfalse場合、間違いなくd3の2つのインスタンスを実行しています。 私の場合、使用していたライブラリの1つにd3がバンドルされていることがわかりました。

インポート/エクスポート構文を使用してd3から可変フィールドをインポートするのに問題があるBabelを使用している可能性が非常に高いです。

これを参照してください: https

次のようにd3をインポートする方法を変更する必要があります。

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

そして、 d3.eventすべての出現をcurrentEvent置き換えます。

これにより、d3.jsv3の問題が修正されます。

このページは役に立ちましたか?
0 / 5 - 0 評価