React: d3.event ist null in einer ReactJS + d3JS-Komponente

Erstellt am 28. Apr. 2016  ·  3Kommentare  ·  Quelle: facebook/react

Ich verwende ReactJS, d3JS und ES6 , um ein Organigramm zu erstellen. Ich kann das Diagramm erstellen und sehen. Aber ich möchte dem Diagramm das Zoom- und Ziehverhalten hinzufügen, also habe ich gezoomt genannt wird, aber die d3.event ist null.

Ich habe versucht, das Zoomverhalten an div, svg und g anzuhängen, aber nichts hilft. Das gezoomte Verhalten wird aufgerufen, aber das Ereignis ist null.

In meinem ASP.NET-Projekt habe ich sichergestellt, dass ich keinen Verweis auf d3.js habe, außer in der systemJS-Konfiguration, die in vielen Stackoverflow-Antworten als das Problem erwähnt wird, warum d3.event null ist.

Mein Code ist dem in einem Beispiel wie diesem sehr ähnlich https://github.com/Swizec/candidate-bucket-chart/blob/169779e110c8825f4545c71ae5845ff7bad4f1f4/src/BubbleChart.jsx , das die alte Version von ReactJS verwendet.

Dies ist meine systemJS-Konfiguration:

<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;

Hilfreichster Kommentar

Es ist sehr wahrscheinlich, dass Sie Babel verwenden, das Probleme beim Importieren eines veränderlichen Felds aus d3 mit der Import-/Export-Syntax hat.

Siehe dies: https://github.com/d3/d3/issues/2733#issuecomment -190743489

Sie sollten die Art und Weise, wie Sie d3 importieren, folgendermaßen ändern:

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

Und ersetze alle Vorkommen von d3.event durch currentEvent .

Dies behebt das Problem mit d3.js v3.

Alle 3 Kommentare

Der Code, auf den Sie verweisen, scheint allgemeines d3-Javascript zu sein, und das Ereignis passiert nicht das Ereignissystem von React. Dies sieht aus wie eine d3-Frage, die nichts mit React zu tun hat. Aus diesem Grund schließe ich dieses Thema ab.

Außerdem sollten Sie ref um auf einen DOM-Knoten zu verweisen, und NICHT nach ID auswählen. Die Verwendung von Dingen wie d3.select("#viewport") kann zu Interoperabilitätsproblemen mit anderen Komponenten führen, die zufällig dieselbe ID wählen, und verhindern, dass eine Komponente mehrmals auf derselben Seite verwendet wird. Die Verwendung eines ref löst diese Probleme.

Andere mit diesem Problem werden sicherlich hier landen, also hier ist ein Ansatz, der für mich funktioniert hat:

  1. Öffnen Sie den Quellenbereich des (Chrom-)Debuggers
  2. Legen Sie einen Ereignis-Listener-Haltepunkt für das Ereignis fest, das das Problem verursacht.
  3. Problem neu erstellen
  4. Die Ausführung sollte in Debug einbrechen. Gehen Sie vorwärts, bis Sie in d3 sind (insbesondere d3_selection_onListener(listener, argumentz)).
  5. Geben Sie in die Konsole ein und speichern Sie eine globale Referenz auf das d3-Objekt:

> window.theD3versionHostingTheEvent = d3;

  1. Gehen Sie vorwärts bis listener.apply(this, argumentz); und wählen Sie dann Schritt in den nächsten Funktionsaufruf, bis Sie zu der Stelle gelangen, an der der Fehler ausgegeben wird.
  2. Brechen Sie erneut in die Konsole ein und führen Sie Folgendes aus: window.theD3versionHostingTheEvent == d3

Wenn das Ergebnis false lautet, führen Sie definitiv zwei Instanzen von d3 aus. In meinem Fall stellte sich heraus, dass eine der Libs, die ich benutzte, d3 gebündelt hatte.

Es ist sehr wahrscheinlich, dass Sie Babel verwenden, das Probleme beim Importieren eines veränderlichen Felds aus d3 mit der Import-/Export-Syntax hat.

Siehe dies: https://github.com/d3/d3/issues/2733#issuecomment -190743489

Sie sollten die Art und Weise, wie Sie d3 importieren, folgendermaßen ändern:

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

Und ersetze alle Vorkommen von d3.event durch currentEvent .

Dies behebt das Problem mit d3.js v3.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

Prinzhorn picture Prinzhorn  ·  3Kommentare

jvorcak picture jvorcak  ·  3Kommentare

trusktr picture trusktr  ·  3Kommentare

huxiaoqi567 picture huxiaoqi567  ·  3Kommentare

zpao picture zpao  ·  3Kommentare