diff --git a/api_exploration/DLC_data_gatherer.py b/api_exploration/DLC_data_gatherer.py
index f019845845187a9e61e4e1502f27ba09a81850ce..07b05c1ce8fe3c894b58f63eca1a8ea07d77d990 100644
--- a/api_exploration/DLC_data_gatherer.py
+++ b/api_exploration/DLC_data_gatherer.py
@@ -7,7 +7,8 @@ import pandas
 import pandas as pd
 
 from main import get_steam_API_response, get_steamspy_API_response, STEAM_SPY_GAME_INFO, STEAM_API_LANGUAGE, \
-    STEAM_GAME_INFO_URL, replace_owner_number_with_symbol
+    STEAM_GAME_INFO_URL
+from dash_plot_generation.utils import replace_owner_number_with_symbol_real_numeric
 
 
 def get_dlc_data_steam(id):
@@ -90,7 +91,7 @@ if __name__ == "__main__":
             data = pandas.read_csv(os.path.join(os.getcwd(), path, file_name), index_col=0)
             # data = data.iloc[0:10] # for testing
             full_df = get_dlc_for_df(data)
-            full_df = replace_owner_number_with_symbol(full_df)
+            full_df = replace_owner_number_with_symbol_real_numeric(full_df)
             file_name = "".join(["dlc_data", "_", str(file_index), ".csv"])
             file_path = os.path.join(os.getcwd(), dlc_path, file_name)
 
diff --git a/api_exploration/main.py b/api_exploration/main.py
index 172d766e161b05ca2f238b79ea355a72b7cdb4a9..8dd8334f6cfff9d66651b3af1fd0f1a6408740a2 100644
--- a/api_exploration/main.py
+++ b/api_exploration/main.py
@@ -11,6 +11,8 @@ import numpy
 import matplotlib.pyplot as plt
 from pandas.core.dtypes.common import is_numeric_dtype
 
+from dash_plot_generation.utils import replace_owner_number_with_symbol_real_numeric
+
 STEAMSPY_ALL_GAMES_URL = "https://steamspy.com/api.php?request=all&page="
 STEAM_GAME_INFO_URL = "https://store.steampowered.com/api/appdetails?appids="
 STEAM_API_LANGUAGE = "&l=english"
@@ -178,17 +180,6 @@ def create_hist_plots(df):
             plt.show()
 
 
-def replace_owner_number_with_symbol(df):
-    def owner_strip(user_range: str):
-        if isinstance(user_range, str):
-            user_range = user_range.replace(",000,000", " M")
-            user_range = user_range.replace(",000", " k")
-        return user_range
-
-    df["owners"] = df["owners"].apply(lambda name: owner_strip((name)))
-    return df
-
-
 def create_heat_maps(df, plot_pairs):
     for (x, y) in plot_pairs:
         plt.figure()  # Create a new figure for each heatmap
@@ -229,7 +220,7 @@ if __name__ == "__main__":
     for i in range(0, 68):
         df = get_all_data(iterations=[i])
         df = add_user_rating(df)
-        df = replace_owner_number_with_symbol(df)
+        df = replace_owner_number_with_symbol_real_numeric(df)
         df = price_to_dollars(df)
         file_name = "".join(["game_data", "_", str(i), ".csv"])
         file_path = os.path.join(os.getcwd(), path, file_name)
