@@ -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": { | |||