SolarSystemPrintout

This commit is contained in:
Patrick Haßel 2024-10-23 14:06:51 +02:00
parent 453ad488ed
commit 43bb77e856
11 changed files with 259 additions and 40 deletions

View File

@ -19,8 +19,7 @@ export class Unit {
constructor(
readonly unit: string,
readonly locale: string,
) {
readonly locale: string) {
// -
}
@ -43,6 +42,11 @@ export class Unit {
this._divisor = Math.pow(10, exponentFromGroup);
}
updateAndApplyPrefixUnit(value: number): string {
this.update(value);
return this.applyPrefixUnit(value);
}
applyPrefixUnit(value: number): string {
return applyPrefixUnit(value, this.unit, this.divisor, this.prefix, 2, this.locale);
}

View File

@ -1,5 +1,5 @@
<div id="mainMenu">
<div id="mainMenu" *ngIf="menuVisible">
<div class="mainMenuItem" routerLinkActive="mainMenuItemActive" routerLink="/Solar">Sonnensystem</div>
<div class="mainMenuItem" routerLinkActive="mainMenuItemActive" routerLink="/VoltageDrop">Spannungsabfall</div>
</div>
<router-outlet/>
<router-outlet (activate)="onActivate($event)"/>

View File

@ -1,12 +1,20 @@
import {Component} from '@angular/core';
import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
import {NgIf} from "@angular/common";
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, RouterLink, RouterLinkActive],
imports: [RouterOutlet, RouterLink, RouterLinkActive, NgIf],
templateUrl: './app.component.html',
styleUrl: './app.component.less'
})
export class AppComponent {
protected menuVisible = true;
onActivate(component: any) {
this.menuVisible = !("PRINTABLE_ONLY" in component) || !component.PRINTABLE_ONLY;
}
}

View File

@ -1,9 +1,16 @@
import {Routes} from '@angular/router';
import {SolarSystemComponent} from './solar-system/solar-system.component';
import {VoltageDropComponent} from "./voltage-drop/voltage-drop.component";
import {SolarSystemPrintoutComponent} from "./solar-system/printout/solar-system-printout.component";
export const routes: Routes = [
{path: 'Solar', component: SolarSystemComponent},
{path: 'SolarSystemPrintout', component: SolarSystemPrintoutComponent},
{path: 'SolarSystem', component: SolarSystemComponent},
{path: 'VoltageDrop', component: VoltageDropComponent},
// historic
{path: 'Solar', redirectTo: '/SolarSystem'},
// fallback
{path: '**', redirectTo: '/Solar'},
];

View File

