angular-visjs icon indicating copy to clipboard operation
angular-visjs copied to clipboard

network.fit() for network graph behind hidden tab

Open mg1075 opened this issue 10 years ago • 15 comments

It might help if the directive is updated to include network.fit() so that a network graph behind a hidden tab is handled better in terms of network position.

mg1075 avatar Jul 17 '15 05:07 mg1075

What do you mean by 'updated' to include this - exactly what would you propose to add?

You are of course free to call network.fit if you want already?

cdjackson avatar Jul 17 '15 11:07 cdjackson

When the following line in the visNetwork directive is called, network = new vis.Network(element[0], scope.data, scope.options); I think calling network.fit() here would be necessary because otherwise what happens when you have a network graph behind a tab (like an angular-ui tab) is that the network graph gets positioned to the upper left corner. By calling network.fit() in the directive, this problem can be avoided.

However, that looks like only part of the problem. I notice that when the window is resized, the network graph does not adjust its size/position, so I am wondering if the directive needs a listener for the window resize event as well. http://stackoverflow.com/questions/28044124/vis-graph-library-responsive-design-issue-with-twitter-bootstrap

mg1075 avatar Jul 17 '15 18:07 mg1075

I prefer to avoid putting listeners like this in directives as it enforces a certain configuration that might not be to everyones liking. Personally, I agree - I have a directive that resizes the div that contains certain elements, but I would prefer to avoid adding it to the vis directive.

cdjackson avatar Jul 17 '15 18:07 cdjackson

I have the same problem when using a network graph behind a bootstrap tab that isn't positioned correctly and that the network.fit() should be called. Is it possible to provide some sample code how this can be accomplished by creating an extra custom directive?

christophdebaene avatar Aug 10 '15 20:08 christophdebaene

Can you put a listener to call network.fit when the tab is changed?

I use the following directive to resize a bootstrap panel with a vis directive inside (just adding the element resize-panel to the panel).

angular.module('ResizePanel', [])
    .directive('resizePanel', function ($window) {
        return {
            restrict: 'A',
            link: function ($scope, element, attrs) {
                var top = element[0].offsetTop;
                var w = angular.element($window);
                $scope.getWindowDimensions = function () {
                    if ($(element).is(":visible") === false) {
                        return;
                    }

                    var pa = element.parent('.panel');
                    var top = pa.offset().top;
                    var h = pa[0].offsetHeight;
                    var h1 = element[0].offsetHeight;
                    $scope.headerSize = h - h1;

                    var pHeight = (w.height() - $scope.headerSize - top - 25);
                    element.css('height', pHeight + 'px');
                    return {
                        'h': w.height()
                    };
                };
                $scope.$watch($scope.getWindowDimensions, function (newValue, oldValue) {
                }, true);

                w.bind('resize', function () {
                    if(!$scope.$$phase) {
                        $scope.$apply();
                    }
                });
            }
        };
    })

;

cdjackson avatar Aug 10 '15 20:08 cdjackson

Oh - and I think you then need to ensure that the panel, and the div that contains the vis directive is set to width/height = 100%...

I've not tried this with network, but you should (??) hopefully be able to customise it...

Let me know how it goes.

cdjackson avatar Aug 10 '15 20:08 cdjackson

Hi All,

I'll address this issue for the next release which should be within 1 or 2 weeks.

I will make sure that the viewport will look exactly the same as it did before the change in container size but scaled correctly.

Regards,

Alex

On 10 aug. 2015, at 22:14, Chris Jackson [email protected] wrote:

Can you put a listener to call network.fit when the tab is changed?

I use the following directive to resize a bootstrap panel with a vis directive inside (just adding the element resize-panel to the panel).

angular.module('ResizePanel', []) .directive('resizePanel', function ($window) { return { restrict: 'A', link: function ($scope, element, attrs) { var top = element[0].offsetTop; var w = angular.element($window); $scope.getWindowDimensions = function () { if ($(element).is(":visible") === false) { return; }

                var pa = element.parent('.panel');
                var top = pa.offset().top;
                var h = pa[0].offsetHeight;
                var h1 = element[0].offsetHeight;
                $scope.headerSize = h - h1;

                var pHeight = (w.height() - $scope.headerSize - top - 25);
                element.css('height', pHeight + 'px');
                return {
                    'h': w.height()
                };
            };
            $scope.$watch($scope.getWindowDimensions, function (newValue, oldValue) {
            }, true);

            w.bind('resize', function () {
                if(!$scope.$$phase) {
                    $scope.$apply();
                }
            });
        }
    };
})

