swimlane / ngx-graph

Graph visualization library for angular
https://swimlane.github.io/ngx-graph
MIT License
915 stars 282 forks source link

ngx-graph TypeError and ReferenceError on runtime #546

Open leobouts opened 2 months ago

leobouts commented 2 months ago

Describe the bug Hello, I am using ngx-graphs with Angular 17 (currently there is an open PR for the angular 17 support but not merged so I used a forked version of the user made the PR (https://github.com/Kr0san89/ngx-graph) of ngx-charts that includes this change for the support in Angular 17).

I don't stumbled in any functional issues with the graph and data I am using but I have 2 runtime errors that I don't know if will result in some problems. My code does not deviate a lot from the ngx-graphs demos and I have no build errors.

Specifically

ERROR TypeError: hostElem.parentNode.getBoundingClientRect is not a function
    at _GraphComponent.getContainerDims (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:2503:40)
    at _GraphComponent.basicUpdate (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:2478:25)
    at _GraphComponent.ngOnChanges (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:1641:10)
    at _GraphComponent.rememberChangeHistoryAndInvokeOnChangesHook (/ui/node_modules/@angular/core/fesm2022/core.mjs:4101:14)
    at callHookInternal (/ui/node_modules/@angular/core/fesm2022/core.mjs:5136:14)
    at callHook (/ui/node_modules/@angular/core/fesm2022/core.mjs:5167:9)
    at callHooks (/ui/node_modules/@angular/core/fesm2022/core.mjs:5118:17)
    at executeInitAndCheckHooks (/ui/node_modules/@angular/core/fesm2022/core.mjs:5068:9)
    at refreshView (/ui/node_modules/@angular/core/fesm2022/core.mjs:12351:21)
    at detectChangesInView$1 (/ui/node_modules/@angular/core/fesm2022/core.mjs:12560:9)
ERROR TypeError: hostElem.parentNode.getBoundingClientRect is not a function
    at _GraphComponent.getContainerDims (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:2503:40)
    at _GraphComponent.basicUpdate (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:2478:25)
    at _GraphComponent.ngOnChanges (/ui/node_modules/@kr0san89/ngx-graph/fesm2022/kr0san89-ngx-graph.mjs:1641:10)
    at _GraphComponent.rememberChangeHistoryAndInvokeOnChangesHook (/ui/node_modules/@angular/core/fesm2022/core.mjs:4101:14)
    at callHookInternal (/ui/node_modules/@angular/core/fesm2022/core.mjs:5136:14)
    at callHook (/ui/node_modules/@angular/core/fesm2022/core.mjs:5167:9)
    at callHooks (/ui/node_modules/@angular/core/fesm2022/core.mjs:5118:17)
    at executeInitAndCheckHooks (/ui/node_modules/@angular/core/fesm2022/core.mjs:5068:9)
    at refreshView (/ui/node_modules/@angular/core/fesm2022/core.mjs:12351:21)
    at detectChangesInView$1 (/ui/node_modules/@angular/core/fesm2022/core.mjs:12560:9)
ERROR ReferenceError: window is not defined

I'm not sure how I can handle this, one thought was to debug this through changes directly from node_modules but I cannot see the reflected changes in the browser, I understand that they won't be reflected because the package has to be rebuilt again and angular has to understand it as new and reload it but i'm not exactly sure how to do this. Also I'm not sure if this problem is due to the Angular 17 or it is also present in the previous versions.

To Reproduce Steps to reproduce the behavior:

Code similar with the ngx-graph demo inside a mat-drawer-content, cannot reproduce it with the official ngx-graph because Angular 17 is not supported yet.

     <mat-drawer-content>
      <div class="page">
      <ngx-spinner size="medium" [type]="typeSelected" [fullScreen]="false"></ngx-spinner>
      <ngx-graph
        *ngIf="!uploadingInProgress"
        [links]="links"
        [nodes]="nodes"
        [layout]="layout"
        [curve]="curve"
        [draggingEnabled]="draggingEnabled"
        [panningEnabled]="panningEnabled"
        [enableZoom]="zoomEnabled"
        [zoomSpeed]="zoomSpeed"
        [minZoomLevel]="minZoomLevel"
        [maxZoomLevel]="maxZoomLevel"
        [panOnZoom]="panOnZoom"
        [autoZoom]="autoZoom"
        [autoCenter]="autoCenter"
        [center$]="center$"
        [update$]="update$"
        [zoomToFit$]="zoomToFit$"
      >

        <ng-template #defsTemplate>
          <svg:marker id="arrow" viewBox="0 -5 10 10" refX="8" refY="0" markerWidth="4" markerHeight="4" orient="auto">
            <svg:path d="M0,-5L10,0L0,5" class="arrow-head" />
          </svg:marker>
        </ng-template>

        <ng-template #nodeTemplate let-node> 
          <svg:circle  [attr.r]="node.dimension.width/2" [attr.cx]="node.dimension.width/2" [attr.cy]="node.dimension.width/2" [attr.fill]="node.data.color"/>
          <svg:text alignment-baseline="central" [attr.x]="10" [attr.y]="node.dimension.height / 2">{{node.label}}</svg:text>
        </ng-template>

        <ng-template #linkTemplate let-link>
          <svg:g class="edge">
            <svg:path class="line" stroke-width="2" marker-end="url(#arrow)">
            </svg:path>
            <svg:text class="edge-label" text-anchor="middle">
              <textPath class="text-path" [attr.href]="'#' + link.id" [style.dominant-baseline]="link.dominantBaseline" startOffset="50%">
                {{link.label}}
              </textPath>
            </svg:text>
          </svg:g>
        </ng-template>
      </ngx-graph>
    </div>
  </mat-drawer-content>

Expected behavior should not contain runtime errors

ngx-graph version forked from here: https://github.com/Kr0san89/ngx-graph as mentioned, most probably this is present in latest version?

Kr0san89 commented 2 months ago

I'm unsure why you get this error but you can breakpoint it and look what is inside of hostElem.parentNode by going to the browser dev-tools and open the file kr0san89-ngx-graph.mjs you would expect that the parentNode is as it says the parentNode and therefore should have this function (normal JS function). So i guess here happens something unexpected.

Here is the code which might help you to better understand it. https://github.com/swimlane/ngx-graph/blob/6d3c9d3cbc84107a55d95a83f7b037617e0ea062/projects/swimlane/ngx-graph/src/lib/graph/graph.component.ts#L1320

The function get called on each change (see call stack ngonChanges) so i assume on some point getBoundingClientRect will work out and you should be good.

Not sure why you used the drawer and mentioned it, it is really not needed.

hope this helps you to find a solution :)