filtering by roles
Some checks are pending
ci / docker (push) Waiting to run

This commit is contained in:
Álvaro 2024-05-31 02:40:03 +02:00
parent 22b79f5376
commit 77b292e47e
6 changed files with 111 additions and 95 deletions

View File

@ -6,7 +6,6 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo do
alias LolAnalytics.Dimensions.Champion.ChampionRepo alias LolAnalytics.Dimensions.Champion.ChampionRepo
alias LolAnalytics.Dimensions.Match.MatchRepo alias LolAnalytics.Dimensions.Match.MatchRepo
alias LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameSchema alias LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameSchema
alias LolAnalytics.Facts.ChampionPlayedGame
alias LoLAnalytics.Repo alias LoLAnalytics.Repo
def insert(attrs) do def insert(attrs) do
@ -21,13 +20,13 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo do
Repo.all(ChampionPlayedGameSchema) Repo.all(ChampionPlayedGameSchema)
end end
def get_win_rates2 do def get_win_rates do
query2 = query =
from m in ChampionPlayedGameSchema, from m in ChampionPlayedGameSchema,
join: c in ChampionSchema, join: c in ChampionSchema,
on: c.champion_id == m.champion_id, on: c.champion_id == m.champion_id,
select: %{ select: %{
wins: count(m.is_win), wins: fragment("count(CASE WHEN ? THEN 1 END)", m.is_win),
win_rate: win_rate:
fragment( fragment(
" "
@ -37,41 +36,13 @@ defmodule LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo do
), ),
id: m.champion_id, id: m.champion_id,
name: c.name, name: c.name,
image: c.image image: c.image,
team_position: m.team_position,
total_games: count("*")
}, },
group_by: [m.champion_id, c.image, c.name] group_by: [m.champion_id, c.image, c.name, m.team_position]
Repo.all(query2) Repo.all(query)
end
def get_win_rates() do
query = """
SELECT
(cast(count(CASE WHEN is_win THEN 1 END) as float) / cast(count(*) as float)) * 100.0 as win_rate,
count(CASE WHEN is_win THEN 1 END) as games_won,
count(*) as total_games,
champion_id
FROM fact_champion_played_game
GROUP BY champion_id
ORDER BY win_rate desc;
"""
case Ecto.Adapters.SQL.query(Repo, query, []) do
{:ok, %Postgrex.Result{rows: rows}} ->
rows
|> Enum.map(fn [win_rate, wins, games, champion_id] ->
%{
win_rate: win_rate,
wins: wins,
games: games,
champion_id: champion_id
}
end)
{:error, _exception} ->
:error
end
end end
def get_win_rates_by_roles() do def get_win_rates_by_roles() do

View File

@ -11,7 +11,7 @@
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}> <script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
</script> </script>
</head> </head>
<body class="bg-white antialiased"> <body class="bg-slate-700 antialiased">
<%= @inner_content %> <%= @inner_content %>
</body> </body>
</html> </html>

View File

@ -0,0 +1,3 @@
defmodule LolAnalyticsWeb.ChampionLive.Champion do
defstruct [:id, :win_rate, :image, :name, :team_position, :wins, :total_games]
end

View File

