anvaka / VivaGraphJS

Graph drawing library for JavaScript
Other
3.75k stars 424 forks source link

pin node in angular : accessing layout.pinNode(): controllers of nodes in controller, layout of graph in directive #110

Open gg4u opened 9 years ago

gg4u commented 9 years ago

Hello,

this is actually not an issue in vivagraph, but I need a little debriefing. I have a scaffolding in angular embedding vivagraph: I want to edit it, so that I can include pinDown.

I can't access layout object, so that to call layout.pinNode(node, true)

While I can follow up your examples in javascript well, implementing the same function in angular is, to me, convoluted (also because I am trying to edit the code :)

Conceptually, I read that event Listener should go in a directive http://stackoverflow.com/questions/12874797/how-to-register-my-own-event-listeners-in-angularjs

in my case I have a directive to render the graph, while nodes and controllers associated to nodes are in the controller: so may be it looks a good idea to extent the listener in the controller.

Despite the layout object seems in the scope, it result undefined in my "tweak". Could you please help and shed light in what I am doing wrong and clarify some confusion?

it is more an angular related question, but maybe someone who have been trying to port the examples on angular.

thank you!


I am trying to adapt the following example: ui.addEventListener('click', function () { // toggle pinned mode layout.pinNode(node, !layout.isNodePinned(node)); });


In my controller (coffeescript scaffolding):

angular.module('myApp') .controller 'GraphCtrl', (...) ->

...

        layout: (graph) -> Viva.Graph.Layout.forceDirected graph,

            #... (graph coefficients) ...

        graphics: (graph) -> Viva.Graph.View.svgGraphics()
            .node((node) ->
                ui = Viva.Graph.svg("g")
                drawNode(ui)
                node.ui = ui

                                    #############
                #PIN NODE 1
                # How do I pass layout ?
                ui.addEventListener "click", ->
                                          layout.pinNode node, not layout.isNodePinned(node)    
                                          #layout is undefined                  
                                          Viva.Graph.layout.pinNode node, not Viva.Graph.layout.isNodePinned(node)
                                          # pinNode is undefined
                    console.log(node)
                                    #############

                # Adding hover and click handlers for graph node ui
                angular.element(ui).hammer()
                    .on('click tap', -> $scope.$apply ->
                        # PIN DOWN 2
                        # how do i pass layout and bind it to the event handler ? 
                        # link : layout.pinNode node, not layout.isNodePinned(node)

                                            )
                                    #############

In my directive I also tried to apply the resize example, but still have same issue in accessing layout: layout is undefined:

app.directive('vivaGraph', function () { return { .... scope: { ... layout: '&', graphics: '&', ... } link: function (scope, element, attrs) { renderer = Viva.Graph.View.renderer(graph, { // graph parameters }); renderer.run(); //// HOW TO ACCESS LAYOUT ?? Layout get undefined graphRect = layout.getGraphRect(); /// resize graph to match scale with screensize > see examples in demo ... }

julbra commented 9 years ago

It's because you're using a function binding for layout using the '&' notation. In your controller you need to access the layout using layout() (as a function call).

Instead you could also use a normal Object binding: scope: { ... layout: '=', graphics: '=', ... }

And you code above should work.