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

Mouse hover event handler missing! #365

Closed
dreambold opened this issue Mar 1, 2024 · 12 comments
Closed

Mouse hover event handler missing! #365

dreambold opened this issue Mar 1, 2024 · 12 comments

Comments

@dreambold
Copy link

Am using this package to draw an org, it works fine, but just one thing is missing, tooltip on hover

I think many others want this, I have checked some issues in the repository and @bumbeishvili said to use the onNodeUpdate event, but it doesn't even exist in the package source, I checked.

The only thing is there, onNodeClick, which works fine.

Is there a quick solution to capture the mouseover event???

Any help would be greatly appreciated, thank you!


@dreambold
Copy link
Author

        .onNodeClick((d)=>{console.log(d.data.name)})
        .nodeUpdate((d)=>{console.log(d.data.name)})
        .nodeEnter((d)=>{console.log(d.data.name)})

I tried these methods, which are working fine,

@dreambold
Copy link
Author

@bumbeishvili Do you have any updates on this?

@bumbeishvili
Copy link
Owner

bumbeishvili commented Mar 14, 2024

@dreambold it's nodeUpdate , not onNodeUpdate , it's up to you to add that event inside nodeUpdate and handle the tooltip setup

chart.nodeUpdate(function(d){
   const currentlyHoveredElement = this;

  /* 
     You can then use the tip lib of your choice. 
     For tippy, it would be something like tippy(this,{ additionalArguments})
  */
})

@dreambold
Copy link
Author

I already tried it, which doesn't seem to work for me

        .onNodeClick((d)=>{console.log(d.data.name)})
        .nodeUpdate((d)=>{console.log(d.data.name)})
        .nodeEnter((d)=>{console.log(d.data.name)})

I tried these methods, which are working fine,

@bumbeishvili
Copy link
Owner

Can you link a reproduced example, where you tried nodeUpdate and it failed?

You can fork one of the examples linked in readme

@dreambold
Copy link
Author

image

Here's the screenshot of my code, which I tried to output in the console. Nothing works, unfortunately

Thank you for your input here, @bumbeishvili

@dreambold
Copy link
Author

Am adding the full code below:

import "./App.css";
import ReactDOMServer from "react-dom/server";
import { useLayoutEffect, useRef, useState } from "react";
import { OrgChart } from "d3-org-chart";
import "./Card.css";
import { dataCustom } from "./dataCustom";
import CardDetail from "./components/card/CardDetail";
import CardCenter from "./components/card/CardCenter";


function App(props) {
  const d3Container = useRef(null);
  const [cardShow, setCardShow] = useState(false);
  const [employeeId, setEmployeeId] = useState("");
  const [x, setX] = useState(0);
  const [y, setY] = useState(0);
  const handleShow = () => setCardShow(true);
  const handleClose = () => {
    setCardShow(false);
  };

  useLayoutEffect(() => {
    const toggleDetailsCard = (nodeId) => {
      handleShow();
      setEmployeeId(nodeId);
    };

    const chart = new OrgChart();
    const finalData = dataCustom.units.map((unit, index) => {
      const upperUnitId = dataCustom.units?.find(
        (item) => item.name === unit.upper_unit
      )?.id;
      return {
        ...unit,
        nodeId: unit.id,
        parentNodeId: upperUnitId || unit.upper_unit_id,
        index: index + 1,
      };
    });
    const showPopup = (target, width = 250 + 2) => {
      const child = target.children[0];
      const id = child.id;
      const cardElem = document.getElementById(id);
      const bounding = cardElem.getBoundingClientRect();
      setX(bounding.x + (bounding.width + 20));
      setY(bounding.y);
      toggleDetailsCard(id.split('-')[1]);
    }
    window.showPopup = showPopup;
    window.handleClose = handleClose;

    if (d3Container.current) {
      chart
        .container(d3Container.current)
        .data(finalData)
        .nodeHeight((d) => 85 + 25)
        .nodeWidth((d) => 250 + 2)
        .childrenMargin((d) => 50)
        .compactMarginBetween((d) => 35)
        .compactMarginPair((d) => 30)
        .neighbourMargin((a, b) => 20)
        .onZoom(() => handleClose())
        .onExpandOrCollapse(() => {
          handleClose();
        })
        .nodeContent((d) => {
          return `
          <div onmouseenter="window.showPopup(this);" onmouseleave="window.handleClose();">
            ${ReactDOMServer.renderToStaticMarkup(<CardCenter data={d.data} />)}
          </div>
          `
        })
        .nodeUpdate(function(d){
          const currentlyHoveredElement = this;
          console.log(currentlyHoveredElement);         /* 
            You can then use the tip lib of your choice. 
            For tippy, it would be something like tippy(this,{ additionalArguments})
         */
       })
        .render();
    }
    return () => {
      window.showPopup = null;
      window.handleClose = null;
    }
  }, [props, props.data]);

  return (
    <div className="App">
      <div className="org-chart" ref={d3Container}>
        {cardShow && (
          <CardDetail
            x={x}
            y={y}
            data={dataCustom.units.find(
              (employee) => employee.id === employeeId
            )}
            handleClose={handleClose}
          />
        )}
      </div>
    </div>
  );
}

export default App;

@dreambold
Copy link
Author

https://stackblitz.com/edit/js-d38vwy?file=index.html
here's the forked sample, which doesn't do anything on hover event

@bumbeishvili
Copy link
Owner

@dreambold you need to include a tippy library and then uncomment this line

It's not part of org-chart library, but entirely independent thing, it's up to you how to implement it, org chart just gives you an element reference which you will need to append the tip to

image

@dreambold
Copy link
Author

Yes, I understand it, but nothing prints in the console when I hover mouse over the elements, as you can see in the code, I used console log

@bumbeishvili
Copy link
Owner

bumbeishvili commented Mar 14, 2024

@dreambold nodeUpdate is not invoked on hover, but it's invoked when the node is being updated (content changes, node expanded or collapsed)

The only responsibility for it is to expose the node. And it's up to you to attach hover events and handlers to it like you'd do for normal HTML elements.

I've checked Stackblitz and three element is logged (like it should)
image

(don't open browser console, use their built in console)

@dreambold
Copy link
Author

I was able to attach the event listener to the nodes, awesome! Appreciate your help!

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

2 participants