excubo-ag / Blazor.Diagrams

https://excubo-ag.github.io/Blazor.Diagrams/
MIT License
136 stars 18 forks source link

Callback after graph is rendered? #89

Open destrugter opened 2 years ago

destrugter commented 2 years ago

I may be missing something, but it would be awesome if I could create a callback after a graph is rendered. I'm attempting to provide a screenshot to the user after calling ZoomToFit, but the ZoomToFit function returns before the graph has been re-rendered, so the screenshot is of the graph's previous state.

stefanloerwald commented 2 years ago

Hi @destrugter,

I see how that would be useful, but am not sure whether it's going to be easy to implement. It might be as easy as providing a callback/event in OnAfterRenderAsync of the Diagram component, but I don't know for sure. Could you experiment with this and let me know?

Out of curiosity: how are you taking screenshots?

BR Stefan

destrugter commented 2 years ago

Currently the way I'm doing it is calling ZoomToFit, awaiting a 1s Task, then using html2canvas to convert the element to a canvas, and then converting it to a blob, and finally converting that blob to a png and copying it to the clipboard.

Clive321A commented 1 year ago

@destrugter id love to see how you have implemented this, so you are able to render a diagram to a PNG?

destrugter commented 1 year ago

@CliveBennett I used this JS called html2canvas. It works pretty well. The command I have after you have downloaded html2canvas is await html2canvas(document.querySelector("#" + id)).then(canvas => canvas.toBlob(blob => navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })])));

Clive321A commented 1 year ago

Awesome, appreciate that ill give it a go.

Clive321A commented 1 year ago

I managed to get the copying of the diagram to a PNG working, thanks for the pointer.

But, because some of the diagrams that get generated can be quite large, I really need to have a dynamic sized image, so I can have a large image for the large ones, and a small image for the small ones.

Is there a property for the diagram class that would give me the max rendered width and height in pixels?, even if cropped on screen?

destrugter commented 1 year ago

@CliveBennett The code I was using was this:

private async Task GetDiagramScreenshot()
{
    diagram.ZoomToFit();
    await Task.Delay(1000);
    image_url = await TakeScreenshot();
}

I am using the await Task.Delay(1000) because I am unsure of when ZoomToFit is finished working, which is why I opened this issue in the first place. If I'm understanding you correctly, this should get you what you're after?

Clive321A commented 1 year ago

@destrugter the issue is that a lot of our diagrams can render off screen as they are quite large, I use the little viewport control to enable people to scroll around the diagram.

This is an example of what they can look like

image

But I needed to grab the entire diagram in one hit onto a single image.

What I ended up doing was to change the containing div to 5000x5000 pix with JS prior to running Html2Canvas which then generates a large image with the diagram at the top, then I wrote some code to Crop the image to a sensible size by scanning the pixels for whitespace. Works well (so far!) thanks again for the help