; — Reply to this email directly or view it on GitHub.

AlexDM0 avatar Aug 10 '15 20:08 AlexDM0

Wow, thank you for the quick response. I will try it out and looking forward for the next release.

Regards, Christoph

christophdebaene avatar Aug 10 '15 20:08 christophdebaene

It's not the right place, but as a quick fix, I have added the javascript below in the directive and it works fine now.

  $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
       network.fit();
  });

christophdebaene avatar Aug 11 '15 19:08 christophdebaene

Hi,

Just to give you a heads up, the fix I plan on implementing will ensure that the view center and range are preserved (for as much as possible given that aspect ratio may change on a resize). This is different from a fit, as that zooms out to encompass the entire network.

If a fit is what you're after than this fix will have to remain in place after my fix :).

Regards

On 11 aug. 2015, at 21:15, Christoph De Baene [email protected] wrote:

It's not the right place, but as a quick fix, I have added the javascript below in the directive and it works fine now.

$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { network.fit(); }); — Reply to this email directly or view it on GitHub.

AlexDM0 avatar Aug 11 '15 19:08 AlexDM0

Is there any update on this?

i am using materialize css and their tabs, just kind of confused the best way to implement this.

dylandechant avatar Mar 01 '16 20:03 dylandechant

Hi,

It is not possible to fit on a hidden tab. You should manually call fit on showing the network.

Regards

AlexDM0 avatar Mar 01 '16 20:03 AlexDM0

Hey Thanks Alex,

Sorry new to angular and just figuring this out, a little help would go a long way.

in my view i have

<div class="process-tabview" ng-controller="flowChartCtrl">
  <div class="col s12">
    <ul class="tabs">
      <li class="tab col s3"><a href="#process-workspace"  class="active">Process View</a></li>
      <li class="tab col s3"><a class="" href="#list-view">List View</a></li>
      <li class="tab col s3" ng-click="fitNetwork()"><a href="#neighborhood-view" >Neighborhood View</a></li>
    </ul>
  </div>
</div>


<div id="neighborhood-view">
  <div ng-controller="flowChartCtrl" >
    <vis-network data="testdata" options="options" height="100%" resize-tab></vis-network>
  </div>
</div>

then in my controller I have

$scope.fitNetwork = function(){
    console.log(vis.network);
    vis.network.fit();
  };

i keep getting

Object {dotparser: Object, gephiParser: Object, allOptions: Object}Images: t(e)allOptions: ObjectconvertDot: (t)convertGephi: (t,i)dotparser: ObjectgephiParser: Object__proto__: Object TypeError: vis.network.fit is not a function

Does this need to be done in the directive?

Thanks!

dylandechant avatar Mar 01 '16 21:03 dylandechant

Hi,

I can't help you there. I don't use angular. Maybe Chris can help out for this specific question? It sounds like vis.network is undefined and I'd think it's scoping.

Regards

On 01 Mar 2016, at 22:13, dylan dechant [email protected] wrote:

Hey Thanks Alex,

Sorry new to angular and just figuring this out, a little help would go a long way.

in my view i have

  • Process View
  • List View
  • Neighborhood View

then in my controller I have

$scope.fitNetwork = function(){ vis.network.fit(); }; i keep getting

TypeError: vis.network.fit is not a function

Does this need to be done in the directive?

Thanks!

— Reply to this email directly or view it on GitHub.

AlexDM0 avatar Mar 01 '16 21:03 AlexDM0

It’s a bit hard to tell what you’re doing, but I suspect you should be using the onload callback to get the vis object and store it in your controller.

cdjackson avatar Mar 02 '16 18:03 cdjackson

I have a graph component in React app,

<Graph
   graph={this.state.graph}
   options={graph_options}
   events={this.events}
/>

I hope to make it automatically zoom in/out when the graph changes, just like in vis.js document use network.fit()

But how I can call this fit method?

amithit avatar Aug 07 '18 13:08 amithit