node-red / flow-library

Node-RED Flow Library
Apache License 2.0
70 stars 44 forks source link

Flow Viewer on Flow Inspector Page #99

Closed joepavitt closed 9 months ago

joepavitt commented 9 months ago

Closes https://github.com/node-red/flow-library/issues/2

Utilises a local variation of https://github.com/gorenje/node-red-flowviewer-js in order to render the flow.json. Added extra functionality to switch between tabs & subflows.

Example: Flow with Group & Subflow

Screenshot 2023-09-16 at 16 52 38

Example: Viewing the Subflow

Screenshot 2023-09-16 at 16 52 30

TODO:

linux-foundation-easycla[bot] commented 9 months ago

CLA Signed

The committers listed above are authorized under a signed CLA.

joepavitt commented 9 months ago

Just tried a few more nodes:

Work:

Not Working (currently):

Screenshot 2023-09-17 at 11 03 45
joepavitt commented 9 months ago
Screenshot 2023-09-17 at 11 17 33
joepavitt commented 9 months ago

Also just fixed the port positioning for "Link" nodes:

Screenshot 2023-09-17 at 11 25 32
joepavitt commented 9 months ago

@knolleary the only outstanding item left here is pan/zoom. It was recommended to just use d3 for this, but thought I'd check with you before I build, as that's a heavy inclusion for the page, just for pan/zoom. I'm happy to try and implement manually if you'd prefer.

gorenje commented 9 months ago

On the pan/zoom thing, I finally got something working that seems to work on all devices:

       var svg = $("#flowdatacontainer .svg-container-noderedjson svg");

        svg.attr('width','');
        svg.attr('height','');
        svg.css('width', $('#flowdatacontainer').width() + "px");
        svg.css('height', $('#flowdatacontainer').height() + "px");
        var bbx = $("#flowdatacontainer .svg-container-noderedjson svg .containerGroup")[0].getBBox();
        svg.attr('viewBox', bbx.x + " " + bbx.y + " " + (bbx.width * 1.1) + " " + (bbx.height * 1.1) )

        var svg = d3.select("#flowdatacontainer .svg-container-noderedjson svg");

        svg.html("<g>" + svg.html() + "</g>");
        var inner = svg.select("g");

        window.__flowZoom = d3.zoom().on("zoom", function(event) {
            inner.attr("transform", event.transform);
        });

        window.__flowZoomElem = svg.call(window.__flowZoom);

My problem was that the svg had width & height that was completely wrong, I had to set width & height to match that of the container. Then I set the viewBox of the svg to the bounding box of the content. Finally I use d3 to handle the zoom. It took me a while to get it right but now it works now on mobile and desktop.

I have a semi-plan to tryout timmywil/panzoom, it seems promising...

joepavitt commented 9 months ago

Junction test:

Screenshot 2023-09-19 at 13 12 29
joepavitt commented 9 months ago

pan/zoom added (with zoom in/out, and pan left/up limits):

Screenshot 2023-09-19 at 15 17 01
knolleary commented 9 months ago

@joepavitt great! Do we think this is ready to review to push out live?

gorenje commented 9 months ago

@joepavitt can I ask how pan/zoom came to be? did you end up using d3 or something else?

joepavitt commented 9 months ago

can I ask how pan/zoom came to be? did you end up using d3 or something else?

This is the function I've added, it extends the idea you shared here. It also adds dragging CSS class for cursor control, and also places zoom/pan limits so that you don't go beyond the top-left (0,0) where there will never be flow defined anyway due to NR's own limits in place.

function addPanZoom () {
    var svgs = d3.selectAll('.flowviewer svg');
    svgs.each(function() {
        var svg = d3.select(this);

        svg.html('<g>' + svg.html() + '</g>');
        var inner = svg.select('g');
        var zoom = d3.zoom()
            .translateExtent([[0, 0], [3000, 3000]])
            .scaleExtent([0.5, 1])
            .on("start", function () {
                svg.classed("dragging", true);
            })
            .on('zoom', function(event) {
                inner.attr('transform', event.transform);
            })
            .on("end", function () {
                svg.classed("dragging", false);
            });
            svg.call(zoom);
    });
}
joepavitt commented 9 months ago

Do we think this is ready to review to push out live?

I would say yes

gorenje commented 9 months ago

can I ask how pan/zoom came to be? did you end up using d3 or something else?

This is the function I've added, it extends the idea you shared here. It also adds dragging CSS class for cursor control, and also places zoom/pan limits so that you don't go beyond the top-left (0,0) where there will never be flow defined anyway due to NR's own limits in place.

Wow, cool! :large-eye-smiley: - can I "borrow" that code ;)

joepavitt commented 9 months ago

can I "borrow" that code ;)

Of course

marcus-j-davies commented 9 months ago

I have been watching this closely... Let me introduce you to my box that belongs to Pandora

Wouldn't the examples folder also benefit massively here? This will give a true sense of connection between the Info page and the Examples that can be packaged with Nodes?

I'd guess this will require some work and isn't something that will happen soon - but possible right?

joepavitt commented 9 months ago

I'd guess this will require some work and isn't something that will happen soon - but possible right?

This is definitely a "Step 1". Our next step would be to npm-ise the JS/CSS into a node module such that the viewer is easier to port into other applications and use-cases.