swimlane / ngx-graph

Graph visualization library for angular

Home Page:https://swimlane.github.io/ngx-graph

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Issue when Using [autoCenter]="true"

maxwellfargoseCactus opened this issue · comments

I have used below default code :
<ngx-graph
class="chart-container" [autoCenter]="true"
[view]="[700, 80]"
[links]="[
{
id: 'a',
source: 'first',
target: 'second',
label: 'is parent of'
}, {
id: 'b',
source: 'first',
target: 'third',
label: 'custom label'
}
]"
[nodes]="[
{
id: 'first',
label: 'A'
}, {
id: 'second',
label: 'B'
}, {
id: 'third',
label: 'C'
}
]"
(select)="onNodeSelect($event)"
>

when I use [autoCenter]="true" the graph is not display properly, Please see below,

Actual Result :
image

Expected Result :
image

It looks to me like the problem is that its using panTo and not the pan method which accounts for zoom level, also it does not account for minimap.

I encountered a similar problem with the centering.
Therefore, I investigated the related methods center and updateGraphDims.

From my view there is a problem in calculating the position that is used when calling the the panTo method in center.
The problem is that middle point of the graphs width and height is used as a pan location.
This is however no position that can be used since this "center" is relative to the position of the nodes themselves.

So instead of doing

center(): void {
    this.panTo(this.graphDims.width / 2, this.graphDims.height / 2);
}

the position should be made absolut by including the minX and minY values of the overall graph:

center(): void {
    this.panTo(this.minX + this.graphDims.width / 2, this.minY + this.graphDims.height / 2);
}

These minX and minY are in theory calculated in the updateGraphDims method. However here a similar problem exists: From what I can see, the position.x and position.y properties of each node correspond to the nodes center. This should be considered when calculating the minX, minY, maxX, and maxY values. Therefore, I would change the for loop inside the updateGraphDims method as follows:

 for (let i = 0; i < this.graph.nodes.length; i++) {
    const node = this.graph.nodes[i];
    let halfWidth = node.dimension.width / 2; 
    let halfHeight = node.dimension.height / 2;
    minX = node.position.x - halfWidth < minX ? node.position.x - halfWidth : minX;
    minY = node.position.y - halfHeight < minY ? node.position.y - halfHeight : minY;
    maxX = node.position.x + halfWidth > maxX ? node.position.x + halfWidth : maxX;
    maxY = node.position.y + halfHeight > maxY ? node.position.y + halfHeight : maxY;  
}

One can than use these calculated minX and minY values as mentioned above to get the correct center.

I have applied these changes locally and now centering seems to work correctly.

I am happy to provide a merge requests if this also fixes the bug from your perspective.