102 lines
2.2 KiB
Vue
102 lines
2.2 KiB
Vue
<script lang="ts" setup>
|
|
import {
|
|
Chart as ChartJS,
|
|
Title,
|
|
Tooltip,
|
|
Legend,
|
|
BarElement,
|
|
CategoryScale,
|
|
LinearScale
|
|
} from 'chart.js'
|
|
import { Bar } from 'vue-chartjs'
|
|
|
|
// Register
|
|
ChartJS.register(Title, Tooltip, Legend, BarElement, CategoryScale, LinearScale)
|
|
|
|
const props = defineProps<{
|
|
data: Array<{ title: string; data: Array<{ lane: LaneData; champion: Champion }> }>
|
|
}>()
|
|
|
|
const labels: Array<string> = []
|
|
const pickrates: Array<number> = []
|
|
const images: Array<string> = []
|
|
const backgroundColors: Array<string> = []
|
|
const CHAMPION_CUT_THRESHOLD = 32
|
|
const TIER_COLORS = ['#ff7f7e', '#ffbf7f', '#ffdf80', '#feff7f', '#beff7f', '#7eff80']
|
|
|
|
let count = 0
|
|
let colorIndex = 0
|
|
for (const tier of props.data) {
|
|
for (const { champion: champion, lane: lane } of tier.data) {
|
|
if (count > CHAMPION_CUT_THRESHOLD) break
|
|
|
|
labels.push(champion.name)
|
|
pickrates.push(lane.pickrate * 100)
|
|
images.push(CDRAGON_BASE + mapPath(champion.squarePortraitPath))
|
|
backgroundColors.push(TIER_COLORS[colorIndex])
|
|
|
|
count++
|
|
}
|
|
colorIndex++
|
|
}
|
|
|
|
const chartData = ref({
|
|
labels: labels,
|
|
datasets: [
|
|
{
|
|
label: 'Pickrate',
|
|
backgroundColor: backgroundColors,
|
|
barPercentage: 1.0,
|
|
data: pickrates
|
|
}
|
|
]
|
|
})
|
|
const chartOptions = ref({
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
scales: {
|
|
x: {
|
|
ticks: {
|
|
callback: () => ''
|
|
}
|
|
}
|
|
},
|
|
plugins: {
|
|
legend: {
|
|
display: false
|
|
}
|
|
}
|
|
})
|
|
const chartPlugins = [
|
|
{
|
|
id: 'image-draw',
|
|
afterDraw: (chart: unknown) => {
|
|
const ctx: CanvasRenderingContext2D = (chart as { ctx: CanvasRenderingContext2D }).ctx
|
|
const xAxis = (
|
|
chart as {
|
|
scales: {
|
|
x: {
|
|
ticks: Array<unknown>
|
|
getPixelForTick: (_index: number) => number
|
|
bottom: number
|
|
}
|
|
}
|
|
}
|
|
).scales.x
|
|
xAxis.ticks.forEach((value: unknown, index: number) => {
|
|
const x = xAxis.getPixelForTick(index)
|
|
const image = new Image()
|
|
image.src = images[index]
|
|
ctx.drawImage(image, x - 14, xAxis.bottom - 28, 28, 28)
|
|
})
|
|
}
|
|
}
|
|
]
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<Bar :data="chartData" :options="chartOptions" :plugins="chartPlugins" />
|
|
</div>
|
|
</template>
|