diff --git a/dash_plot_generation/dash_assets/background_image.jpg b/dash_plot_generation/dash_assets/background_image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1637282547b6ef0b65327c800c5cafff8542ed0d
Binary files /dev/null and b/dash_plot_generation/dash_assets/background_image.jpg differ
diff --git a/dash_plot_generation/dash_assets/broken car.jpg b/dash_plot_generation/dash_assets/broken car.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..a06c8675ca28b8275ef2dc11a5ac7c6130aa66b2
Binary files /dev/null and b/dash_plot_generation/dash_assets/broken car.jpg differ
diff --git a/dash_plot_generation/dash_assets/dark city.jpg b/dash_plot_generation/dash_assets/dark city.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6ea99ba64e17388dd2a460a4a6be4400637997a8
Binary files /dev/null and b/dash_plot_generation/dash_assets/dark city.jpg differ
diff --git a/dash_plot_generation/dash_assets/dark_computer_room.jpg b/dash_plot_generation/dash_assets/dark_computer_room.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..6b27929de7911116d83e031c529832571a2ea807
Binary files /dev/null and b/dash_plot_generation/dash_assets/dark_computer_room.jpg differ
diff --git a/dash_plot_generation/dash_assets/radioactive.jpg b/dash_plot_generation/dash_assets/radioactive.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d1c018634b79e6a5a496c71e6ce05073264da869
Binary files /dev/null and b/dash_plot_generation/dash_assets/radioactive.jpg differ
diff --git a/dash_plot_generation/dash_assets/styles.css b/dash_plot_generation/dash_assets/styles.css
new file mode 100644
index 0000000000000000000000000000000000000000..e2f7895cc48d409988f7a34353daebc672b0105d
--- /dev/null
+++ b/dash_plot_generation/dash_assets/styles.css
@@ -0,0 +1,77 @@
+
+html, body {
+  height: 100%;
+  margin: 0;
+  background-color: rgb(27,40,56);
+}
+#app-container {
+  height: 100%;
+  width: 100%;
+  position: relative;
+}
+
+.ag-theme-custom-dark {
+    --ag-background-color: #ddd !important;
+}
+
+.dash-dropdown .Select-control {
+    border: 2px solid rgb(37, 55, 77);
+    border-radius: 4px;
+}
+
+.dash-dropdown .Select-value {
+    color: rgb(235, 235, 235);
+}
+
+.dash-dropdown .Select-control {
+    background-color: rgb(50, 70, 101);
+}
+.dash-dropdown.is-minimized .Select-value-label {
+    color: rgb(235, 235, 235);
+}
+
+.dash-dropdown .Select-value-label {
+    color: rgb(235, 235, 235);
+
+}
+
+.dash-dropdown .Select-menu-outer {
+    background-color: rgb(50, 70, 101);
+}
+
+.jsx-4017309047.tab-container{
+    border-bottom: 2px solid rgb(37,55,77);
+}
+
+.dark_plot{
+    background-color: black;
+}
+
+/* Track rgb(197,195,192) */
+div.scrollable::-webkit-scrollbar {
+    width: 6px; /* width of the vertical scrollbar */
+    border-radius: 6px;
+}
+
+div.scrollable::-webkit-scrollbar-track {
+    margin-top: 20px;
+    margin-bottom: 20px;
+}
+
+
+div.scrollable::-webkit-scrollbar-thumb {
+    background-color: rgb(235, 235, 235);
+    border-right: none;
+    border-left: none;
+    border-radius: 6px;
+}
+
+div.scrollable::-webkit-scrollbar-track-piece:end {
+    background: rgb(37,55,77);
+    margin-bottom: 10px;
+}
+
+div.scrollable::-webkit-scrollbar-track-piece:start {
+    background: rgb(37,55,77);
+    margin-top: 10px;
+}
\ No newline at end of file
diff --git a/dash_plot_generation/dash_plot_generator.py b/dash_plot_generation/dash_plot_generator.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a05b81728e95e650a41b6a6dfdad02cbe14c0be
--- /dev/null
+++ b/dash_plot_generation/dash_plot_generator.py
@@ -0,0 +1,479 @@
+import math
+import os
+
+import numpy
+import pandas
+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, round_to_three_largest_digits, replace_owner_number_with_symbol_real_numeric, \
+    convert_to_numeric_str, label_with_rev, label_with_text
+from dash.exceptions import PreventUpdate
+import plotly.graph_objects as go
+import plotly.express as px
+
+SPACE_NORMAL_ENTRY = 35
+
+DEV_AVERAGE_RATING_LABEL = "dev_average_rating"
+
+RIGHT_SIDE_TEXT_DICT = {'display': 'inline-block',
+                        'float': 'right', 'margin-right': '0%', 'margin-bottom': '0px'}
+
+DARK_STEAM = "rgb(23,29,37)"
+WHITE_STEAM = "rgb(235,235,235)"
+TITLE_WHITE_STEAM = "rgb(197,195,192)"
+DARK_BLUE_STEAM = "rgb(27,40,56)"
+TAB_COLOR = "rgb(31,46,65)"
+TAB_EDGE = "rgb(37,55,77)"
+DROPDOWN_COLOR = "rgb(50,70,101"
+SMALL_PANEL_COLOR = "rgb(22,32,45)"
+
+DEFAULT_TABS_DICT = {'width': 'auto', 'display': 'flex',
+                     'background-color': TAB_COLOR, 'border-color': TAB_EDGE}
+TAB_HEADER_COLOR = "rgb(45,96,150)"
+DEVELOPER_DROPDOWN = "developer_dropdown"
+TAB_NORMAL_DICT = {'background-color': TAB_COLOR, 'color': TITLE_WHITE_STEAM,
+                   'border': '0px solid',
+                   'font-size': '15px',
+                   'border_bottom': '2px solid ' + TAB_EDGE}
+TAB_HIGHLIGHT_DICT = {'backgroundColor': TAB_HEADER_COLOR, 'color': 'white', "border-color": "transparent",
+                      'font-size': '15px'}
+PANEL_DEFAULT_DICT = {'display': 'inline-block',
+                      'background-color': TAB_COLOR, 'border': '2px solid', 'border-color': TAB_EDGE,
+                      'color': WHITE_STEAM, 'height': '600px'}
+SMALL_PANEL_DICT = {'float': 'left', 'background-color': 'transparent', 'box-sizing': 'border-box',
+                    'padding': '10px'}
+SMALL_TAB_PANEL_DICT = SMALL_PANEL_DICT | {'width': '48%', 'height': '100%',
+                                           'margin-bottom': '50px',
+                                           'padding-top': '4%', 'padding-bottom': '5%', 'padding-left': '5%',
+                                           'padding-right': '5%',
+                                           'margin-top': '20px'
+                                           }
+SMALL_PANEL_HEADER_DICT = {'text-align': 'center', 'padding-top': '5%', 'padding-bottom': '2%'}
+
+DEV_TOP_GENRES_LABEL = "dev_top_genres"
+
+LIST_DICT = {'display': 'inline-block', 'margin-bottom': '0px', 'padding-right': '0px'}
+
+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"
+
+DEV_TOP_GAMES = "pub_top_games"
+
+PUB_TOP_GENRES_LABEL = "pub_top_genres"
+
+PUB_CCU_LABEL = "pub_ccu"
+
+PUB_GAME_COUNT_LABEL = "pub_game_count"
+
+PUB_REV_PER_GAME_LABEL = "pub_rev_per_game"
+
+PUB_REVENUE_LABEL = "pub_revenue"
+
+PUB_TOP_GAMES = "pub_top_games"
+DEMO_PLOT_LABELS = ["Action", "Adventure", "RPG", "Puzzle", "Strategy", "Other"]
+DEMO_PLOT_COLORS = list(zip(DEMO_PLOT_LABELS, px.colors.qualitative.G10))
+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")
+# steam_dark_template = dict(layout=go.Layout(title_font))
+
+df = 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
+    dataframe = None
+    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)
+    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"),
+               Output(DEV_TOP_GAMES, "children"),
+               Output(DEV_AVERAGE_RATING_LABEL, "children")],
+              inputs=[Input(DEVELOPER_DROPDOWN, "value")])
+def update_dev_info(dev_name):
+    global df
+    if not (dev_name and isinstance(df,pandas.DataFrame)):
+        raise PreventUpdate
+
+    # Remove empty rows
+    mask = df.developer.apply(lambda x: dev_name in x if isinstance(x, str) else False)
+    dev_data = df[mask]
+
+    # Engineer revenue data into the dataframe
+    add_game_revenues_and_owner_means(dev_data)
+
+    # Top games
+    dev_top_games_label = get_top_revenue_game_labels(dev_data)
+
+    # Dev total revenue
+    dev_revenue = get_total_revenue_label(dev_data)
+
+    # Dev revenue per game
+    dev_game_revenue_per_game = get_average_game_rev_label(dev_data)
+
+    # Top genres
+    dev_top_genre_labels = get_top_genre_labels(dev_data)
+
+    # CCU
+    dev_ccu = get_ccu_label(dev_data)
+
+    # Game count
+    dev_game_count = get_game_count_label(dev_data)
+
+    user_rating_value = get_average_user_rating_label(dev_data)
+    return dev_revenue, dev_top_genre_labels, dev_ccu, dev_game_count, dev_game_revenue_per_game, dev_top_games_label, \
+        user_rating_value
+
+
+def get_average_user_rating_label(dev_data):
+    value_str = str(round(100 * dev_data["Review_rating"].mean())) + "%"
+    label = label_with_text("Average game rating", value_str, SPACE_NORMAL_ENTRY, ".")
+    return label
+
+
+def get_game_count_label(dev_data):
+    return label_with_text("Number of games", str(dev_data.shape[0]), SPACE_NORMAL_ENTRY, ".")
+
+
+def add_game_revenues_and_owner_means(data):
+    data["owner_means"] = data["owners"].apply(lambda x: get_owner_means(convert_owners_to_limits(x)))
+    data["game_revenue"] = data.apply(lambda x: x["owner_means"] * x["price"] if
+    not (pandas.isna(x["owner_means"]) or pandas.isna(x["price"]))
+    else 0, axis=1)
+
+
+def get_top_revenue_game_labels(data):
+    top_games = data.sort_values(by=["game_revenue"], ascending=False).head(3)
+    top_games_processed = top_games.apply(lambda x: label_with_rev(x["name"], x["game_revenue"], SPACE_NORMAL_ENTRY,
+                                                                   ".", "$"), axis=1)
+    dev_top_games_with_dot = [" ".join(["•", game]) for game in top_games_processed]
+    dev_top_games_label = html.Div("\n".join(dev_top_games_with_dot),
+                                   style={'white-space': 'pre-line', 'padding-left': '5%'})
+    return dev_top_games_label
+
+
+def get_total_revenue_label(data):
+    top_games_processed = label_with_rev("• Total", numpy.nansum(data["game_revenue"]), SPACE_NORMAL_ENTRY, ".", "$")
+    return top_games_processed
+
+
+def get_top_genre_labels(data):
+    genre_totals = [genre for genre_list in data["genres"] if isinstance(genre_list, str)
+                    for genre in genre_list.split(", ")]
+    genre_counts = Counter(genre_totals).most_common(3)
+    top_genres_rows = [label_with_text(genre[0], str(genre[1]), 50, ".") for genre in genre_counts]
+    top_genres_with_dot = [" ".join(["•", row]) for row in top_genres_rows]
+    top_genre_labels = html.Div("\n".join(top_genres_with_dot),
+                                    style={'white-space': 'pre-line', 'padding-left': '5%'})
+    return top_genre_labels
+
+
+def get_ccu_label(data):
+    ccu = sum(data["ccu"])
+    dev_ccu = convert_to_numeric_str(ccu)
+
+    return label_with_text("Concurrent users", dev_ccu, SPACE_NORMAL_ENTRY, ".")
+
+
+def get_average_game_rev_label(data):
+    game_revenue_per_game_raw = numpy.nansum(data["game_revenue"]) / len(data["game_revenue"])
+    dev_game_revenue_per_game_row = label_with_rev("Average", game_revenue_per_game_raw, SPACE_NORMAL_ENTRY, ".", "$")
+    dev_game_revenue_per_game = " ".join(["•", dev_game_revenue_per_game_row])
+    return dev_game_revenue_per_game
+
+
+def initialize_dash(host: str = "0.0.0.0", **kwargs):
+    """
+    Runs the Dash server.
+    Args:
+        host: IP address of the server
+        kwargs: Variables which are passed down to APP.run function as named arguments.
+    Note:
+        The server IP is not actually 0.0.0.0; if the dash app is not accessible via this address, use the same port
+        number but replace the IP address with your local network IP instead.
+    """
+
+    global APP, df, DEMO_PLOT_COLORS, DEMO_PLOT_LABELS
+
+    unique_publishers = extract_unique_companies(df["publisher"].apply(lambda x: split_companies(x)))
+    unique_developers = extract_unique_companies(df["developer"].iloc[0:10].apply(lambda x: split_companies(x)))
+    # unique_publishers = ["Valve"]
+    # unique_developers = ["Valve"]
+
+    APP.css.append_css({
+        'external_url': 'styles.css'
+    })
+    APP.layout = html.Div(
+        children=[
+            html.Nav(className="nav nav-pills", children=[
+                html.H6("SteamSavvy - Steam game data insights",
+                        style={"margin-left": "60px", "width": "20%", "display": "inline-block"}),
+                html.A('About', className="nav-item nav-link btn", href='/apps/App1',
+                       style={"margin-left": "300px"}),
+                html.A('Technical report', className="nav-item nav-link active btn", href='/apps/App2',
+                       style={"margin-left": "150px"})
+            ],
+                     style={"background-color": "rgb(23,29,37)", "color": "rgb(197,195,192)", 'width': '100%'}),
+            html.Div(className="row", children=[
+                html.Div(children=[
+                    dcc.Tabs(id="main_plots", value="tab1", children=[
+                        dcc.Tab(label="Genre performance", value="tab1",
+                                style=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT,
+                                children=[
+                                    html.Div(children=[
+                                        html.Div(
+                                            children=[
+                                                html.Div(style=SMALL_PANEL_DICT | {'width': '60%', 'height': '100%',
+                                                                                   'margin-right': '5%',
+                                                                                   'padding-left': '5%',
+                                                                                   'margin-bottom': '5%',
+                                                                                   'background-color': TAB_COLOR},
+                                                         children=[dcc.Graph(
+                                                             figure=go.Figure(data=[
+                                                                 {'x': ["Action", "Adventure", "RPG", "Puzzle",
+                                                                        "Strategy"],
+                                                                  'y': [0.7, 0.4, 0.8, 1.2, 1.3],
+                                                                  'type': 'bar'},
+                                                             ],
+                                                                 layout=dict(template="plotly_dark",
+                                                                             title="Relative genre perfomance",
+                                                                             plot_bgcolor=TAB_COLOR,
+                                                                             paper_bgcolor=TAB_COLOR)),
+
+                                                         ),
+                                                             html.P(f"""Genre performance measures the assessed exploitability of the 
+                                            specific game genre. The assesment is done by estimating the genre popularity,
+                                            and games developed in the next two years and showing the relative differences
+                                            between the genres.""")]),
+                                                html.Div(style=SMALL_PANEL_DICT | {'width': '35%', 'height': '100%',
+                                                                                   'background-color': TAB_COLOR},
+                                                         children=[
+                                                             html.Div(children=[
+                                                                 html.Div(style={'width': '100%', 'height': '50%'},
+                                                                          children=[dcc.Graph(
+                                                                              figure=go.Figure(data=[go.Pie(
+                                                                                  labels=["Action", "Adventure", "RPG",
+                                                                                          "Puzzle",
+                                                                                          "Strategy",
+                                                                                          "Other"],
+                                                                                  values=[0.8, 0.3, 0.4, 0.4, 0.3,
+                                                                                          0.55],
+                                                                                  sort=False)],
+                                                                                  layout=dict(template="plotly_dark",
+                                                                                              title="Genre popularity",
+                                                                                              plot_bgcolor=TAB_COLOR,
+                                                                                              paper_bgcolor=TAB_COLOR,
+                                                                                              margin=dict(l=20, r=20,
+                                                                                                          t=50, b=20))),
+                                                                              style={'width': '100%',
+                                                                                     'height': '100%'})]),
+                                                                 html.Div(style={'width': '100%', 'height': '50%'},
+                                                                          children=[dcc.Graph(
+                                                                              figure=go.Figure(data=[go.Pie(
+                                                                                  labels=["Action", "Adventure", "RPG",
+                                                                                          "Puzzle",
+                                                                                          "Strategy",
+                                                                                          "Other"],
+                                                                                  values=[0.7, 0.5, 0.1, 0.4, 0.3, 0.7],
+                                                                                  sort=False)],
+                                                                                  layout=dict(template="plotly_dark",
+                                                                                              title="Genre revenue share",
+                                                                                              plot_bgcolor=TAB_COLOR,
+                                                                                              paper_bgcolor=TAB_COLOR,
+                                                                                              margin=dict(l=20, r=20,
+                                                                                                          t=50, b=20))),
+                                                                              style={'width': '100%',
+                                                                                     'height': '100%'})]
+                                                                          )
+
+                                                             ], style={'height': '540px'}
+                                                             ),
+                                                         ]
+                                                         )
+                                            ]
+                                        ),
+
+                                        html.Div(children=[
+                                            html.H5("Genre prediction", style={'margin-bottom':'50px'}),
+                                            html.Div(children=[
+                                                html.Div(children=[
+                                                    html.P("Selected genre:", style={'margin-bottom':'10px'}),
+                                                    dcc.Dropdown(id="genre_dropdown", value="action",
+                                                                 options=[{"label": html.Span([genre],
+                                                                                              style={
+                                                                                                  'color': WHITE_STEAM}),
+                                                                           "value": genre} for genre in
+                                                                          ["action"]],
+                                                                 style={'color': WHITE_STEAM, 'display': 'inline-block',
+                                                                        'width': '50%'},
+                                                                 className='dash-dropdown',
+                                                                 ),
+
+                                                ],
+                                                    style={'width': '100%', 'margin-bottom':'50px'})
+                                            ]),
+                                            dcc.Graph(figure=go.Figure(layout=dict(template="plotly_dark",
+                                                                                   title="Genre prediction plot",
+                                                                                   plot_bgcolor=TAB_COLOR,
+                                                                                   paper_bgcolor=TAB_COLOR,
+                                                                                   margin=dict(l=20, r=20,
+                                                                                               t=50, b=20)))),
+                                            html.P("""This is an individual regression estimate for the genre that represents
+                                        the estimated amount of games to be produced in the next two years""")
+
+                                        ], style=SMALL_PANEL_DICT | {'height': '100%', 'margin-right': '5%',
+                                                                     'padding-left': '5%', 'margin-bottom': '5%',
+                                                                     'margin-top': '5%', 'background-color': TAB_COLOR})
+
+                                    ],
+                                        style={'height': '550px', 'width': '100%', 'margin': '0', 'overflow': 'auto'},
+                                        className="scrollable")
+                                ]),
+                        dcc.Tab(label="Game popularity", value="tab2",
+                                style=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT),
+                        dcc.Tab(label="Market performance", value="tab4",
+                                style=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT),
+                        dcc.Tab(label="Market prediction tool", value="tab5",
+                                style=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT),
+                    ],
+                             style=DEFAULT_TABS_DICT),
+
+                ], style=PANEL_DEFAULT_DICT | {'width': '900px',
+                                               'margin-right': '100px', 'padding-left': '50px',
+                                               'padding-right': '50px', 'padding-bottom': '50px',
+                                               'padding-top': '50px', 'margin-bottom': '50px'
+                                               }),
+                html.Div(children=[
+                    dcc.Tabs(id="company_information", value="tab3", children=[
+                        dcc.Tab(label="Developer infromation", value="tab3", children=[
+                            html.Div(children=[
+                                dcc.Dropdown(id=DEVELOPER_DROPDOWN, value="Valve",
+                                             options=[{"label": html.Span([developer], style={'color': WHITE_STEAM}),
+                                                       "value": developer} for developer in unique_developers],
+                                             style={'margin-top': '20px', 'color': WHITE_STEAM},
+                                             className='dash-dropdown',
+                                             ),
+                                html.Div(children=[
+                                    html.Div(
+                                        children=[
+                                            html.Div(
+                                                children=[html.P("Revenue", style=SMALL_PANEL_HEADER_DICT)],
+                                                style={'margin-bottom': '10%',
+                                                       'border-bottom': '2px solid ' + TAB_EDGE}),
+                                            html.Div(children=[
+                                                html.Div(children=[
+                                                    html.P("Game sale revenue estimates"),
+                                                    html.Div(children=[
+                                                        html.Div(children=[
+                                                            html.P(id=DEV_REVENUE_LABEL, children="$524 M",
+                                                                   style=LIST_DICT | {'padding-left': '5%'})
+                                                        ]),
+                                                        html.Div(children=[
+                                                            html.P(id=DEV_REV_PER_GAME_LABEL, children="$925 M",
+                                                                   style=LIST_DICT | {'padding-left': '5%'})
+                                                        ]),
+                                                    ],
+                                                        style={'margin-bottom': '20px'}),
+                                                    html.Div(children=[
+                                                        html.P("Top games by revenue:"),
+                                                        html.Small(id=DEV_TOP_GAMES, children="Half life 2"),
+                                                    ])
+                                                ]),
+                                            ], style={'padding-left': '5%', 'padding-right': '5%',
+                                                      'padding-bottom': '5%'})
+                                        ],
+                                        style=SMALL_TAB_PANEL_DICT | {'margin-right': '20px', 'margin-left': '0px'}
+                                    ),
+                                    html.Div(children=[
+                                        html.Div(
+                                            children=[
+                                                html.Div(
+                                                    children=[html.P("General information",
+                                                                     style=SMALL_PANEL_HEADER_DICT)],
+                                                    style={'margin-bottom': '30px',
+                                                           'border-bottom': '2px solid ' + TAB_EDGE}),
+                                                html.Div(children=[
+                                                    html.Div(children=[
+                                                        html.P(id=DEV_GAME_COUNT_LABEL, children="5",
+                                                               style=LIST_DICT),
+                                                    ],
+                                                        style={'margin-bottom': '10px'}
+                                                    ),
+                                                    html.Div(children=[
+                                                        html.P(id=DEV_CCU_LABEL, children="",
+                                                               style=LIST_DICT),
+                                                    ],
+                                                        style={'margin-bottom': '10px'}
+                                                    ),
+                                                    html.Div(children=[
+                                                        html.P("Popular game genres:"),
+                                                        html.Small(id=DEV_TOP_GENRES_LABEL,
+                                                                   children="FPS, Action, Puzzle"),
+                                                    ],
+                                                        style={'margin-bottom': '10px'}
+                                                    ),
+                                                    html.Div(children=[
+                                                        html.P(id=DEV_AVERAGE_RATING_LABEL,
+                                                               children="",
+                                                               style=LIST_DICT)
+                                                    ])
+                                                ])
+                                            ])
+
+                                    ], style=SMALL_TAB_PANEL_DICT | {'width': '45%', 'height': '100%',
+                                                                     'margin-right': '0px', 'margin-left': '20px'}
+                                    )
+                                ], style={'height': '100%'})
+                            ], style={'margin-left': '20px', 'margin-right': '0px'}
+                            )
+                        ], style=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT),
+                        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=TAB_NORMAL_DICT, selected_style=TAB_HIGHLIGHT_DICT)
+
+                    ],
+                             style=DEFAULT_TABS_DICT),
+                ],
+                    style=PANEL_DEFAULT_DICT | {'width':'700px',
+                                                'padding-left': '50px',
+                                                'padding-right': '50px', 'padding-bottom': '50px',
+                                                'padding-top': '50px', 'margin-bottom': '50px'
+                                                })
+            ],
+                     style={'width': '100%', "padding-top": "30px", 'padding-left': "50px"}),
+        ],
+        style={"font-family": "Tahoma"}
+    )
+    APP.run(host=host, **kwargs)
+    print("The server has closed!")
+
+
+if __name__ == "__main__":
+    initialize_data()
+    initialize_dash(debug=True)
+
+print(csv_path)
diff --git a/dash_plot_generation/utils.py b/dash_plot_generation/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..6d380af871fae79d7b108a061f93ee172bcd7264
--- /dev/null
+++ b/dash_plot_generation/utils.py
@@ -0,0 +1,122 @@
+import math
+import re
+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
+    continuations happen. In such a case, the string split does not happen that said comma.
+    :param arr: Array containing the developers/publishers for a single game
+    :param illegal_continuations: A list of illegal continuations. Must be uppercase.
+    :return: Returns the given split input string as a list.
+    :note: If the arr is numpy.NaN, this value is returned instead of a list.
+    """
+    if illegal_continuations is None:
+        illegal_continuations = DEFAULT_ILLEGAL_CONTINUATIONS
+    if pandas.isna(arr):
+        return arr
+
+    results_list = []
+    start_index = 0
+    split_char = ", "
+
+    for index in range(len(arr)):
+        if index < len(arr) - 1:
+            txt = arr[index:index + 2]
+            if txt == split_char:
+                found_illegal = False
+                min_continuation = min([len(continuation) for continuation in illegal_continuations])
+                max_continuation = max([len(continuation) for continuation in illegal_continuations])
+                next_chars = arr[index + min_continuation:index + min_continuation + max_continuation]
+                for i in range(index + min_continuation, index + len(next_chars) + 2):
+                    comp_txt = arr[index + 2:i + 2].upper()
+                    if comp_txt in illegal_continuations:
+                        found_illegal = True
+                        break
+                if not found_illegal:
+                    results_list.append(arr[start_index:index].strip())
+                    start_index = index + 1
+        elif index == len(arr) - 1:
+            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
+
+
+def replace_owner_number_with_symbol(df):
+    def owner_strip(user_range: str):
+        if isinstance(user_range, str):
+            user_range = user_range.replace(",000,000", " M")
+            user_range = user_range.replace(",000", " k")
+        return user_range
+
+    df["owners"] = df["owners"].apply(lambda name: owner_strip((name)))
+    return df
+
+
+def replace_owner_number_with_symbol_real_numeric(value):
+    value_str = str(value)
+    value_str = re.sub("0" * 9 + "$", " billion", value_str)
+    value_str = re.sub("0" * 6 + "$", " million", value_str)
+    # value_str = re.sub("0" * 3 + "$", " thousand", value_str)
+    return value_str
+
+
+def update_dots(n):
+    num_dots = (n % 10) + 1
+    dots = "." * num_dots
+    return [dots]
+
+
+def convert_to_numeric_str(value, **kwargs):
+    return replace_owner_number_with_symbol_real_numeric(round_to_three_largest_digits(value, **kwargs))
+
+
+def label_with_rev(label, rev, space, char=".", currency_symbol=""):
+    processed_rev = convert_to_numeric_str(int(rev))
+    return_val = label_with_text(label, "".join([currency_symbol, processed_rev]), space, char)
+    return return_val
+
+
+def label_with_text(first_str, second_str, space, char="."):
+    white_space_filler = char * (space - (len(first_str) + len(second_str)) - 2)
+    return_val = " ".join([first_str, white_space_filler, second_str])
+    return return_val
+
+
+def round_to_three_largest_digits(number, accuracy=2):
+    round_val = -(len(str(round(number))) - accuracy)
+    return_val = round(round(number), min(round_val, 0))
+    return return_val