menubar, tiles, VoltageDrop from old project
This commit is contained in:
parent
5c493be073
commit
58496e74ec
@ -1 +1,5 @@
|
||||
<div id="mainMenu">
|
||||
<div class="mainMenuItem" routerLinkActive="mainMenuItemActive" routerLink="/Solar">Sonnensystem</div>
|
||||
<div class="mainMenuItem" routerLinkActive="mainMenuItemActive" routerLink="/VoltageDrop">Spannungsabfall</div>
|
||||
</div>
|
||||
<router-outlet/>
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
#mainMenu {
|
||||
border-bottom: 1px solid black;
|
||||
|
||||
.mainMenuItem {
|
||||
float: left;
|
||||
padding: 0.5em;
|
||||
border-right: 1px solid black;
|
||||
}
|
||||
|
||||
.mainMenuItemActive {
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
import {Component} from '@angular/core';
|
||||
import {RouterOutlet} from '@angular/router';
|
||||
import {RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
standalone: true,
|
||||
imports: [RouterOutlet],
|
||||
imports: [RouterOutlet, RouterLink, RouterLinkActive],
|
||||
templateUrl: './app.component.html',
|
||||
styleUrl: './app.component.less'
|
||||
})
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import {Routes} from '@angular/router';
|
||||
import {SolarComponent} from './solar/solar.component';
|
||||
import {VoltageDropComponent} from "./voltage-drop/voltage-drop.component";
|
||||
|
||||
export const routes: Routes = [
|
||||
{path: 'Solar', component: SolarComponent},
|
||||
{path: 'VoltageDrop', component: VoltageDropComponent},
|
||||
{path: '**', redirectTo: '/Solar'},
|
||||
];
|
||||
|
||||
@ -4,12 +4,12 @@ export class Mass {
|
||||
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly diameterMeters: number,
|
||||
readonly realMeters: number,
|
||||
readonly massKg: number,
|
||||
readonly moons: Mass[],
|
||||
modeMeters?: number,
|
||||
) {
|
||||
this.modelMeters = modeMeters || diameterMeters;
|
||||
this.modelMeters = modeMeters || realMeters;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,11 +1,40 @@
|
||||
<div class="tileContainer">
|
||||
|
||||
<div class="tile">
|
||||
|
||||
<div class="tileInner">
|
||||
<div class="tileTitle">
|
||||
Sonnensystem Skalieren
|
||||
</div>
|
||||
<div class="tileContent">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="name">Name</td>
|
||||
<td class="real">Realität</td>
|
||||
<td class="model" colspan="2">Skaliert</td>
|
||||
</tr>
|
||||
<tr *ngFor="let mass of masses">
|
||||
<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>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
<select [(ngModel)]="pivot">
|
||||
<option *ngFor="let mass of masses" [ngValue]="mass">{{ mass.name }}</option>
|
||||
</select>
|
||||
<input type="number" [(ngModel)]="pivot.modelMeters" (ngModelChange)="ngOnInit()">m
|
||||
<table>
|
||||
<tr *ngFor="let mass of masses">
|
||||
<th>{{ mass.name }}</th>
|
||||
<td>{{ doPrefix(mass.diameterMeters, 'm', 1000, 'k', 0) }}</td>
|
||||
<td>{{ unit(mass.modelMeters, 'm') }}</td>
|
||||
</th>
|
||||
<td colspan="2">
|
||||
<input type="number" [(ngModel)]="pivot.modelMeters" (ngModelChange)="ngOnInit()">
|
||||
</td>
|
||||
<td class="unit">
|
||||
m
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@ -1,19 +1,36 @@
|
||||
@import "../../tile.less";
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
td {
|
||||
white-space: nowrap;
|
||||
border: 0.2em solid white;
|
||||
}
|
||||
|
||||
td {
|
||||
.name {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.real {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
table {
|
||||
width: 400px;
|
||||
.model {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
select {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.unit {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ export class SolarComponent implements OnInit {
|
||||
protected prefix = "";
|
||||
|
||||
ngOnInit() {
|
||||
const scale = this.pivot.modelMeters / this.pivot.diameterMeters;
|
||||
this.masses.filter(m => m != this.pivot).forEach(m => m.modelMeters = scale * m.diameterMeters);
|
||||
const scale = this.pivot.modelMeters / this.pivot.realMeters;
|
||||
this.masses.filter(m => m != this.pivot).forEach(m => m.modelMeters = scale * m.realMeters);
|
||||
this.updatePrefix();
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
<div class="value">
|
||||
<div class="label">{{title}}</div>
|
||||
<div class="input">
|
||||
<input disabled type="number" [value]="round(value, places)">
|
||||
<div class="unit">{{unit}}</div>
|
||||
</div>
|
||||
<div class="input" *ngIf="percentDivisor !== undefined">
|
||||
<input *ngIf="value !== undefined" disabled type="number" [class.tooHigh]="percentMax !== undefined && value / percentDivisor > percentMax" [value]="formatPercent()">
|
||||
<div class="unit">%</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,44 @@
|
||||
.value {
|
||||
clear: both;
|
||||
|
||||
.label {
|
||||
padding: 1vmin 0 0.5vmin 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
clear: both;
|
||||
float: left;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
float: left;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input.tooHigh {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.unit {
|
||||
padding-left: 0.5vmin;
|
||||
}
|
||||
|
||||
.shortcuts {
|
||||
clear: both;
|
||||
|
||||
.shortcut {
|
||||
float: left;
|
||||
font-size: 90%;
|
||||
padding: 0.2vmin 0.7vmin;
|
||||
margin: 0.5vmin;
|
||||
border-radius: 0.5vmin;
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.shortcutSelected {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
import {Component, Input, OnInit} from '@angular/core';
|
||||
import {NgIf} from "@angular/common";
|
||||
|
||||
@Component({
|
||||
selector: 'app-value',
|
||||
templateUrl: './value.component.html',
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgIf
|
||||
],
|
||||
styleUrls: ['./value.component.less']
|
||||
})
|
||||
export class ValueComponent implements OnInit {
|
||||
|
||||
@Input()
|
||||
title!: string;
|
||||
|
||||
@Input()
|
||||
unit!: string;
|
||||
|
||||
@Input()
|
||||
value?: number;
|
||||
|
||||
@Input()
|
||||
places?: number;
|
||||
|
||||
@Input()
|
||||
percentDivisor?: number;
|
||||
|
||||
@Input()
|
||||
percentPlaces?: number;
|
||||
|
||||
@Input()
|
||||
percentMax?: number;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
round(value: number | undefined, places: number | undefined): number | undefined {
|
||||
if (value === undefined || places === undefined) {
|
||||
return value;
|
||||
}
|
||||
const divisor = Math.pow(10, places);
|
||||
return Math.round(value * divisor) / divisor;
|
||||
}
|
||||
|
||||
formatPercent(): number | undefined {
|
||||
if (this.value === undefined || this.percentDivisor === undefined || this.percentPlaces === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
return this.round(this.value / this.percentDivisor * 100, this.percentPlaces)
|
||||
}
|
||||
|
||||
defined() {
|
||||
for (let argument of arguments) {
|
||||
if (argument === undefined || argument === null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
<div class="box">
|
||||
<div class="value">
|
||||
<div class="label">Spannung</div>
|
||||
<div class="input"><input type="number" [(ngModel)]="values.voltage" (ngModelChange)="update()"></div>
|
||||
<div class="unit">V</div>
|
||||
<div class="shortcuts">
|
||||
<ng-container *ngFor="let v of voltages">
|
||||
<div class="shortcut" [class.shortcutSelected]="values.voltage===v" (click)="values.voltage=v; update()">{{v}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="value">
|
||||
<div class="label">Leistung</div>
|
||||
<div class="input"><input type="number" [(ngModel)]="values.power" (ngModelChange)="update()"></div>
|
||||
<div class="unit">kW</div>
|
||||
<div class="shortcuts">
|
||||
<ng-container *ngFor="let c of powers">
|
||||
<div class="shortcut" [class.shortcutSelected]="values.power===c" (click)="values.power=c; update()">{{c}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="value">
|
||||
<div class="label">Querschnitt</div>
|
||||
<div class="input"><input type="number" [(ngModel)]="values.crossSection" (ngModelChange)="update()"></div>
|
||||
<div class="unit">mm²</div>
|
||||
<div class="shortcuts">
|
||||
<ng-container *ngFor="let c of crossSections">
|
||||
<div class="shortcut" [class.shortcutSelected]="values.crossSection===c" (click)="values.crossSection=c; update()">{{c}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="value">
|
||||
<div class="label">Länge (1-fach)</div>
|
||||
<div class="input"><input type="number" [(ngModel)]="values.length" (ngModelChange)="update()"></div>
|
||||
<div class="unit">m</div>
|
||||
<div class="shortcuts">
|
||||
<ng-container *ngFor="let l of lengths">
|
||||
<div class="shortcut" [class.shortcutSelected]="values.length===l" (click)="values.length=l; update()">{{l}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="value">
|
||||
<div class="label">Spezifischer Widerstand</div>
|
||||
<div class="input"><input type="number" [(ngModel)]="values.resistanceSpecific" (ngModelChange)="update()"></div>
|
||||
<div class="unit">Ω*m</div>
|
||||
<div class="shortcuts">
|
||||
<ng-container *ngFor="let r of resistances">
|
||||
<div class="shortcut" [class.shortcutSelected]="values.resistanceSpecific===r.value" (click)="values.resistanceSpecific=r.value; update()">{{r.name}}</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<app-value title="Spannungsverlust" unit="V" [value]="voltageDrop2Way" [places]="1" [percentDivisor]="values.voltage" [percentPlaces]="2" [percentMax]="0.03"></app-value>
|
||||
<app-value title="Verlustleistung" unit="W" [value]="powerLoss2Way" [places]="0"></app-value>
|
||||
<app-value title="Verfügbare Spannung" unit="V" [value]="voltageDropLoad" [places]="1" [percentDivisor]="values.voltage" [percentPlaces]="2"></app-value>
|
||||
<app-value title="Verfügbare Leistung" unit="W" [value]="powerLoad" [places]="0" [percentDivisor]="values.power * 1000" [percentPlaces]="2"></app-value>
|
||||
<app-value title="Strom" unit="A" [value]="current" [places]="1"></app-value>
|
||||
<app-value title="Leitungwiderstand" unit="Ω" [value]="resistance2Way" [places]="3"></app-value>
|
||||
<app-value title="Lastwiderstand" unit="Ω" [value]="resistanceLoad" [places]="3"></app-value>
|
||||
<app-value title="Gesamtwiderstand" unit="Ω" [value]="resistanceTotal" [places]="3"></app-value>
|
||||
</div>
|
||||
@ -0,0 +1,76 @@
|
||||
@import "../../tile.less";
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
td {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.box {
|
||||
border-top: 1px solid black;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.box:first-child {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
clear: both;
|
||||
|
||||
.label {
|
||||
padding: 1vmin 0 0.5vmin 0;
|
||||
}
|
||||
|
||||
.input {
|
||||
clear: both;
|
||||
float: left;
|
||||
}
|
||||
|
||||
input[type=number] {
|
||||
float: left;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
input.tooHigh {
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
.unit {
|
||||
padding-left: 0.5vmin;
|
||||
}
|
||||
|
||||
.shortcuts {
|
||||
clear: both;
|
||||
|
||||
.shortcut {
|
||||
float: left;
|
||||
font-size: 90%;
|
||||
padding: 0.2vmin 0.7vmin;
|
||||
margin: 0.5vmin;
|
||||
border-radius: 0.5vmin;
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
.shortcutSelected {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 800px) {
|
||||
.box {
|
||||
float: left;
|
||||
width: 50%;
|
||||
border-top-width: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
121
src/main/angular/src/app/voltage-drop/voltage-drop.component.ts
Normal file
121
src/main/angular/src/app/voltage-drop/voltage-drop.component.ts
Normal file
@ -0,0 +1,121 @@
|
||||
import { Component } from '@angular/core';
|
||||
import {FormsModule} from "@angular/forms";
|
||||
import {ValueComponent} from "./value/value.component";
|
||||
import {NgForOf} from "@angular/common";
|
||||
|
||||
class Resistance {
|
||||
|
||||
constructor(
|
||||
readonly name: string,
|
||||
readonly value: number,
|
||||
) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Values {
|
||||
|
||||
constructor(
|
||||
public length: number,
|
||||
public voltage: number,
|
||||
public power: number,
|
||||
public crossSection: number,
|
||||
public resistanceSpecific: number,
|
||||
) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-voltage-drop',
|
||||
standalone: true,
|
||||
imports: [
|
||||
FormsModule,
|
||||
ValueComponent,
|
||||
NgForOf
|
||||
],
|
||||
templateUrl: './voltage-drop.component.html',
|
||||
styleUrl: './voltage-drop.component.less'
|
||||
})
|
||||
export class VoltageDropComponent {
|
||||
|
||||
readonly lengths: number[] = [10, 15, 20, 30, 40, 50, 75, 100];
|
||||
|
||||
readonly voltages: number[] = [5, 12, 24, 36, 230, 400];
|
||||
|
||||
readonly powers: number[] = [0.5, 1, 2, 3.68, 5, 7.5, 10, 15, 20, 25, 30];
|
||||
|
||||
readonly crossSections: number[] = [0.75, 1.5, 2.5, 4, 6, 10, 16, 25, 35, 50];
|
||||
|
||||
readonly resistances: Resistance[] = [
|
||||
{name: 'Silber', value: 0.015},
|
||||
{name: 'Kupfer', value: 0.017},
|
||||
{name: 'Aluminium', value: 0.0278},
|
||||
];
|
||||
|
||||
readonly testSet: Values = {
|
||||
length: this.lengths[4],
|
||||
voltage: this.voltages[4],
|
||||
power: this.powers[3],
|
||||
crossSection: this.crossSections[3],
|
||||
resistanceSpecific: this.resistances[1].value,
|
||||
}
|
||||
|
||||
readonly testSet2: Values = {
|
||||
length: 100,
|
||||
voltage: 230,
|
||||
power: 2.5,
|
||||
crossSection: 1.5,
|
||||
resistanceSpecific: this.resistances[1].value,
|
||||
}
|
||||
|
||||
readonly values: Values = this.testSet;
|
||||
|
||||
resistance2Way?: number;
|
||||
|
||||
resistanceLoad?: number;
|
||||
|
||||
resistanceTotal?: number;
|
||||
|
||||
current?: number;
|
||||
|
||||
voltageDrop2Way?: number;
|
||||
|
||||
powerLoss2Way?: number;
|
||||
|
||||
voltageDropLoad?: number;
|
||||
|
||||
powerLoad?: number;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
if (!this.values || !this.values.resistanceSpecific || !this.values.length || !this.values.crossSection || !this.values.power || !this.values.voltage) {
|
||||
this.resistance2Way = undefined;
|
||||
this.resistanceLoad = undefined;
|
||||
this.resistanceTotal = undefined;
|
||||
this.current = undefined;
|
||||
this.voltageDrop2Way = undefined;
|
||||
this.powerLoss2Way = undefined;
|
||||
this.voltageDropLoad = undefined;
|
||||
this.powerLoad = undefined;
|
||||
return;
|
||||
}
|
||||
this.resistance2Way = (this.values.resistanceSpecific * this.values.length / this.values.crossSection) * 2;
|
||||
this.resistanceLoad = (this.values.voltage * this.values.voltage) / (this.values.power * 1000);
|
||||
this.resistanceTotal = this.resistance2Way + this.resistanceLoad;
|
||||
this.current = this.values.voltage / this.resistanceTotal;
|
||||
this.voltageDrop2Way = this.resistance2Way * this.current;
|
||||
this.powerLoss2Way = this.voltageDrop2Way * this.current;
|
||||
this.voltageDropLoad = this.resistanceLoad * this.current;
|
||||
this.powerLoad = this.voltageDropLoad * this.current;
|
||||
}
|
||||
|
||||
}
|
||||
1
src/main/angular/src/config.less
Normal file
1
src/main/angular/src/config.less
Normal file
@ -0,0 +1 @@
|
||||
@space: 0.5em;
|
||||
@ -1,6 +1,7 @@
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
font-size: 4vw;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
@ -12,6 +13,16 @@ a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
input {
|
||||
all: unset;
|
||||
background-color: white;
|
||||
border: 1px solid lightgray;
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
41
src/main/angular/src/tile.less
Normal file
41
src/main/angular/src/tile.less
Normal file
@ -0,0 +1,41 @@
|
||||
@import "config.less";
|
||||
|
||||
.tileContainer {
|
||||
padding: calc(@space / 2);
|
||||
|
||||
.tile {
|
||||
width: 100%;
|
||||
padding: calc(@space / 2);
|
||||
|
||||
.tileInner {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: @space;
|
||||
background-color: #fbfbfb;
|
||||
|
||||
.tileTitle {
|
||||
font-weight: bold;
|
||||
padding: calc(@space / 2) @space;
|
||||
background-color: lightskyblue;
|
||||
}
|
||||
|
||||
.tileContent {
|
||||
padding: calc(@space / 2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (min-width: 1000px) {
|
||||
|
||||
.tileContainer {
|
||||
|
||||
.tile {
|
||||
float: left;
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user