Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d3.event is null in a ReactJS + d3JS component #6641

Closed
varghesep opened this issue Apr 28, 2016 · 8 comments
Closed

d3.event is null in a ReactJS + d3JS component #6641

varghesep opened this issue Apr 28, 2016 · 8 comments

Comments

@varghesep
Copy link

varghesep commented Apr 28, 2016

I'm using ReactJS, d3JS and ES6 to create an org chart. I can create the chart and see it. But I want to add the zoom and drag behavior to the chart, so I used d3.behavior.zoom. I can see the method zoomed is called, but the d3.event is null.

I tried attaching the zoom behavior to the div, svg and g but nothing helps. The zoomed behavior is called but the event is null.

In my ASP.NET project I made sure that I don't have any reference to d3.js other than in the systemJS configuration which many stackoverflow answers mentioned as the issue related to why d3.event is null.

My code is very similar to what is in an example like this https://github.com/Swizec/candidate-bucket-chart/blob/169779e110c8825f4545c71ae5845ff7bad4f1f4/src/BubbleChart.jsx which uses the old version of ReactJS.

This is my systemJS configuration:

<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;
@jimfb
Copy link
Contributor

jimfb commented Apr 28, 2016

The code you reference appears to be general d3 javascript, and the event does not pass through React's event system. This looks like a d3 question, unrelated to React. For this reason, I'm going to close out this issue.

On another note, you should use a ref to reference a DOM node, NOT selecting by ID. Using things like d3.select("#viewport") can cause interoperability issues with other components that happen to choose the same ID, and prevent a component from being used multiple times on the same page. Using a ref will solve these issues.

@lgrkvst
Copy link

lgrkvst commented Jun 29, 2016

Others with this issue will surely end up here, so here's an approach that worked for me:

  1. Open the (chrome) debugger's sources pane

  2. Set an event listener breakpoint for the event causing the issue

  3. Recreate the issue

  4. Execution should break into debug. Step forward until you're in d3 (particularly d3_selection_onListener(listener, argumentz)).

  5. Enter into console and save a global reference to the d3 object:

    > window.theD3versionHostingTheEvent = d3;

  6. Step forward until listener.apply(this, argumentz); and then choose Step into next function call until you get to the place throwing the error.

  7. Break into console again, and do: window.theD3versionHostingTheEvent == d3

If the result is false, you're definitely running two instances of d3. In my case, it turned out one of the libs I was using had d3 bundled into it.

@jbmusso
Copy link

jbmusso commented Dec 15, 2016

It's very likely that you're using Babel, which has trouble importing a mutable field from d3 using the import / export syntax.

See this: d3/d3#2733 (comment)

You'll want to change the way you import d3 with the following:

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

And replace all occurences of d3.event with currentEvent.

This fixes the issue with d3.js v3.

@hakuna0829
Copy link

Hi @jbmusso.
Your code doesn't work with d3 v5.
It occurs like this error.

Attempted import error: 'event' is not exported from 'd3' (imported as 'currentEvent').

Do you have any solution?
Thanks

@magdastone
Copy link

I am working on a bursh-able parallel coordinates graph with d3 v6 in react. I have the exact same issue: Attempted import error: 'event' is not exported from 'd3-selection' (imported as 'currentEvent').

@magdastone
Copy link

okay. 1 minute later I appear to have found an answer: like written in this article let selected = d3.brushSelection(this); should fix the problem

@KhRania
Copy link

KhRania commented Nov 17, 2021

Hello i faced the same problem after using

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

I'm working with react v16 and d3 v7 and i'm using

const me = d3.select(this);

Any help please ?

@guidoabelleira
Copy link

Hola comunidad!
Tengo el mismo problema.
Estoy trabajando con
"react 17.0.2" y "d3 7.2.0"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants