SolarSystem code clean + Unit refactor
This commit is contained in:
parent
e2738716be
commit
df09c65b2b
50
src/main/angular/src/app/Unit.ts
Normal file
50
src/main/angular/src/app/Unit.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import {formatNumber} from "@angular/common";
|
||||
|
||||
export const PREFIXES_POSITIVE: string[] = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q'];
|
||||
export const PREFIXES_NEGATIVE: string[] = ['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y', 'r', 'q'];
|
||||
|
||||
export function applyPrefixUnit(value: number, unit: string, divisor: number, prefix: string, digits: number, locale: string) {
|
||||
if (isNaN(value) || isNaN(divisor) || divisor === 0) {
|
||||
return '-';
|
||||
}
|
||||
const format = '0.' + digits + '-' + digits;
|
||||
return formatNumber(value / divisor, locale, format) + ' ' + prefix + unit;
|
||||
}
|
||||
|
||||
export class Unit {
|
||||
|
||||
private _divisor: number = 1;
|
||||
|
||||
private _prefix: string = "";
|
||||
|
||||
constructor(
|
||||
readonly unit: string,
|
||||
readonly locale: string,
|
||||
) {
|
||||
// -
|
||||
}
|
||||
|
||||
get divisor(): number {
|
||||
return this._divisor;
|
||||
}
|
||||
|
||||
get prefix(): string {
|
||||
return this._prefix;
|
||||
}
|
||||
|
||||
public update(value: number) {
|
||||
const prefixGroup = Math.floor(Math.floor(Math.log10(value)) / 3);
|
||||
if (prefixGroup <= 0) {
|
||||
this._prefix = PREFIXES_NEGATIVE[-prefixGroup];
|
||||
} else {
|
||||
this._prefix = PREFIXES_POSITIVE[prefixGroup];
|
||||
}
|
||||
const exponentFromGroup = prefixGroup * 3;
|
||||
this._divisor = Math.pow(10, exponentFromGroup);
|
||||
}
|
||||
|
||||
applyPrefixUnit(value: number): string {
|
||||
return applyPrefixUnit(value, this.unit, this.divisor, this.prefix, 2, this.locale);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,8 +1,17 @@
|
||||
import {ApplicationConfig, provideZoneChangeDetection} from '@angular/core';
|
||||
import {ApplicationConfig, LOCALE_ID, provideZoneChangeDetection} from '@angular/core';
|
||||
import {provideRouter} from '@angular/router';
|
||||
|
||||
import {routes} from './app.routes';
|
||||
import {registerLocaleData} from "@angular/common";
|
||||
import localeDe from '@angular/common/locales/de';
|
||||
import localeDeExtra from '@angular/common/locales/extra/de';
|
||||
|
||||
registerLocaleData(localeDe, 'de-DE', localeDeExtra);
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideZoneChangeDetection({eventCoalescing: true}), provideRouter(routes)]
|
||||
providers: [
|
||||
{provide: LOCALE_ID, useValue: 'de-DE'},
|
||||
provideZoneChangeDetection({eventCoalescing: true}),
|
||||
provideRouter(routes),
|
||||
]
|
||||
};
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import {Routes} from '@angular/router';
|
||||
import {SolarComponent} from './solar/solar.component';
|
||||
import {SolarSystemComponent} from './solar-system/solar-system.component';
|
||||
import {VoltageDropComponent} from "./voltage-drop/voltage-drop.component";
|
||||
|
||||
export const routes: Routes = [
|
||||
{path: 'Solar', component: SolarComponent},
|
||||
{path: 'Solar', component: SolarSystemComponent},
|
||||
{path: 'VoltageDrop', component: VoltageDropComponent},
|
||||
{path: '**', redirectTo: '/Solar'},
|
||||
];
|
||||
|
||||
43
src/main/angular/src/app/solar-system/SOLAR_SYSTEM.ts
Normal file
43
src/main/angular/src/app/solar-system/SOLAR_SYSTEM.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import {SolarSystemBody} from "./SolarSystemBody";
|
||||
|
||||
export const SUN = new SolarSystemBody('Sonne', 1392700000, 0, 1.989e33, []);
|
||||
|
||||
export const MERCURY = new SolarSystemBody('Merkur', 4879400, 57.9, 3.285e26, []);
|
||||
|
||||
export const VENUS = new SolarSystemBody('Venus', 12104000, 108.2, 4.867e27, []);
|
||||
|
||||
export const EARTH = new SolarSystemBody('Erde', 12742000, 149.6, 5.972e27, [
|
||||
new SolarSystemBody('Mond', 3474800, 0, 7.342e25, [])
|
||||
]);
|
||||
|
||||
export const MARS = new SolarSystemBody('Mars', 6779000, 228, 6.39e26, [
|
||||
new SolarSystemBody('Phobos', 22533, 0, 1.0659e19, []),
|
||||
new SolarSystemBody('Deimos', 12400, 0, 1.4762e18, [])
|
||||
]);
|
||||
|
||||
export const JUPITER = new SolarSystemBody('Jupiter', 139820000, 778.5, 1.898e30, [
|
||||
new SolarSystemBody('Io', 3643000, 0, 8.932e25, []),
|
||||
new SolarSystemBody('Europa', 3121600, 0, 4.799e25, []),
|
||||
new SolarSystemBody('Ganymede', 5262400, 0, 1.4819e26, []),
|
||||
new SolarSystemBody('Callisto', 4820600, 0, 1.0759e26, [])
|
||||
]
|
||||
);
|
||||
|
||||
export const SATURN = new SolarSystemBody('Saturn', 116460000, 1432, 5.683e29, [
|
||||
new SolarSystemBody('Titan', 5149460, 0, 1.3452e26, []),
|
||||
new SolarSystemBody('Enceladus', 504200, 0, 1.08e23, [])
|
||||
]);
|
||||
|
||||
export const URANUS = new SolarSystemBody('Uranus', 50724000, 2867, 8.681e28, [
|
||||
new SolarSystemBody('Miranda', 471600, 0, 6.59e22, []),
|
||||
new SolarSystemBody('Ariel', 1157800, 0, 1.35e24, []),
|
||||
new SolarSystemBody('Umbriel', 1169400, 0, 1.17e24, []),
|
||||
new SolarSystemBody('Titania', 1576800, 0, 3.42e24, []),
|
||||
new SolarSystemBody('Oberon', 1522800, 0, 3.01e24, [])
|
||||
]);
|
||||
|
||||
export const NEPTUNE = new SolarSystemBody('Neptun', 49244000, 4515, 1.024e29, [
|
||||
new SolarSystemBody('Triton', 2706800, 0, 2.14e25, [])
|
||||
]);
|
||||
|
||||
export const BODIES: SolarSystemBody[] = [SUN, MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE];
|
||||
21
src/main/angular/src/app/solar-system/SolarSystemBody.ts
Normal file
21
src/main/angular/src/app/solar-system/SolarSystemBody.ts
Normal file
@ -0,0 +1,21 @@
|
||||
export class SolarSystemBody {
|
||||
|
||||
readonly realDistanceMeters: number;
|
||||
|
||||
modelMeters: number;
|
||||
|
||||
modelDistance: number;
|
||||
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly realMeters: number,
|
||||
realDistanceMioKm: number,
|
||||
readonly massKg: number,
|
||||
readonly moons: SolarSystemBody[],
|
||||
) {
|
||||
this.realDistanceMeters = realDistanceMioKm * 1000 * 1000 * 1000;
|
||||
this.modelMeters = realMeters;
|
||||
this.modelDistance = realDistanceMioKm;
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,23 +9,25 @@
|
||||
<div class="tileContent">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="name">Name</td>
|
||||
<td class="real">Realität</td>
|
||||
<td class="model" colspan="2">Skaliert</td>
|
||||
<th>Name</th>
|
||||
<th>Realität</th>
|
||||
<th>Skaliert</th>
|
||||
</tr>
|
||||
<tr *ngFor="let mass of masses">
|
||||
<tr *ngFor="let mass of BODIES">
|
||||
<td class="name">{{ mass.name }}</td>
|
||||
<td class="real">{{ doPrefix(mass.realMeters, 'm', 1000, 'k', 0) }}</td>
|
||||
<td class="model" colspan="2">{{ unit(mass.modelMeters, 'm') }}</td>
|
||||
<td class="real">{{ applyPrefixUnit(mass.realMeters, 'm', 1000, 'k', 0, locale) }}</td>
|
||||
<td class="model">{{ diameterUnit.applyPrefixUnit(mass.modelMeters) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
<select [(ngModel)]="pivot">
|
||||
<option *ngFor="let mass of masses" [ngValue]="mass">{{ mass.name }}</option>
|
||||
<select [(ngModel)]="pivot" (ngModelChange)="update()">
|
||||
<option *ngFor="let mass of BODIES" [ngValue]="mass">{{ mass.name }}</option>
|
||||
</select>
|
||||
</th>
|
||||
<td colspan="2">
|
||||
<input type="number" [(ngModel)]="pivot.modelMeters" (ngModelChange)="ngOnInit()">
|
||||
<td>
|
||||
<input type="number" [(ngModel)]="pivot.modelMeters" (ngModelChange)="update()">
|
||||
</td>
|
||||
<td class="unit">
|
||||
m
|
||||
@ -12,14 +12,17 @@ td {
|
||||
.name {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.real {
|
||||
text-align: right;
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
.model {
|
||||
text-align: right;
|
||||
width: 33.33%;
|
||||
}
|
||||
|
||||
input {
|
||||
@ -0,0 +1,46 @@
|
||||
import {Component, Inject, LOCALE_ID, OnInit} from '@angular/core';
|
||||
import {DecimalPipe, NgForOf} from "@angular/common";
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {SolarSystemBody} from "./SolarSystemBody";
|
||||
import {BODIES, JUPITER} from "./SOLAR_SYSTEM";
|
||||
import {applyPrefixUnit, Unit} from "../Unit";
|
||||
|
||||
@Component({
|
||||
selector: 'app-solar-system',
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgForOf,
|
||||
DecimalPipe,
|
||||
FormsModule,
|
||||
],
|
||||
templateUrl: './solar-system.component.html',
|
||||
styleUrl: './solar-system.component.less'
|
||||
})
|
||||
export class SolarSystemComponent implements OnInit {
|
||||
|
||||
protected readonly applyPrefixUnit = applyPrefixUnit;
|
||||
|
||||
protected readonly BODIES = BODIES;
|
||||
|
||||
protected pivot: SolarSystemBody = JUPITER;
|
||||
|
||||
protected diameterUnit: Unit;
|
||||
|
||||
constructor(
|
||||
@Inject(LOCALE_ID) readonly locale: string,
|
||||
) {
|
||||
this.diameterUnit = new Unit('m', this.locale);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.pivot.modelMeters = 0.18;
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected update() {
|
||||
const scale = this.pivot.modelMeters / this.pivot.realMeters;
|
||||
BODIES.filter(m => m != this.pivot).forEach(m => m.modelMeters = scale * m.realMeters);
|
||||
this.diameterUnit.update(this.pivot.modelMeters);
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
export class Mass {
|
||||
|
||||
modelMeters: number;
|
||||
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly realMeters: number,
|
||||
readonly massKg: number,
|
||||
readonly moons: Mass[],
|
||||
modeMeters?: number,
|
||||
) {
|
||||
this.modelMeters = modeMeters || realMeters;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,90 +0,0 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {DecimalPipe, NgForOf} from "@angular/common";
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {Mass} from "./Mass";
|
||||
|
||||
const PREFIXES_POSITIVE: string[] = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q'];
|
||||
|
||||
const PREFIXES_NEGATIVE: string[] = ['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y', 'r', 'q'];
|
||||
|
||||
@Component({
|
||||
selector: 'app-solar',
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgForOf,
|
||||
DecimalPipe,
|
||||
FormsModule
|
||||
],
|
||||
templateUrl: './solar.component.html',
|
||||
styleUrl: './solar.component.less'
|
||||
})
|
||||
export class SolarComponent implements OnInit {
|
||||
|
||||
protected readonly jupiter = new Mass('Jupiter', 139820000, 1.898e30, [
|
||||
new Mass('Io', 3643000, 8.932e25, []),
|
||||
new Mass('Europa', 3121600, 4.799e25, []),
|
||||
new Mass('Ganymede', 5262400, 1.4819e26, []),
|
||||
new Mass('Callisto', 4820600, 1.0759e26, [])
|
||||
], 0.18);
|
||||
|
||||
protected masses: Mass[] = [
|
||||
new Mass('Sonne', 1392700000, 1.989e33, []),
|
||||
new Mass('Merkur', 4879400, 3.285e26, []),
|
||||
new Mass('Venus', 12104000, 4.867e27, []),
|
||||
new Mass('Erde', 12742000, 5.972e27, [
|
||||
new Mass('Mond', 3474800, 7.342e25, [])
|
||||
]),
|
||||
new Mass('Mars', 6779000, 6.39e26, [
|
||||
new Mass('Phobos', 22533, 1.0659e19, []),
|
||||
new Mass('Deimos', 12400, 1.4762e18, [])
|
||||
]),
|
||||
this.jupiter,
|
||||
new Mass('Saturn', 116460000, 5.683e29, [
|
||||
new Mass('Titan', 5149460, 1.3452e26, []),
|
||||
new Mass('Enceladus', 504200, 1.08e23, [])
|
||||
]),
|
||||
new Mass('Uranus', 50724000, 8.681e28, [
|
||||
new Mass('Miranda', 471600, 6.59e22, []),
|
||||
new Mass('Ariel', 1157800, 1.35e24, []),
|
||||
new Mass('Umbriel', 1169400, 1.17e24, []),
|
||||
new Mass('Titania', 1576800, 3.42e24, []),
|
||||
new Mass('Oberon', 1522800, 3.01e24, [])
|
||||
]),
|
||||
new Mass('Neptun', 49244000, 1.024e29, [
|
||||
new Mass('Triton', 2706800, 2.14e25, [])
|
||||
])
|
||||
];
|
||||
|
||||
protected pivot: Mass = this.jupiter;
|
||||
|
||||
protected divisor: number = 1;
|
||||
|
||||
protected prefix = "";
|
||||
|
||||
ngOnInit() {
|
||||
const scale = this.pivot.modelMeters / this.pivot.realMeters;
|
||||
this.masses.filter(m => m != this.pivot).forEach(m => m.modelMeters = scale * m.realMeters);
|
||||
this.updatePrefix();
|
||||
}
|
||||
|
||||
private updatePrefix() {
|
||||
const exponent = Math.floor(Math.log10(this.jupiter.modelMeters));
|
||||
const prefixGroup = Math.floor(exponent / 3);
|
||||
if (prefixGroup <= 0) {
|
||||
this.prefix = PREFIXES_NEGATIVE[-prefixGroup];
|
||||
} else {
|
||||
this.prefix = PREFIXES_POSITIVE[prefixGroup];
|
||||
}
|
||||
const exponentFromGroup = prefixGroup * 3;
|
||||
this.divisor = Math.pow(10, exponentFromGroup);
|
||||
}
|
||||
|
||||
unit(value: number, unit: string) {
|
||||
return this.doPrefix(value, unit, this.divisor, this.prefix, 2);
|
||||
}
|
||||
|
||||
doPrefix(value: number, unit: string, divisor: number, prefix: string, digits: number) {
|
||||
return (value / divisor).toFixed(digits) + ' ' + prefix + unit;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Patrix Tools</title>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user