| @@ -42,6 +42,7 @@ | |||
| "@microsoft/signalr": "^8.0.0", | |||
| "@microsoft/signalr-protocol-msgpack": "^8.0.0", | |||
| "@types/signalr": "^2.4.3", | |||
| "@types/three": "^0.162.0", | |||
| "ag-grid-angular": "^31.0.2", | |||
| "echarts": "^5.5.0", | |||
| "moment": "^2.30.1", | |||
| @@ -50,6 +51,8 @@ | |||
| "ngx-mqtt": "^17.0.0", | |||
| "rxjs": "~7.8.0", | |||
| "screenfull": "^6.0.2", | |||
| "three": "^0.162.0", | |||
| "three-orbitcontrols-ts": "^0.1.2", | |||
| "tslib": "^2.3.0", | |||
| "zone.js": "~0.14.3" | |||
| }, | |||
| @@ -38,8 +38,18 @@ export class DataVNavigationComponent implements OnInit { | |||
| }, | |||
| { | |||
| code: '03', | |||
| text: '3D', | |||
| url: '/data-v/threejs' | |||
| text: '重磅3D', | |||
| url: '/data-v/t1' | |||
| }, | |||
| { | |||
| code: '04', | |||
| text: '煤流总览', | |||
| url: '/data-v/t1' | |||
| }, | |||
| { | |||
| code: '05', | |||
| text: '毛重计量', | |||
| url: '/data-v/t1' | |||
| }, | |||
| { | |||
| text: '...' | |||
| @@ -5,6 +5,7 @@ import { DataVDateComponent } from './date/date.component'; | |||
| import { DataVWorkstationComponent } from './workstation/workstation.component'; | |||
| import { DataVS1Component } from './s1/s1.component'; | |||
| import { DataVThreejsComponent } from './threejs/threejs.component'; | |||
| import { DataVT1Component } from './t1/t1.component'; | |||
| export const routes: Routes = [ | |||
| { | |||
| @@ -12,4 +13,5 @@ export const routes: Routes = [ | |||
| component: DataVS1Component | |||
| } | |||
| , | |||
| { path: 'threejs', component: DataVThreejsComponent }]; | |||
| { path: 'threejs', component: DataVThreejsComponent }, | |||
| { path: 't1', component: DataVT1Component }]; | |||
| @@ -66,7 +66,7 @@ | |||
| 量热仪 | |||
| </div> | |||
| <div nz-col nzSpan="12" class="sys-status-title"> | |||
| 谈情氮元素 | |||
| 碳氢氮元素 | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -103,5 +103,4 @@ | |||
| <div class="sys-status-title">煤样超差率:超差样量/总样量 03/16</div> | |||
| <div class="sys-status-title">煤样合格率:合格样量/总样量 15/16</div> | |||
| </data-v-card> --> | |||
| </div> | |||
| @@ -12,6 +12,8 @@ import { NzProgressModule } from 'ng-zorro-antd/progress'; | |||
| import { NzBadgeModule } from 'ng-zorro-antd/badge'; | |||
| import { Subscription } from 'rxjs'; | |||
| import { IMqttMessage, MqttService } from 'ngx-mqtt'; | |||
| import { TitleService } from '@delon/theme'; | |||
| @Component({ | |||
| selector: 'app-data-v-s1', | |||
| standalone: true, | |||
| @@ -22,6 +24,7 @@ import { IMqttMessage, MqttService } from 'ngx-mqtt'; | |||
| export class DataVS1Component implements OnInit { | |||
| private readonly http = inject(_HttpClient); | |||
| private readonly modal = inject(ModalHelper); | |||
| private readonly titleService = inject(TitleService); | |||
| private c1OptionC = { | |||
| series: [ | |||
| @@ -108,6 +111,90 @@ export class DataVS1Component implements OnInit { | |||
| } | |||
| ] | |||
| }; | |||
| private c2OptionC = { | |||
| series: [ | |||
| { | |||
| type: 'gauge', | |||
| startAngle: 180, | |||
| endAngle: 0, | |||
| center: ['50%', '75%'], | |||
| radius: '90%', | |||
| min: 0, | |||
| max: 1, | |||
| splitNumber: 8, | |||
| axisLine: { | |||
| lineStyle: { | |||
| width: 6, | |||
| color: [ | |||
| [0.6, '#FF6E76'], | |||
| [0.9, '#FDDD60'], | |||
| [1, '#7CFFB2'] | |||
| ] | |||
| } | |||
| }, | |||
| pointer: { | |||
| icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z', | |||
| length: '12%', | |||
| width: 20, | |||
| offsetCenter: [0, '-60%'], | |||
| itemStyle: { | |||
| color: 'auto' | |||
| } | |||
| }, | |||
| axisTick: { | |||
| length: 12, | |||
| lineStyle: { | |||
| color: 'auto', | |||
| width: 2 | |||
| } | |||
| }, | |||
| splitLine: { | |||
| length: 20, | |||
| lineStyle: { | |||
| color: 'auto', | |||
| width: 5 | |||
| } | |||
| }, | |||
| axisLabel: { | |||
| color: '#464646', | |||
| fontSize: 20, | |||
| distance: -60, | |||
| rotate: 'tangential', | |||
| formatter: function (value: number) { | |||
| if (value === 0.875) { | |||
| return ''; | |||
| } else if (value === 0.625) { | |||
| return ''; | |||
| } else if (value === 0.125) { | |||
| return ''; | |||
| } | |||
| return ''; | |||
| } | |||
| }, | |||
| title: { | |||
| offsetCenter: [0, '-10%'], | |||
| fontSize: 20 | |||
| }, | |||
| detail: { | |||
| fontSize: 30, | |||
| offsetCenter: [0, '-5%'], | |||
| valueAnimation: true, | |||
| formatter: function (value: number) { | |||
| return Math.round(value * 100) + ''; | |||
| }, | |||
| color: 'inherit' | |||
| }, | |||
| data: [ | |||
| { | |||
| value: 0.7, | |||
| name: '' | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| }; | |||
| private c1Chart: any; | |||
| rowData = [ | |||
| @@ -240,97 +327,12 @@ export class DataVS1Component implements OnInit { | |||
| } | |||
| ngOnInit(): void { | |||
| this.titleService.setTitle('化验总览'); | |||
| var c1 = document.getElementById('c1')!; | |||
| this.c1Chart = echarts.init(c1); | |||
| var c2 = document.getElementById('c2')!; | |||
| var c2Chart = echarts.init(c2); | |||
| let c2OptionC = { | |||
| series: [ | |||
| { | |||
| type: 'gauge', | |||
| startAngle: 180, | |||
| endAngle: 0, | |||
| center: ['50%', '75%'], | |||
| radius: '90%', | |||
| min: 0, | |||
| max: 1, | |||
| splitNumber: 8, | |||
| axisLine: { | |||
| lineStyle: { | |||
| width: 6, | |||
| color: [ | |||
| [0.25, '#74FAFB'], | |||
| [0.5, '#74FAFB'], | |||
| [0.75, '#74FAFB'], | |||
| [1, '#74FAFB'] | |||
| ] | |||
| } | |||
| }, | |||
| pointer: { | |||
| icon: 'path://M12.8,0.7l12,40.1H0.7L12.8,0.7z', | |||
| length: '12%', | |||
| width: 20, | |||
| offsetCenter: [0, '-60%'], | |||
| itemStyle: { | |||
| color: 'auto' | |||
| } | |||
| }, | |||
| axisTick: { | |||
| length: 12, | |||
| lineStyle: { | |||
| color: 'auto', | |||
| width: 2 | |||
| } | |||
| }, | |||
| splitLine: { | |||
| length: 20, | |||
| lineStyle: { | |||
| color: 'auto', | |||
| width: 5 | |||
| } | |||
| }, | |||
| axisLabel: { | |||
| color: '#464646', | |||
| fontSize: 20, | |||
| distance: -60, | |||
| rotate: 'tangential', | |||
| formatter: function (value: any) { | |||
| if (value === 0.875) { | |||
| return ''; | |||
| } else if (value === 0.625) { | |||
| return ''; | |||
| } else if (value === 0.375) { | |||
| return ''; | |||
| } else if (value === 0.125) { | |||
| return ''; | |||
| } | |||
| return ''; | |||
| } | |||
| }, | |||
| title: { | |||
| offsetCenter: [0, '0%'], | |||
| fontSize: 20 | |||
| }, | |||
| detail: { | |||
| fontSize: 30, | |||
| offsetCenter: [0, '-5%'], | |||
| valueAnimation: true, | |||
| formatter: function (value: any) { | |||
| return Math.round(value * 100) + ''; | |||
| }, | |||
| color: 'inherit' | |||
| }, | |||
| data: [ | |||
| { | |||
| value: 0.97, | |||
| name: '' | |||
| } | |||
| ] | |||
| } | |||
| ] | |||
| }; | |||
| var d1 = document.getElementById('d1'); | |||
| var d1Chart = echarts.init(d1, 'dark'); | |||
| var d2 = document.getElementById('d2'); | |||
| @@ -608,7 +610,7 @@ export class DataVS1Component implements OnInit { | |||
| optionD2 && d2Chart.setOption(optionD2); | |||
| this.c1Chart.setOption(this.c1OptionC); | |||
| c2Chart.setOption(c2OptionC); | |||
| c2Chart.setOption(this.c2OptionC); | |||
| var r1 = document.getElementById('r1'); | |||
| var r1Chart = echarts.init(r1, 'dark'); | |||
| @@ -0,0 +1,6 @@ | |||
| <!-- <div #Three style="background-color: red;"></div> --> | |||
| <div style="display: flex; flex-direction: column; height: 100vh;"> | |||
| <div #Three style="flex-grow: 1;"></div> | |||
| </div> | |||
| @@ -0,0 +1,120 @@ | |||
| import { Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core'; | |||
| import { STColumn, STComponent } from '@delon/abc/st'; | |||
| import { SFSchema } from '@delon/form'; | |||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | |||
| import { SHARED_IMPORTS } from '@shared'; | |||
| import * as THREE from 'three'; | |||
| import { OrbitControls } from 'three-orbitcontrols-ts'; | |||
| import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'; | |||
| import { TitleService } from '@delon/theme'; | |||
| const clock = new THREE.Clock(); | |||
| let mixer: { update: (arg0: number) => void; }; | |||
| @Component({ | |||
| selector: 'app-data-v-t1', | |||
| standalone: true, | |||
| imports: [...SHARED_IMPORTS], | |||
| templateUrl: './t1.component.html', | |||
| }) | |||
| export class DataVT1Component implements OnInit { | |||
| private readonly http = inject(_HttpClient); | |||
| private readonly modal = inject(ModalHelper); | |||
| private readonly titleService = inject(TitleService); | |||
| @ViewChild('Three', { static: true }) container!: ElementRef; | |||
| public scene!: THREE.Scene; | |||
| public camera!: THREE.PerspectiveCamera; | |||
| public renderer!: THREE.WebGLRenderer; | |||
| public cube!: THREE.Mesh; | |||
| ngOnInit(): void { | |||
| this.titleService.setTitle('重磅3D'); | |||
| this.initThreeJs(); | |||
| this.animate(); | |||
| } | |||
| private initThreeJs(): void { | |||
| // 创建相机 | |||
| this.camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 20000); | |||
| this.camera.position.set(2200, 300, -3100); | |||
| //创建场景 | |||
| this.scene = new THREE.Scene(); | |||
| this.scene.background = new THREE.Color(0x040516); | |||
| const hemiLight = new THREE.HemisphereLight(0xffffff, 0x444444, 5); | |||
| hemiLight.position.set(0, 200, 0); | |||
| this.scene.add(hemiLight); | |||
| const dirLight = new THREE.DirectionalLight(0xffffff, 5); | |||
| dirLight.position.set(0, 200, 100); | |||
| dirLight.castShadow = true; | |||
| dirLight.shadow.camera.top = 180; | |||
| dirLight.shadow.camera.bottom = - 100; | |||
| dirLight.shadow.camera.left = - 120; | |||
| dirLight.shadow.camera.right = 120; | |||
| this.scene.add(dirLight); | |||
| const that = this; | |||
| const loader = new FBXLoader(); | |||
| loader.load('assets/fbx/bb.fbx', function (object) { | |||
| object.traverse(function (child) { | |||
| // if (child.isMesh) { | |||
| // child.castShadow = true; | |||
| // child.receiveShadow = true; | |||
| // } | |||
| }); | |||
| that.scene.add(object); | |||
| }, | |||
| (xhr) => { | |||
| // loading progress | |||
| }, | |||
| (err) => { | |||
| console.error('An error happened', err); | |||
| }); | |||
| this.renderer = new THREE.WebGLRenderer({ antialias: true }); | |||
| this.renderer.setPixelRatio(window.devicePixelRatio); | |||
| this.renderer.setSize(window.innerWidth, window.innerHeight); | |||
| this.renderer.shadowMap.enabled = true; | |||
| this.container.nativeElement.appendChild(this.renderer.domElement); | |||
| const radius = 5; // 圆的半径 | |||
| const segments = 32; // 圆的分段数 | |||
| const geometry = new THREE.CircleGeometry(radius, segments); | |||
| const material = new THREE.MeshBasicMaterial({ color: 0xff0000 }); // 红色材质,你可以根据需要调整颜色 | |||
| const circle = new THREE.Mesh(geometry, material); | |||
| circle.position.set(850, 100, -2000); // 设置圆的位置 | |||
| this.scene.add(circle); | |||
| const controls = new OrbitControls(this.camera, this.renderer.domElement); | |||
| controls.target.set(850, 100, -2000); | |||
| controls.update(); | |||
| //const axesHelper = new THREE.AxesHelper(1000); | |||
| //this.scene.add(axesHelper); | |||
| window.addEventListener('resize', this.onWindowResize); | |||
| } | |||
| public render(): void { | |||
| this.cube.rotation.x += 0.01; | |||
| this.cube.rotation.y += 0.01; | |||
| this.renderer.render(this.scene, this.camera); | |||
| } | |||
| onWindowResize() { | |||
| this.camera.aspect = window.innerWidth / window.innerHeight; | |||
| this.camera.updateProjectionMatrix(); | |||
| this.renderer.setSize(window.innerWidth, window.innerHeight); | |||
| } | |||
| animate = () => { | |||
| requestAnimationFrame(this.animate); | |||
| const delta = clock.getDelta(); | |||
| if (mixer) mixer.update(delta); | |||
| this.renderer.render(this.scene, this.camera); | |||
| }; | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| import { AfterViewInit, Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core'; | |||
| import { ModalHelper, _HttpClient } from '@delon/theme'; | |||
| import { ModalHelper, TitleService, _HttpClient } from '@delon/theme'; | |||
| import { SHARED_IMPORTS } from '@shared'; | |||
| import { AgGridAngular } from 'ag-grid-angular'; | |||
| import { ColDef } from 'ag-grid-community'; | |||
| @@ -23,6 +23,7 @@ export class DataVWorkstationComponent implements OnInit, AfterViewInit { | |||
| private readonly http = inject(_HttpClient); | |||
| private readonly modal = inject(ModalHelper); | |||
| private readonly elementRef = inject(ElementRef); | |||
| private readonly titleService = inject(TitleService); | |||
| @ViewChild('myGrid') grid!: AgGridAngular; | |||
| public defaultColDef: ColDef = { | |||
| @@ -103,7 +104,7 @@ export class DataVWorkstationComponent implements OnInit, AfterViewInit { | |||
| ]; | |||
| ngOnInit(): void { | |||
| console.log('ngOnInit' + this.rowData.length); | |||
| this.titleService.setTitle('我的工作站'); | |||
| for (var i = 1; i < 30; i++) { | |||
| this.rowData.push({ | |||
| @@ -29,8 +29,6 @@ | |||
| </div> | |||
| </div> | |||
| <ng-template #coverTemplate> | |||
| <img style="height: 100px;" alt="example" src="assets/bg2.jpg" /> | |||
| </ng-template> | |||
| @@ -91,15 +91,20 @@ | |||
| color: #515151; | |||
| vertical-align: middle; | |||
| } | |||
| } | |||
| .color-515151 { | |||
| color: #515151; | |||
| } | |||
| .color-515151 { | |||
| color: #515151; | |||
| } | |||
| } | |||
| [data-theme='dark'] { | |||
| :host ::ng-deep { | |||
| display: block; | |||
| width: 538px; | |||
| margin: 0 auto; | |||
| .icon { | |||
| color: rgb(255 255 255 / 20%); | |||
| @@ -36,7 +36,9 @@ | |||
| ], | |||
| "@_mock": [ | |||
| "_mock/index" | |||
| ] | |||
| ], | |||
| "three": ["./node_modules/three/src/Three"], | |||
| "three/*": ["./node_modules/three/*"] | |||
| } | |||
| }, | |||
| "angularCompilerOptions": { | |||