Skip to content

Commit e03d58b

Browse files
committed
Use manager helpers to compute group rankings
1 parent e548e5a commit e03d58b

File tree

4 files changed

+13
-143
lines changed

4 files changed

+13
-143
lines changed

src/dom.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Match, ParticipantResult, FinalType, GroupType, Id, MatchGame } from 'brackets-model';
2-
import { Connection, Placement, Ranking, RankingItem } from './types';
1+
import { Match, ParticipantResult, FinalType, GroupType, Id, MatchGame, type RankingItem } from 'brackets-model';
2+
import { Connection, Placement } from './types';
33
import { isMatchGame, rankingHeader } from './helpers';
44
import { t } from './lang';
55

@@ -239,7 +239,7 @@ export function createCell(data: string | number): HTMLElement {
239239
*
240240
* @param ranking The object containing the ranking.
241241
*/
242-
export function createRankingHeaders(ranking: Ranking): HTMLElement {
242+
export function createRankingHeaders(ranking: RankingItem[]): HTMLElement {
243243
const headers = document.createElement('tr');
244244
const firstItem = ranking[0];
245245

src/helpers.ts

Lines changed: 2 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Match, ParticipantResult, GroupType, MatchGame } from 'brackets-model';
2-
import { RankingHeader, Ranking, RankingFormula, RankingItem, RankingMap, Side, MatchWithMetadata } from './types';
1+
import { Match, GroupType, MatchGame, RankingItem } from 'brackets-model';
2+
import { RankingHeader, Side, MatchWithMetadata } from './types';
33
import { t } from './lang';
44

55
/**
@@ -171,103 +171,6 @@ export function rankingHeader(itemName: keyof RankingItem): RankingHeader {
171171
return t(`ranking.${itemName}`, { returnObjects: true }) as RankingHeader;
172172
}
173173

174-
/**
175-
* Calculates the ranking based on a list of matches and a formula.
176-
*
177-
* @param matches The list of matches.
178-
* @param formula The points formula to apply.
179-
*/
180-
export function getRanking(matches: Match[], formula?: RankingFormula): Ranking {
181-
formula = formula || (
182-
(item: RankingItem): number => 3 * item.wins + 1 * item.draws + 0 * item.losses
183-
);
184-
185-
const rankingMap: RankingMap = {};
186-
187-
for (const match of matches) {
188-
processParticipant(rankingMap, formula, match.opponent1, match.opponent2);
189-
processParticipant(rankingMap, formula, match.opponent2, match.opponent1);
190-
}
191-
192-
return createRanking(rankingMap);
193-
}
194-
195-
/**
196-
* Processes a participant and edits the ranking map.
197-
*
198-
* @param rankingMap The ranking map to edit.
199-
* @param formula The points formula to apply.
200-
* @param current The current participant.
201-
* @param other The opponent.
202-
*/
203-
function processParticipant(rankingMap: RankingMap, formula: RankingFormula, current: ParticipantResult | null, other: ParticipantResult | null): void {
204-
if (!current || current.id === null) return;
205-
206-
const state = rankingMap[current.id] || {
207-
rank: 0,
208-
id: 0,
209-
played: 0,
210-
wins: 0,
211-
draws: 0,
212-
losses: 0,
213-
forfeits: 0,
214-
scoreFor: 0,
215-
scoreAgainst: 0,
216-
scoreDifference: 0,
217-
points: 0,
218-
};
219-
220-
state.id = current.id;
221-
222-
if (current.forfeit || current.result)
223-
state.played++;
224-
225-
if (current.result === 'win')
226-
state.wins++;
227-
228-
if (current.result === 'draw')
229-
state.draws++;
230-
231-
if (current.result === 'loss')
232-
state.losses++;
233-
234-
if (current.forfeit)
235-
state.forfeits++;
236-
237-
state.scoreFor += current.score || 0;
238-
state.scoreAgainst += other && other.score || 0;
239-
state.scoreDifference = state.scoreFor - state.scoreAgainst;
240-
241-
state.points = formula(state);
242-
243-
rankingMap[current.id] = state;
244-
}
245-
246-
/**
247-
* Creates the final ranking based on a ranking map. (Sort + Total points)
248-
*
249-
* @param rankingMap The ranking map (object).
250-
*/
251-
function createRanking(rankingMap: RankingMap): RankingItem[] {
252-
const ranking = Object.values(rankingMap).sort((a, b) => a.points !== b.points
253-
? b.points - a.points
254-
: a.played !== b.played
255-
? b.played - a.played
256-
: b.scoreDifference - a.scoreDifference);
257-
258-
const rank = {
259-
value: 0,
260-
lastPoints: -1,
261-
};
262-
263-
for (const item of ranking) {
264-
item.rank = rank.lastPoints !== item.points ? ++rank.value : rank.value;
265-
rank.lastPoints = item.points;
266-
}
267-
268-
return ranking;
269-
}
270-
271174
/**
272175
* Indicates whether the input is a match.
273176
*

src/main.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import './style.scss';
2-
import { Participant, Match, ParticipantResult, Stage, Status, GroupType, FinalType, Id } from 'brackets-model';
3-
import { splitBy, getRanking, getOriginAbbreviation, findRoot, completeWithBlankMatches, sortBy, isMatchGame, isMatch, splitByWithLeftovers } from './helpers';
2+
import { Participant, Match, ParticipantResult, Stage, Status, GroupType, FinalType, Id, type RankingItem } from 'brackets-model';
3+
import { splitBy, getOriginAbbreviation, findRoot, completeWithBlankMatches, sortBy, isMatchGame, isMatch, splitByWithLeftovers } from './helpers';
44
import * as dom from './dom';
55
import * as lang from './lang';
66
import { Locale } from './lang';
@@ -9,7 +9,6 @@ import {
99
Config,
1010
OriginHint,
1111
ParticipantContainers,
12-
RankingItem,
1312
RoundNameGetter,
1413
ViewerData,
1514
ParticipantImage,
@@ -78,7 +77,7 @@ export class BracketsViewer {
7877
showPopoverOnMatchLabelClick: config?.showPopoverOnMatchLabelClick ?? true,
7978
highlightParticipantOnHover: config?.highlightParticipantOnHover ?? true,
8079
showRankingTable: config?.showRankingTable ?? true,
81-
rankingFormula: config?.rankingFormula,
80+
rankingFormula: config?.rankingFormula ?? ((item): number => 3 * item.wins + 1 * item.draws + 0 * item.losses),
8281
};
8382

8483
if (config?.onMatchClick)
@@ -482,13 +481,13 @@ export class BracketsViewer {
482481
}
483482

484483
/**
485-
* Creates a ranking table based on matches of a round-robin stage.
484+
* Creates a ranking table for a group of a round-robin stage.
486485
*
487-
* @param matches The list of matches.
486+
* @param matches The list of matches in the group.
488487
*/
489488
private createRanking(matches: Match[]): HTMLElement {
490489
const table = dom.createTable();
491-
const ranking = getRanking(matches, this.config.rankingFormula);
490+
const ranking = helpers.getRanking(matches, this.config.rankingFormula!);
492491

493492
table.append(dom.createRankingHeaders(ranking));
494493

src/types.ts

Lines changed: 2 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Stage, Match, MatchGame, Participant, GroupType, FinalType, Id, StageType } from 'brackets-model';
1+
import { Stage, Match, MatchGame, Participant, GroupType, FinalType, StageType, RankingItem, RankingFormula } from 'brackets-model';
22
import { CallbackFunction, FormConfiguration } from './form';
33
import { InMemoryDatabase } from 'brackets-memory-db';
44
import { BracketsViewer } from './main';
@@ -190,7 +190,7 @@ export interface Config {
190190
highlightParticipantOnHover?: boolean,
191191

192192
/**
193-
* Whether to show a ranking table on round-robin stages.
193+
* Whether to show a ranking table in each group of a round-robin stage.
194194
*
195195
* @default true
196196
*/
@@ -263,23 +263,6 @@ export interface Connection {
263263
connectNext?: ConnectionType,
264264
}
265265

266-
/**
267-
* An item of the ranking.
268-
*/
269-
export interface RankingItem {
270-
rank: number,
271-
id: Id,
272-
played: number,
273-
wins: number,
274-
draws: number,
275-
losses: number,
276-
forfeits: number,
277-
scoreFor: number,
278-
scoreAgainst: number,
279-
scoreDifference: number,
280-
points: number,
281-
}
282-
283266
/**
284267
* Contains information about a header of the ranking and its tooltip.
285268
*/
@@ -288,26 +271,11 @@ export interface RankingHeader {
288271
tooltip: string,
289272
}
290273

291-
/**
292-
* A formula which computes points given a ranking row.
293-
*/
294-
export type RankingFormula = (ranking: RankingItem) => number;
295-
296274
/**
297275
* An object mapping ranking properties to their header.
298276
*/
299277
export type RankingHeaders = Record<keyof RankingItem, RankingHeader>;
300278

301-
/**
302-
* An object mapping a participant id to its row in the ranking.
303-
*/
304-
export type RankingMap = Record<Id, RankingItem>;
305-
306-
/**
307-
* Definition of a ranking.
308-
*/
309-
export type Ranking = RankingItem[];
310-
311279
/**
312280
* Structure containing all the containers for a participant.
313281
*/

0 commit comments

Comments
 (0)