Angular生产构建开启脚本优化后Plotly 3D图形无法显示问题
问题:开启Angular生产环境脚本优化后Plotly 3D图形无法显示,提示WebGL不支持
当在angular.json中设置projects:app:architect:build:configurations:production:optimization:scripts为true时,3D图形无法显示,无报错信息,但页面显示替代提示:"WebGL is not supported by your browser - visit https://get.webgl.org for more info"。
模块代码
import * as PlotlyJS from 'plotly.js-dist-min'; import { PlotlyModule } from 'angular-plotly.js'; PlotlyModule.plotlyjs = PlotlyJS; @NgModule({ declarations: [ AnalyticsVisualizationComponent, and another ], imports: [ CommonModule, PlotlyModule, and another ], })
组件代码
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Location } from '@angular/common'; import { PREDICTIONS_MOCK } from '@app/app/shared/mock/predictions.mock'; import { ActivatedRoute, Router } from '@angular/router'; import { AnalyticsService } from '@app/app/shared/services/dashboard/analytics.service'; import { Plotly } from 'angular-plotly.js/lib/plotly.interface'; import { LoadingService } from '@app/app/shared/services/app-state/loader.service'; import { finalize, takeUntil } from 'rxjs/operators'; import { PlotlyComponent } from 'angular-plotly.js'; import { Point } from 'plotly.js-dist-min'; import { AppStateService } from '@app/app/shared/services/app-state/app-state.service'; import { Subject } from 'rxjs'; import { ContrastService } from '@app/app/shared/services/settings/contrast.service'; @Component({ selector: 'app-analytics-visualization', templateUrl: './analytics-visualization.component.html', styleUrls: ['./analytics-visualization.component.scss'], }) export class AnalyticsVisualizationComponent implements OnInit, OnDestroy { @ViewChild('plot', { static: false }) public plot: PlotlyComponent; public graph: Plotly.Layout; public isActive = false; public minScale = 0.8; public maxScale = 3.5; public maxRadius = 6; public minRadius = 1.3; public graphName: {}; public coords: { x: number, y: number, z: number }; public items = PREDICTIONS_MOCK; private _destroy$ = new Subject<void>(); constructor( private _route: ActivatedRoute, private _location: Location, private _router: Router, private _analyticsServices: AnalyticsService, private _loadingService: LoadingService, private _appStateService: AppStateService, private _contrastService: ContrastService, ) { } public ngOnInit(): void { this._loadingService.changeLoadingState(true); this._analyticsServices.getAnalytics3d_data() .pipe(finalize(() => this._loadingService.changeLoadingState(false))) .subscribe((res) => { const ret = res.replace('[NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN]', '[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]'); this.graphName = JSON.parse(ret); this.isActive = true; this.onCreateGraph(this.graphName); }); this._subscribeOnAccessibility(); } public ngOnDestroy(): void { this._destroy$.next(); this._destroy$.complete(); } public onCreateGraph(name: {}): void { if (name) { this.graph = { data: [ { opacity: 0.7, color: 'rgba(20, 121, 186, 1)', type: 'mesh3d', x: name[0].flat(), y: name[1].flat(), z: name[2].flat(), }, ], width: 1000, height: 700, margin: { l: 0, r: 0, b: 50, t: 50, }, scene: { camera: { eye: { ...this.coords }, }, xaxis: { title: 'X – Dates', gridcolor: this._contrastService.getPropertyValue('--light-black'), }, yaxis: { title: 'Y – Maturities', gridcolor: this._contrastService.getPropertyValue('--light-black'), }, zaxis: { title: 'Z – Spot yields', gridcolor: this._contrastService.getPropertyValue('--light-black'), }, }, }; } } public onRelayout(event: { 'scene.camera': { eye: Point } }): void { this.coords = { ...event['scene.camera']?.eye }; const dist = Math.sqrt(this.coords.x ** 2 + this.coords.y ** 2 + this.coords.z ** 2); if (dist <= this.maxRadius || dist >= this.minRadius) { this._minMaxRelayout(0, event['scene.camera']?.eye); } if (dist < this.minRadius) { this._minMaxRelayout(this.minScale); } if (dist > this.maxRadius) { this._minMaxRelayout(this.maxScale); } } private _minMaxRelayout(count: number, eye?: Point): void { this.graph.scene.camera.eye.x = count || eye.x; this.graph.scene.camera.eye.y = count || eye.y; this.graph.scene.camera.eye.z = count || eye.z; this.plot.updatePlot().then(); } private _subscribeOnAccessibility(): void { this._appStateService.contrast .pipe(takeUntil(this._destroy$)) .subscribe(() => this.onCreateGraph(this.graphName)); } }
模板代码
<div class="c-dashboard__ticket-details"> <plotly-plot *ngIf="isActive" #plot [data]="graph.data" [layout]="graph" (relayout)="onRelayout($event)"></plotly-plot> </div>
已尝试的解决方案
- 通过脚本引入库
- 将渲染方法放入
runOutsideAngular() - 连接/断开zone
- 排除组件构建
- 开启浏览器硬件加速(Chrome 107.0.5304.89 64位,驱动已更新)
该问题仅在开启应用优化时出现,对应angular.json配置如下:
"optimization": { "scripts": true, "styles": true, "fonts": true },
"outputHashing": "all", "sourceMap": false, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true,
期望
开启"optimization": {"scripts": true,"styles": true,"fonts": true}配置时,能正常显示3D图形。
内容的提问来源于stack exchange,提问作者Александр Нестеров
相关产品推荐
相关产品推荐

