Π― ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ReactJS, d3JS ΠΈ ES6 Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΠΎΡΠ³Π°Π½ΠΈΠ·Π°ΡΠΈΠΎΠ½Π½ΠΎΠΉ Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΡ. Π― ΠΌΠΎΠ³Ρ ΡΠΎΠ·Π΄Π°ΡΡ Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΡ ΠΈ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π΅Π΅. ΠΠΎ Ρ Ρ ΠΎΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΊ Π΄ΠΈΠ°Π³ΡΠ°ΠΌΠΌΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΠΏΠ΅ΡΠ΅ΡΠ°ΡΠΊΠΈΠ²Π°Π½ΠΈΡ, ΠΏΠΎΡΡΠΎΠΌΡ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π» d3.behavior.zoom . Π― ΠΌΠΎΠ³Ρ Π²ΠΈΠ΄Π΅ΡΡ , ΠΌΠ΅ΡΠΎΠ΄ Π£Π²Π΅Π»ΠΈΡΠ΅Π½Π½ΡΠΉ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ, Π½ΠΎ d3.event ΡΠ°Π²Π½ΠΎ Π½ΡΠ»Ρ.
Π― ΠΏΠΎΠΏΡΡΠ°Π»ΡΡ ΠΏΡΠΈΠ²ΡΠ·Π°ΡΡ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΊ div, svg ΠΈ g, Π½ΠΎ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΏΠΎΠΌΠΎΠ³Π°Π΅Ρ. ΠΡΠ·ΡΠ²Π°Π΅ΡΡΡ ΡΠ²Π΅Π»ΠΈΡΠ΅Π½Π½ΠΎΠ΅ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅, Π½ΠΎ ΡΠΎΠ±ΡΡΠΈΠ΅ ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ NULL.
Π ΠΌΠΎΠ΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠ΅ ASP.NET Ρ ΡΠ±Π΅Π΄ΠΈΠ»ΡΡ, ΡΡΠΎ Ρ ΠΌΠ΅Π½Ρ Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ ΡΡΡΠ»ΠΎΠΊ Π½Π° d3.js, ΠΊΡΠΎΠΌΠ΅ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ systemJS, ΠΊΠΎΡΠΎΡΠ°Ρ Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ ΠΎΡΠ²Π΅ΡΠ°Ρ stackoverflow ΡΠΏΠΎΠΌΠΈΠ½Π°Π΅ΡΡΡ ΠΊΠ°ΠΊ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°, ΡΠ²ΡΠ·Π°Π½Π½Π°Ρ Ρ ΡΠ΅ΠΌ, ΠΏΠΎΡΠ΅ΠΌΡ d3.event ΠΈΠΌΠ΅Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ null.
ΠΠΎΠΉ ΠΊΠΎΠ΄ ΠΎΡΠ΅Π½Ρ ΠΏΠΎΡ ΠΎΠΆ Π½Π° ΠΏΡΠΈΠΌΠ΅Ρ, ΠΏΠΎΠ΄ΠΎΠ±Π½ΡΠΉ ΡΡΠΎΠΌΡ https://github.com/Swizec/candidate-bucket-chart/blob/169779e110c8825f4545c71ae5845ff7bad4f1f4/src/BubbleChart.jsx, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ ΡΡΠ°ΡΡΡ Π²Π΅ΡΡΠΈΡ ReactJS.
ΠΡΠΎ ΠΌΠΎΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ 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;
ΠΠΎΠ΄, Π½Π° ΠΊΠΎΡΠΎΡΡΠΉ Π²Ρ ΡΡΡΠ»Π°Π΅ΡΠ΅ΡΡ, ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΎΠ±ΡΠΈΠΌ javascript d3, ΠΈ ΡΠΎΠ±ΡΡΠΈΠ΅ Π½Π΅ ΠΏΡΠΎΡ ΠΎΠ΄ΠΈΡ ΡΠ΅ΡΠ΅Π· ΡΠΈΡΡΠ΅ΠΌΡ ΡΠΎΠ±ΡΡΠΈΠΉ React. ΠΡΠΎ ΠΏΠΎΡ ΠΎΠΆΠ΅ Π½Π° Π²ΠΎΠΏΡΠΎΡ d3, Π½Π΅ ΡΠ²ΡΠ·Π°Π½Π½ΡΠΉ Ρ React. ΠΠΎ ΡΡΠΎΠΉ ΠΏΡΠΈΡΠΈΠ½Π΅ Ρ Π·Π°ΠΊΡΡΠ²Π°Ρ ΡΡΠΎΡ Π²ΠΎΠΏΡΠΎΡ.
Π‘ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½Ρ, Π²Ρ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ref
Π΄Π»Ρ ΡΡΡΠ»ΠΊΠΈ Π½Π° ΡΠ·Π΅Π» DOM, ΠΠ Π²ΡΠ±ΠΈΡΠ°Ρ ΠΏΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ°ΠΊΠΈΡ
Π²Π΅ΡΠ΅ΠΉ, ΠΊΠ°ΠΊ d3.select("#viewport")
ΠΌΠΎΠΆΠ΅Ρ Π²ΡΠ·Π²Π°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΠΈ Ρ Π΄ΡΡΠ³ΠΈΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π²ΡΠ±ΠΈΡΠ°ΡΡ ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ, ΠΈ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ ΠΌΠ½ΠΎΠ³ΠΎΠΊΡΠ°ΡΠ½ΠΎΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ° Π½Π° ΠΎΠ΄Π½ΠΎΠΉ ΠΈ ΡΠΎΠΉ ΠΆΠ΅ ΡΡΡΠ°Π½ΠΈΡΠ΅. ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ref
ΡΠ΅ΡΠΈΡ ΡΡΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ.
ΠΡΡΠ³ΠΈΠ΅, Ρ ΠΊΠΎΠ³ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΡΡΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°, Π½Π°Π²Π΅ΡΠ½ΡΠΊΠ° ΠΎΠΊΠ°ΠΆΡΡΡΡ Π·Π΄Π΅ΡΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π²ΠΎΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄, ΠΊΠΎΡΠΎΡΡΠΉ ΡΡΠ°Π±ΠΎΡΠ°Π» Π΄Π»Ρ ΠΌΠ΅Π½Ρ:
> window.theD3versionHostingTheEvent = d3;
listener.apply(this, argumentz);
Π° Π·Π°ΡΠ΅ΠΌ Π²ΡΠ±Π΅ΡΠΈΡΠ΅ Β« ΠΠ΅ΡΠ΅ΠΉΡΠΈ ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ Π²ΡΠ·ΠΎΠ²Ρ ΡΡΠ½ΠΊΡΠΈΠΈΒ», ΠΏΠΎΠΊΠ° Π½Π΅ Π΄ΠΎΠ±Π΅ΡΠ΅ΡΠ΅ΡΡ Π΄ΠΎ ΠΌΠ΅ΡΡΠ°, window.theD3versionHostingTheEvent == d3
ΠΡΠ»ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ false
, Π²Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ Π΄Π²Π° ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° d3. Π ΠΌΠΎΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΎΠΊΠ°Π·Π°Π»ΠΎΡΡ, ΡΡΠΎ Π² ΠΎΠ΄Π½Ρ ΠΈΠ· Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ, ΠΊΠΎΡΠΎΡΡΠ΅ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π», Π±ΡΠ» Π²ΡΡΡΠΎΠ΅Π½ d3.
ΠΡΠ΅Π½Ρ Π²Π΅ΡΠΎΡΡΠ½ΠΎ, ΡΡΠΎ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ Babel, Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ ΠΈΠΌΠΏΠΎΡΡΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ ΠΈΠ· d3 Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° ΠΈΠΌΠΏΠΎΡΡΠ° / ΡΠΊΡΠΏΠΎΡΡΠ°.
Π‘ΠΌΠΎΡΡΠΈΡΠ΅ ΡΡΠΎ: https://github.com/d3/d3/issues/2733#issuecomment -190743489
ΠΡ Π·Π°Ρ ΠΎΡΠΈΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΠΏΠΎΡΠΎΠ± ΠΈΠΌΠΏΠΎΡΡΠ° d3 ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
import * as d3 from 'd3';
import {event as currentEvent} from 'd3';
Π Π·Π°ΠΌΠ΅Π½ΠΈΡΠ΅ Π²ΡΠ΅ Π²Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΡ d3.event
Π½Π° currentEvent
.
ΠΡΠΎ ΡΡΡΡΠ°Π½ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ d3.js v3.
Π‘Π°ΠΌΡΠΉ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠΉ
ΠΡΠ΅Π½Ρ Π²Π΅ΡΠΎΡΡΠ½ΠΎ, ΡΡΠΎ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ Babel, Ρ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ ΠΈΠΌΠΏΠΎΡΡΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΏΠΎΠ»Ρ ΠΈΠ· d3 Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ° ΠΈΠΌΠΏΠΎΡΡΠ° / ΡΠΊΡΠΏΠΎΡΡΠ°.
Π‘ΠΌΠΎΡΡΠΈΡΠ΅ ΡΡΠΎ: https://github.com/d3/d3/issues/2733#issuecomment -190743489
ΠΡ Π·Π°Ρ ΠΎΡΠΈΡΠ΅ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΠΏΠΎΡΠΎΠ± ΠΈΠΌΠΏΠΎΡΡΠ° d3 ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
Π Π·Π°ΠΌΠ΅Π½ΠΈΡΠ΅ Π²ΡΠ΅ Π²Ρ ΠΎΠΆΠ΄Π΅Π½ΠΈΡ
d3.event
Π½Π°currentEvent
.ΠΡΠΎ ΡΡΡΡΠ°Π½ΡΠ΅Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Ρ d3.js v3.