Skip to content
Snippets Groups Projects
Commit 26ff7105 authored by maxvaisto's avatar maxvaisto
Browse files

Merge branch 'dash_plots' of...

Merge branch 'dash_plots' of https://version.helsinki.fi/maxvaist/steam-data-project into dash_plots
parents fd2fea26 b21ab399
No related branches found
No related tags found
No related merge requests found
import math
import os
import pandas
from dash import dash, dcc, html, ctx, callback
from dash import dash, dcc, html, Output, Input
from collections import Counter
from dash_plot_generation.utils import split_companies, extract_unique_companies, convert_owners_to_limits, \
get_owner_means
DEVELOPER_DROPDOWN = "developer_dropdown"
DEV_TOP_GENRES_LABEL = "dev_top_genres"
DEV_CCU_LABEL = "dev_ccu"
DEV_GAME_COUNT_LABEL = "dev_game_count"
DEV_REV_PER_GAME_LABEL = "dev_rev_per_game"
DEV_REVENUE_LABEL = "dev_revenue"
csv_path = os.path.normpath(os.getcwd() + os.sep + os.pardir + os.sep + "api_exploration")
split_csv_path = os.path.join(csv_path, "file_segments")
df = None
APP = None
DASH_ASSETS_PATH = "dash_assets"
APP = dash.Dash(
name=__name__,
assets_folder=DASH_ASSETS_PATH,
external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css']
)
def initialize_data():
global df
files = os.listdir(split_csv_path)
......@@ -15,10 +40,31 @@ def initialize_data():
for file in os.listdir(split_csv_path):
file_path = os.path.join(split_csv_path, file)
dataframe = pandas.concat([dataframe, pandas.read_csv(file_path)]) if dataframe is not None \
else pandas.read_csv(file_path)
else pandas.read_csv(file_path)
df = dataframe
@APP.callback([Output(DEV_REVENUE_LABEL, "children"),
Output(DEV_TOP_GENRES_LABEL, "children"),
Output(DEV_CCU_LABEL, "children"),
Output(DEV_GAME_COUNT_LABEL, "children"),
Output(DEV_REV_PER_GAME_LABEL, "children")],
inputs=[Input(DEVELOPER_DROPDOWN, "value")])
def update_dev_info(dev_name):
global df
mask = df.developer.apply(lambda x: dev_name in x if isinstance(x,str) else False)
dev_data = df[mask]
ccu = sum(dev_data["ccu"])
dev_data["owner_means"] = dev_data["owners"].apply(lambda x: get_owner_means(convert_owners_to_limits(x)))
dev_data["game_prices"] = dev_data["price"]
game_revenue = [owner_count*game_price for (owner_count, game_price) in
zip(dev_data["owner_means"],dev_data["game_prices"]) if
not (pandas.isna(game_price) or pandas.isna(owner_count))]
genre_totals = [genre for genre_list in dev_data["genres"] if isinstance(genre_list,str) for genre in genre_list]
genre_counts = Counter(genre_totals).keys()
return str(sum(game_revenue)), "hello2", str(ccu), str(dev_data.shape[0]), str(round(sum(game_revenue)/len(game_revenue))
def initialize_dash(host: str = "0.0.0.0", **kwargs):
"""
Runs the Dash server.
......@@ -32,73 +78,94 @@ def initialize_dash(host: str = "0.0.0.0", **kwargs):
global APP, df
unique_developers = [dev for dev_list in df["developer"].fillna("Valve").unique() for dev in dev_list.split(",")]
unique_publishers = df["developer"].fillna("Valve").unique()
unique_publishers = extract_unique_companies(df["publisher"].apply(lambda x: split_companies(x)))
unique_developers = extract_unique_companies(df["developer"].apply(lambda x: split_companies(x)))
# unique_publishers = ["Valve"]
# unique_developers = ["Valve"]
# This is ok but the results are still unsatisfactory due to the game company names containing a comma
# unique_publishers = [publisher for publisher_list in df["developer"].fillna("Valve").unique() for publisher
# unique_developers = [dev for dev_list in df["developer"].fillna("Valve").unique() for dev in dev_list.split(",")]
APP = dash.Dash(
name=__name__,
assets_folder=DASH_ASSETS_PATH,
external_stylesheets=['https://codepen.io/chriddyp/pen/bWLwgP.css']
)
APP.layout = html.Div(children=[
html.Nav(className="nav nav-pills", children=[
html.H6("STEAM-SAVVY", style={"margin-left": "30px", "width": "20%", "display": "inline-block"}),
html.A('About', className="nav-item nav-link btn", href='/apps/App1',
style={"margin-left": "300px"}),
html.A('Process paper', className="nav-item nav-link active btn", href='/apps/App2',
html.A('Technical report', className="nav-item nav-link active btn", href='/apps/App2',
style={"margin-left": "150px"})
],
style={"background-color": "rgb(30,30,30)", "color": "rgb(255,255,255)"}),
html.H6("TEXT"),
style={"background-color": "rgb(30,30,30)", "color": "rgb(255,255,255)"}),
html.Div(className="row", children=[
html.Div(children = [
dcc.Tabs(id="tabs_main_plots1", value="tab1", children=[
dcc.Tab(label="Genre performance", value="tab1"),
dcc.Tab(label="Game popularity", value="tab2"),
dcc.Tab(label="Company revenues", value="tab3"),
dcc.Tab(label="Market performance", value="tab4"),
],
style={'width': '80%', 'display': 'inline-block', "outline": "2px dotted black"}),
], style={'width': '48%', 'display': 'inline-block'}),
html.Div(children=[
dcc.Tabs(id="tabs_main_plots2", value="tab3", children=[
dcc.Tab(label="Developer infromation", value="Valve", children=[
dcc.Dropdown(id="developer_dropdown",
options=[{"label": developer, "value": developer} for developer in unique_developers]
)
]),
dcc.Tab(label="Publisher information", value="tab4", children= [
dcc.Dropdown(id="publisher_dropdown",
options=[{"label": publisher, "value": publisher} for publisher in unique_publishers]
),
])
],
style={'width': '48%', 'display': 'inline-block'}),
dcc.Tabs(id="tabs_main_plots1", value="tab1", children=[
dcc.Tab(label="Genre performance", value="tab1"),
dcc.Tab(label="Game popularity", value="tab2"),
dcc.Tab(label="Company revenues", value="tab3"),
dcc.Tab(label="Market performance", value="tab4"),
],
style={'width': '80%', 'display': 'inline-block', "outline": "2px dot'ted black"}),
], style={'width': '60%', 'display': 'inline-block'}),
html.Div(children=[
dcc.Tabs(id="tabs_main_plots2", value="tab3", children=[
dcc.Tab(label="Developer infromation", value="Valve", children=[
html.Div(children=[
dcc.Dropdown(id=DEVELOPER_DROPDOWN, value="Valve",
options=[{"label": developer, "value": developer} for developer in
unique_developers]
),
html.Div(children=[
html.H6("General statistics"),
html.Div( # Revenue
children=[html.P("Revenue"),
html.Div(children=[
html.P("Total game sale revenue"),
html.Small(id=DEV_REVENUE_LABEL, children="524.245.000€"),
html.P("Total game sale revenue per game"),
html.Small(id=DEV_REV_PER_GAME_LABEL, children="92.625.000€"),
html.P("Highest game sale revenue games:"),
html.Small("Half life 2"),
html.Small("CS GO"),
html.Small("Portal 2")
])
],
style={'width': '48%', 'display': 'inline-block'}
),
html.Div(children=[
html.Div(children=[
html.P("Number of games"),
html.Small(id=DEV_GAME_COUNT_LABEL, children="5"),
html.P("Number of concurrent users"),
html.Small(id=DEV_CCU_LABEL, children="92.625.000€"),
html.P("Most common game genres"),
html.Small(id=DEV_TOP_GENRES_LABEL, children="FPS, Action, Puzzle"),
html.P("Average game rating"),
])
], style={'width': '48%', 'display': 'inline-block'}
)
])
],
)
]),
dcc.Tab(label="Publisher information", value="tab4", children=[
dcc.Dropdown(id="publisher_dropdown", value="Valve",
options=[{"label": publisher, "value": publisher} for publisher in
unique_publishers]
),
])
],
style={'width': '100%', 'display': 'inline-block'}),
],
style={'width': '48%', 'display': 'inline-block', "outline": "2px dotted black"})
style={'width': '30%', 'display': 'inline-block', "outline": "2px dotted black"})
],
style={'width': '100%'}),
])
style={'width': '100%', "padding-top": "15px"}),
])
APP.run(host=host, **kwargs)
print("The server has closed!")
if __name__ == "__main__":
initialize_data()
initialize_dash()
initialize_dash(debug=True)
print(csv_path)
from typing import Sequence, Optional
from typing import Sequence, Optional, Any
import pandas
DEFAULT_ILLEGAL_CONTINUATIONS = {"INC.", "LLC", "CO.", "LTD.", "S.R.O."}
def get_owner_means(owner_limits: Sequence[Any]):
if not isinstance(owner_limits, list):
return owner_limits
else:
return (owner_limits[0]+owner_limits[1])/2
def convert_owners_to_limits(owner_limit):
if not isinstance(owner_limit, str):
return owner_limit
owners_raw = [rev.replace(" ", "") for rev in owner_limit.split(" .. ")]
owners_clean = []
for owner_limit in owners_raw:
owner_limit = owner_limit.replace("M", "0"*6)
owner_limit = owner_limit.replace("k", "0"*3)
owners_clean.append(int(owner_limit))
return owners_clean
def split_companies(arr, illegal_continuations: Optional[Sequence[str]] = None):
"""
Splits the given string at comma sign as long as following the comma none of the illegal
......@@ -44,3 +59,13 @@ def split_companies(arr, illegal_continuations: Optional[Sequence[str]] = None):
results_list.append(arr[start_index:index + 1].strip())
return results_list
def extract_unique_companies(nested_companies):
full_company_list = [dev for company_list in nested_companies
if isinstance(company_list, list) for dev in company_list]
unique_companies = []
for company in full_company_list:
if company not in unique_companies:
unique_companies.append(company)
return unique_companies
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment