BigBrother: Add percentages.
This commit is contained in:
parent
59ecbec22d
commit
6e127fe839
|
@ -5,6 +5,7 @@ Dragonslayer:
|
||||||
color: "e20a00"
|
color: "e20a00"
|
||||||
ids:
|
ids:
|
||||||
- 22888
|
- 22888
|
||||||
|
required: false
|
||||||
classes:
|
classes:
|
||||||
- ALL
|
- ALL
|
||||||
|
|
||||||
|
@ -12,6 +13,7 @@ Zandalar:
|
||||||
color: "41ca46"
|
color: "41ca46"
|
||||||
ids:
|
ids:
|
||||||
- 24425
|
- 24425
|
||||||
|
required: false
|
||||||
classes:
|
classes:
|
||||||
- ALL
|
- ALL
|
||||||
|
|
||||||
|
@ -21,6 +23,7 @@ DM:T:
|
||||||
- 22817 # Fengus' Ferocity
|
- 22817 # Fengus' Ferocity
|
||||||
- 22820 # Slip'kik's Savvy
|
- 22820 # Slip'kik's Savvy
|
||||||
- 22818 # Mol'dar's Moxie
|
- 22818 # Mol'dar's Moxie
|
||||||
|
required: false
|
||||||
classes:
|
classes:
|
||||||
- ALL
|
- ALL
|
||||||
|
|
||||||
|
@ -30,9 +33,11 @@ Zanza:
|
||||||
- 24382 # Spirit of Zanza
|
- 24382 # Spirit of Zanza
|
||||||
- 20081 # Swiftness of Zanza
|
- 20081 # Swiftness of Zanza
|
||||||
- 20080 # Sheen of Zanza
|
- 20080 # Sheen of Zanza
|
||||||
|
required: false
|
||||||
classes:
|
classes:
|
||||||
- Druid
|
- Druid
|
||||||
- Priest
|
- Priest
|
||||||
|
- Warrior
|
||||||
|
|
||||||
|
|
||||||
Alcohol:
|
Alcohol:
|
||||||
|
@ -41,6 +46,7 @@ Alcohol:
|
||||||
- 22790 # Kreeg's Stout Beatdown
|
- 22790 # Kreeg's Stout Beatdown
|
||||||
- 22789 # Gordok Green Grog
|
- 22789 # Gordok Green Grog
|
||||||
- 25804 # Rumsey Rum Black Label
|
- 25804 # Rumsey Rum Black Label
|
||||||
|
required: false
|
||||||
classes:
|
classes:
|
||||||
- Druid
|
- Druid
|
||||||
- Priest
|
- Priest
|
||||||
|
@ -55,6 +61,8 @@ Food:
|
||||||
- 18125 # Blessed Sunfruit
|
- 18125 # Blessed Sunfruit
|
||||||
- 19710 # Tender Wolf Steak
|
- 19710 # Tender Wolf Steak
|
||||||
- 22730 # Runn Tum Tuber Surprise
|
- 22730 # Runn Tum Tuber Surprise
|
||||||
|
- 25661 # Dirge's Kickin' Chimaerok Chops
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- ALL
|
- ALL
|
||||||
|
|
||||||
|
@ -62,6 +70,7 @@ Mageblood:
|
||||||
color: "550c65"
|
color: "550c65"
|
||||||
ids:
|
ids:
|
||||||
- 24363
|
- 24363
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Balance Druid
|
- Balance Druid
|
||||||
- Druid
|
- Druid
|
||||||
|
@ -73,6 +82,7 @@ Strength:
|
||||||
ids:
|
ids:
|
||||||
- 11405 # Elixir of the Giants
|
- 11405 # Elixir of the Giants
|
||||||
- 16323 # Juju Power
|
- 16323 # Juju Power
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Feral Druid
|
- Feral Druid
|
||||||
- Retribution Paladin
|
- Retribution Paladin
|
||||||
|
@ -85,6 +95,7 @@ Mongoose:
|
||||||
ids:
|
ids:
|
||||||
- 17538 # Elixir of the Mongoose
|
- 17538 # Elixir of the Mongoose
|
||||||
- 11334 # Greater Agility
|
- 11334 # Greater Agility
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Feral Druid
|
- Feral Druid
|
||||||
- Hunter
|
- Hunter
|
||||||
|
@ -98,6 +109,7 @@ Arcane:
|
||||||
ids:
|
ids:
|
||||||
- 17539 # Greater Arcane Elixir
|
- 17539 # Greater Arcane Elixir
|
||||||
#- 11390 # Arcane Elixir
|
#- 11390 # Arcane Elixir
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Balance Druid
|
- Balance Druid
|
||||||
- Mage
|
- Mage
|
||||||
|
@ -108,6 +120,7 @@ Shadow:
|
||||||
color: "510164"
|
color: "510164"
|
||||||
ids:
|
ids:
|
||||||
- 11474
|
- 11474
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Shadow Priest
|
- Shadow Priest
|
||||||
- Warlock
|
- Warlock
|
||||||
|
@ -117,6 +130,7 @@ Frost/Fire:
|
||||||
ids:
|
ids:
|
||||||
- 21920 # Frost Power
|
- 21920 # Frost Power
|
||||||
- 26276 # Greater Firepower
|
- 26276 # Greater Firepower
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Mage
|
- Mage
|
||||||
|
|
||||||
|
@ -124,6 +138,7 @@ Frost/Fire:
|
||||||
# color: "2bddc7"
|
# color: "2bddc7"
|
||||||
# ids:
|
# ids:
|
||||||
# - 11374
|
# - 11374
|
||||||
|
# required: true
|
||||||
# classes:
|
# classes:
|
||||||
# - Tank Warrior
|
# - Tank Warrior
|
||||||
|
|
||||||
|
@ -131,5 +146,6 @@ Defense:
|
||||||
color: "0a0a0a"
|
color: "0a0a0a"
|
||||||
ids:
|
ids:
|
||||||
- 11348
|
- 11348
|
||||||
|
required: true
|
||||||
classes:
|
classes:
|
||||||
- Tank Warrior
|
- Tank Warrior
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import base64
|
import base64
|
||||||
import io
|
import io
|
||||||
from collections import defaultdict
|
from collections import defaultdict, Counter
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import List
|
from typing import List
|
||||||
|
@ -11,6 +11,7 @@ from . import config
|
||||||
|
|
||||||
|
|
||||||
def graph(raid: List[dict]) -> None:
|
def graph(raid: List[dict]) -> None:
|
||||||
|
# TODO: This entire function is shit.
|
||||||
figs = []
|
figs = []
|
||||||
buff_ids = {
|
buff_ids = {
|
||||||
buff_id: buff_name
|
buff_id: buff_name
|
||||||
|
@ -18,6 +19,7 @@ def graph(raid: List[dict]) -> None:
|
||||||
for buff_id in buff_data["ids"]
|
for buff_id in buff_data["ids"]
|
||||||
}
|
}
|
||||||
classes = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
|
classes = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
|
||||||
|
player_buff_counts = defaultdict(Counter)
|
||||||
xticks = []
|
xticks = []
|
||||||
first_encounter_date = None
|
first_encounter_date = None
|
||||||
last_encounter_date = None
|
last_encounter_date = None
|
||||||
|
@ -33,24 +35,32 @@ def graph(raid: List[dict]) -> None:
|
||||||
for player_name, buffs in sorted(players.items()):
|
for player_name, buffs in sorted(players.items()):
|
||||||
real_class_name = config.class_overrides.get(player_name, str.title(class_name))
|
real_class_name = config.class_overrides.get(player_name, str.title(class_name))
|
||||||
classes[real_class_name][player_name] # ensure player is added, irregardless if they have any buffs
|
classes[real_class_name][player_name] # ensure player is added, irregardless if they have any buffs
|
||||||
|
player_buff_names = set()
|
||||||
for buff_id in buffs:
|
for buff_id in buffs:
|
||||||
with suppress(KeyError): # KeyError on buff_id => buff not tracked
|
with suppress(KeyError): # KeyError on buff_id => buff not tracked
|
||||||
buff_name = buff_ids[buff_id]
|
buff_name = buff_ids[buff_id]
|
||||||
|
player_buff_names.add(buff_name)
|
||||||
classes[real_class_name][player_name][buff_name].append(
|
classes[real_class_name][player_name][buff_name].append(
|
||||||
(previous_encounter_date, (encounter_date - previous_encounter_date))
|
(previous_encounter_date, (encounter_date - previous_encounter_date))
|
||||||
)
|
)
|
||||||
|
player_buff_counts[player_name].update(player_buff_names)
|
||||||
previous_encounter_date = encounter_date
|
previous_encounter_date = encounter_date
|
||||||
|
|
||||||
for class_name, players in sorted(classes.items()):
|
for class_name, players in sorted(classes.items()):
|
||||||
fig, ax = plt.subplots()
|
fig, ax = plt.subplots()
|
||||||
required_class_buffs = {
|
class_buffs = {
|
||||||
buff_name: buff_data
|
buff_name: buff_data
|
||||||
for buff_name, buff_data in config.buffs.items()
|
for buff_name, buff_data in config.buffs.items()
|
||||||
if any(x in buff_data["classes"] for x in ("ALL", class_name))
|
if any(x in buff_data["classes"] for x in ("ALL", class_name))
|
||||||
}
|
}
|
||||||
|
required_class_buffs = {
|
||||||
|
buff_name: buff_data
|
||||||
|
for buff_name, buff_data in class_buffs.items()
|
||||||
|
if buff_data["required"]
|
||||||
|
}
|
||||||
#legend_handles = []
|
#legend_handles = []
|
||||||
bar_width = 1 / (len(required_class_buffs) + 1)
|
bar_width = 1 / (len(class_buffs) + 1)
|
||||||
for b, (buff_name, buff) in enumerate(required_class_buffs.items()):
|
for b, (buff_name, buff) in enumerate(class_buffs.items()):
|
||||||
bar_color = "#{color}".format(**buff)
|
bar_color = "#{color}".format(**buff)
|
||||||
#legend_handles.append(Patch(label=buff_name, color=bar_color))
|
#legend_handles.append(Patch(label=buff_name, color=bar_color))
|
||||||
for y0, (player_name, player_buffs) in enumerate(players.items()):
|
for y0, (player_name, player_buffs) in enumerate(players.items()):
|
||||||
|
@ -78,9 +88,18 @@ def graph(raid: List[dict]) -> None:
|
||||||
ax.axhline(y=y0, linewidth=1.0, color="black")
|
ax.axhline(y=y0, linewidth=1.0, color="black")
|
||||||
|
|
||||||
plt.xticks(*zip(*xticks), rotation=30, ha="right")
|
plt.xticks(*zip(*xticks), rotation=30, ha="right")
|
||||||
|
required_buff_fraction = {
|
||||||
|
p: sum(
|
||||||
|
c
|
||||||
|
for b, c in player_buff_counts[p].items()
|
||||||
|
if b in required_class_buffs
|
||||||
|
) / (len(raid) * len(required_class_buffs))
|
||||||
|
for p in players
|
||||||
|
}
|
||||||
plt.yticks(
|
plt.yticks(
|
||||||
list(range(len(players))),
|
list(range(len(players))),
|
||||||
players
|
[f"{p}\n{required_buff_fraction[p]:.0%}" for p in players],
|
||||||
|
verticalalignment="top"
|
||||||
)
|
)
|
||||||
ax.invert_yaxis()
|
ax.invert_yaxis()
|
||||||
ax.grid(axis="x", linestyle="--")
|
ax.grid(axis="x", linestyle="--")
|
||||||
|
|
Loading…
Reference in a new issue