Files
football-competitiveness/ui.R
T
2026-08-21 17:59:54 +01:00

698 lines
28 KiB
R

ui <- fluidPage(
title="Football league competitiveness and countries European performance",lang="en",
theme="css.css",
useShinyjs(),
tags$head(
tags$script(HTML("
Shiny.addCustomMessageHandler('bindModalHidden', function(message) {
$('#shiny-modal').off('hidden.bs.modal.modalListener');
$('#shiny-modal').on('hidden.bs.modal.modalListener', function () {
Shiny.setInputValue('modal_closed_nonce', Math.random(), {priority: 'event'});
});
});
"),
"function sendWidth() {
Shiny.setInputValue('screen_width', window.innerWidth);
}
$(document).on('shiny:connected', sendWidth);
$(window).on('resize', sendWidth);"),
tags$style(
# the create_scrolly_side will return a list, the first object is the CSS classes that create the stick position scrolling behaviour.
# the second object is the javascript that links the scrolling to change CSS classes and update shiny inputs (loaded at end of page)
HTML(as.character(create_scrolly_side("time_plot")[1])),
HTML(as.character(create_scrolly_side("league_averages_plot")[1])),
HTML(as.character(create_scrolly_side("basic_profiling_plot")[1])),
HTML(as.character(create_scrolly_side("regression_current_year_plot")[1])),
HTML(as.character(create_scrolly_side("regression_next_year_plot")[1])),
HTML(as.character(create_scrolly_side("regression_competition_plot")[1])),
HTML(as.character(create_scrolly_side("clustering_plot")[1]))
),
HTML(
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">
<meta property=\"og:title\" content=\"Football league competitiveness and countries European performance\">
<meta property=\"og:description\" content=\"Football league competitiveness and countries European performance\">"
)
),
#### header ####
div(class = "header",
tags$div(
style = "display: flex; flex-direction: column;",
tags$a(`aria-label` = "Jump back to contents", href = "#contents", class = "jump-link", "Jump back to contents")
)
),
#### title and contents ####
div(id = "contents", class = "toc",
tags$h1(title),
tags$a(href = "https://youtu.be/_mnsaDJzpso?si=3EnfpdRqXp4afBiI", tags$strong("Click here for a link to a static version of the report")),
p(style = 'font-weight: bold; text-align: right; font-size: 1.2em;', "Scroll to begin ▼"),
tags$h3("Table of Contents"),
tags$ul(
tags$li(tags$a(href = "#motivation", tags$strong("Motivation"))),
tags$li(tags$a(href = "#exploratory_analysis", tags$strong("Exploratory analysis"))),
tags$ul(
tags$li(tags$a(href = "#time_plot", "Europe's top 6 leagues European performance since 1999-2000")),
tags$li(tags$a(href = "#variable_selection", "Variables used in analysis of leagues competitiveness")),
tags$li(tags$a(href = "#league_averages_plot", "Characteristics of leagues since 1999-2000")),
tags$li(tags$a(href = "#basic_profiling", "Characteristics of leagues grouped by performance"))
),
tags$li(tags$a(href = "#modelling", tags$strong("Modelling"))),
tags$ul(
tags$li(tags$a(href = "#variable_creation", tags$strong("Variable creation"))),
tags$li(tags$a(href = "#regression", tags$strong("Regression analysis"))),
tags$ul(
tags$li(tags$a(href = "#regression_current_year", "On league characteristics and same season's European performance")),
tags$li(tags$a(href = "#regression_next_year", "On league characteristics and next season's European performance")),
tags$li(tags$a(href = "#regression_competition", "On league characteristics and same season's European performance by competition"))
),
tags$li(tags$a(href = "#clustering", tags$strong("Clustering to group similar seasons together")))
),
tags$li(tags$a(href = "#conclusion", tags$strong("Conclusion")))
),
div(
style = "display: flex; justify-content: space-between; align-items: center; margin-top: 20px;",
p(style = "margin: 0;", paste0(name)),
p(style = "margin: 0;", date)
)
),
br(),
br(),
#### motivation ####
tags$header(
id = "motivation",
class = "colourheader",
tags$div(
class = "paddeddiv",
style = "position: relative;",
tags$h2(paste0("Motivation"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px; white-space: normal;", HTML(motivation_one)),
p(style = "margin-top: 5px;", paste0(motivation_two)),
p(style = "margin-top: 5px;", paste0(motivation_three))
)
),
br(),
br(),
div(
class = "bigfixedimage",
style = paste0("background-image: url('psg.jpg');min-height: 100vh;")
),
br(),
br(),
#### Exploratory analysis ####
tags$header(id = "exploratory_analysis", class="colourheader",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Exploratory analysis"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px;", paste0(exploratory_analysis_one))
)
),
br(),
br(),
#### European performance over time ####
tags$div(ID = "time_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "European performance over time, from 1999-2000 to 2025-26"),
plotlyOutput("european_performance_over_time_plot", height = "100%")
),
tags$article(
lapply(seq_along(league_names), function(i) {
div(
class = "time_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(
paste0(
" ",
league_names[i],
" teams European performance "
)
),
br(),
HTML(performance_text[[i]])
)
)
})
)
)
),
br(),
br(),
#### Variable selection ####
tags$header(id = "variable_selection", class="colourheader3",
tags$div(
class = "paddeddiv",
style = "position: relative;",
tags$h3(
"Variables used in analysis of leagues competitiveness",
style = "font-weight: bold; text-align: center;"
),
lapply(
c(
variables_used_in_analysis_of_leagues_competitiveness_one,
variables_used_in_analysis_of_leagues_competitiveness_two,
variables_used_in_analysis_of_leagues_competitiveness_three,
variables_used_in_analysis_of_leagues_competitiveness_four,
variables_used_in_analysis_of_leagues_competitiveness_five,
variables_used_in_analysis_of_leagues_competitiveness_six,
variables_used_in_analysis_of_leagues_competitiveness_seven,
variables_used_in_analysis_of_leagues_competitiveness_eight,
variables_used_in_analysis_of_leagues_competitiveness_nine,
variables_used_in_analysis_of_leagues_competitiveness_ten,
variables_used_in_analysis_of_leagues_competitiveness_eleven,
variables_used_in_analysis_of_leagues_competitiveness_twelve,
variables_used_in_analysis_of_leagues_competitiveness_thirteen,
variables_used_in_analysis_of_leagues_competitiveness_fourteen,
variables_used_in_analysis_of_leagues_competitiveness_fifteen,
variables_used_in_analysis_of_leagues_competitiveness_sixteen
),
function(x) p(style = "margin-top: 5px;", HTML(x))
)
)
),
br(),
br(),
#### League average characteristics ####
tags$div(ID = "league_averages_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "Average characteristics of leagues, from 1999-2000 to 2025-26"),
plotlyOutput("league_characteristics_plot", height = "100%")
),
tags$article(
lapply(seq_along(league_names), function(i) {
div(
class = "league_averages_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(paste0(" ", league_names[i], " league characteristics ")),
br(),
HTML(characteristics[[i]])
)
)
})
)
)
),
br(),
br(),
tags$header(class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
p(style="margin-top: 5px;",HTML(characteristics_of_leagues_extra_one)),
p(style="margin-top: 5px;",HTML(characteristics_of_leagues_extra_two))
)
),
br(),
br(),
#### Basic profiles characteristics ####
tags$header(id = "basic_profiling", class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
p(paste0(characteristics_of_leagues_grouped_by_performance))
)
),
br(),
br(),
tags$div(ID = "basic_profiling_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "Average characteristics of leagues, grouped by performance"),
plotlyOutput("basic_profiles_characteristic_plot", height = "100%")
),
tags$article(
lapply(seq_along(basic_profiling_titles), function(i) {
div(
class = "basic_profiling_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(
paste0(
" ",
basic_profiling_titles[i],
" "
)
),
br(),
HTML(basic_profiling_text[[i]])
)
)
})
)
)
),
br(),
br(),
div(
class = "bigfixedimage",
style = paste0("background-image: url('aston-villa.jpg');min-height: 100vh;")
),
br(),
br(),
#### Modelling ####
tags$header(id = "modelling", class="colourheader",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Modelling"), style = "font-weight: bold; text-align: center;"),
p(style="margin-top: 5px;",paste0(modelling_one)),
p(style="margin-top: 5px;",paste0(modelling_two))
)
),
br(),
br(),
#### Variable creation ####
tags$header(id = "variable_creation", class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Variable creation"), style = "font-weight: bold; text-align: center;"),
tags$h3(paste0(competitiveness_indices), style = "font-weight: bold;"),
lapply(
c(
competitiveness_indices_one,
competitiveness_indices_two,
competitiveness_indices_three,
competitiveness_indices_four,
competitiveness_indices_five,
competitiveness_indices_six,
competitiveness_indices_seven
),
function(x) p(style = "margin-top: 5px;", HTML(x))
),
br(),
tags$h3(paste0(principal_component_analysis_pca), style = "font-weight: bold;"),
lapply(
c(
principal_component_analysis_pca_one,
the_five_principal_components_can_be_broadly_interpreted_as,
the_five_principal_components_can_be_broadly_interpreted_as_one,
the_five_principal_components_can_be_broadly_interpreted_as_two,
the_five_principal_components_can_be_broadly_interpreted_as_three,
the_five_principal_components_can_be_broadly_interpreted_as_four,
the_five_principal_components_can_be_broadly_interpreted_as_five,
the_five_principal_components_can_be_broadly_interpreted_as_six
),
function(x) p(style = "margin-top: 5px;", HTML(x))
)
)
),
br(),
br(),
#### Regression ####
tags$header(id = "regression", class="colourheader2",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Regression analysis"), style = "font-weight: bold; text-align: center;"),
p(style="margin-top: 5px;",HTML(regression_analysis_one)),
p(style="margin-top: 5px;",HTML(regression_analysis_two)),
tags$button(
class = "btn btn-light mt-3 detail-toggle-btn-black",
type = "button",
"data-toggle-target" = "#regression-moreContent",
"data-show-text" = "Click to view more detailed description of methodology ▼",
"data-hide-text" = "Show less ▲",
"Click to view more detailed description of methodology ▼"
),
tags$div(
id = "regression-moreContent",
class = "collapse mt-3",
p(style = "margin-top: 5px;", paste0(hidden_click_to_view_more_detailed_description_of_methodology_one)),
p(style = "margin-top: 5px;", paste0(hidden_click_to_view_more_detailed_description_of_methodology_two)),
p(style = "margin-top: 5px;", paste0(hidden_click_to_view_more_detailed_description_of_methodology_three))
),
)
),
br(),
br(),
#### Regression in one season ####
tags$header(id = "regression_current_year", class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Regression analysis on league characteristics and same season's European performance"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px;", HTML(on_league_characteristics_and_same_season_s_european_performance_one))
)
),
br(),
br(),
conditionalPanel(
condition = "input.screen_width >= 768",
tags$div(
id = "regression_current_year_plot",
div(
class = "scrolly",
tags$figure(
class = "sticky",
style = "order: 0; display: flex; flex-direction: column;",
tags$h4(
style = "text-align: center;",
"Coefficient estimates for regression"
),
plotlyOutput(
"regression_coefficients_current_plot",
height = "100%"
)
),
tags$article(
lapply(seq_along(regression_current_year_titles), function(i) {
div(
class = "regression_current_year_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(paste0(" ", regression_current_year_titles[i], " ")),
br(),
HTML(regression_current_year_text[[i]])
)
)
})
)
)
)
),
br(),
br(),
#### Regression in next season ####
tags$header(id = "regression_next_year", class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Regression analysis on league characteristics and next season's European performance"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px;", HTML(on_league_characteristics_and_next_season_s_european_performance_one))
)
),
br(),
br(),
conditionalPanel(
condition = "input.screen_width >= 768",
tags$div(ID = "regression_next_year_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "Coefficient estimates for regression"),
plotlyOutput("regression_coefficients_next_plot", height = "100%")
),
tags$article(
lapply(seq_along(regression_next_year_titles), function(i) {
div(
class = "regression_next_year_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(
paste0(
" ",
regression_next_year_titles[i],
" "
)
),
br(),
HTML(regression_next_year_text[[i]])
)
)
})
)
)
)
),
br(),
br(),
#### Regression by competition ####
tags$header(id = "regression_competition", class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Regression analysis on league characteristics and same season's European performance by competition"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px;", HTML(on_league_characteristics_and_same_season_s_european_performance_by_co_one))
)
),
br(),
br(),
conditionalPanel(
condition = "input.screen_width >= 768",
tags$div(ID = "regression_competition_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "Coefficient estimates for regression"),
plotlyOutput("regression_coefficients_competition_plot", height = "100%")
),
tags$article(
lapply(seq_along(regression_competition_titles), function(i) {
div(
class = "regression_competition_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(
paste0(
" ",
regression_competition_titles[i],
" "
)
),
br(),
HTML(regression_competition_text[[i]])
)
)
})
)
)
)
),
br(),
br(),
#### Clustering ####
tags$header(id = "clustering", class="colourheader2",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Clustering to group similar seasons together"), style = "font-weight: bold; text-align: center;"),
p(style = "margin-top: 5px;", HTML(clustering_to_group_similar_seasons_together_one)),
p(style = "margin-top: 5px;", HTML(clustering_to_group_similar_seasons_together_two)),
p(style = "margin-top: 5px;", HTML(clustering_to_group_similar_seasons_together_three))
)
),
br(),
br(),
tags$div(ID = "clustering_plot",
div(class="scrolly",
tags$figure(class="sticky",style=("order: 0; display: flex; flex-direction: column;"),
tags$h4(style="text-align: center;", "Average characteristics of clusters"),
plotlyOutput("clustering_characteristics_plot", height = "100%")
),
tags$article(
lapply(seq_along(clustering_titles), function(i) {
div(
class = "clustering_plot text-article",
`data-width` = "1",
`data-index` = i - 1,
p(
tags$u(
paste0(
" ",
clustering_titles[i],
" "
)
),
br(),
HTML(clustering_text[[i]])
)
)
})
)
)
),
br(),
br(),
tags$header(class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
p(style = "margin-top: 5px;", HTML(radar_plots_for_clusters_overall))
)
),
br(),
br(),
div(
class = "bigfixedimage",
style = paste0("background-image: url('cpfc.jpg');min-height: 100vh;")
),
#### Conclusion ####
tags$header(id = "conclusion", class="colourheader",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Conclusion"), style = "font-weight: bold; text-align: center;"),
lapply(
c(
overall_conclusion_one,
overall_conclusion_two,
overall_conclusion_three,
overall_conclusion_four,
overall_conclusion_five
),
function(x) {
p(
style = "margin-top: 5px;",
HTML(x)
)
}
)
)
),
br(),
br(),
#### Limitations ####
tags$header(class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Limitations"), style = "font-weight: bold; text-align: center;"),
lapply(
c(
limitations_one,
limitations_two,
limitations_three,
limitations_four,
limitations_five,
limitations_six,
limitations_seven
),
function(x) {
p(
style = "margin-top: 5px;",
HTML(x)
)
}
)
)
),
br(),
br(),
#### Footnote ####
tags$header(class="colourheader3",
tags$div(class="paddeddiv",style="position: relative;",
tags$h2(paste0("Data collection, sources and analysis process"), style = "font-weight: bold; text-align: center;"),
lapply(
c(
data_sources_and_how_data_was_collected_and_analysis_was_done_one,
data_sources_and_how_data_was_collected_and_analysis_was_done_eleven,
data_sources_and_how_data_was_collected_and_analysis_was_done_two,
data_sources_and_how_data_was_collected_and_analysis_was_done_three,
data_sources_and_how_data_was_collected_and_analysis_was_done_four,
data_sources_and_how_data_was_collected_and_analysis_was_done_five,
data_sources_and_how_data_was_collected_and_analysis_was_done_six,
data_sources_and_how_data_was_collected_and_analysis_was_done_seven,
data_sources_and_how_data_was_collected_and_analysis_was_done_eight,
data_sources_and_how_data_was_collected_and_analysis_was_done_nine,
data_sources_and_how_data_was_collected_and_analysis_was_done_ten
),
function(x) {
p(
style = "margin-top: 5px;",
HTML(x)
)
}
)
)
),
#### expandable/collapsable text function ####
tags$script(HTML("
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('[data-toggle-target]').forEach(function(button) {
const targetSelector = button.getAttribute('data-toggle-target');
const target = document.querySelector(targetSelector);
if (!target) return;
const showText = (button.getAttribute('data-show-text') || button.textContent || '').trim();
const hideText = (button.getAttribute('data-hide-text') || 'Show less ▲').trim();
const isVisible = function(el) {
return window.getComputedStyle(el).display !== 'none' && !el.hidden;
};
button.textContent = isVisible(target) ? hideText : showText;
button.addEventListener('click', function() {
if (isVisible(target)) {
target.classList.remove('show');
target.style.display = 'none';
button.textContent = showText;
} else {
target.classList.add('show');
target.style.display = 'block';
button.textContent = hideText;
}
});
});
});
")),
#### scrolly javascript ####
HTML("<script src='https://unpkg.com/d3@5.4.0/dist/d3.min.js'></script>"),
HTML("<script src='https://unpkg.com/enter-view@1.0.0/enter-view.min.js'></script>"),
HTML("<script src='https://unpkg.com/stickyfilljs@2.0.5/dist/stickyfill.js'></script>"),
HTML(as.character(create_scrolly_side("time_plot")[2])),
HTML(as.character(create_scrolly_side("league_averages_plot")[2])),
HTML(as.character(create_scrolly_side("basic_profiling_plot")[2])),
HTML(as.character(create_scrolly_side("regression_current_year_plot")[2])),
HTML(as.character(create_scrolly_side("regression_next_year_plot")[2])),
HTML(as.character(create_scrolly_side("regression_competition_plot")[2])),
HTML(as.character(create_scrolly_side("clustering_plot")[2]))
)