@ -1,43 +1,48 @@
import {SolarSystemBody} from "./SolarSystemBody";
export const SUN = new SolarSystemBody('Sonne', 1392700000, 0, 1.989e33, []);
export const JUPITER_SCALED_DIAMETER = 0.19;
export const MERCURY = new SolarSystemBody('Merkur', 4879400, 57.9, 3.285e26, []);
export const SUN = new SolarSystemBody('Sonne', 1392700000, 0, 1.989e33, '#FFD700', '#FFD700', []);
export const VENUS = new SolarSystemBody('Venus', 12104000, 108.2, 4.867e27, []);
export const MERCURY = new SolarSystemBody('Merkur', 4879400, 57.9, 3.285e26, '#B1B1B1', '#B1B1B1', []);
export const EARTH = new SolarSystemBody('Erde', 12742000, 149.6, 5.972e27, [
new SolarSystemBody('Mond', 3474800, 0, 7.342e25, [])
export const VENUS = new SolarSystemBody('Venus', 12104000, 108.2, 4.867e27, '#D4AF37', '#D4AF37', []);
export const EARTH_MOON = new SolarSystemBody('Mond', 3474800, 0, 7.342e25, '#C0C0C0', '#C0C0C0', []);
export const EARTH = new SolarSystemBody('Erde', 12742000, 149.6, 5.972e27, '#1E90FF', '#1E90FF', [
EARTH_MOON
]);
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 MARS = new SolarSystemBody('Mars', 6779000, 228, 6.39e26, '#FF4500', '#FF4500', [
new SolarSystemBody('Phobos', 22533, 0, 1.0659e19, '#8B4513', '#8B4513', []),
new SolarSystemBody('Deimos', 12400, 0, 1.4762e18, '#A0522D', '#A0522D', [])
]);
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 JUPITER = new SolarSystemBody('Jupiter', 139820000, 778.5, 1.898e30, '#D2691E', '#d8b197', [
new SolarSystemBody('Io', 3643000, 0, 8.932e25, '#FFD700', '#FFD700', []),
new SolarSystemBody('Europa', 3121600, 0, 4.799e25, '#C0C0C0', '#C0C0C0', []),
new SolarSystemBody('Ganymede', 5262400, 0, 1.4819e26, '#808080', '#808080', []),
new SolarSystemBody('Callisto', 4820600, 0, 1.0759e26, '#A9A9A9', '#A9A9A9', [])
]);
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 SATURN = new SolarSystemBody('Saturn', 116460000, 1432, 5.683e29, '#F4A460', '#F4A460', [
new SolarSystemBody('Titan', 5149460, 0, 1.3452e26, '#F4A460', '#F4A460', []),
new SolarSystemBody('Enceladus', 504200, 0, 1.08e23, '#FFFFFF', '#FFFFFF', [])
]);
export const NEPTUNE = new SolarSystemBody('Neptun', 49244000, 4515, 1.024e29, [
new SolarSystemBody('Triton', 2706800, 0, 2.14e25, [])
export const URANUS = new SolarSystemBody('Uranus', 50724000, 2867, 8.681e28, '#40E0D0', '#40E0D0', [
new SolarSystemBody('Miranda', 471600, 0, 6.59e22, '#B0E0E6', '#B0E0E6', []),
new SolarSystemBody('Ariel', 1157800, 0, 1.35e24, '#ADD8E6', '#ADD8E6', []),
new SolarSystemBody('Umbriel', 1169400, 0, 1.17e24, '#696969', '#696969', []),
new SolarSystemBody('Titania', 1576800, 0, 3.42e24, '#C0C0C0', '#C0C0C0', []),
new SolarSystemBody('Oberon', 1522800, 0, 3.01e24, '#A9A9A9', '#A9A9A9', [])
]);
export const NEPTUNE = new SolarSystemBody('Neptun', 49244000, 4515, 1.024e29, '#0000FF', '#0000FF', [
new SolarSystemBody('Triton', 2706800, 0, 2.14e25, '#B0C4DE', '#B0C4DE', [])
]);
export const BODIES: SolarSystemBody[] = [SUN, MERCURY, VENUS, EARTH, MARS, JUPITER, SATURN, URANUS, NEPTUNE];
export const BODIES_PRINT: SolarSystemBody[] = [NEPTUNE, URANUS, SATURN, EARTH_MOON, MERCURY, VENUS, EARTH, MARS, JUPITER, SUN];

View File

@ -1,4 +1,4 @@
export const MIO_KM: number = 1000 * 1000 * 1000;
export const MIO_KILO: number = 1000 * 1000 * 1000;
export class SolarSystemBody {
@ -12,10 +12,12 @@ export class SolarSystemBody {
readonly name: string,
readonly realDiameter: number,
realDistanceMioKm: number,
readonly massKg: number,
readonly massGrams: number,
readonly backColor: string,
readonly fontColor: string,
readonly moons: SolarSystemBody[],
) {
this.realDistance = realDistanceMioKm * MIO_KM;
this.realDistance = realDistanceMioKm * MIO_KILO;
this.scaledDiameter = realDiameter;
this.scaledDistance = realDistanceMioKm;
}
@ -23,6 +25,11 @@ export class SolarSystemBody {
scale(scale: number) {
this.scaledDiameter = this.realDiameter * scale;
this.scaledDistance = this.realDistance * scale;
this.moons.forEach(m => m.scale(scale));
}
static compareSize(a: SolarSystemBody, b: SolarSystemBody): number {
return a.realDiameter - b.realDiameter;
};
}

View File

@ -0,0 +1,27 @@
<div class="pageWidth">
<ng-container *ngFor="let body of BODIES_PRINT">
<div class="planet {{body.name}}"
[style.font-size]="fontSize(body)"
[style.width]="calcWidth(body)"
[style.line-height]="calcWidth(body)"
[style.background-color]="makePaler(body.backColor, 0.7)"
>
<div class="label" *ngIf="body !== EARTH_MOON">
<ng-container *ngIf="!tooSmall(body)">{{ body.name }}</ng-container>
<ng-container *ngIf="tooSmall(body)">{{ body.name.substring(0, 2) }}</ng-container>
<table *ngIf="body.scaledDiameter >= 0.04">
<tr>
<td class="title">Masse:</td>
<td class="value">{{ body.massGrams / EARTH.massGrams | number:'0.1-1' }}</td>
<td class="unit">&nbsp;mal Erde</td>
</tr>
<tr *ngIf="body !== SUN">
<td class="title">Abstand:</td>
<td class="value">{{ body.realDistance / MIO_KILO | number:'0.1-1' }}</td>
<td class="unit">&nbsp;Mio. km</td>
</tr>
</table>
</div>
</div>
</ng-container>
</div>

View File

@ -0,0 +1,68 @@
@page {
size: A4;
margin: 10mm;
}
.pageWidth {
width: 210mm;
padding-right: 20mm;
}
.planet {
float: left;
border: 3px solid black;
border-radius: 50%;
aspect-ratio: 1;
margin-left: auto;
margin-right: auto;
page-break-inside: avoid;
text-align: center;
.label {
margin-top: -0.55em;
display: inline-block;
line-height: 1.5;
vertical-align: middle;
white-space: nowrap;
table {
margin-left: auto;
margin-right: auto;
width: 80%;
font-size: 25%;
.title {
text-align: left;
width: 10em;
}
.value {
text-align: right;
font-weight: bold;
}
.unit {
text-align: left;
}
}
}
}
.Sonne {
text-align: left;
page-break-inside: unset;
.label {
margin-top: -2em;
margin-left: 0.5cm;
font-size: 5cm;
text-align: center;
table {
width: 17cm;
}
}
}

View File

@ -0,0 +1,90 @@
import {Component, Inject, LOCALE_ID, OnInit} from '@angular/core';
import {BODIES, BODIES_PRINT, EARTH, EARTH_MOON, JUPITER, JUPITER_SCALED_DIAMETER, SUN} from "../SOLAR_SYSTEM";
import {ActivatedRoute, Params} from "@angular/router";
import {DecimalPipe, NgForOf, NgIf} from "@angular/common";
import {MIO_KILO, SolarSystemBody} from "../SolarSystemBody";
import {Unit} from "../../Unit";
function getScale(params: Params) {
if ('scale' in params) {
return parseFloat(params['scale']);
}
return JUPITER.scaledDiameter / JUPITER.realDiameter;
}
export function makePaler(hexColor: string, factor: number): string {
if (!hexColor.startsWith('#') || hexColor.length !== 7) {
throw new Error('Invalid hex color format. Use #rrggbb format.');
}
const r = parseInt(hexColor.slice(1, 3), 16);
const g = parseInt(hexColor.slice(3, 5), 16);
const b = parseInt(hexColor.slice(5, 7), 16);
const newR = Math.round(r + (255 - r) * factor);
const newG = Math.round(g + (255 - g) * factor);
const newB = Math.round(b + (255 - b) * factor);
const toHex = (component: number) => component.toString(16).padStart(2, '0');
return `#${toHex(newR)}${toHex(newG)}${toHex(newB)}`;
}
@Component({
selector: 'app-solar-system-printout',
standalone: true,
imports: [
NgForOf,
NgIf,
DecimalPipe
],
templateUrl: './solar-system-printout.component.html',
styleUrl: './solar-system-printout.component.less'
})
export class SolarSystemPrintoutComponent implements OnInit {
public readonly PRINTABLE_ONLY: boolean = true;
protected readonly BODIES_PRINT = BODIES_PRINT;
protected readonly SolarSystemBody = SolarSystemBody;
protected readonly makePaler = makePaler;
protected readonly MIO_KILO = MIO_KILO;
protected readonly EARTH = EARTH;
protected readonly EARTH_MOON = EARTH_MOON;
protected readonly SUN = SUN;
protected distanceUnit: Unit;
constructor(
@Inject(LOCALE_ID) readonly locale: string,
readonly activatedRoute: ActivatedRoute,
) {
this.distanceUnit = new Unit('m', locale);
}
ngOnInit(): void {
JUPITER.scaledDiameter = JUPITER_SCALED_DIAMETER;
this.activatedRoute.params.subscribe(params => {
const scale = getScale(params);
BODIES.forEach(b => b.scale(scale));
});
}
fontSize(body: SolarSystemBody): string {
if (this.tooSmall(body)) {
return body.scaledDiameter * 50 + 'cm';
}
return body.scaledDiameter * 25 + 'cm';
}
protected tooSmall(body: SolarSystemBody): boolean {
return body.scaledDiameter < 0.015;
}
calcWidth(body: SolarSystemBody): string {
return body.scaledDiameter * 100 + 'cm';
}
}

View File

@ -61,6 +61,7 @@
</td>
</tr>
</table>
<button [routerLink]="['/SolarSystemPrintout',{scale: scale}]">Druckvorlage</button>
</div>
</div>
</div>

View File

@ -1,9 +1,10 @@
import {Component, Inject, LOCALE_ID, OnInit} from '@angular/core';
import {DecimalPipe, NgForOf} from "@angular/common";
import {FormsModule} from "@angular/forms";
import {MIO_KM, SolarSystemBody} from "./SolarSystemBody";
import {BODIES, JUPITER} from "./SOLAR_SYSTEM";
import {MIO_KILO, SolarSystemBody} from "./SolarSystemBody";
import {BODIES, JUPITER, JUPITER_SCALED_DIAMETER} from "./SOLAR_SYSTEM";
import {applyPrefixUnit, Unit} from "../Unit";
import {RouterLink} from "@angular/router";
@Component({
selector: 'app-solar-system',
@ -12,6 +13,7 @@ import {applyPrefixUnit, Unit} from "../Unit";
NgForOf,
DecimalPipe,
FormsModule,
RouterLink,
],
templateUrl: './solar-system.component.html',
styleUrl: './solar-system.component.less'
@ -22,7 +24,7 @@ export class SolarSystemComponent implements OnInit {
protected readonly BODIES = BODIES;
protected readonly MIO_KM = MIO_KM;
protected readonly MIO_KM = MIO_KILO;
protected readonly diameterUnit: Unit;
@ -40,7 +42,7 @@ export class SolarSystemComponent implements OnInit {
}
ngOnInit() {
this.pivot.scaledDiameter = 0.18;
this.pivot.scaledDiameter = JUPITER_SCALED_DIAMETER;
this.update();
}