forked from Foblex/f-flow
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: Added tournament bracket example
- Loading branch information
1 parent
fd1465d
commit a934e8c
Showing
23 changed files
with
507 additions
and
18 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
projects/f-pro-examples/tournament-bracket/calculate-maximum-items-in-column.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { IMap } from '@foblex/flow'; | ||
import { ITournamentBracketItem } from './i-tournament-bracket-item'; | ||
|
||
export function calculateMaximumItemsInColumn(columns: IMap<number>, items: ITournamentBracketItem[]): number { | ||
const result: IMap<number> = {}; | ||
|
||
Object.entries(columns).forEach((value: [ phase: string, columnIndex: number ]) => { | ||
if (!result[ value[ 1 ] ]) { | ||
result[ value[ 1 ] ] = 0; | ||
} | ||
result[ value[ 1 ] ] += items.filter((item) => item.competitionPhase.toLowerCase() === value[ 0 ]).length; | ||
}); | ||
|
||
return Math.max(...Object.values(result)) | ||
} |
5 changes: 5 additions & 0 deletions
5
projects/f-pro-examples/tournament-bracket/get-items-in-phase.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { ITournamentBracketItem } from './i-tournament-bracket-item'; | ||
|
||
export function getItemsInPhase(phase: string, items: ITournamentBracketItem[]): ITournamentBracketItem[] { | ||
return items.filter((item) => item.competitionPhase.toLowerCase() === phase.toLowerCase()); | ||
} |
5 changes: 5 additions & 0 deletions
5
projects/f-pro-examples/tournament-bracket/get-phases-by-column-index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { IMap } from '@foblex/flow'; | ||
|
||
export function getPhasesByColumnIndex(columns: IMap<number>, columnIndex: number): string[] { | ||
return Object.entries(columns).filter((value) => value[ 1 ] === columnIndex).map((value) => value[ 0 ]); | ||
} |
6 changes: 6 additions & 0 deletions
6
projects/f-pro-examples/tournament-bracket/i-tournament-bracket-competitor.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export interface ITournamentBracketCompetitor { | ||
|
||
title: string; | ||
|
||
score: number; | ||
} |
19 changes: 19 additions & 0 deletions
19
projects/f-pro-examples/tournament-bracket/i-tournament-bracket-item.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { ITournamentBracketCompetitor } from './i-tournament-bracket-competitor'; | ||
import { IPoint } from '@foblex/2d'; | ||
|
||
export interface ITournamentBracketItem { | ||
|
||
position?: IPoint; | ||
|
||
id: string; | ||
|
||
competitionPhase: string; | ||
|
||
color: string; | ||
|
||
date: Date; | ||
|
||
competitors: ITournamentBracketCompetitor[]; | ||
|
||
nextMatchId: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { ITournamentBracketItem } from './i-tournament-bracket-item'; | ||
|
||
export const TOURNAMENT_BRACKET_STORE: ITournamentBracketItem[] = [ | ||
{ id: '1', color: 'blue', competitionPhase: 'UB Quarterfinal', date: new Date(), competitors: [{ title: 'Xtreme gaming', score: 0 }, { title: 'Team liquid', score: 2 }], nextMatchId: '5' }, | ||
{ id: '2', color: 'blue', competitionPhase: 'UB Quarterfinal', date: new Date(), competitors: [{ title: 'Cloud9', score: 2 }, { title: 'Aurora gaming', score: 0 }], nextMatchId: '5' }, | ||
{ id: '3', color: 'blue', competitionPhase: 'UB Quarterfinal', date: new Date(), competitors: [{ title: 'Team Falcons', score: 0 }, { title: 'Tundra Esport', score: 2 }], nextMatchId: '6' }, | ||
{ id: '4', color: 'blue', competitionPhase: 'UB Quarterfinal', date: new Date(), competitors: [{ title: 'Nouns', score: 1 }, { title: 'Gaimin Gladiators', score: 2 }], nextMatchId: '6' }, | ||
|
||
{ id: '5', color: 'yellow', competitionPhase: 'UB Semifinal', date: new Date(), competitors: [{ title: 'Team liquid', score: 2 }, { title: 'Cloud9', score: 0 }], nextMatchId: '7' }, | ||
{ id: '6', color: 'yellow', competitionPhase: 'UB Semifinal', date: new Date(), competitors: [{ title: 'Tundra Esport', score: 0 }, { title: 'Gaimin Gladiators', score: 2 }], nextMatchId: '7' }, | ||
|
||
{ id: '7', color: 'purple', competitionPhase: 'UB Final', date: new Date(), competitors: [{ title: 'Team liquid', score: 2 }, { title: 'Gaimin Gladiators', score: 0 }], nextMatchId: 'grand-final' }, | ||
|
||
|
||
{ id: '8', color: 'red', competitionPhase: 'LB Round 1', date: new Date(), competitors: [{ title: 'Talon', score: 1 }, { title: 'Betboom Team', score: 2 }], nextMatchId: '12' }, | ||
{ id: '9', color: 'red', competitionPhase: 'LB Round 1', date: new Date(), competitors: [{ title: '1w Team', score: 2 }, { title: 'Team Zero', score: 0 }], nextMatchId: '13' }, | ||
{ id: '10', color: 'red', competitionPhase: 'LB Round 1', date: new Date(), competitors: [{ title: 'Beastcoast', score: 1 }, { title: 'Heroic', score: 2 }], nextMatchId: '14' }, | ||
{ id: '11', color: 'red', competitionPhase: 'LB Round 1', date: new Date(), competitors: [{ title: 'Team spirit', score: 2 }, { title: 'Invictus gaming', score: 0 }], nextMatchId: '15' }, | ||
|
||
{ id: '12', color: 'blue', competitionPhase: 'LB Round 2', date: new Date(), competitors: [{ title: 'Nouns', score: 0 }, { title: 'Betboom Team', score: 2 }], nextMatchId: '16' }, | ||
{ id: '13', color: 'blue', competitionPhase: 'LB Round 2', date: new Date(), competitors: [{ title: 'Team Falcons', score: 2 }, { title: '1w Team', score: 0 }], nextMatchId: '16' }, | ||
{ id: '14', color: 'blue', competitionPhase: 'LB Round 2', date: new Date(), competitors: [{ title: 'Aurora gaming', score: 2 }, { title: 'Heroic', score: 1 }], nextMatchId: '17' }, | ||
{ id: '15', color: 'blue', competitionPhase: 'LB Round 2', date: new Date(), competitors: [{ title: 'Xtreme gaming', score: 2 }, { title: 'Team spirit', score: 1 }], nextMatchId: '17' }, | ||
|
||
{ id: '16', color: 'yellow', competitionPhase: 'LB Round 3', date: new Date(), competitors: [{ title: 'Betboom Team', score: 0 }, { title: 'Team Falcons', score: 2 }], nextMatchId: '18' }, | ||
{ id: '17', color: 'yellow', competitionPhase: 'LB Round 3', date: new Date(), competitors: [{ title: 'Aurora gaming', score: 0 }, { title: 'Xtreme gaming', score: 2 }], nextMatchId: '19' }, | ||
|
||
{ id: '18', color: 'yellow', competitionPhase: 'LB Round 4', date: new Date(), competitors: [{ title: 'Cloud9', score: 0 }, { title: 'Team Falcons', score: 2 }], nextMatchId: '20' }, | ||
{ id: '19', color: 'yellow', competitionPhase: 'LB Round 4', date: new Date(), competitors: [{ title: 'Tundra Esport', score: 2 }, { title: 'Xtreme gaming', score: 0 }], nextMatchId: '20' }, | ||
|
||
{ id: '20', color: 'purple', competitionPhase: 'LB Round 5', date: new Date(), competitors: [{ title: 'Team Falcons', score: 0 }, { title: 'Tundra Esport', score: 2 }], nextMatchId: '21' }, | ||
|
||
{ id: '21', color: 'purple', competitionPhase: 'LB Final', date: new Date(), competitors: [{ title: 'Gaimin Gladiators', score: 2 }, { title: 'Tundra Esport', score: 1 }], nextMatchId: 'grand-final' }, | ||
|
||
{ id: 'grand-final', color: 'green', competitionPhase: 'Grand Final', date: new Date(), competitors: [{ title: 'Team liquid', score: 3 }, { title: 'Gaimin Gladiators', score: 0 }], nextMatchId: '' }, | ||
]; |
36 changes: 36 additions & 0 deletions
36
projects/f-pro-examples/tournament-bracket/tournament-bracket.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<f-flow fDraggable | ||
(fLoaded)="onInitialized()"> | ||
<f-canvas fZoom> | ||
|
||
@for (item of viewModel; track item.id) { | ||
<f-connection [fReassignDisabled]="true" | ||
[fSelectionDisabled]="true" | ||
fBehavior="fixed_center" | ||
fType="segment" | ||
[fOutputId]="item.id" [fInputId]="item.nextMatchId"> | ||
</f-connection> | ||
} | ||
|
||
@for (item of viewModel; track item.id) { | ||
<div fNode [fNodeId]="item.id" [fNodePosition]="item.position!" | ||
fDragHandle | ||
fNodeOutput [fOutputId]="item.id" fOutputConnectableSide="right" | ||
fNodeInput [fInputId]="item.id" fInputConnectableSide="left" | ||
[fNodeDraggingDisabled]="true"> | ||
<div class="header" [class]="item.color"> | ||
<div class="title">{{ item.competitionPhase }}</div> | ||
<div class="date">{{ item.date | date }}</div> | ||
</div> | ||
<div class="body"> | ||
@for (competitor of item.competitors; track competitor.title) { | ||
<div class="competitor"> | ||
<div class="name">{{ competitor.title }}</div> | ||
<div class="score">{{ competitor.score }}</div> | ||
</div> | ||
} | ||
</div> | ||
</div> | ||
} | ||
</f-canvas> | ||
</f-flow> | ||
|
130 changes: 130 additions & 0 deletions
130
projects/f-pro-examples/tournament-bracket/tournament-bracket.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
:host { | ||
position: relative; | ||
display: flex; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
|
||
::ng-deep :root { | ||
--node-background-color: #ffffff; | ||
--node-border-color: rgba(60, 60, 67, 0.36); | ||
--node-color: rgba(60, 60, 67, 0.78); | ||
|
||
--connection-color: rgba(60, 60, 67, 0.78); | ||
|
||
--blue: #3451b2; | ||
--blue-soft: rgba(100, 108, 255, 0.14); | ||
|
||
--purple: #6f42c1; | ||
--purple-soft: rgba(159, 122, 234, 0.14); | ||
|
||
--green: #18794e; | ||
--green-soft: rgba(16, 185, 129, 0.14); | ||
|
||
--yellow: #915930; | ||
--yellow-soft: rgba(234, 179, 8, 0.14); | ||
|
||
--red: #b8272c; | ||
--red-soft: rgba(244, 63, 94, 0.14); | ||
|
||
|
||
&.dark { | ||
--node-background-color: #000000; | ||
--node-border-color: rgba(235, 235, 245, 0.38); | ||
--node-color: rgba(235, 235, 245, 0.6); | ||
|
||
--connection-color: rgba(235, 235, 245, 0.6); | ||
|
||
--indigo: #a8b1ff; | ||
--indigo-soft: rgba(100, 108, 255, 0.16); | ||
|
||
--purple: #c8abfa; | ||
--purple-soft: rgba(159, 122, 234, 0.16); | ||
|
||
--green-1: #3dd68c; | ||
--green-soft: rgba(16, 185, 129, 0.16); | ||
|
||
--yellow: #f9b44e; | ||
--yellow-soft: rgba(234, 179, 8, 0.16); | ||
|
||
--red: #f66f81; | ||
--red-soft: rgba(244, 63, 94, 0.16); | ||
} | ||
} | ||
|
||
::ng-deep tournament-bracket { | ||
.f-connection { | ||
.f-connection-drag-handle { | ||
fill: transparent; | ||
} | ||
|
||
.f-connection-selection { | ||
fill: none; | ||
} | ||
|
||
.f-connection-path { | ||
fill: none; | ||
stroke: var(--connection-color); | ||
stroke-width: 2; | ||
} | ||
} | ||
} | ||
|
||
.f-node { | ||
width: 200px; | ||
color: var(--node-color); | ||
background: var(--node-background-color); | ||
border-radius: var(--node-border-radius); | ||
border: 0.2px solid var(--node-border-color); | ||
cursor: move; | ||
box-shadow: var(--node-shadow); | ||
|
||
.header { | ||
padding: 4px 12px; | ||
|
||
|
||
.title { | ||
font-size: 14px; | ||
font-weight: 700; | ||
} | ||
|
||
.date { | ||
font-size: 12px; | ||
font-weight: 400; | ||
} | ||
|
||
&.blue { | ||
color: var(--blue); | ||
background-color: var(--blue-soft); | ||
} | ||
|
||
&.red { | ||
color: var(--red); | ||
background-color: var(--red-soft); | ||
} | ||
|
||
&.green { | ||
color: var(--green); | ||
background-color: var(--green-soft); | ||
} | ||
|
||
&.yellow { | ||
color: var(--yellow); | ||
background-color: var(--yellow-soft); | ||
} | ||
|
||
&.purple { | ||
color: var(--purple); | ||
background-color: var(--purple-soft); | ||
} | ||
} | ||
|
||
.competitor { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
padding: 2px 12px; | ||
font-size: 14px; | ||
} | ||
} | ||
|
37 changes: 37 additions & 0 deletions
37
projects/f-pro-examples/tournament-bracket/tournament-bracket.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core'; | ||
import { | ||
FCanvasComponent, | ||
FFlowModule, FNodeBase, | ||
} from '@foblex/flow'; | ||
import { ITournamentBracketItem } from './i-tournament-bracket-item'; | ||
import { TournamentBracket } from './tournament-bracket'; | ||
import { TOURNAMENT_BRACKET_STORE } from './storage'; | ||
import { DatePipe } from '@angular/common'; | ||
import { PointExtensions } from '@foblex/2d'; | ||
|
||
@Component({ | ||
selector: 'tournament-bracket', | ||
templateUrl: './tournament-bracket.component.html', | ||
styleUrls: [ './tournament-bracket.component.scss' ], | ||
standalone: true, | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
imports: [ | ||
FFlowModule, | ||
DatePipe, | ||
] | ||
}) | ||
export class TournamentBracketComponent implements OnInit { | ||
|
||
@ViewChild(FCanvasComponent, { static: true }) | ||
public fCanvasComponent!: FCanvasComponent; | ||
|
||
public viewModel: ITournamentBracketItem[] = []; | ||
|
||
public ngOnInit(): void { | ||
this.viewModel = new TournamentBracket(TOURNAMENT_BRACKET_STORE, 200, 113, 100, 150).calculate(); | ||
} | ||
|
||
public onInitialized(): void { | ||
this.fCanvasComponent.fitToScreen(PointExtensions.initialize(100, 100), false); | ||
} | ||
} |
Oops, something went wrong.