Skip to content
Snippets Groups Projects

feat: use floating ui for node link tooltips

Merged Dennis Collaris requested to merge feat/nodelink-tooltips into main
1 file
+ 20
25
Compare changes
  • Side-by-side
  • Inline
@@ -23,7 +23,7 @@ import { Viewport } from 'pixi-viewport';
import { NodelinkVisProps } from '../nodelinkvis';
import { Tooltip, TooltipContent, TooltipTrigger } from '@graphpolaris/shared/lib/components/tooltip';
import { MovedEvent } from 'pixi-viewport/dist/types';
import { ConstructionOutlined } from '@mui/icons-material';
type Props = {
onClick: (event?: { node: NodeTypeD3; pos: IPointData }) => void;
@@ -123,25 +123,23 @@ export const NLPixi = (props: Props) => {
const imperative = useRef<any>(null);
const mouseClickThreshold = 200; // Time between mouse up and down events that is considered a click, and not a drag.
const mouseClickThreshold = 200; // Time between mouse up and down events that is considered a click, and not a drag.
useImperativeHandle(imperative, () => ({
onMouseDown(event: FederatedPointerEvent) {
(event as any).mouseDownTimeStamp = event.timeStamp;
},
onMouseUpNode(event: FederatedPointerEvent) {
// If its a short click (not a drag) on the stage but not on a node: clear the selection and remove all popups.
const holdDownTime = event.timeStamp - (event as any).mouseDownTimeStamp;
if(holdDownTime > mouseClickThreshold) {
if (holdDownTime > mouseClickThreshold) {
return;
}
const sprite = event.target as Sprite;
const node = (sprite as any).node as NodeType;
if (event.shiftKey) {
setPopups([...popups, { node: node, pos: toGlobal(node) }]);
} else {
@@ -162,7 +160,7 @@ export const NLPixi = (props: Props) => {
onMouseUpStage(event: FederatedPointerEvent) {
// If its a short click (not a drag) on the stage but not on a node: clear the selection and remove all popups.
const holdDownTime = event.timeStamp - (event as any).mouseDownTimeStamp;
if(holdDownTime < mouseClickThreshold) {
if (holdDownTime < mouseClickThreshold) {
for (const popup of popups) {
const sprite = nodeMap.current.get(popup.node._id) as Sprite;
sprite.texture = Assets.get(textureId(false));
@@ -191,11 +189,11 @@ export const NLPixi = (props: Props) => {
onMoved(event: MovedEvent) {
for (const popup of popups) {
if (popup.node.x == null || popup.node.y == null) continue;
popup.pos.x = event.viewport.transform.position.x + (popup.node.x * event.viewport.scale.x);
popup.pos.y = event.viewport.transform.position.y + (popup.node.y * event.viewport.scale.y);
popup.pos.x = event.viewport.transform.position.x + popup.node.x * event.viewport.scale.x;
popup.pos.y = event.viewport.transform.position.y + popup.node.y * event.viewport.scale.y;
}
setPopups([...popups]);
}
},
}));
function resize() {
@@ -288,7 +286,7 @@ export const NLPixi = (props: Props) => {
const scale = (Math.max(nodeMeta.radius || 5, 5) / 70) * 2;
sprite.scale.set(scale, scale);
sprite.anchor.set(0.5, 0.5);
sprite.eventMode = 'static';
sprite.on('mousedown', (e) => imperative.current.onMouseDown(e));
sprite.on('mouseup', (e) => imperative.current.onMouseUpNode(e));
@@ -579,8 +577,8 @@ export const NLPixi = (props: Props) => {
viewport.current.addChild(linkGfx);
viewport.current.addChild(nodeLayer);
viewport.current.on('moved', (event) => {
imperative.current.onMoved(event)
})
imperative.current.onMoved(event);
});
app.stage.eventMode = 'dynamic';
app.stage.on('mousedown', (e) => imperative.current.onMouseDown(e));
@@ -615,20 +613,17 @@ export const NLPixi = (props: Props) => {
}
layoutAlgorithm.current.layout(graphologyGraph, boundingBox);
};
return (
<>
<Tooltip open={popups.length > 0} boundaryElement={ref} showArrow={true}>
<TooltipTrigger x={popups[0]?.pos.x} y={popups[0]?.pos.y} />
<TooltipContent>
{popups[0] != null && <NLPopup onClose={() => {}} data={popups[0]} key={popups[0].node._id} />}
</TooltipContent>
</Tooltip>
<Tooltip open={popups.length > 1} boundaryElement={ref} showArrow={true}>
<TooltipTrigger x={popups[1]?.pos.x} y={popups[1]?.pos.y} />
<TooltipContent>
{popups[1] != null && <NLPopup onClose={() => {}} data={popups[1]} key={popups[1].node._id} />}
</TooltipContent>
</Tooltip>
{popups.map((popup, index) => (
<Tooltip key={popup.node._id} open={true} boundaryElement={ref} showArrow={true}>
<TooltipTrigger x={popup.pos.x} y={popup.pos.y} />
<TooltipContent>
<NLPopup onClose={() => {}} data={popup} key={popup.node._id} />
</TooltipContent>
</Tooltip>
))}
<div
className="h-full w-full overflow-hidden"
ref={ref}
Loading