champion detail win rate chart
This commit is contained in:
parent
648dacdd1a
commit
3e443617e9
@ -51,7 +51,8 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.Repo do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_all_win_rates do
|
@spec champion_win_rates_by_patch(String.t(), String.t()) :: [map()]
|
||||||
|
def champion_win_rates_by_patch(champion_id, team_position) do
|
||||||
query =
|
query =
|
||||||
from m in Schema,
|
from m in Schema,
|
||||||
join: c in ChampionSchema,
|
join: c in ChampionSchema,
|
||||||
@ -66,13 +67,15 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.Repo do
|
|||||||
m.is_win
|
m.is_win
|
||||||
),
|
),
|
||||||
id: m.champion_id,
|
id: m.champion_id,
|
||||||
|
patch_number: m.patch_number,
|
||||||
name: c.name,
|
name: c.name,
|
||||||
image: c.image,
|
image: c.image,
|
||||||
team_position: m.team_position,
|
team_position: m.team_position,
|
||||||
total_games: count("*")
|
total_games: count("*")
|
||||||
},
|
},
|
||||||
group_by: [m.champion_id, c.image, c.name, m.team_position],
|
group_by: [m.champion_id, c.image, c.name, m.patch_number, m.team_position],
|
||||||
having: count("*") > 100
|
where: m.team_position == ^team_position and m.champion_id == ^champion_id,
|
||||||
|
having: count("*") > 50
|
||||||
|
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
@ -18,18 +18,22 @@
|
|||||||
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
|
// Include phoenix_html to handle method=PUT/DELETE in forms and buttons.
|
||||||
import "phoenix_html"
|
import "phoenix_html"
|
||||||
// Establish Phoenix Socket and LiveView configuration.
|
// Establish Phoenix Socket and LiveView configuration.
|
||||||
import {Socket} from "phoenix"
|
import { Socket } from "phoenix"
|
||||||
import {LiveSocket} from "phoenix_live_view"
|
import { LiveSocket } from "phoenix_live_view"
|
||||||
import topbar from "../vendor/topbar"
|
import topbar from "../vendor/topbar"
|
||||||
|
import { ChampionWinRate } from "./hooks/champion_win_rate_patch"
|
||||||
|
|
||||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||||
let liveSocket = new LiveSocket("/live", Socket, {
|
let liveSocket = new LiveSocket("/live", Socket, {
|
||||||
longPollFallbackMs: 2500,
|
longPollFallbackMs: 2500,
|
||||||
params: {_csrf_token: csrfToken}
|
params: { _csrf_token: csrfToken },
|
||||||
|
hooks: {
|
||||||
|
ChampionWinRate,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Show progress bar on live navigation and form submits
|
// Show progress bar on live navigation and form submits
|
||||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
topbar.config({ barColors: { 0: "#29d" }, shadowColor: "rgba(0, 0, 0, .3)" })
|
||||||
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
|
window.addEventListener("phx:page-loading-start", _info => topbar.show(300))
|
||||||
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
|
window.addEventListener("phx:page-loading-stop", _info => topbar.hide())
|
||||||
|
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
import Chart from "chart.js/auto"
|
||||||
|
|
||||||
|
const ChampionWinRate = {
|
||||||
|
mounted() {
|
||||||
|
console.log("mounted")
|
||||||
|
this.handleEvent("points", (event) => console.log("123"))
|
||||||
|
|
||||||
|
// this.props = { id: this.el.getAttribute("data-id") };
|
||||||
|
this.handleEvent("win-rate", ({ winRates }) => {
|
||||||
|
console.log(">>>>>>>")
|
||||||
|
console.log(winRates);
|
||||||
|
patches = winRates.map((winRate) => {
|
||||||
|
return winRate.patch_number
|
||||||
|
})
|
||||||
|
winRateValues = winRates.map((winRate) => winRate.win_rate)
|
||||||
|
setInterval(() => {
|
||||||
|
const data = {
|
||||||
|
labels: patches,
|
||||||
|
datasets: [{
|
||||||
|
label: 'Win rate',
|
||||||
|
data: winRateValues,
|
||||||
|
fill: false,
|
||||||
|
borderColor: 'rgb(75, 192, 192)',
|
||||||
|
tension: 0.1
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
this.chart = new Chart(document.getElementById("win-rate"), {
|
||||||
|
type: 'line',
|
||||||
|
data: data
|
||||||
|
})
|
||||||
|
this.chart.canvas.parentNode.style.height = '250px';
|
||||||
|
this.chart.canvas.parentNode.style.width = '400px';
|
||||||
|
}, 1000)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ChampionWinRate };
|
28
apps/lol_analytics_web/assets/package-lock.json
generated
Normal file
28
apps/lol_analytics_web/assets/package-lock.json
generated
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"name": "assets",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"dependencies": {
|
||||||
|
"chart.js": "^4.4.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@kurkle/color": {
|
||||||
|
"version": "0.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
|
||||||
|
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
|
||||||
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "4.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.3.tgz",
|
||||||
|
"integrity": "sha512-qK1gkGSRYcJzqrrzdR6a+I0vQ4/R+SoODXyAjscQ/4mzuNzySaMCd+hyVxitSY1+L2fjPD1Gbn+ibNqRmwQeLw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@kurkle/color": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"pnpm": ">=8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
5
apps/lol_analytics_web/assets/package.json
Normal file
5
apps/lol_analytics_web/assets/package.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"chart.js": "^4.4.3"
|
||||||
|
}
|
||||||
|
}
|
@ -4,11 +4,19 @@ defmodule LolAnalyticsWeb.ChampionComponents.ChampionAvatar do
|
|||||||
attr :id, :integer, required: true
|
attr :id, :integer, required: true
|
||||||
attr :image, :string, required: true
|
attr :image, :string, required: true
|
||||||
attr :name, :string, required: true
|
attr :name, :string, required: true
|
||||||
|
attr :width, :integer, default: 100
|
||||||
|
attr :height, :integer, default: 100
|
||||||
|
|
||||||
def champion_avatar(assigns) do
|
def champion_avatar(assigns) do
|
||||||
~H"""
|
~H"""
|
||||||
|
<style>
|
||||||
|
.champion-avatar {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<div class="flex flex-col w-40">
|
<div class="flex flex-col w-40">
|
||||||
<img src={@image} alt="champion-icon" />
|
<img src={@image} class="champion-avatar" alt="champion-icon" />
|
||||||
</div>
|
</div>
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
|
@ -19,23 +19,37 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do
|
|||||||
socket
|
socket
|
||||||
|> assign(:page_title, page_title(socket.assigns.live_action))
|
|> assign(:page_title, page_title(socket.assigns.live_action))
|
||||||
|> assign(:champion, load_champion_info(id))
|
|> assign(:champion, load_champion_info(id))
|
||||||
|
|> load_win_rates(id, team_position)
|
||||||
|> load_summoner_spells(id, team_position)
|
|> load_summoner_spells(id, team_position)
|
||||||
|> load_items(id, team_position, patch)}
|
|> load_items(id, team_position, patch)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_win_rates(socket, champion_id, team_position) do
|
||||||
|
socket
|
||||||
|
|> start_async(:get_win_rates, fn ->
|
||||||
|
LolAnalytics.Facts.ChampionPlayedGame.Repo.champion_win_rates_by_patch(
|
||||||
|
champion_id,
|
||||||
|
team_position
|
||||||
|
)
|
||||||
|
|> Enum.sort(fn p1, p2 ->
|
||||||
|
[_, minor_1] = String.split(p1.patch_number, ".") |> Enum.map(&String.to_integer/1)
|
||||||
|
[_, minor_2] = String.split(p2.patch_number, ".") |> Enum.map(&String.to_integer/1)
|
||||||
|
|
||||||
|
p1 < p2 && minor_1 < minor_2
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp load_summoner_spells(socket, champion_id, team_position) do
|
defp load_summoner_spells(socket, champion_id, team_position) do
|
||||||
socket
|
socket
|
||||||
|> assign(:summoner_spells, %{status: :loading})
|
|> assign(:summoner_spells, %{status: :loading})
|
||||||
|> start_async(
|
|> start_async(:get_summoners, fn ->
|
||||||
:get_summoners,
|
|
||||||
fn ->
|
|
||||||
LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo.get_champion_picked_summoners(
|
LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo.get_champion_picked_summoners(
|
||||||
champion_id,
|
champion_id,
|
||||||
team_position
|
team_position
|
||||||
)
|
)
|
||||||
|> ShowMapper.map_spells()
|
|> ShowMapper.map_spells()
|
||||||
end
|
end)
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp load_items(socket, champion_id, team_position, patch) do
|
defp load_items(socket, champion_id, team_position, patch) do
|
||||||
@ -61,9 +75,12 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_async(:get_items, {:ok, %{popular: popular, boots: boots}} = result, socket) do
|
def handle_async(:get_win_rates, {:ok, result}, socket) do
|
||||||
IO.inspect(result)
|
IO.inspect(result)
|
||||||
|
{:noreply, push_event(socket, "win-rate", %{winRates: result})}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_async(:get_items, {:ok, %{popular: popular, boots: boots}} = result, socket) do
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|> assign(:items, %{
|
|> assign(:items, %{
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
<style>
|
||||||
|
.win-rate {
|
||||||
|
height: 250px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
<.header>
|
<.header>
|
||||||
<h1 class="text-4xl">
|
<h1 class="text-4xl">
|
||||||
<%= @champion.name %>
|
<%= @champion.name %>
|
||||||
@ -6,9 +12,11 @@
|
|||||||
|
|
||||||
<div class="my-6" />
|
<div class="my-6" />
|
||||||
|
|
||||||
<.champion_avatar id={@champion.id} name={@champion.name}
|
<div class="flex flex-row gap-4">
|
||||||
|
<.champion_avatar class="w-20" id={@champion.id} name={@champion.name}
|
||||||
image={"https://ddragon.leagueoflegends.com/cdn/14.11.1/img/champion/#{@champion.image}"} />
|
image={"https://ddragon.leagueoflegends.com/cdn/14.11.1/img/champion/#{@champion.image}"} />
|
||||||
|
<canvas class="w-full win-rate" height="250" class="win-rate" id="win-rate" phx-hook="ChampionWinRate" />
|
||||||
|
</div>
|
||||||
<div class="my-4" />
|
<div class="my-4" />
|
||||||
|
|
||||||
<.render_summoners summoner_pells={@summoner_spells} />
|
<.render_summoners summoner_pells={@summoner_spells} />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user