Created new component and refactored

- Created new component to display the game of life algo
- created an algo info component to combine the algo header for all algos
This commit is contained in:
2026-02-06 09:59:12 +01:00
parent ff1ee9b5f6
commit da43213808
18 changed files with 223 additions and 80 deletions

View File

@@ -10,7 +10,7 @@
mat-card {
cursor: pointer;
min-width: 300px;
max-width: 400px;
min-width: 450px;
max-width: 450px;
}
}

View File

@@ -0,0 +1,8 @@
<mat-card class="container">
<mat-card-header>
<mat-card-title>{{ 'GOL.TITLE' | translate }}</mat-card-title>
</mat-card-header>
<mat-card-content>
<app-information [algorithmInformation]="algoInformation"/>
</mat-card-content>
</mat-card>

View File

@@ -0,0 +1,43 @@
import { Component } from '@angular/core';
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from "@angular/material/card";
import {TranslatePipe} from "@ngx-translate/core";
import {UrlConstants} from '../../../constants/UrlConstants';
import {Information} from '../information/information';
import {AlgorithmInformation} from '../information/information.models';
@Component({
selector: 'app-conway-gol',
imports: [
MatCard,
MatCardContent,
MatCardHeader,
MatCardTitle,
TranslatePipe,
Information
],
templateUrl: './conway-gol.html',
styleUrl: './conway-gol.scss',
})
export class ConwayGol {
protected readonly UrlConstants = UrlConstants;
algoInformation: AlgorithmInformation = {
title: 'PATHFINDING.EXPLANATION.TITLE',
entries: [
{
name: 'Dijkstra',
description: 'PATHFINDING.EXPLANATION.DIJKSTRA_EXPLANATION',
link: UrlConstants.DIJKSTRA_WIKI
},
{
name: 'A*',
description: 'PATHFINDING.EXPLANATION.ASTAR_EXPLANATION',
link: UrlConstants.ASTAR_WIKI
}
],
disclaimer: 'PATHFINDING.EXPLANATION.DISCLAIMER',
disclaimerBottom: '',
disclaimerListEntry: []
};
}

View File

@@ -0,0 +1,35 @@
<div class="algo-info">
<h3>{{ algorithmInformation.title | translate }}</h3>
@if(algorithmInformation.entries && algorithmInformation.entries.length > 0){
@for (algo of algorithmInformation.entries; track algo)
{
<p>
<strong>{{ algo.name }}</strong> {{ algo.description | translate }}
<a href="{{algo.link}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
}
}
@if (algorithmInformation.disclaimer !== '')
{
<p>
<strong>{{ 'ALGORITHM.NOTE' | translate}}</strong> {{ algorithmInformation.disclaimer | translate}}
</p>
@if (algorithmInformation.disclaimerListEntry && algorithmInformation.disclaimerListEntry.length > 0)
{
<ul>
@for (entry of algorithmInformation.disclaimerListEntry; track entry)
{
<li>{{ entry | translate}}</li>
}
</ul>
}
@if (algorithmInformation.disclaimerBottom !== '')
{
<p>
{{ algorithmInformation.disclaimerBottom | translate}}
</p>
}
}
</div>

View File

@@ -0,0 +1,14 @@
export interface AlgorithmInformation {
title: string;
entries: AlgorithmEntry[];
disclaimer: string;
disclaimerBottom: string;
disclaimerListEntry: string[];
}
export interface AlgorithmEntry {
name: string;
description: string;
link: string;
}

View File

@@ -0,0 +1,19 @@
import {Component, Input} from '@angular/core';
import {TranslatePipe} from "@ngx-translate/core";
import {UrlConstants} from "../../../constants/UrlConstants";
import {AlgorithmInformation} from './information.models';
@Component({
selector: 'app-information',
imports: [
TranslatePipe
],
templateUrl: './information.html',
styleUrl: './information.scss',
})
export class Information {
@Input({ required: true }) algorithmInformation!: AlgorithmInformation;
protected readonly UrlConstants = UrlConstants;
}

View File

@@ -3,23 +3,7 @@
<mat-card-title>{{ 'PATHFINDING.TITLE' | translate }}</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="algo-info">
<h3>{{ 'PATHFINDING.EXPLANATION.TITLE' | translate }}</h3>
<p>
<strong>Dijkstra</strong> {{ 'PATHFINDING.EXPLANATION.DIJKSTRA_EXPLANATION' | translate }}
<a href="{{UrlConstants.DIJKSTRA_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>A*</strong> {{ 'PATHFINDING.EXPLANATION.ASTAR_EXPLANATION' | translate}}
<a href="{{UrlConstants.ASTAR_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>{{ 'PATHFINDING.EXPLANATION.NOTE' | translate}}</strong> {{ 'PATHFINDING.EXPLANATION.DISCLAIMER' | translate}}
</p>
</div>
<app-information [algorithmInformation]="algoInformation"/>
<div class="controls-container">
<div class="controls">

