Display picked items by champion
Some checks are pending
ci / docker (push) Waiting to run

This commit is contained in:
Álvaro 2024-06-14 01:08:23 +02:00
parent bd8148f3e2
commit aafb805194
16 changed files with 147 additions and 22 deletions

View File

@ -0,0 +1,27 @@
defmodule LolAnalytics.Dimensions.Item.ItemMetadata do
alias LolAnalytics.Dimensions.Item.ItemRepo
alias LolAnalytics.Dimensions.Champion.ChampionRepo
@items_data_url "https://ddragon.leagueoflegends.com/cdn/14.11.1/data/en_US/item.json"
def update_metadata() do
data = get_items()
data
# |> IO.inspect()
|> Enum.each(&save_metadata/1)
end
defp get_items() do
with {:ok, resp} <- HTTPoison.get(@items_data_url),
%{"data" => data} <- Poison.decode!(resp.body) do
data
else
_ -> {:error, :get_items_error}
end
end
defp save_metadata({item_id, metadata}) do
# IO.inspect(item)
ItemRepo.update(item_id, %{metadata: metadata})
end
end

View File

@ -10,7 +10,7 @@ defmodule LolAnalytics.Dimensions.Item.ItemRepo do
case Repo.one(query) do
nil ->
item_changeset = ItemSchema.changeset(%ItemSchema{}, %{item_id: item_id})
Repo.insert(item_changeset)
Repo.insert!(item_changeset)
item ->
item
@ -20,4 +20,11 @@ defmodule LolAnalytics.Dimensions.Item.ItemRepo do
def list_items() do
Repo.all(ItemSchema)
end
@spec update(item_id :: String.t(), attrs :: map()) :: any()
def update(item_id, attrs) do
get_or_create(item_id)
|> ItemSchema.changeset(attrs)
|> Repo.update()
end
end

View File

@ -2,14 +2,17 @@ defmodule LolAnalytics.Dimensions.Item.ItemSchema do
use Ecto.Schema
import Ecto.Changeset
@args [:item_id, :metadata]
schema "dim_item" do
field :item_id, :integer
field :metadata, :map
timestamps()
end
def changeset(item = %__MODULE__{}, attrs \\ %{}) do
item
|> cast(attrs, [:item_id])
|> validate_required([:item_id])
|> cast(attrs, @args)
|> validate_required(@args)
end
end

View File

@ -11,5 +11,6 @@ defmodule LolAnalytics.Dimensions.Player.PlayerSchema do
player
|> cast(attrs, [:puuid])
|> validate_required([:puuid])
|> unique_constraint([:puuid])
end
end

View File