@ -1,46 +1,95 @@
defmodule LoLAnalyticsWeb.ChampionLive.Index do defmodule LoLAnalyticsWeb.ChampionLive.Index do
alias ElixirLS.LanguageServer.Providers.Completion.Reducers.Struct alias LolAnalyticsWeb.ChampionLive.Mapper
use LoLAnalyticsWeb, :live_view use LoLAnalyticsWeb, :live_view
defstruct id: "", win_rate: 0, wins: 0, image: "", name: "" @roles [
%{title: "All", value: "all"},
@roles ["all", "TOP", "JUNGLE", "MIDDLE", "BOTTOM", "UTILITY"] %{title: "Top", value: "TOP"},
%{title: "Jungle", value: "JUNGLE"},
%{title: "Mid", value: "MIDDLE"},
%{title: "Bot", value: "BOTTOM"},
%{title: "Support", value: "UTILITY"}
]
@impl true @impl true
def mount(_params, _session, socket) do def mount(_params, _session, socket) do
champs = LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo.get_win_rates2() champs = LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo.get_win_rates()
mapped = mapped =
champs champs
|> Enum.map(fn champ -> |> Mapper.map_champs()
Kernel.struct!(%__MODULE__{}, champ)
end)
|> Enum.sort(&(&1.win_rate >= &2.win_rate)) |> Enum.sort(&(&1.win_rate >= &2.win_rate))
{:ok, roles =
stream( @roles
socket, |> Enum.reduce(%{}, fn role, acc ->
:champions, Map.merge(acc, %{"#{role.value}" => false})
mapped end)
) |> Map.merge(%{"all" => true})
|> assign(:form, to_form(%{"name" => ""}))}
form =
Map.merge(
%{"name" => ""},
roles
)
socket =
socket
|> stream(
:champions,
mapped
)
|> assign(:form, to_form(form))
|> assign(:roles, @roles)
{:ok, socket}
end end
@impl true
def handle_event("filter", params, socket) do def handle_event("filter", params, socket) do
%{"name" => query_name} = params %{
"name" => query_name,
"all" => all,
"TOP" => top,
"JUNGLE" => jungle,
"MIDDLE" => mid,
"BOTTOM" => bot,
"UTILITY" => utility
} = params
IO.inspect(params)
filter =
if all == "true" do
nil
else
%{
"TOP" => top == "true",
"JUNGLE" => jungle == "true",
"MIDDLE" => mid == "true",
"BOTTOM" => bot == "true",
"UTILITY" => utility == "true"
}
|> Enum.filter(fn {_k, v} -> v end)
|> Enum.map(fn {k, _v} -> k end)
end
IO.puts(">>>>> 3")
IO.inspect(filter)
champs = champs =
LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo.get_win_rates2() LolAnalytics.Facts.ChampionPlayedGame.ChampionPlayedGameRepo.get_win_rates()
|> Enum.filter(fn %{name: name} -> |> Enum.filter(fn %{name: name} ->
String.downcase(name) |> String.contains?(query_name) String.downcase(name) |> String.contains?(query_name)
end) end)
|> Enum.map(fn champ -> |> Enum.filter(fn champ ->
Kernel.struct!(%__MODULE__{}, champ) if filter != nil do
Enum.any?(filter, fn f -> f == champ.team_position end)
end
end) end)
|> Mapper.map_champs()
|> Enum.sort(&(&1.win_rate >= &2.win_rate)) |> Enum.sort(&(&1.win_rate >= &2.win_rate))
IO.inspect(champs)
{:noreply, {:noreply,
stream( stream(
socket, socket,
@ -49,8 +98,8 @@ defmodule LoLAnalyticsWeb.ChampionLive.Index do
)} )}
end end
def handle_event("filter_by", %{"name" => name}, socket) do def handle_event("filter", unsigned_params, socket) do
{:noreply, assign(socket, %{filter_by: name})} {:noreply, socket}
end end
@impl true @impl true
@ -69,12 +118,4 @@ defmodule LoLAnalyticsWeb.ChampionLive.Index do
def handle_info({LoLAnalyticsWeb.ChampionLive.FormComponent, {:saved, champion}}, socket) do def handle_info({LoLAnalyticsWeb.ChampionLive.FormComponent, {:saved, champion}}, socket) do
{:noreply, stream_insert(socket, :champions, champion)} {:noreply, stream_insert(socket, :champions, champion)}
end end
# @impl true
# def handle_event("delete", %{"id" => id}, socket) do
# champion = Accounts.get_champion!(id)
# {:ok, _} = Accounts.delete_champion(champion)
# {:noreply, stream_delete(socket, :champions, champion)}
# end
end end

View File

@ -4,42 +4,30 @@
<h1>Champions</h1> <h1>Champions</h1>
<.form for={@form} phx-change="filter" phx-submit="save"> <.form for={@form} phx-change="filter" phx-submit="save">
<.input type="text" field={@form["name"]} /> <div class="flex flex-col gap-2">
<.input type="checkbox" field={@form["all_roles"]} /> <.input type="text" field={@form["name"]} />
<div class="flex flex-col justify-between"> <div class="flex flex-row justify-between">
<div class="flex flex-row gap-2"> <%= for role <- @roles do %>
<.input type="checkbox" field={@form["top_role"]} /> <div class="flex flex-row gap-2 align-middle">
<p>Top</p> <.input type="checkbox" field={@form[role.value]} />
</div> <p><%= role.title %></p>
<div class="flex flex-row"> </div>
<.input type="checkbox" field={@form["middle_role"]} /> <% end %>
<p>Middle</p>
</div>
<div class="flex flex-row">
<.input type="checkbox" field={@form["jungle_role"]} />
<p>Jungle</p>
</div>
<div class="flex flex-row">
<.input type="checkbox" field={@form["bottom_role"]} />
<p>Bottom</p>
</div>
<div class="flex flex-row">
<.input type="checkbox" field={@form["utility_role"]} />
<p>Utility</p>
</div> </div>
</div> </div>
<button>Save</button> <%!-- <button>Save</button> --%>
</.form> </.form>
<div id="champions" class="grid grid-cols-4 gap-4"> <div id="champions" class="grid grid-cols-4 gap-4">
<%= for {_, champion} <- @streams.champions do %> <%= for {_, champion} <- @streams.champions do %>
<div class="flex flex-col"> <div class="flex flex-col max-w-sm bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700">
<img src={"https://ddragon.leagueoflegends.com/cdn/14.11.1/img/champion/#{champion.image}"} /> <img src={"https://ddragon.leagueoflegends.com/cdn/14.11.1/img/champion/#{champion.image}"} />
<div class="flex-auto flex-col"> <div class="flex-auto flex-col p-4 ">
<p><%= champion.name %></p> <p><%= champion.name %></p>
<p><%= champion.id %></p> <p><%= champion.wins %> / <%= champion.total_games %></p>
<p><%= champion.win_rate %>%</p> <p><%= champion.win_rate %>%</p>
<p><%= champion.team_position %></p>
</div> </div>
</div> </div>

View File

@ -0,0 +1,13 @@
defmodule LolAnalyticsWeb.ChampionLive.Mapper do
alias LolAnalyticsWeb.ChampionLive.Champion
def map_champs(champs) do
champs
|> Enum.map(fn champ ->
%{
Kernel.struct!(%Champion{}, champ)
| win_rate: :erlang.float_to_binary(champ.win_rate, decimals: 2)
}
end)
end
end