speedup player List sorting
This commit is contained in:
@@ -2,26 +2,26 @@
|
|||||||
<div class="playerTable" v-on:keydown="selectNextPlayer" tabindex="0">
|
<div class="playerTable" v-on:keydown="selectNextPlayer" tabindex="0">
|
||||||
<div class="playerHeaders">
|
<div class="playerHeaders">
|
||||||
<span></span>
|
<span></span>
|
||||||
<span v-on:click="sortPlayerList('username')"
|
<span v-on:click="updateSort('username')"
|
||||||
:class="sortingData.argument == 'username' ? 'selected' : ''">Username</span>
|
:class="sortingData.argument == 'username' ? 'selected' : ''">Username</span>
|
||||||
<span v-on:click="sortPlayerList('kills')" :class="sortingData.argument == 'kills' ? 'selected' : ''">K</span>
|
<span v-on:click="updateSort('kills')" :class="sortingData.argument == 'kills' ? 'selected' : ''">K</span>
|
||||||
<span v-on:click="sortPlayerList('deaths')" :class="sortingData.argument == 'deaths' ? 'selected' : ''">D</span>
|
<span v-on:click="updateSort('deaths')" :class="sortingData.argument == 'deaths' ? 'selected' : ''">D</span>
|
||||||
<span v-on:click="sortPlayerList('k/d')" :class="sortingData.argument == 'k/d' ? 'selected' : ''">K/D</span>
|
<span v-on:click="updateSort('k/d')" :class="sortingData.argument == 'k/d' ? 'selected' : ''">K/D</span>
|
||||||
<span v-on:click="sortPlayerList('max_distance')"
|
<span v-on:click="updateSort('max_distance')"
|
||||||
:class="sortingData.argument == 'max_distance' ? 'selected' : ''">max distance</span>
|
:class="sortingData.argument == 'max_distance' ? 'selected' : ''">max distance</span>
|
||||||
<span v-on:click="sortPlayerList('avg_distance')"
|
<span v-on:click="updateSort('avg_distance')"
|
||||||
:class="sortingData.argument == 'avg_distance' ? 'selected' : ''">average distance</span>
|
:class="sortingData.argument == 'avg_distance' ? 'selected' : ''">average distance</span>
|
||||||
</div>
|
</div>
|
||||||
<div :class="'playerRow ' + (playerId === $props.playerHighlighted ? 'selected' : '')"
|
<div :class="'playerRow ' + (player.id === $props.playerHighlighted ? 'selected' : '')"
|
||||||
v-for="(playerId, index) in playerIdList" v-bind:key="playerId" v-on:click="$emit('highlightPlayer', playerId)"
|
v-for="(player, index) in playerList" v-bind:key="player.id" v-on:click="$emit('highlightPlayer', player.id)"
|
||||||
:ref="`player:` + playerId">
|
:ref="`player:` + player.id">
|
||||||
<div><span>{{ index+1 }}</span></div>
|
<div><span>{{ index+1 }}</span></div>
|
||||||
<div><span>{{ players[playerId].username }}</span></div>
|
<div><span>{{ player.username }}</span></div>
|
||||||
<div><span>{{ players[playerId].kills }}</span></div>
|
<div><span>{{ player.kills }}</span></div>
|
||||||
<div><span>{{ players[playerId].deaths }}</span></div>
|
<div><span>{{ player.deaths }}</span></div>
|
||||||
<div><span>{{ Math.round(players[playerId].kills / Math.max(1, players[playerId].deaths) * 100) / 100 }}</span></div>
|
<div><span>{{ Math.round(player.kills / Math.max(1, player.deaths) * 100) / 100 }}</span></div>
|
||||||
<div><span>{{ players[playerId].max_distance }}</span></div>
|
<div><span>{{ player.max_distance }}</span></div>
|
||||||
<div><span>{{ Math.round(((players[playerId].total_distance / players[playerId].kills) || 0) * 100) / 100 }}</span></div>
|
<div><span>{{ Math.round(((player.total_distance / player.kills) || 0) * 100) / 100 }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -49,17 +49,44 @@ export default defineComponent({
|
|||||||
const data = this.store.getPlayerList(withoutPlayer)?.value.data
|
const data = this.store.getPlayerList(withoutPlayer)?.value.data
|
||||||
if (!data) return this.store.fetchPlayers(withoutPlayer).value.data
|
if (!data) return this.store.fetchPlayers(withoutPlayer).value.data
|
||||||
return data
|
return data
|
||||||
|
},
|
||||||
|
playerList ():(Player & {id:string})[] {
|
||||||
|
if (!this.players) return []
|
||||||
|
let players = Object.entries(this.players).map(e => ({ id: e[0], ...e[1] }))
|
||||||
|
|
||||||
|
if (this.sortingData.argument === 'username') {
|
||||||
|
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' })
|
||||||
|
players.sort((a: Player, b: Player) => {
|
||||||
|
return collator.compare(a.username, b.username)
|
||||||
|
})
|
||||||
|
} else if (this.sortingData.argument === 'k/d') {
|
||||||
|
players.sort((a: Player, b: Player) => {
|
||||||
|
return a.kills / Math.max(1, a.deaths) - b.kills / Math.max(1, b.deaths)
|
||||||
|
})
|
||||||
|
} else if (this.sortingData.argument === 'avg_distance') {
|
||||||
|
players.sort((a: Player, b: Player) => {
|
||||||
|
return ((a.total_distance / a.kills) || 0) - ((b.total_distance / b.kills) || 0)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const argument = this.sortingData.argument
|
||||||
|
players.sort((a: Player, b: Player) => {
|
||||||
|
return a[argument] - b[argument]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sortingData.direction < 0) {
|
||||||
|
players.reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
players = players.slice(0, 500)
|
||||||
|
return players
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
players: {
|
players: {
|
||||||
handler (newval: { [key: string]: Player }): void {
|
handler (newval: { [key: string]: Player }): void {
|
||||||
if (!newval) return
|
if (!newval) return
|
||||||
this.playerIdList = []
|
|
||||||
this.sortingData.direction *= -1
|
this.sortingData.direction *= -1
|
||||||
this.playerIdList = Object.keys(newval)
|
|
||||||
this.sortPlayerList(this.sortingData.argument)
|
|
||||||
this.playerIdList = this.playerIdList.slice(0, 500)
|
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
},
|
},
|
||||||
@@ -74,41 +101,6 @@ export default defineComponent({
|
|||||||
element[0].scrollIntoView({ behavior: 'smooth', block: 'center' })
|
element[0].scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
sortPlayerList (arg: ((keyof Player) | 'k/d' | 'avg_distance')) {
|
|
||||||
if (arg === this.sortingData.argument) {
|
|
||||||
this.sortingData.direction *= -1
|
|
||||||
} else {
|
|
||||||
if (arg === 'username') {
|
|
||||||
this.sortingData.direction = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.sortingData.argument = arg
|
|
||||||
|
|
||||||
this.playerIdList.sort((a: string, b: string) => {
|
|
||||||
if (!this.players) {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
let varA, varB
|
|
||||||
if (arg === 'k/d') {
|
|
||||||
varA = this.players[a].kills / Math.max(1, this.players[a].deaths)
|
|
||||||
varB = this.players[b].kills / Math.max(1, this.players[b].deaths)
|
|
||||||
} else if (arg === 'avg_distance') {
|
|
||||||
varA = (this.players[a].total_distance / this.players[a].kills) || 0
|
|
||||||
varB = (this.players[b].total_distance / this.players[b].kills) || 0
|
|
||||||
} else {
|
|
||||||
varA = this.players[a][arg]
|
|
||||||
varB = this.players[b][arg]
|
|
||||||
}
|
|
||||||
if (varA === undefined || varB === undefined) return 0
|
|
||||||
if (varA < varB) {
|
|
||||||
return -1 * this.sortingData.direction
|
|
||||||
}
|
|
||||||
if (varA > varB) {
|
|
||||||
return 1 * this.sortingData.direction
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
})
|
|
||||||
},
|
|
||||||
selectNextPlayer (e: KeyboardEvent) {
|
selectNextPlayer (e: KeyboardEvent) {
|
||||||
const values = {
|
const values = {
|
||||||
Home: -Infinity,
|
Home: -Infinity,
|
||||||
@@ -128,6 +120,14 @@ export default defineComponent({
|
|||||||
if (nextIndex >= this.playerIdList.length) nextIndex = this.playerIdList.length - 1
|
if (nextIndex >= this.playerIdList.length) nextIndex = this.playerIdList.length - 1
|
||||||
if (nextIndex < 0) nextIndex = 0
|
if (nextIndex < 0) nextIndex = 0
|
||||||
this.$emit('highlightPlayer', this.playerIdList[nextIndex])
|
this.$emit('highlightPlayer', this.playerIdList[nextIndex])
|
||||||
|
},
|
||||||
|
updateSort (argument:string) {
|
||||||
|
if (this.sortingData.argument === argument) {
|
||||||
|
this.sortingData.direction *= -1
|
||||||
|
} else {
|
||||||
|
this.sortingData.direction = -1
|
||||||
|
}
|
||||||
|
this.sortingData.argument = argument as typeof this.sortingData.argument
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export default defineComponent({
|
|||||||
datalabels: {
|
datalabels: {
|
||||||
formatter: (value: any, context: any) => {
|
formatter: (value: any, context: any) => {
|
||||||
const weaponId = this.sortedWeaponList[context.dataIndex]
|
const weaponId = this.sortedWeaponList[context.dataIndex]
|
||||||
if (!(weapons as {[key:string]:string})[weaponId]) console.log(weaponId)
|
// if (!(weapons as {[key:string]:string})[weaponId]) console.log(weaponId)
|
||||||
return (weapons as {[key:string]:string})[weaponId] || weaponId
|
return (weapons as {[key:string]:string})[weaponId] || weaponId
|
||||||
},
|
},
|
||||||
backgroundColor: (context: any) => {
|
backgroundColor: (context: any) => {
|
||||||
|
|||||||
+1
-1
@@ -43,7 +43,7 @@ export interface KillData<T extends Kill> {
|
|||||||
export interface Player extends Kill {
|
export interface Player extends Kill {
|
||||||
username: string;
|
username: string;
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
deaths_while_equipped?: number;
|
// deaths_while_equipped?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Weapon extends Kill {
|
export interface Weapon extends Kill {
|
||||||
|
|||||||
+18
-15
@@ -21,15 +21,15 @@
|
|||||||
></VueMultiselect>
|
></VueMultiselect>
|
||||||
|
|
||||||
<VueMultiselect selectLabel="" deselectLabel="remove" placeholder="Search player" v-model="playerHighlighted"
|
<VueMultiselect selectLabel="" deselectLabel="remove" placeholder="Search player" v-model="playerHighlighted"
|
||||||
:options="sortedPlayerList" :allow-empty="true" :custom-label="((e:string) => players[e]?.username)"></VueMultiselect>
|
:options="sortedPlayerList" :allow-empty="true" :custom-label="((e:Player) => e?.username)"></VueMultiselect>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="playerView">
|
<div id="playerView">
|
||||||
<PlayerList :filters="filters" v-on:highlight-player="playerHighlighted = $event"
|
<PlayerList :filters="filters" v-on:highlightPlayer="highlight_player"
|
||||||
:playerHighlighted="playerHighlighted"></PlayerList>
|
:playerHighlighted="playerHighlighted?.id"></PlayerList>
|
||||||
<PlayerChart :filters="filters" v-on:highlight-player="playerHighlighted = $event"
|
<PlayerChart :filters="filters" v-on:highlight-player="highlight_player"
|
||||||
:playerHighlighted="playerHighlighted"></PlayerChart>
|
:playerHighlighted="playerHighlighted?.id"></PlayerChart>
|
||||||
<WeaponChart :filters="{player: playerHighlighted, ...filters}" :playerHighlighted="playerHighlighted"></WeaponChart>
|
<WeaponChart :filters="{player: playerHighlighted?.id, ...filters}" :playerHighlighted="playerHighlighted?.id"></WeaponChart>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ export default defineComponent({
|
|||||||
model: { server: undefined, weapon: undefined } as unknown as {weapon:Weapon | Weapon[], server: (Server& {name?:string}) | (Server& {name?:string})[]},
|
model: { server: undefined, weapon: undefined } as unknown as {weapon:Weapon | Weapon[], server: (Server& {name?:string}) | (Server& {name?:string})[]},
|
||||||
filters: {} as Filters,
|
filters: {} as Filters,
|
||||||
store: useKillStore(),
|
store: useKillStore(),
|
||||||
playerHighlighted: undefined,
|
playerHighlighted: undefined as (Player & {id:string}) | undefined,
|
||||||
weaponLocale: weapons as {[key:string]:string}
|
weaponLocale: weapons as {[key:string]:string}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -98,17 +98,14 @@ export default defineComponent({
|
|||||||
const servers = Object.keys(this.servers)
|
const servers = Object.keys(this.servers)
|
||||||
return servers.sort()
|
return servers.sort()
|
||||||
},
|
},
|
||||||
sortedPlayerList (): string[] {
|
sortedPlayerList (): Player[] {
|
||||||
if (!this.players) return []
|
if (!this.players) return []
|
||||||
const players = Object.keys(this.players)
|
const players = Object.entries(this.players).map(e => ({ id: e[0], ...e[1] }))
|
||||||
return players.sort((a: string, b: string) => {
|
return players.sort((a: Player, b: Player) => {
|
||||||
if (!this.players) {
|
if (a.username < b.username) {
|
||||||
return 0
|
|
||||||
}
|
|
||||||
if (this.players[a].username < this.players[b].username) {
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if (this.players[a].username > this.players[b].username) {
|
if (a.username > b.username) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@@ -123,6 +120,12 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
highlight_player (playerid:string) {
|
||||||
|
const player = this.players[playerid]
|
||||||
|
if (player) this.playerHighlighted = { id: playerid, ...player }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user