force-graph icon indicating copy to clipboard operation
force-graph copied to clipboard

draw {rectangle, circle, line etc} with mouse in force-graph

Open NoviceInWeb opened this issue 2 years ago • 6 comments

hi @vasturiano It's working fine, but something wrong with me. I have some question today.

  1. Is it possible to draw a rectangle, circle etc. on a 'Images as nodes'? (https://vasturiano.github.io/force-graph/example/img-nodes/)
  2. I drew a rectangle with mouse on the basic symbol force graph, but it keeps drawing in a different place than the mouse coordinates. -> How can I draw it with the correct coordinates? (I want the drawn figure to have the same size and position as a normal node.)

canvas = document.getElementsByClassName('force-graph-container')[0]

onMousedown = (event) => {
    last_mousex = parseInt(event.clientX - canvas.getBoundingClientRect().left);
    last_mousey = parseInt(event.clientY - canvas.getBoundingClientRect().top);

    let rect = canvas.getBoundingClientRect();
    let x = event.clientX - rect.left;
    let y = event.clientY - rect.top;

    isMouseDown = true;
}

onMouseMove = (event) => {
    if(isMouseDown){
        mousex = parseInt(event.clientX - canvas.getBoundingClientRect().left);
        mousey = parseInt(event.clientY - canvas.getBoundingClientRect().top);
      }
}

onMouseUp = (event) => {
    isMouseDown = false;

    let rect = canvas.getBoundingClientRect();
    let x = event.clientX - rect.left;
    let y = event.clientY - rect.top;

    let Object = {
        layrId: "layr",
        type: "figure",
        pos: {
          x1 : last_mousex,
          y1 : last_mousey,
          x2 : x,
          y2 : y,
        }
      };

    Array.push(Object);
    this.reDraw(Array);
}

reDraw = (Array) => {

    myGraph
        .nodeCanvasObject((node, ctx) => {
            ctx.strokeStyle = '#00ff00';
            ctx.beginPath();
            Array.forEach(element => {
                ctx.strokeRect(element.pos.x1, element.pos.y1, element.pos.x2 - element.pos.x1, element.pos.y2);
            })

            ctx.fill();
            ctx.lineWidth = 5;
        })
}

Sorry for being long and incomplete code. thank you...

NoviceInWeb avatar Jun 26 '22 14:06 NoviceInWeb

@NoviceInWeb you'd need to translate between the two coordinate domains screen<->graph. They are not equivalent due to zooming levels, panning, etc.

Please look at the utility methods that allow you to do this: screen2GraphCoords and graph2ScreenCoords.

vasturiano avatar Jun 26 '22 14:06 vasturiano

@vasturiano Thank you😎 screen2GraphCoords works well.

NoviceInWeb avatar Jun 28 '22 01:06 NoviceInWeb

@vasturiano hello master

I have one more question.

Objects (images, rectangle, circles) are well drawn. -> It is not added to data like a normal node, it is just drawn through ctx at .nodeCanvasObject()

I want to rotate, move, resize, etc. drawn objects. I tried to select objects, but it didn't work. (I couldn't find the object when I clicked it)

Do I have to use the library related to canvas? If so, can it be used simultaneously with force-graph?

Or is it possible to operate only with force-graph?

Thank you so much always.

NoviceInWeb avatar Jul 08 '22 02:07 NoviceInWeb

Hi @NoviceInWeb, it's not clear the issue you're having, could you elaborate? It's also helpful if you can create a simple example on https://codepen.io/.

vasturiano avatar Jul 08 '22 12:07 vasturiano

Hi @NoviceInWeb, it's not clear the issue you're having, could you elaborate? It's also helpful if you can create a simple example on https://codepen.io/.

@vasturiano I'm sorry. I'll Ask you a question again.

when I clicked 'android character',(In my example link's Green Monster) I want get 'android character's all Info like position, size, name etc. because I want to do rotate, move, resize, etc. drawn objects. but, I don't know how to get android character's Info at click event.

this is part of the code.(example link) https://codesandbox.io/s/force-graph-svg-images-forked-022y50?file=/index.js

I want to know how to get object Info at click. thank you...!🤷‍♂️

NoviceInWeb avatar Jul 11 '22 04:07 NoviceInWeb

Thanks for clarifying, I think I see what you mean.

The first thing worth mentioning is that it seems you are drawing the Android image multiple times per frame, once per every node actually. Since this is a single item unrelated to the nodes, I would suggest to move this external drawing to the onRenderFramePre or onRenderFramePost functions. That will make sure you're only drawing once per frame.

To get interaction on these external items, I believe you can only do it using the onBackgroundClick method. This method will give you access to bothe pointerUp and pointerDown events, which you can use to verify if the drawing you wish is directly under the pointer, possibly using some coordinate intersection logic.

vasturiano avatar Jul 11 '22 15:07 vasturiano