View File

@@ -13,6 +13,8 @@ import {DEFAULT_GRID_COLS, DEFAULT_GRID_ROWS, MAX_GRID_PX, MAX_GRID_SIZE, MAX_RA
import {PathfindingService} from './service/pathfinding.service';
import {UrlConstants} from '../../../constants/UrlConstants';
import {MatCard, MatCardContent, MatCardHeader, MatCardTitle} from '@angular/material/card';
import {Information} from '../information/information';
import {AlgorithmInformation} from '../information/information.models';
enum NodeType {
Start = 'start',
@@ -37,7 +39,8 @@ interface GridPos { row: number; col: number }
MatCard,
MatCardHeader,
MatCardTitle,
MatCardContent
MatCardContent,
Information
],
templateUrl: './pathfinding.component.html',
styleUrls: ['./pathfinding.component.scss']
@@ -50,6 +53,25 @@ export class PathfindingComponent implements AfterViewInit {
readonly MIN_GRID_SIZE = MIN_GRID_SIZE;
readonly MAX_GRID_SIZE = MAX_GRID_SIZE;
algoInformation: AlgorithmInformation = {
title: 'PATHFINDING.EXPLANATION.TITLE',
entries: [
{
name: 'Dijkstra',
description: 'PATHFINDING.EXPLANATION.DIJKSTRA_EXPLANATION',
link: UrlConstants.DIJKSTRA_WIKI
},
{
name: 'A*',
description: 'PATHFINDING.EXPLANATION.ASTAR_EXPLANATION',
link: UrlConstants.ASTAR_WIKI
}
],
disclaimer: 'PATHFINDING.EXPLANATION.DISCLAIMER',
disclaimerBottom: '',
disclaimerListEntry: []
};
@ViewChild('gridCanvas', { static: true })
canvas!: ElementRef<HTMLCanvasElement>;

View File

@@ -20,6 +20,12 @@ export class AlgorithmsService {
title: 'ALGORITHM.SORTING.TITLE',
description: 'ALGORITHM.SORTING.DESCRIPTION',
routerLink: RouterConstants.SORTING.LINK
},
{
id: 'gameOfLife',
title: 'ALGORITHM.GOL.TITLE',
description: 'ALGORITHM.GOL.DESCRIPTION',
routerLink: RouterConstants.GOL.LINK
}
];

View File

@@ -4,47 +4,13 @@
<mat-card-title>{{ 'SORTING.TITLE' | translate }}</mat-card-title>
</mat-card-header>
<mat-card-content>
<div class="algo-info">
<h3>{{ 'SORTING.EXPLANATION.TITLE' | translate }}</h3>
<p>
<strong>Bubble Sort</strong> {{ 'SORTING.EXPLANATION.BUBBLE_SORT_EXPLANATION' | translate }}
<a href="{{UrlConstants.BUBBLE_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>Cocktail Sort</strong> {{ 'SORTING.EXPLANATION.COCKTAIL_SORT_EXPLANATION' | translate}}
<a href="{{UrlConstants.SHAKE_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>Quick Sort</strong> {{ 'SORTING.EXPLANATION.QUICK_SORT_EXPLANATION' | translate}}
<a href="{{UrlConstants.QUICK_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>Heap Sort</strong> {{ 'SORTING.EXPLANATION.HEAP_SORT_EXPLANATION' | translate}}
<a href="{{UrlConstants.HEAP_SORT_WIKI}}" target="_blank" rel="noopener noreferrer">Wikipedia</a>
</p>
<p>
<strong>{{ 'SORTING.EXPLANATION.NOTE' | translate}}</strong> {{ 'SORTING.EXPLANATION.DISCLAIMER' | translate}}
</p>
<ul>
<li>{{ 'SORTING.EXPLANATION.DISCLAIMER_1' | translate}}</li>
<li>{{ 'SORTING.EXPLANATION.DISCLAIMER_2' | translate}}</li>
<li>{{ 'SORTING.EXPLANATION.DISCLAIMER_3' | translate}}</li>
</ul>
<p>
{{ 'SORTING.EXPLANATION.DISCLAIMER_4' | translate}}
</p>
</div>
<app-information [algorithmInformation]="algoInformation"/>
<div class="controls-panel">
<mat-form-field appearance="fill">
<mat-label>{{ 'SORTING.ALGORITHM' | translate }}</mat-label>
<mat-select [(ngModel)]="selectedAlgorithm">
@for (algo of availableAlgorithms; track algo.value) {
<mat-option [value]="algo.value">{{ algo.name }}</mat-option>
@for (algo of algoInformation.entries; track algo.name) {
<mat-option [value]="algo.name">{{ algo.name }}</mat-option>
}
</mat-select>
</mat-form-field>

View File

@@ -11,11 +11,12 @@ import {SortData, SortSnapshot} from './sorting.models';
import { FormsModule } from '@angular/forms';
import {MatInput} from '@angular/material/input';
import {UrlConstants} from '../../../constants/UrlConstants';
import {MIN} from '@angular/forms/signals';
import {AlgorithmInformation} from '../information/information.models';
import {Information} from '../information/information';
@Component({
selector: 'app-sorting',
standalone: true,
imports: [CommonModule, MatCardModule, MatFormFieldModule, MatSelectModule, MatButtonModule, MatIconModule, TranslateModule, FormsModule, MatInput],
imports: [CommonModule, MatCardModule, MatFormFieldModule, MatSelectModule, MatButtonModule, MatIconModule, TranslateModule, FormsModule, MatInput, Information],
templateUrl: './sorting.component.html',
styleUrls: ['./sorting.component.scss']
})
@@ -27,21 +28,46 @@ export class SortingComponent implements OnInit {
readonly MAX_ARRAY_SIZE: number = 200;
readonly MIN_ARRAY_SIZE: number = 20;
algoInformation: AlgorithmInformation = {
title: 'SORTING.EXPLANATION.TITLE',
entries: [
{
name: 'Bubble Sort',
description: 'SORTING.EXPLANATION.BUBBLE_SORT_EXPLANATION',
link: UrlConstants.BUBBLE_SORT_WIKI
},
{
name: 'Cocktail Sort',
description: 'SORTING.EXPLANATION.COCKTAIL_SORT_EXPLANATION',
link: UrlConstants.SHAKE_SORT_WIKI
},
{
name: 'Quick Sort',
description: 'SORTING.EXPLANATION.QUICK_SORT_EXPLANATION',
link: UrlConstants.QUICK_SORT_WIKI
},
{
name: 'Heap Sort',
description: 'SORTING.EXPLANATION.HEAP_SORT_EXPLANATION',
link: UrlConstants.HEAP_SORT_WIKI
}
],
disclaimer: 'SORTING.EXPLANATION.DISCLAIMER',
disclaimerBottom: 'SORTING.EXPLANATION.DISCLAIMER_4',
disclaimerListEntry: [
'SORTING.EXPLANATION.DISCLAIMER_1',
'SORTING.EXPLANATION.DISCLAIMER_2',
'SORTING.EXPLANATION.DISCLAIMER_3'
]
};
private timeoutIds: number[] = [];
sortArray: SortData[] = [];
unsortedArrayCopy: SortData[] = [];
arraySize = 50;
maxArrayValue = 100;
animationSpeed = 50; // Milliseconds per step
// Placeholder for available sorting algorithms
availableAlgorithms: { name: string; value: string }[] = [
{ name: 'Bubble Sort', value: 'bubbleSort' },
{ name: 'Cocktail Sort', value: 'cocktailSort' },
{ name: 'Quick Sort', value: 'quickSort' },
{ name: 'Heap Sort', value: 'heapSort' },
];
selectedAlgorithm: string = this.availableAlgorithms[0].value;
selectedAlgorithm: string = this.algoInformation.entries[0].name;
executionTime = 0;
ngOnInit(): void {
@@ -93,22 +119,22 @@ export class SortingComponent implements OnInit {
let snapshots: SortSnapshot[] = [];
switch (this.selectedAlgorithm) {
case 'bubbleSort':
case 'Bubble Sort':
snapshots = this.sortingService.bubbleSort(this.sortArray);
break;
case 'quickSort':
case 'Quick Sort':
snapshots = this.sortingService.quickSort(this.sortArray);
break;
case 'heapSort':
case 'Heap Sort':
snapshots = this.sortingService.heapSort(this.sortArray);
break;
case 'cocktailSort':
case 'Cocktail Sort':
snapshots = this.sortingService.cocktailSort(this.sortArray);
break;
}
const endTime = performance.now();
this.executionTime = parseFloat((endTime - startTime).toFixed(4));
this.executionTime = Number.parseFloat((endTime - startTime).toFixed(4));
console.log(snapshots.length);
this.animateSorting(snapshots);