Compare commits
3 Commits
0c0c7f1230
...
ccac1fec15
Author | SHA1 | Date | |
---|---|---|---|
ccac1fec15 | |||
bba1913d65 | |||
d24dc4726b |
@ -14,7 +14,9 @@ defmodule LolAnalytics.Facts.ChampionPickedItem.FactProcessor do
|
|||||||
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
||||||
process_game_data(decoded_match)
|
process_game_data(decoded_match)
|
||||||
else
|
else
|
||||||
_ -> {:error, "Could not process data from #{url}"}
|
_ ->
|
||||||
|
Logger.error("Could not process data from #{url} for ChampionPickedItem")
|
||||||
|
{:error, "Could not process data from #{url}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ defmodule LolAnalytics.Facts.ChampionPickedSummonerSpell.FactProcessor do
|
|||||||
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
||||||
process_game_data(decoded_match)
|
process_game_data(decoded_match)
|
||||||
else
|
else
|
||||||
_ -> {:error, "Could not process data from #{url}"}
|
_ ->
|
||||||
|
Logger.error("Could not process data from #{url} for ChampionPickedSummonerSpell")
|
||||||
|
{:error, "Could not process data from #{url}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -32,7 +32,26 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.Repo do
|
|||||||
Repo.all(Schema)
|
Repo.all(Schema)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_win_rates do
|
def get_win_rates(opts \\ []) do
|
||||||
|
team_position = Keyword.get(opts, :team_position)
|
||||||
|
patch = Keyword.get(opts, :patch_number, "14.12")
|
||||||
|
|
||||||
|
case {team_position, patch} do
|
||||||
|
{nil, nil} ->
|
||||||
|
get_win_rates()
|
||||||
|
|
||||||
|
{"all", patch} ->
|
||||||
|
get_win_rates_for_patch(patch)
|
||||||
|
|
||||||
|
{nil, patch} ->
|
||||||
|
get_win_rates_for_patch(patch)
|
||||||
|
|
||||||
|
{team_position, patch} ->
|
||||||
|
get_win_rates_for_patch_and_team_position(patch, team_position)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_all_win_rates do
|
||||||
query =
|
query =
|
||||||
from m in Schema,
|
from m in Schema,
|
||||||
join: c in ChampionSchema,
|
join: c in ChampionSchema,
|
||||||
@ -58,10 +77,9 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.Repo do
|
|||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_win_rates_by_patch(champion_id, team_position) do
|
defp get_win_rates_for_patch(patch_number) do
|
||||||
query =
|
query =
|
||||||
from m in Schema,
|
from m in Schema,
|
||||||
where: m.team_position == ^team_position,
|
|
||||||
join: c in ChampionSchema,
|
join: c in ChampionSchema,
|
||||||
on: c.champion_id == m.champion_id,
|
on: c.champion_id == m.champion_id,
|
||||||
select: %{
|
select: %{
|
||||||
@ -80,12 +98,38 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.Repo do
|
|||||||
team_position: m.team_position,
|
team_position: m.team_position,
|
||||||
total_games: count("*")
|
total_games: count("*")
|
||||||
},
|
},
|
||||||
where: c.champion_id == ^champion_id,
|
group_by: [m.champion_id, c.image, c.name, m.team_position, m.patch_number],
|
||||||
group_by: [m.champion_id, c.image, c.name, m.team_position, m.patch_number]
|
having: m.patch_number == ^patch_number and count("*") > 100
|
||||||
|
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_win_rates_by_roles() do
|
defp get_win_rates_for_patch_and_team_position(patch_number, team_position) do
|
||||||
|
query =
|
||||||
|
from m in Schema,
|
||||||
|
join: c in ChampionSchema,
|
||||||
|
on: c.champion_id == m.champion_id,
|
||||||
|
select: %{
|
||||||
|
wins: fragment("count(CASE WHEN ? THEN 1 END)", m.is_win),
|
||||||
|
win_rate:
|
||||||
|
fragment(
|
||||||
|
"
|
||||||
|
((cast(count(CASE WHEN ? THEN 1 END) as float) / cast(count(*) as float)) * 100.0
|
||||||
|
)",
|
||||||
|
m.is_win
|
||||||
|
),
|
||||||
|
id: m.champion_id,
|
||||||
|
patch_number: m.patch_number,
|
||||||
|
name: c.name,
|
||||||
|
image: c.image,
|
||||||
|
team_position: m.team_position,
|
||||||
|
total_games: count("*")
|
||||||
|
},
|
||||||
|
group_by: [m.champion_id, c.image, c.name, m.team_position, m.patch_number],
|
||||||
|
having:
|
||||||
|
m.team_position == ^team_position and m.patch_number == ^patch_number and
|
||||||
|
count("*") > 100
|
||||||
|
|
||||||
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,7 +11,9 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.FactProcessor do
|
|||||||
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
{:ok, decoded_match} <- Poison.decode(body, as: %LoLAPI.Model.MatchResponse{}) do
|
||||||
process_game_data(decoded_match)
|
process_game_data(decoded_match)
|
||||||
else
|
else
|
||||||
_ -> {:error, "Could not process data from #{url}"}
|
_ ->
|
||||||
|
Logger.error("Could not process data from #{url} for ChampionPlayedGame")
|
||||||
|
{:error, "Could not process data from #{url}"}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
defmodule LolAnalyticsWeb.PatchSelector do
|
||||||
|
use LoLAnalyticsWeb, :live_component
|
||||||
|
|
||||||
|
def mount(socket) do
|
||||||
|
patches =
|
||||||
|
LolAnalytics.Dimensions.Patch.PatchRepo.list_patches()
|
||||||
|
|> Enum.sort(fn %{patch_number: p1}, %{patch_number: p2} ->
|
||||||
|
[_, minor_1] = String.split(p1, ".") |> Enum.map(&String.to_integer/1)
|
||||||
|
[_, minor_2] = String.split(p2, ".") |> Enum.map(&String.to_integer/1)
|
||||||
|
|
||||||
|
p1 > p2 && minor_1 > minor_2
|
||||||
|
end)
|
||||||
|
|
||||||
|
patch_numbers = Enum.map(patches, & &1.patch_number)
|
||||||
|
[last_patch | _] = patch_numbers
|
||||||
|
|
||||||
|
send(self(), %{patch: last_patch})
|
||||||
|
|
||||||
|
socket =
|
||||||
|
assign(socket, :patch_numbers, patch_numbers)
|
||||||
|
|> assign(:patch_form, to_form(%{"selected_patch" => last_patch}))
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("selected_patch", %{"patch" => patch} = unsigned_params, socket) do
|
||||||
|
send(self(), %{patch: patch})
|
||||||
|
|
||||||
|
{:noreply, assign(socket, :selected_patch, patch)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(assigns) do
|
||||||
|
~H"""
|
||||||
|
<div phx-feedback-for={@id}>
|
||||||
|
<.form for={@patch_form} phx-change="validate" phx-target={@myself} phx-submit="save">
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<p class="my-auto">Patch</p>
|
||||||
|
<select
|
||||||
|
phx-change="selected_patch"
|
||||||
|
id="patch"
|
||||||
|
name="patch"
|
||||||
|
class="block w-full rounded-md border border-gray-300 bg-white shadow-sm focus:border-zinc-400 focus:ring-0 sm:text-sm"
|
||||||
|
>
|
||||||
|
<%= for patch <- @patch_numbers do %>
|
||||||
|
<option key={patch} phx-click="select-patch" name={patch} value={patch}>
|
||||||
|
<%= patch %>
|
||||||
|
</option>
|
||||||
|
<% end %>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</.form>
|
||||||
|
</div>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
end
|
@ -7,22 +7,19 @@ defmodule LoLAnalyticsWeb.ChampionLive.Index do
|
|||||||
|
|
||||||
alias LolAnalyticsWeb.ChampionLive.Mapper
|
alias LolAnalyticsWeb.ChampionLive.Mapper
|
||||||
alias LolAnalyticsWeb.ChampionLive.Components.ChampionFilters
|
alias LolAnalyticsWeb.ChampionLive.Components.ChampionFilters
|
||||||
|
alias LolAnalyticsWeb.PatchSelector
|
||||||
|
|
||||||
@behaviour LolAnalyticsWeb.ChampionFilters.EventHandler
|
@behaviour LolAnalyticsWeb.ChampionFilters.EventHandler
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def mount(params, _session, socket) do
|
def mount(params, _session, socket) do
|
||||||
role =
|
role = params["role"] || "all"
|
||||||
case params["role"] do
|
|
||||||
nil -> "all"
|
|
||||||
role -> role
|
|
||||||
end
|
|
||||||
|
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
|> assign(:selected_role, role)
|
|> assign(:selected_role, role)
|
||||||
|> assign(:champions, %{status: :loading})
|
|> assign(:champions, %{status: :loading})
|
||||||
|> load_champs(role)
|
|> load_champs(role, "all")
|
||||||
|
|
||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
@ -38,19 +35,46 @@ defmodule LoLAnalyticsWeb.ChampionLive.Index do
|
|||||||
def handle_event("filter", %{"role" => selected_role} = params, socket) do
|
def handle_event("filter", %{"role" => selected_role} = params, socket) do
|
||||||
{:reply, %{},
|
{:reply, %{},
|
||||||
socket
|
socket
|
||||||
|> push_navigate(to: ~p"/champions?#{params}")
|
|> push_patch(to: ~p"/champions?#{params}")
|
||||||
|> assign(:champions, %{status: :loading})
|
|> assign(:champions, %{status: :loading})
|
||||||
|> load_champs(selected_role)
|
|> load_champs(selected_role, socket.assigns.selected_patch)
|
||||||
|> assign(:selected_role, selected_role)}
|
|> assign(:selected_role, selected_role)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp load_champs(socket, selected_role) do
|
def handle_info(%{patch: patch}, socket) do
|
||||||
|
selected_role = socket.assigns.selected_role
|
||||||
|
|
||||||
|
socket =
|
||||||
|
assign(socket, :champions, %{status: :loading})
|
||||||
|
|> assign(:selected_patch, patch)
|
||||||
|
|> load_champs(selected_role, patch)
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp load_champs(socket, selected_role, "all") do
|
||||||
socket
|
socket
|
||||||
|> start_async(
|
|> start_async(
|
||||||
:get_champs,
|
:get_champs,
|
||||||
fn ->
|
fn ->
|
||||||
LolAnalytics.Facts.ChampionPlayedGame.Repo.get_win_rates()
|
LolAnalytics.Facts.ChampionPlayedGame.Repo.get_win_rates(team_position: selected_role)
|
||||||
|> filter_champs(selected_role)
|
|> Mapper.map_champs()
|
||||||
|
|> Enum.sort(&(&1.win_rate >= &2.win_rate))
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp load_champs(socket, selected_role, patch) do
|
||||||
|
socket
|
||||||
|
|> start_async(
|
||||||
|
:get_champs,
|
||||||
|
fn ->
|
||||||
|
LolAnalytics.Facts.ChampionPlayedGame.Repo.get_win_rates(
|
||||||
|
team_position: selected_role,
|
||||||
|
patch_number: patch
|
||||||
|
)
|
||||||
|
|> Mapper.map_champs()
|
||||||
|
|> Enum.sort(&(&1.win_rate >= &2.win_rate))
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -77,14 +101,6 @@ defmodule LoLAnalyticsWeb.ChampionLive.Index do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp filter_champs(champs, selected_role) do
|
|
||||||
champs =
|
|
||||||
LolAnalytics.Facts.ChampionPlayedGame.Repo.get_win_rates()
|
|
||||||
|> Enum.filter((&filter_role/1).(selected_role))
|
|
||||||
|> Mapper.map_champs()
|
|
||||||
|> Enum.sort(&(&1.win_rate >= &2.win_rate))
|
|
||||||
end
|
|
||||||
|
|
||||||
defp filter_role(role) do
|
defp filter_role(role) do
|
||||||
fn champ ->
|
fn champ ->
|
||||||
champ.team_position == role || role == "all"
|
champ.team_position == role || role == "all"
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
<.live_component module={ChampionFilters} id="role-filters" selectedrole={@selected_role || "all" } />
|
<.live_component module={ChampionFilters} id="role-filters" selectedrole={@selected_role || "all" } />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<.live_component module={PatchSelector} id="patch-selector" />
|
||||||
|
|
||||||
<div class="h-4"></div>
|
<div class="h-4"></div>
|
||||||
|
|
||||||
<.render_champions champions={@champions} />
|
<.render_champions champions={@champions} />
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
<.header>
|
<.header>
|
||||||
<%= @champion.name %>
|
<h1 class="text-4xl">
|
||||||
|
<%= @champion.name %>
|
||||||
|
</h1>
|
||||||
</.header>
|
</.header>
|
||||||
|
|
||||||
|
<div class="my-6" />
|
||||||
|
|
||||||
<.champion_avatar id={@champion.id} name={@champion.name}
|
<.champion_avatar 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}"} />
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user