React: d3.event est nul dans un composant ReactJS + d3JS

Créé le 28 avr. 2016  ·  3Commentaires  ·  Source: facebook/react

J'utilise ReactJS, d3JS et ES6 pour créer un organigramme. Je peux créer le graphique et le voir. Mais je veux ajouter le comportement de zoom et de glissement au graphique, j'ai donc utilisé d3.behavior.zoom . Je peux voir que la méthode zoomée est appelée, mais le d3.event est nul.

J'ai essayé d'attacher le comportement de zoom aux div, svg et g mais rien n'y fait. Le comportement zoomé est appelé mais l' événement est nul.

Dans mon projet ASP.NET, je me suis assuré de n'avoir aucune référence à d3.js autre que dans la configuration systemJS que de nombreuses réponses de stackoverflow ont mentionné comme le problème lié à la raison pour laquelle d3.event est null.

Mon code est très similaire à ce qui est dans un exemple comme celui-ci https://github.com/Swizec/candidate-bucket-chart/blob/169779e110c8825f4545c71ae5845ff7bad4f1f4/src/BubbleChart.jsx qui utilise l'ancienne version de ReactJS.

Voici ma configuration 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;

Commentaire le plus utile

Il est très probable que vous utilisiez Babel, qui a du mal à importer un champ mutable depuis d3 en utilisant la syntaxe import/export.

Voir ceci : https://github.com/d3/d3/issues/2733#issuecomment -190743489

Vous voudrez changer la façon dont vous importez d3 avec les éléments suivants :

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

Et remplacez toutes les occurrences de d3.event par currentEvent .

Cela résout le problème avec d3.js v3.

Tous les 3 commentaires

Le code que vous référencez semble être du javascript d3 général et l'événement ne passe pas par le système d'événements de React. Cela ressemble à une question d3, sans rapport avec React. Pour cette raison, je vais clore ce sujet.

Sur une autre note, vous devez utiliser un ref pour référencer un nœud DOM, PAS en sélectionnant par ID. L'utilisation d'éléments tels que d3.select("#viewport") peut entraîner des problèmes d'interopérabilité avec d'autres composants qui choisissent le même ID et empêcher qu'un composant soit utilisé plusieurs fois sur la même page. L'utilisation d'un ref résoudra ces problèmes.

D'autres avec ce problème finiront sûrement ici, alors voici une approche qui a fonctionné pour moi :

  1. Ouvrez le volet des sources du débogueur (chrome)
  2. Définir un point d'arrêt d'écouteur d'événement pour l'événement à l'origine du problème
  3. Recréer le problème
  4. L'exécution doit entrer dans le débogage. Avancez jusqu'à ce que vous soyez dans d3 (en particulier d3_selection_onListener(listener, argumentz)).
  5. Entrez dans la console et enregistrez une référence globale à l'objet d3 :

> window.theD3versionHostingTheEvent = d3;

  1. Avancez jusqu'à listener.apply(this, argumentz); , puis choisissez Avancer dans l'appel de fonction suivant jusqu'à ce que vous arriviez à l'endroit qui a généré l'erreur.
  2. Entrez à nouveau dans la console et faites : window.theD3versionHostingTheEvent == d3

Si le résultat est false , vous exécutez certainement deux instances de d3. Dans mon cas, il s'est avéré que d3 était intégré à l'une des bibliothèques que j'utilisais.

Il est très probable que vous utilisiez Babel, qui a du mal à importer un champ mutable depuis d3 en utilisant la syntaxe import/export.

Voir ceci : https://github.com/d3/d3/issues/2733#issuecomment -190743489

Vous voudrez changer la façon dont vous importez d3 avec les éléments suivants :

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

Et remplacez toutes les occurrences de d3.event par currentEvent .

Cela résout le problème avec d3.js v3.

Cette page vous a été utile?
0 / 5 - 0 notes