如何为ngx-graph添加水平滚动条?解决宽数据集适配问题
为ngx-graph添加水平滚动条并兼容缩放功能
我正在使用ngx-graph可视化一个跨多年的大型数据集,数据集宽度过大无法在单页完整显示,因此希望为ngx-graph添加水平滚动条,以便用户查看全部数据。
我曾尝试为父容器设置固定宽度,但该方案与缩放功能冲突。请问有人能协助我解决这个问题吗?
现有HTML代码
<div class="space-top-16 vc-form-container"> <ngx-graph class="mss-graph-container" [layout]="dagreLayout" [curve]="curve" [links]="links" [nodes]="nodes" [autoZoom]="true" [autoCenter]="true"> <ng-template #nodeTemplate let-node> <svg height="80" [attr.width]="node.data.children && node.data.children.length > 0 ? '112' : '72'" [attr.max-width]="112"> <foreignObject height="80" [attr.width]="node.data.children && node.data.children.length > 0 ? '112' : '72'" [attr.max-width]="112"> <div class="vc-mss-device-node-wrapper"> <div class="vc-mss-device-node" (click)="$event.preventDefault(); showWidget(node)"> <span class="vc-mss-device-icon material-icons" [style.border-color]="'#dadbdc'" [style.color]="node.data.icon.color" >{{ node.data.icon.label }}</span > <div xmlns="http://www.w3.org/1999/xhtml" class="vc-mss-device-node-text body-s-1" [matTooltip]="node.label" [matTooltipPosition]="'above'"> {{ node.label }} - {{ node.data.type }} </div> </div> @if (node.data.children && node.data.children.length > 0) { <div class="vc-mss-device-node"> <button mat-icon-button class="vc-mss-device-expand-icon" (click)="$event.preventDefault(); node.data.type !== 'INTERNET' ? (selectedNode = node) : (selectedNode = null)"> <mat-icon>{{ node.data.expanded ? 'expand_more' : 'expand_less' }}</mat-icon> </button> <span>({{ node.data.children.length }})</span> </div> } </div> </foreignObject> </svg> </ng-template> <ng-template #linkTemplate let-link> <svg:g class="edge" xmlns:svg="http://www.w3.org/2000/svg"> <path class="edge line mss-device-overview-line" [attr.d]="link.line"></path> </svg:g> </ng-template> </ngx-graph> </div>
现有SCSS代码
:host { display: block; height: 100%; width: 100%; .vc-mss-device-node-wrapper { display: flex; align-items: center; gap: 8px; padding: 8px; .vc-mss-device-node { display: flex; flex-direction: column; align-items: center; gap: 8px; .vc-mss-device-icon { display: flex; justify-content: center; align-items: center; height: 36px; width: 36px; border: 1px solid; border-radius: 50%; } .vc-mss-device-node-text { width: 56px; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } .vc-mss-device-node { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; button.vc-mss-device-expand-icon { height: 24px !important; width: 24px !important; box-shadow: none !important; .mat-icon { height: 24px; width: 24px; line-height: 24px; font-size: 24px; } &.mat-mdc-icon-button:not([disabled]) { &:hover, &:focus-visible { border-radius: 4px !important; background-color: var(--primary-50); } &:focus-visible { outline: 1px solid var(--primary-600); outline-offset: 1px; } } } } } .mss-graph-container { display: block; height: calc(100vh - 345px); width: 100%; } .mss-device-overview-line { stroke: var(--outline); stroke-width: 1; } .vc-mss-device-legend { display: flex; flex-direction: column; gap: 8px; position: absolute; top: 32px; left: 16px; width: 150px; background-color: var(--ghost-white); .vc-mss-device-legend-item { display: inline-flex; align-items: center; gap: 8px; } } }
解决方案
要实现水平滚动同时兼容ngx-graph的缩放功能,关键是让滚动容器只限制可视区域,而让ngx-graph的SVG自由扩展宽度,同时保留缩放交互逻辑,按以下步骤修改:
1. 修改HTML结构,新增滚动容器
给ngx-graph外层添加一个专用的滚动容器:
<div class="space-top-16 vc-form-container"> <!-- 新增滚动容器 --> <div class="graph-scroll-container"> <ngx-graph class="mss-graph-container" [layout]="dagreLayout" [curve]="curve" [links]="links" [nodes]="nodes" [autoZoom]="true" [autoCenter]="true"> <!-- 原有模板内容保持不变 --> </ngx-graph> </div> </div>
2. 更新SCSS样式
调整容器样式,让滚动容器负责横向滚动,同时允许ngx-graph自适应内容宽度:
:host { display: block; height: 100%; width: 100%; /* 新增滚动容器样式 */ .graph-scroll-container { width: 100%; height: calc(100vh - 345px); overflow-x: auto; overflow-y: hidden; position: relative; } .mss-graph-container { display: block; height: 100%; /* 移除固定宽度限制,让SVG随内容扩展 */ width: auto; /* 确保数据集宽度不足时占满容器 */ min-width: 100%; } /* 原有其他样式保持不变 */ .vc-mss-device-node-wrapper { /* ... 原有代码 ... */ } .mss-device-overview-line { /* ... 原有代码 ... */ } .vc-mss-device-legend { /* ... 原有代码 ... */ } }
3. 优化初始视图(可选)
如果autoZoom导致初始缩放异常,可在组件初始化后手动适配视图:
import { Component, ViewChild, OnInit } from '@angular/core'; import { NgxGraphComponent } from '@swimlane/ngx-graph'; @Component({ // 你的组件元数据 }) export class YourGraphComponent implements OnInit { @ViewChild(NgxGraphComponent) graphComponent!: NgxGraphComponent; ngOnInit() { setTimeout(() => { this.graphComponent.fitView(); }, 300); } }
原理说明
- 滚动容器通过
overflow-x: auto提供横向滚动能力,同时固定高度确保纵向布局稳定。 - ngx-graph容器移除固定宽度,允许内部SVG根据数据集实际宽度自由扩展,避免内容被截断。
min-width: 100%保证当数据集宽度小于容器时,图表仍占满可视区域,不会出现留白。
修改后即可通过水平滚动查看完整数据集,同时保留ngx-graph的缩放、拖拽等交互功能。
内容的提问来源于stack exchange,提问作者Harvi Patel
相关产品推荐
相关产品推荐

