@@ -42,6 +42,7 @@ | |||||
"@microsoft/signalr": "^8.0.0", | "@microsoft/signalr": "^8.0.0", | ||||
"@microsoft/signalr-protocol-msgpack": "^8.0.0", | "@microsoft/signalr-protocol-msgpack": "^8.0.0", | ||||
"@types/signalr": "^2.4.3", | "@types/signalr": "^2.4.3", | ||||
"@types/three": "^0.162.0", | |||||
"ag-grid-angular": "^31.0.2", | "ag-grid-angular": "^31.0.2", | ||||
"echarts": "^5.5.0", | "echarts": "^5.5.0", | ||||
"moment": "^2.30.1", | "moment": "^2.30.1", | ||||
@@ -50,6 +51,8 @@ | |||||
"ngx-mqtt": "^17.0.0", | "ngx-mqtt": "^17.0.0", | ||||
"rxjs": "~7.8.0", | "rxjs": "~7.8.0", | ||||
"screenfull": "^6.0.2", | "screenfull": "^6.0.2", | ||||
"three": "^0.162.0", | |||||
"three-orbitcontrols-ts": "^0.1.2", | |||||
"tslib": "^2.3.0", | "tslib": "^2.3.0", | ||||
"zone.js": "~0.14.3" | "zone.js": "~0.14.3" | ||||
}, | }, | ||||
@@ -38,8 +38,18 @@ export class DataVNavigationComponent implements OnInit { | |||||
}, | }, | ||||
{ | { | ||||
code: '03', | 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: '...' | text: '...' | ||||
@@ -5,6 +5,7 @@ import { DataVDateComponent } from './date/date.component'; | |||||
import { DataVWorkstationComponent } from './workstation/workstation.component'; | import { DataVWorkstationComponent } from './workstation/workstation.component'; | ||||
import { DataVS1Component } from './s1/s1.component'; | import { DataVS1Component } from './s1/s1.component'; | ||||
import { DataVThreejsComponent } from './threejs/threejs.component'; | import { DataVThreejsComponent } from './threejs/threejs.component'; | ||||
import { DataVT1Component } from './t1/t1.component'; | |||||
export const routes: Routes = [ | export const routes: Routes = [ | ||||
{ | { | ||||
@@ -12,4 +13,5 @@ export const routes: Routes = [ | |||||
component: DataVS1Component | component: DataVS1Component | ||||
} | } | ||||
, | , | ||||
{ path: 'threejs', component: DataVThreejsComponent }]; | |||||
{ path: 'threejs', component: DataVThreejsComponent }, | |||||
{ path: 't1', component: DataVT1Component }]; |
@@ -66,7 +66,7 @@ | |||||
量热仪 | 量热仪 | ||||
</div> | </div> | ||||
<div nz-col nzSpan="12" class="sys-status-title"> | <div nz-col nzSpan="12" class="sys-status-title"> | ||||
谈情氮元素 | |||||
碳氢氮元素 | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
@@ -103,5 +103,4 @@ | |||||
<div class="sys-status-title">煤样超差率:超差样量/总样量 03/16</div> | <div class="sys-status-title">煤样超差率:超差样量/总样量 03/16</div> | ||||
<div class="sys-status-title">煤样合格率:合格样量/总样量 15/16</div> | <div class="sys-status-title">煤样合格率:合格样量/总样量 15/16</div> | ||||
</data-v-card> --> | </data-v-card> --> | ||||
</div> | </div> |
@@ -12,6 +12,8 @@ import { NzProgressModule } from 'ng-zorro-antd/progress'; | |||||
import { NzBadgeModule } from 'ng-zorro-antd/badge'; | import { NzBadgeModule } from 'ng-zorro-antd/badge'; | ||||
import { Subscription } from 'rxjs'; | import { Subscription } from 'rxjs'; | ||||
import { IMqttMessage, MqttService } from 'ngx-mqtt'; | import { IMqttMessage, MqttService } from 'ngx-mqtt'; | ||||
import { TitleService } from '@delon/theme'; | |||||
@Component({ | @Component({ | ||||
selector: 'app-data-v-s1', | selector: 'app-data-v-s1', | ||||
standalone: true, | standalone: true, | ||||
@@ -22,6 +24,7 @@ import { IMqttMessage, MqttService } from 'ngx-mqtt'; | |||||
export class DataVS1Component implements OnInit { | export class DataVS1Component implements OnInit { | ||||
private readonly http = inject(_HttpClient); | private readonly http = inject(_HttpClient); | ||||
private readonly modal = inject(ModalHelper); | private readonly modal = inject(ModalHelper); | ||||
private readonly titleService = inject(TitleService); | |||||
private c1OptionC = { | private c1OptionC = { | ||||
series: [ | 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; | private c1Chart: any; | ||||
rowData = [ | rowData = [ | ||||
@@ -240,97 +327,12 @@ export class DataVS1Component implements OnInit { | |||||
} | } | ||||
ngOnInit(): void { | ngOnInit(): void { | ||||
this.titleService.setTitle('化验总览'); | |||||
var c1 = document.getElementById('c1')!; | var c1 = document.getElementById('c1')!; | ||||
this.c1Chart = echarts.init(c1); | this.c1Chart = echarts.init(c1); | ||||
var c2 = document.getElementById('c2')!; | var c2 = document.getElementById('c2')!; | ||||
var c2Chart = echarts.init(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 d1 = document.getElementById('d1'); | ||||
var d1Chart = echarts.init(d1, 'dark'); | var d1Chart = echarts.init(d1, 'dark'); | ||||
var d2 = document.getElementById('d2'); | var d2 = document.getElementById('d2'); | ||||
@@ -608,7 +610,7 @@ export class DataVS1Component implements OnInit { | |||||
optionD2 && d2Chart.setOption(optionD2); | optionD2 && d2Chart.setOption(optionD2); | ||||
this.c1Chart.setOption(this.c1OptionC); | this.c1Chart.setOption(this.c1OptionC); | ||||
c2Chart.setOption(c2OptionC); | |||||
c2Chart.setOption(this.c2OptionC); | |||||
var r1 = document.getElementById('r1'); | var r1 = document.getElementById('r1'); | ||||
var r1Chart = echarts.init(r1, 'dark'); | 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 { 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 { SHARED_IMPORTS } from '@shared'; | ||||
import { AgGridAngular } from 'ag-grid-angular'; | import { AgGridAngular } from 'ag-grid-angular'; | ||||
import { ColDef } from 'ag-grid-community'; | import { ColDef } from 'ag-grid-community'; | ||||
@@ -23,6 +23,7 @@ export class DataVWorkstationComponent implements OnInit, AfterViewInit { | |||||
private readonly http = inject(_HttpClient); | private readonly http = inject(_HttpClient); | ||||
private readonly modal = inject(ModalHelper); | private readonly modal = inject(ModalHelper); | ||||
private readonly elementRef = inject(ElementRef); | private readonly elementRef = inject(ElementRef); | ||||
private readonly titleService = inject(TitleService); | |||||
@ViewChild('myGrid') grid!: AgGridAngular; | @ViewChild('myGrid') grid!: AgGridAngular; | ||||
public defaultColDef: ColDef = { | public defaultColDef: ColDef = { | ||||
@@ -103,7 +104,7 @@ export class DataVWorkstationComponent implements OnInit, AfterViewInit { | |||||
]; | ]; | ||||
ngOnInit(): void { | ngOnInit(): void { | ||||
console.log('ngOnInit' + this.rowData.length); | |||||
this.titleService.setTitle('我的工作站'); | |||||
for (var i = 1; i < 30; i++) { | for (var i = 1; i < 30; i++) { | ||||
this.rowData.push({ | this.rowData.push({ | ||||
@@ -29,8 +29,6 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<ng-template #coverTemplate> | <ng-template #coverTemplate> | ||||
<img style="height: 100px;" alt="example" src="assets/bg2.jpg" /> | <img style="height: 100px;" alt="example" src="assets/bg2.jpg" /> | ||||
</ng-template> | </ng-template> | ||||
@@ -91,15 +91,20 @@ | |||||
color: #515151; | color: #515151; | ||||
vertical-align: middle; | vertical-align: middle; | ||||
} | } | ||||
} | |||||
.color-515151 { | |||||
color: #515151; | |||||
} | |||||
.color-515151 { | |||||
color: #515151; | |||||
} | } | ||||
} | } | ||||
[data-theme='dark'] { | [data-theme='dark'] { | ||||
:host ::ng-deep { | :host ::ng-deep { | ||||
display: block; | |||||
width: 538px; | |||||
margin: 0 auto; | |||||
.icon { | .icon { | ||||
color: rgb(255 255 255 / 20%); | color: rgb(255 255 255 / 20%); | ||||
@@ -36,7 +36,9 @@ | |||||
], | ], | ||||
"@_mock": [ | "@_mock": [ | ||||
"_mock/index" | "_mock/index" | ||||
] | |||||
], | |||||
"three": ["./node_modules/three/src/Three"], | |||||
"three/*": ["./node_modules/three/*"] | |||||
} | } | ||||
}, | }, | ||||
"angularCompilerOptions": { | "angularCompilerOptions": { | ||||