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;
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 :
> window.theD3versionHostingTheEvent = d3;
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.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.
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 :
Et remplacez toutes les occurrences de
d3.event
parcurrentEvent
.Cela résout le problème avec d3.js v3.