document.body.onload=loadStatistics() document.getElementById('statistics_nav').classList.add('active') const important_player_name_colors = {'Yarne':'black', 'Lore':'green', 'Lucas':'brown','Louize':'blue','Ruben':'purple', 'Ina':'orange', 'Matthias':'yellow','Kelly':'darkorange','Keanu':'darkblue'} function create_statistic_card(col_number = null){ function create_statistic_card_col(){ const col = document.createElement('col') if (col_number == null){ col.classList.add('col-12') col.classList.add('col-md-6') }else{ col.classList.add('col-' + col_number * 2) col.classList.add('col-md-'+col_number) } const card = document.createElement('div') card.classList.add('card') card.classList.add('h-100') col.appendChild(card) return col } let statistic_row = document.getElementById('statistic_row') const statistic_card_col = create_statistic_card_col() const statistic_card = statistic_card_col.firstChild statistic_row.appendChild(statistic_card_col) return statistic_card } async function create_games_over_time_chart(){ let games_over_time_statistic = await makeRequest(api_url + '/statistics/amount_of_games_over_time?day_step=30') let games_over_time_statistic_no_expanions = await makeRequest(api_url + '/statistics/amount_of_games_over_time?day_step=30&filter_expansions_out=true') let games_over_time_statistic_only_expanions = await makeRequest(api_url + '/statistics/amount_of_games_over_time?day_step=30&only_expansions=true') const card_to_fill = create_statistic_card(12) const chart_canvas_container = document.createElement('div') chart_canvas_container.classList.add('card-body') chart_canvas_container.classList.add('card-img-top') const chart_canvas = document.createElement('canvas') chart_canvas.classList.add('chart_visual') chart_canvas_container.appendChild(chart_canvas) new Chart(chart_canvas, { type: 'bar', data: { labels: Object.keys(games_over_time_statistic.result), datasets: [{ label: games_over_time_statistic.name, data: Object.values(games_over_time_statistic.result), borderWidth: 1, type: 'line' }, { label: "Base games", data: Object.values(games_over_time_statistic_no_expanions.result), borderWidth: 1 }, { label: "Expansions", data: Object.values(games_over_time_statistic_only_expanions.result), borderWidth: 1 } ] }, options: { scales: { y: { beginAtZero: true } } } }); const card_footer = document.createElement('div') card_footer.classList.add('card-header') card_footer.classList.add('text-muted') card_footer.innerHTML = games_over_time_statistic.name card_to_fill.appendChild(card_footer) card_to_fill.appendChild(chart_canvas_container) } async function create_line_chart(statistic_data, name=''){ if (name == ""){ statistic_name = statistic_data.name }else{ statistic_name = name } const card_to_fill = create_statistic_card() const chart_canvas_container = document.createElement('div') chart_canvas_container.classList.add('card-body') chart_canvas_container.classList.add('card-img-top') const chart_canvas = document.createElement('canvas') chart_canvas.classList.add('chart_visual') chart_canvas_container.appendChild(chart_canvas) const highest_bar_value = Math.max(...Object.values(statistic_data.result)) let grid_offset = 0 if (highest_bar_value > 10000){ grid_offset = 25000 }else if(highest_bar_value > 1000){ grid_offset = 2500 }else if(highest_bar_value > 100){ grid_offset = 250 }else if(highest_bar_value > 10){ grid_offset = 25 }else if(highest_bar_value > 2){ grid_offset = 2.5 }else{ grid_offset = 1.25 } new Chart(chart_canvas, { type: 'line', data: { labels: Object.keys(statistic_data.result), datasets: [{ label: statistic_data.name, data: Object.values(statistic_data.result), borderWidth: 1 } ] }, options: { scales: { y: { beginAtZero: true, max: Math.ceil((highest_bar_value) / grid_offset) * grid_offset } } } }); const card_footer = document.createElement('div') card_footer.classList.add('card-header') card_footer.classList.add('text-muted') card_footer.innerHTML = statistic_name card_to_fill.appendChild(card_footer) card_to_fill.appendChild(chart_canvas_container) } async function create_multi_line_chart(statistic_data, name=''){ if (name == ""){ statistic_name = statistic_data.name }else{ statistic_name = name } const card_to_fill = create_statistic_card(12) const chart_canvas_container = document.createElement('div') chart_canvas_container.classList.add('card-body') chart_canvas_container.classList.add('card-img-top') const chart_canvas = document.createElement('canvas') chart_canvas.classList.add('chart_visual') chart_canvas_container.appendChild(chart_canvas) let own_datasets = [] let all_results = [] let all_dates = [] for (key in statistic_data){ for (date in statistic_data[key].result){ if (statistic_data[key].result[date] == 0){ statistic_data[key].result[date] = null } } if (!Object.keys(important_player_name_colors).includes(key)){ dataset = { label: key, data: Object.values(statistic_data[key].result) } }else{ dataset = { label: key, data: Object.values(statistic_data[key].result), borderColor: important_player_name_colors[key] } } own_datasets.push(dataset) for (result_value in Object.values(statistic_data[key].result)){ all_results.push(result_value) } for (date in statistic_data[key].result){ if (!all_dates.includes(date)){ all_dates.push(date) } } } new Chart(chart_canvas, { type: 'line', data: { labels: all_dates, datasets: own_datasets }, options: { scales: { y: { beginAtZero: true, offset: true }, x: { offset: true } } } }); const card_footer = document.createElement('div') card_footer.classList.add('card-header') card_footer.classList.add('text-muted') card_footer.innerHTML = statistic_name card_to_fill.appendChild(card_footer) card_to_fill.appendChild(chart_canvas_container) } async function create_bar_chart(statistic_data, name=''){ if (name == ""){ statistic_name = statistic_data.name }else{ statistic_name = name } const card_to_fill = create_statistic_card() const chart_canvas_container = document.createElement('div') chart_canvas_container.classList.add('card-body') chart_canvas_container.classList.add('card-img-top') const chart_canvas = document.createElement('canvas') chart_canvas.classList.add('chart_visual') chart_canvas_container.appendChild(chart_canvas) const highest_bar_value = Math.max(...Object.values(statistic_data.result)) let grid_offset = 0 if (highest_bar_value > 10000){ grid_offset = 25000 }else if(highest_bar_value > 1000){ grid_offset = 2500 }else if(highest_bar_value > 100){ grid_offset = 250 }else{ grid_offset = 25 } new Chart(chart_canvas, { plugins: [ChartDataLabels], type: 'bar', data: { labels: Object.keys(statistic_data.result), datasets: [{ label: statistic_data.name, data: Object.values(statistic_data.result), borderWidth: 1 } ] }, options: { scales: { y: { beginAtZero: true, max: Math.ceil((highest_bar_value) / grid_offset) * grid_offset } }, plugins: { datalabels: { anchor: 'end', align: 'end' } } } }); const card_footer = document.createElement('div') card_footer.classList.add('card-header') card_footer.classList.add('text-muted') card_footer.innerHTML = statistic_name card_to_fill.appendChild(card_footer) card_to_fill.appendChild(chart_canvas_container) } async function create_multiple_boardgame_chart(statistic_data, name = '', include_footer = false, footer_preamble = ''){ function create_boardgame_image_grid_row(boardgames, include_footer, footer_data, footer_preamble){ const row_container = document.createElement('div') row_container.classList.add('container') const row = document.createElement('div') row.classList.add('row') row.classList.add('row-cols-1') row.classList.add('row-cols-md-3') row.classList.add('g-4') for (let boardgame_index in boardgames){ let current_boardgame = boardgames[boardgame_index] const column = document.createElement('div') column.classList.add('col') const boardgame_card = document.createElement('div') boardgame_card.classList.add('card') boardgame_card.classList.add('h-100') const boardgame_imaged_linked = document.createElement('a') boardgame_imaged_linked.setAttribute('href', '/boardgame?id=' + current_boardgame.id) const boardgame_image = document.createElement('img') boardgame_image.src = current_boardgame.thumbnail_url boardgame_image.classList.add('card-img-top') boardgame_image.classList.add('boardgame_statistic_card_image') boardgame_imaged_linked.appendChild(boardgame_image) const boardgame_card_body = document.createElement('div') boardgame_card_body.classList.add('card-body') const boardgame_title = document.createElement('h6') boardgame_title.innerHTML = current_boardgame.name boardgame_title.classList.add('card-title') boardgame_card_body.appendChild(boardgame_title) if (include_footer){ const boardgame_footer = document.createElement('p') boardgame_footer.innerHTML = footer_preamble + footer_data[current_boardgame.id] boardgame_footer.classList.add('card-text') boardgame_card_body.appendChild(boardgame_footer) } boardgame_card.append(boardgame_imaged_linked) boardgame_card.append(boardgame_card_body) column.appendChild(boardgame_card) row.appendChild(column) } return row } if (name == ""){ statistic_name = statistic_data.name }else{ statistic_name = name } const card_to_fill = create_statistic_card() const card_header = document.createElement('div') card_header.classList.add('card-header') const card_footer_text = document.createElement('div') card_footer_text.classList.add('text-muted') card_footer_text.innerHTML = statistic_name card_header.appendChild(card_footer_text) card_to_fill.appendChild(card_header) const boardgame_image_container = document.createElement('div') boardgame_image_container.classList.add('card-body') boardgame_image_container.classList.add('chart_visual') boardgame_image_container.classList.add('container-fluid') boardgame_image_container.classList.add('overflow-auto') const boardgames_to_grid = statistic_data.games const footer_data = statistic_data.result // if (footer_attribute != ''){ // for (boardgame_index in boardgames_to_grid){ // let footer_string = footer_attribute_to_value(boardgames_to_grid[boardgame_index], footer_attribute) // if (footer_preamble != ''){ // footer_string = footer_preamble + footer_string // } // footer_data.push(footer_string) // } // } const row = create_boardgame_image_grid_row(boardgames_to_grid, include_footer, footer_data, footer_preamble) boardgame_image_container.appendChild(row) card_to_fill.appendChild(boardgame_image_container) } async function create_basic_statistic_chart(statistic_data, name='', preamble=''){ if (name == ""){ statistic_name = statistic_data.name }else{ statistic_name = name } const card_to_fill = create_statistic_card(3) const card_header = document.createElement('div') card_header.classList.add('card-header') card_header.classList.add('text-muted') card_header.innerHTML = statistic_name card_to_fill.appendChild(card_header) const card_body = document.createElement('div') card_body.classList.add('card-body') const card_title = document.createElement('h5') card_title.classList.add('card-title') card_title.innerHTML = preamble + statistic_data.result card_body.appendChild(card_title) card_to_fill.appendChild(card_header) card_to_fill.appendChild(card_body) } async function loadStatistics(){ const amount_of_games_statistic_data = await makeRequest(api_url+'/statistics/amount_of_games') create_basic_statistic_chart(amount_of_games_statistic_data, 'Spellen in bezit') const total_collection_cost_statistic_data = await makeRequest(api_url+'/statistics/total_collection_cost') total_collection_cost_statistic_data.result = total_collection_cost_statistic_data.result.toFixed(2) create_basic_statistic_chart(total_collection_cost_statistic_data, 'Totale kost van spellen in bezit', '\u20AC ') const h_index_statistic_data = await makeRequest(api_url+'/statistics/h_index') create_basic_statistic_chart(h_index_statistic_data, 'H-index') //Seperate because of multiple data await create_games_over_time_chart() const winrate_over_time_statistic_data = await makeRequest(api_url + '/statistics/winrate_over_time?day_step=30') for (let player_name in winrate_over_time_statistic_data){ if (!Object.keys(important_player_name_colors).includes(player_name)){ delete winrate_over_time_statistic_data[player_name] }else{ for (date_key in winrate_over_time_statistic_data[player_name].result) winrate_over_time_statistic_data[player_name].result[date_key] *= 100 } } create_multi_line_chart(winrate_over_time_statistic_data, 'Winrate van spelers over tijd') const games_played_per_year_statistic_data = await makeRequest(api_url + '/statistics/games_played_per_year?filter_expansions_out=true') create_bar_chart(games_played_per_year_statistic_data, 'Spellen gespeeld per jaar') const winrate_statistic_data = await makeRequest(api_url + '/statistics/winrate') for (let player_name in winrate_statistic_data.result){ if (!Object.keys(important_player_name_colors).includes(player_name)){ delete winrate_statistic_data.result[player_name] }else{ winrate_statistic_data.result[player_name] *= 100 winrate_statistic_data.result[player_name] = winrate_statistic_data.result[player_name].toFixed(2) } } create_bar_chart(winrate_statistic_data, 'Winrate van spelers') const most_expensive_games_statistic_data = await makeRequest(api_url+'/statistics/most_expensive_games?top_amount=6') create_multiple_boardgame_chart(most_expensive_games_statistic_data, 'Duurste spellen', true, '\u20AC ') const cheapest_per_play_games_statistic_data = await makeRequest(api_url+'/statistics/cheapest_per_play?top_amount=6') for (let boardgame_id_result in cheapest_per_play_games_statistic_data.result){ cheapest_per_play_games_statistic_data.result[boardgame_id_result] = cheapest_per_play_games_statistic_data.result[boardgame_id_result].toFixed(2) } create_multiple_boardgame_chart(cheapest_per_play_games_statistic_data, 'Goedkoopste per sessie', true, '\u20AC ') const shelf_of_shame_statistic_data = await makeRequest(api_url + '/statistics/shelf_of_shame') create_multiple_boardgame_chart(shelf_of_shame_statistic_data, 'Shelf of Shame', false) const most_bought_from_designer_statistic_data = await makeRequest(api_url + '/statistics/most_bought_designer?filter_expansions_out=true') create_multiple_boardgame_chart(most_bought_from_designer_statistic_data, 'Designer waarvan we het meeste hebben gekocht', true) const most_bought_from_artist_statistic_data = await makeRequest(api_url + '/statistics/most_bought_artist?filter_expansions_out=true') create_multiple_boardgame_chart(most_bought_from_artist_statistic_data, 'Artiest waarvan we het meeste hebben gekocht', true) }