@ -71,12 +71,14 @@ defmodule LolAnalytics.Facts.ChampionPickedItem.Repo do
)",
f.is_win
),
metadata: i.metadata,
item_id: i.item_id,
champion_id: c.champion_id,
team_position: f.team_position,
total_games: count("*")
},
group_by: [
i.metadata,
i.item_id,
c.champion_id,
f.team_position

View File

@ -0,0 +1,9 @@
defmodule LoLAnalytics.Repo.Migrations.ItemMetadata do
use Ecto.Migration
def change do
alter table("dim_item") do
add :metadata, :map
end
end
end

View File

@ -0,0 +1,11 @@
defmodule LoLAnalytics.Repo.Migrations.ItemMetadataIndex do
use Ecto.Migration
def up do
execute("CREATE INDEX dim_item_metadata ON dim_item USING GIN(metadata)")
end
def down do
execute("DROP INDEX dim_item_metadata")
end
end

View File

@ -3,3 +3,14 @@
@import "tailwindcss/utilities";
/* This file is for your main application CSS */
.tooltip {
visibility: hidden;
position: absolute;
}
.has-tooltip:hover .tooltip {
visibility: visible;
z-index: 100;
background-color:lightsteelblue;
}

View File

@ -9,7 +9,6 @@ defmodule LolAnalyticsWeb.ChampionComponents.ChampionAvatar do
~H"""
<div class="flex flex-col w-40">
<img src={@image} alt="champion-icon" />
<p class="w-full text-center"><%= @name %></p>
</div>
"""
end

View File

@ -10,8 +10,10 @@ defmodule LolAnalyticsWeb.ChampionComponents.ChampionCard do
attr :props, Props, default: %Props{}
def champion_card(assigns) do
# IO.inspect(assigns)
~H"""
<.link patch={"/champions/#{@props.id}"}>
<.link patch={"/champions/#{@props.id}?team-position=#{@props.team_position}"}>
<div class="flex flex-col rounded-xl bg-clip-border overflow-hidden bg-gray-200">
<div class="flex flex-col flex-col-reverse">
<div class="flex w-auto px-4 py-1 opacity-80 gap-2 absolute z-10 align-bottom bg-black">

View File

@ -0,0 +1,23 @@
defmodule LolAnalyticsWeb.ChampionComponents.Items do
use Phoenix.Component
def items(assigns) do
image = ""
~H"""
<div class="flex flex-wrap flex-wrap gap-4">
<%= for item <- assigns.items do %>
<div class="has-tooltip">
<div clas="flex flex-col gap-1 p-4">
<img src={item.image} />
<%!-- <p><%= item.name %></p> --%>
<p><%= item.win_rate %>%</p>
<p><%= item.wins %>/<%= item.total_games %></p>
</div>
<span class="tooltip -mt-8 py-2 px-4 rounded-xl"><%= item.name %></span>
</div>
<% end %>
</div>
"""
end
end

View File

@ -6,12 +6,14 @@ defmodule LolAnalyticsWeb.ChampionComponents.SummonerSpells do
~H"""
<div class="flex flex-wrap flex-wrap gap-4">
<%= for spell <- assigns.spells.summoner_spells do %>
<div class="has-tooltip">
<div clas="flex flex-col gap-1">
<img src={spell.image} />
<p><%= spell.name %></p>
<p><%= spell.win_rate %>%</p>
<p><%= spell.wins %>/<%= spell.total_games %></p>
</div>
<div class="tooltip -my-8 px-4 py-2 rounded-xl"><%= spell.name %></div>
</div>
<% end %>
</div>
"""

View File

@ -3,6 +3,7 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do
import LolAnalyticsWeb.ChampionComponents.SummonerSpells
import LolAnalyticsWeb.ChampionComponents.ChampionAvatar
import LolAnalyticsWeb.ChampionComponents.Items
alias LolAnalyticsWeb.ChampionComponents.SummonerSpells.ShowMapper
@ -12,30 +13,30 @@ defmodule LoLAnalyticsWeb.ChampionLive.Show do
end
@impl true
def handle_params(%{"id" => id}, _, socket) do
def handle_params(%{"id" => id, "team-position" => team_position}, _, socket) do
{:noreply,
socket
|> assign(:page_title, page_title(socket.assigns.live_action))
|> assign(:champion, load_champion_info(id) |> ShowMapper.map_champion())
|> assign(:summoner_spells, %{
summoner_spells: load_summoner_spells(id) |> ShowMapper.map_spells()
})}
})
|> assign(:items, load_items(id, team_position) |> ShowMapper.map_items())}
end
defp load_summoner_spells(champion_id) do
LolAnalytics.Facts.ChampionPickedSummonerSpell.Repo.get_champion_picked_summoners(champion_id)
end
defp load_items(champion_id) do
LolAnalytics.Facts.ChampionPickedItem.Repo.get_champion_picked_items(champion_id)
defp load_items(champion_id, team_position) do
LolAnalytics.Facts.ChampionPickedItem.Repo.get_champion_picked_items(
champion_id,
team_position
)
end
defp load_champion_info(champion_id) do
champion = LolAnalytics.Dimensions.Champion.ChampionRepo.get_or_create(champion_id)
IO.inspect(champion)
champion
LolAnalytics.Dimensions.Champion.ChampionRepo.get_or_create(champion_id)
end
defp page_title(:show), do: "Show Champion"

View File

@ -1,6 +1,5 @@
<.header>
Champion <%= @champion.id %>
<:actions></:actions>
<%= @champion.name %>
</.header>
<.champion_avatar id={@champion.id} name={@champion.name}
@ -8,4 +7,16 @@
<div class="my-4" />
<h2 class="text-2xl">Summoner spells</h2>
<div class="my-2" />
<.summoner_spells spells={@summoner_spells} />
<div class="my-4" />
<h2 class="text-2xl">Items</h2>
<div class="my-2" />
<.items items={@items} />

View File

@ -29,6 +29,22 @@ defmodule LolAnalyticsWeb.ChampionComponents.SummonerSpells.ShowMapper do
}
end
def map_items(items) do
items
|> Enum.map(&map_item/1)
|> Enum.sort(&(&1.total_games > &2.total_games))
end
def map_item(item) do
image = item.metadata["image"]["full"]
%{
id: item["id"],
win_rate: :erlang.float_to_binary(item.win_rate, decimals: 2),
total_games: item.total_games,
image: "https://ddragon.leagueoflegends.com/cdn/14.11.1/img/item/#{image}",
name: item.metadata["name"],
wins: item.wins
}
end
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB