Skip to content

Do we have provision to implement minimap ? #511

Open
@ajaiswal595

Description

@ajaiswal595

I want to achieve minimap functionality how can I achieve in react-d3-tree?

import React, { useRef, useState } from 'react';
import { Box } from '@mui/material';
import { Tree } from 'react-d3-tree';
import { data } from './data/TransactionForD3Tree';

const rawData = [data];



const groupByType = (node) => {
  if (!node.children || node.children.length === 0) {
    return node;
  }

  const groupedChildren = node.children.reduce((acc, child) => {
    if (!acc[child.type]) {
      acc[child.type] = { name: child.type, type: child.type, children: [] };
    }
    acc[child.type].children.push(groupByType(child));
    return acc;
  }, {});

  return {
    ...node,
    children: Object.values(groupedChildren)
  };
};

const CustomNode = ({ nodeDatum, toggleNode }) => {
  const isGroup = nodeDatum.children && nodeDatum.children.some(child => child.type === nodeDatum.name);
  return (
    <g>
      <rect width="100" height="50" x="-50" y="-25" fill={isGroup ? "lightcoral" : "lightblue"} stroke="black" />
      <text fill="black" x="-45" y="5" onClick={toggleNode}>
        {nodeDatum.name}
      </text>
      {nodeDatum.children && (
        <text fill="blue" x="-45" y="20" onClick={toggleNode}>
          {`Children: ${nodeDatum.children.length}`}
        </text>
      )}
    </g>
  );
};

const MyTreeComponent = () => {
  const treeData = groupByType(rawData[0]);
  const boxRef = useRef(null);
  const miniMapRef = useRef(null);
  const [zoom, setZoom] = useState(1);
  const [dragPosition, setDragPosition] = useState({ x: 0, y: 0 });
  const [isDragging, setIsDragging] = useState(false);

  const handleMouseDown = (e) => {
    e.preventDefault();
    setIsDragging(true);
  };

  const handleMouseMove = (e) => {
    if (!isDragging) return;

    const miniMap = miniMapRef.current;
    const { left, top, width, height } = miniMap.getBoundingClientRect();

    const newX = Math.min(Math.max(e.clientX - left, 0), width - 20);
    const newY = Math.min(Math.max(e.clientY - top, 0), height - 20);

    setDragPosition({ x: newX, y: newY });

    if (boxRef.current) {
      const scrollableWidth = boxRef.current.scrollWidth - boxRef.current.clientWidth;
      const scrollableHeight = boxRef.current.scrollHeight - boxRef.current.clientHeight;

      boxRef.current.scrollLeft = (newX / (width - 20)) * scrollableWidth;
      setZoom(newX*0.1);
      boxRef.current.scrollTop = (newY / (height - 20)) * scrollableHeight;
    }
  };

  const handleMouseUp = () => {
    setIsDragging(false);
  };

  return (
    <div
      id="treeWrapper"
      style={{ width: '100%', height: '500px', position: 'relative' }}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseUp}
      onMouseLeave={handleMouseUp}
    >
      <Box
        ref={boxRef}
        sx={{
          width: '100%',
          height: '500px',
          overflow: 'auto',
          border: '1px solid black',
          position: 'relative',
          backgroundColor: 'lightgray',
        }}
      >
        <Tree
          data={treeData1}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
       
       <Tree
          data={treeData2}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData3}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData4}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData5}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData6}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData7}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData8}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData9}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />
        <Tree
          data={treeData10}
          renderCustomNodeElement={(rd3tProps) => <CustomNode {...rd3tProps} />}
          orientation="horizontal"
          zoom={zoom}
        />

        
      </Box>
      <div
        ref={miniMapRef}
        className="mini-map"
        style={{
          position: 'absolute',
          bottom: 20,
          right: 20,
          border: '1px solid black',
          backgroundColor: 'white',
          width: 100,
          height: 100,
          overflow: 'hidden',
        }}
      >
        <div
          style={{
            position: 'absolute',
            width: 20,
            height: 20,
            backgroundColor: 'rgba(0,0,0,0.5)',
            cursor: 'pointer',
            left: `${dragPosition.x}px`,
            top: `${dragPosition.y}px`,
          }}
          onMouseDown={handleMouseDown}
        />
      </div>
    </div>
  );
};

export default MyTreeComponent;

minimap

And I want to achieve something similar to this

https://jerosoler.github.io/drawflow-minimap-example/
or
https://codesandbox.io/p/sandbox/react-flow-interactive-minimap-26u9lj?file=%2Fsrc%2Fcomponents%2FMiniMap%2FMiniMapNode.tsx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions