Compare commits

..

No commits in common. "master" and "dev" have entirely different histories.
master ... dev

63 changed files with 40057 additions and 321321 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
.RData

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Aplikacja `CoachStats`
# Analiza piłkarska z aplikacją `CoachStats`
## Wstęp
@ -9,18 +9,21 @@ CoachStats to innowacyjne narzędzie służące do analizowania statystyk Expect
- **Analiza XG:** Analiza XG dla danej sytuacji meczowej.
- **Personalizowana makieta:** Możliwość tworzenia własnej makiety odpowiadającej sytuacji meczowej.
## Uruchomienie
## Technologie
Aby uruchomić aktualną wersję aplikacji, wykonaj następujące kroki:
## Instalacja i Uruchomienie
1. **Uruchomienie serwera:** Aby uruchomić serwer należy wejść w [link](https://sg-server-ne4h.onrender.com/) oraz zaczekać do pojawienia się komunikatu o błędzie 404. Aplikacja korzysta z darmowej wersji obsługi serwera, stąd sposób jego uruchomienia nie jest standardowy.
Aby uruchomić beta wersję aplikacji, wykonaj następujące kroki:
2. **Uruchomienie aplikacji webowej** Po wykonaiu kroku 1 można wejść na właściwą stronę [aplikacji](https://statgoals.onrender.com/).
1. **Uruchomienie Klienta:**
Otwórz terminal w folderze `app` i uruchom następującą komendę:\
`npm run dev`
2. **Uruchomienie Serwera Flask:**
W innym terminalu, przejdź do folderu `app/src/flask-server` i uruchom serwer Flask przy użyciu poniższej komendy:\
`python server.py`
## Dane
- <https://statsbomb.com/what-we-do/soccer-data/>
## Szczegóły
Działanie aplikacji zostało opisane w podręczniku użytkownika znajdującym się w drzewie plików na repozytorium. Poza tym odsyłam do [repozytorium](https://git.wmi.amu.edu.pl/s478993/fantastyczne_gole) uniwersytetu na którym powstała aplikacja. Zawiera ono kod źródłowy aplikacji.

View File

@ -1,7 +1,7 @@
{
"name": "react_bs_web",
"private": true,
"proxy": "http://127.0.0.1:5000/",
"proxy": "http://localhost:5173",
"version": "0.0.0",
"type": "module",
"scripts": {

View File

@ -10,9 +10,9 @@ const App = () => {
<BrowserRouter>
<div className='relative z-0 bg-lightgreen'>
<div className='bg-hero-pattern bg-cover bg-no-repeat'>
<Navbar/>
<Navbar />
</div>
<div className='relative z-0 w-full'>
<div className='relative z-0'>
<Hero/>
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 559 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

BIN
app/src/assets/carrent.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 KiB

3
app/src/assets/close.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="18" height="18" viewBox="0 0 18 18" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
<path d="M10.4099 9L16.7099 2.71C16.8982 2.5217 17.004 2.2663 17.004 2C17.004 1.7337 16.8982 1.47831 16.7099 1.29C16.5216 1.1017 16.2662 0.995911 15.9999 0.995911C15.7336 0.995911 15.4782 1.1017 15.2899 1.29L8.99994 7.59L2.70994 1.29C2.52164 1.1017 2.26624 0.995911 1.99994 0.995911C1.73364 0.995911 1.47824 1.1017 1.28994 1.29C1.10164 1.47831 0.995847 1.7337 0.995847 2C0.995847 2.2663 1.10164 2.5217 1.28994 2.71L7.58994 9L1.28994 15.29C1.19621 15.383 1.12182 15.4936 1.07105 15.6154C1.02028 15.7373 0.994141 15.868 0.994141 16C0.994141 16.132 1.02028 16.2627 1.07105 16.3846C1.12182 16.5064 1.19621 16.617 1.28994 16.71C1.3829 16.8037 1.4935 16.8781 1.61536 16.9289C1.73722 16.9797 1.86793 17.0058 1.99994 17.0058C2.13195 17.0058 2.26266 16.9797 2.38452 16.9289C2.50638 16.8781 2.61698 16.8037 2.70994 16.71L8.99994 10.41L15.2899 16.71C15.3829 16.8037 15.4935 16.8781 15.6154 16.9289C15.7372 16.9797 15.8679 17.0058 15.9999 17.0058C16.132 17.0058 16.2627 16.9797 16.3845 16.9289C16.5064 16.8781 16.617 16.8037 16.7099 16.71C16.8037 16.617 16.8781 16.5064 16.9288 16.3846C16.9796 16.2627 17.0057 16.132 17.0057 16C17.0057 15.868 16.9796 15.7373 16.9288 15.6154C16.8781 15.4936 16.8037 15.383 16.7099 15.29L10.4099 9Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
app/src/assets/creator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
app/src/assets/github.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
app/src/assets/herobg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 909 KiB

View File

@ -1,8 +1,62 @@
import logo from "./logo.svg";
import backend from "./backend.png";
import creator from "./creator.png";
import mobile from "./mobile.png";
import web from "./web.png";
import github from "./github.png";
import menu from "./menu.svg";
import close from "./close.svg";
import css from "./tech/css.png";
import docker from "./tech/docker.png";
import figma from "./tech/figma.png";
import git from "./tech/git.png";
import html from "./tech/html.png";
import javascript from "./tech/javascript.png";
import mongodb from "./tech/mongodb.png";
import nodejs from "./tech/nodejs.png";
import reactjs from "./tech/reactjs.png";
import redux from "./tech/redux.png";
import tailwind from "./tech/tailwind.png";
import typescript from "./tech/typescript.png";
import threejs from "./tech/threejs.svg";
import meta from "./company/meta.png";
import shopify from "./company/shopify.png";
import starbucks from "./company/starbucks.png";
import tesla from "./company/tesla.png";
import carrent from "./carrent.png";
import jobit from "./jobit.png";
import tripguide from "./tripguide.png";
export {
logo,
backend
backend,
creator,
mobile,
web,
github,
menu,
close,
css,
docker,
figma,
git,
html,
javascript,
mongodb,
nodejs,
reactjs,
redux,
tailwind,
typescript,
threejs,
meta,
shopify,
starbucks,
tesla,
carrent,
jobit,
tripguide,
};

BIN
app/src/assets/jobit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 737 KiB

3
app/src/assets/menu.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="20" height="12" viewBox="0 0 20 12" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
<path d="M9 2L19 2C19.2652 2 19.5196 1.89464 19.7071 1.70711C19.8946 1.51957 20 1.26522 20 1C20 0.734784 19.8946 0.480429 19.7071 0.292892C19.5196 0.105356 19.2652 0 19 0L9 0C8.73478 0 8.48043 0.105356 8.29289 0.292892C8.10536 0.480429 8 0.734784 8 1C8 1.26522 8.10536 1.51957 8.29289 1.70711C8.48043 1.89464 8.73478 2 9 2ZM19 10L1 10C0.734784 10 0.480429 10.1054 0.292892 10.2929C0.105356 10.4804 0 10.7348 0 11C0 11.2652 0.105356 11.5196 0.292892 11.7071C0.480429 11.8946 0.734784 12 1 12L19 12C19.2652 12 19.5196 11.8946 19.7071 11.7071C19.8946 11.5196 20 11.2652 20 11C20 10.7348 19.8946 10.4804 19.7071 10.2929C19.5196 10.1054 19.2652 10 19 10V10ZM1 7L19 7C19.2652 7 19.5196 6.89464 19.7071 6.70711C19.8946 6.51957 20 6.26522 20 6C20 5.73478 19.8946 5.48043 19.7071 5.29289C19.5196 5.10536 19.2652 5 19 5L1 5C0.734784 5 0.480429 5.10536 0.292892 5.29289C0.105356 5.48043 0 5.73478 0 6C0 6.26522 0.105356 6.51957 0.292892 6.70711C0.480429 6.89464 0.734784 7 1 7Z" fill="#FFFFFF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
app/src/assets/mobile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
app/src/assets/tech/css.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
app/src/assets/tech/git.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg fill="none" stroke-linecap="square" stroke-miterlimit="10" version="1.1" viewBox="0 0 226.77 226.77" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(8.964 4.2527)" fill-rule="evenodd" stroke="#000" stroke-linecap="butt" stroke-linejoin="round" stroke-width="4">
<path d="m63.02 200.61-43.213-174.94 173.23 49.874z"/>
<path d="m106.39 50.612 21.591 87.496-86.567-24.945z"/>
<path d="m84.91 125.03-10.724-43.465 43.008 12.346z"/>
<path d="m63.458 38.153 10.724 43.465-43.008-12.346z"/>
<path d="m149.47 62.93 10.724 43.465-43.008-12.346z"/>
<path d="m84.915 125.06 10.724 43.465-43.008-12.346z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 677 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

BIN
app/src/assets/web.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@ -2,100 +2,33 @@ import React, { useEffect, useState } from "react";
import { styles } from "../style";
import { ComputersCanvas } from "./canvas";
import { Link } from "react-router-dom";
import { navLinks } from "../constants";
import { logo, menu, close } from "../assets";
const Hero = () => {
const [isOpen, setIsOpen] = useState(false);
const [gameMinute, setGameMinute] = useState('');
const [firstShot, setfirstShot] = useState(0);
const [oneOnOne, SetoneOnOne] = useState(0);
const [afterAirDuel, SetafterAirDuele] = useState(0);
const [openGoal, SetOpenGoal] = useState(0);
const [afterDribbling, SetafterDribbling] = useState(0);
const [redirect, SetRedirect] = useState(0);
const handleMinuteChange = (e) => { setGameMinute(e.target.value);
//sentQuestion();
}
const handleFirstShotChange = (event) => {
setfirstShot(event.target.checked);
//sentQuestion();
};
const handleOneOnOneChange = (event) => {
SetoneOnOne(event.target.checked);
//sentQuestion();
};
const handleAfterAirDuelChange = (event) => {
SetafterAirDuele(event.target.checked);
//sentQuestion();
};
const handleOpenGoalChange = (event) => {
SetOpenGoal(event.target.checked);
//sentQuestion();
};
const handleAfterDribblingChange = (event) => {
SetafterDribbling(event.target.checked);
//sentQuestion();
};
const handleRedirectChange = (event) => {
SetRedirect(event.target.checked);
//sentQuestion();
};
const toggleDropdown = () => setIsOpen(!isOpen);
const handleMinuteChange = (e) => setGameMinute(e.target.value);
const [data, setData] = useState("");
//zmienne globalne
//zmienna mówiąca który przycisk jest aktywny, jest ona wykorzystywana
//przez listener nanoszący zawodników na boisko. 1 - strzelec , 2 - bramkarz , 3 - obronca, 4 - napasnik. zmienna przez aktywacje przycskówk bb1, bb2, bb3 i bb4
let active_bbt = "bbt1";
const [number_of_defenders, setNumberOfDevenders] = useState(()=>{
return 0;
});
const [number_of_strikers, setNumberOfStrikers] = useState(() => {
return 0;
})
const [number_of_goalkeepers, setNumberOfGoalkeppers] = useState(()=>{
return 0;
});
const [number_of_shooters,setNumberOfShooters] = useState(() => {
return 0}
);
const number_of_shooters_rev = React.useRef(number_of_shooters)
const number_of_strikers_rev = React.useRef(number_of_strikers)
const number_of_goalkeepers_rev = React.useRef(number_of_goalkeepers)
const number_of_defenders_rev = React.useRef(number_of_defenders)
let number_of_defenders = 0;
let number_of_strikers = 0;
var shooterX = 0;
var shooterY = 0;
var eX = " ";
// zmienne globalne bedace danymi wejsciowymi do modelu
var shooter = [0,0]
var goalkeeper = [0,0]
var stricers = new Array;
var defenders = new Array;
const [bodyPart,setBodyPart] = useState('Right Foot');
const [technique,setTechnique] = useState('Normal');
const [actionType,setActionType] = useState('Open Play');
const [shooterPossition,setPossition] = useState('Center Forward');
//zamiana procentowych pozycji na kartezyjskie
function konwerturX(x){
var fX = parseFloat(x.slice(0,-1))
return Math.round((fX*105))/100
}
function konwetujY(y){
var fY = parseFloat(y.slice(0,-1))
return Math.round(fY*68)/100
}
function changePlayer(a){
@ -104,275 +37,182 @@ const handleRedirectChange = (event) => {
document.getElementById("bbt3").style.background = "#99FFCC";
document.getElementById("bbt4").style.background = "#99FFCC";
document.getElementById(a).style.background = "#00CC66";
active_bbt = a
}
function changeLeg(a){
document.getElementById("bbt5").style.background = "#99FFCC";
document.getElementById("bbt6").style.background = "#99FFCC";
document.getElementById("bbt7").style.background = "#99FFCC";
document.getElementById("bbt8").style.background = "#99FFCC";
document.getElementById(a).style.background = "#00CC66";
Leg_bbt = a
}
// function changeTechnique(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_one_on_one(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_aerial_won(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_first_time(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_redirect(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_kick_off(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// function is_follows_dribble(a){
// document.getElementById("bbt4").style.background = "#99FFCC";
// technique_bbt = a
// }
// Reset Boiska
function resetField() {
var footballField = document.getElementById('footballField');
var footballs = document.querySelectorAll('.football');
var list = document.getElementById('list')
var players = document.querySelectorAll('.player')
var goalkeepers = document.querySelectorAll('.goalkeeper');
var strikers = document.querySelectorAll('.striker')
var defenders = document.querySelectorAll('.defender')
footballs.forEach(function (ball) {
footballField.removeChild(ball);
});
players.forEach(function(element) {
list.removeChild(element);
goalkeepers.forEach(function (ball) {
footballField.removeChild(ball);
});
strikers.forEach(function(ball){
footballField.removeChild(ball)
})
defenders.forEach(function(ball){
footballField.removeChild(ball)
})
setNumberOfDevenders(0);
setNumberOfStrikers(0)
setNumberOfGoalkeppers(0)
setNumberOfShooters(0)
setGameMinute('')
number_of_defenders = 0
number_of_strikers = 0
number_of_shooters_rev.current = 0;
number_of_goalkeepers_rev.current = 0;
number_of_defenders_rev.current = 0;
number_of_strikers_rev.current = 0;
document.getElementById("ex").innerHTML = 0;
}
//funkcja dodaje zawodnika do listy zawodnikow. zmienne x oraz y to wspolrzedne a position
// to pozycja zawodnika 0 - strzelec, 1 - bramkarz, 2 - broniacy, 3 napastnik
// ball - to odnosnik do punktu na boisku
function deletePlayer(ball,player,possition){
var list = document.getElementById('list');
var bojo = document.getElementById('footballField');
list.removeChild(player)
bojo.removeChild(ball)
if(possition == 1){
setNumberOfGoalkeppers(number_of_goalkeepers_rev.current -= 1);
}else if(possition == 2){
setNumberOfDevenders(number_of_defenders_rev.current -= 1) ;
}else if (possition == 3){
setNumberOfStrikers(number_of_strikers_rev.current -= 1);
}else if(possition == 0){
setNumberOfShooters(number_of_shooters_rev.current -= 1);
}
//sentQuestion()
}
// funkcja zsczytuje pozycje zawodnikow przed wyslaniem zapytania do serwera
function loadPlayers(){
var players = document.querySelectorAll('.player')
// wyczyszczenie list zawierajacych lokalizacje zawodnikow
defenders = []
stricers = []
shooter = null
goalkeeper = null
//zebranie iformacji o kazdym z zawodnikow
players.forEach(function(player){
var type = player.getAttribute('type')
if(type == 0){
shooter = player.getAttribute('possition')
}else if(type == 1 ){
goalkeeper = player.getAttribute('possition')
}else if(type == 2){
defenders.push(player.getAttribute('possition'))
}else {
stricers.push(player.getAttribute('possition'))
}
})
}
function addPlayer(possition, ball){
//Zmiana stylu w zaleznosci czy zawodnik jest obronca/napastnikiem iyp.
var pName = "Strzelec"
//kolor kropki
// kolor tła kafelka
var pColor = "#fc0303"
if(possition == 1){
var pName = "Bramkarz"
var pColor = "#03e7fc"
setNumberOfGoalkeppers(number_of_goalkeepers_rev.current += 1);
}else if(possition == 2){
var pName = "Obrońca"
var pColor = "#0324fc"
setNumberOfDevenders(number_of_defenders_rev.current += 1);
}else if (possition ==3){
var pName = "Napastnik"
var pColor = "#fc6703"
setNumberOfStrikers(number_of_strikers_rev.current += 1);
}else{
setNumberOfShooters(number_of_shooters_rev.current += 1);
}
var player = document.createElement('div');
player.className = 'player';
player.style.width = "inherit"
player.setAttribute("type",possition)
var list = document.getElementById("list")
// div z nazwa gracza
var tekst = document.createElement('div')
tekst.style.fontSize = "12px";
tekst.innerHTML = pName;
// div z pozycja gracza
var posytion = document.createElement('div')
posytion.style.fontSize = "12px"
posytion.innerHTML = konwerturX(ball.style.left) + " m, " + konwetujY(ball.style.top) + " m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)])
//div z przyciskiem usuwającym
var btnDelete = document.createElement('button')
btnDelete.innerHTML = 'Usuń'
btnDelete.style.fontSize = "12px"
btnDelete.style = 'background-color: #FFB266;color:#000000'
btnDelete.addEventListener("click",function(){deletePlayer(ball,player,possition)},false)
//dodanie elementów do kafelka
player.appendChild(tekst)
player.appendChild(posytion)
player.appendChild(btnDelete)
list.appendChild(player)
player.addEventListener("mouseover",function(){
ball.style.background = "#42f5d7"
})
player.addEventListener("mouseout",function(){
ball.style.background = pColor;
})
ball.addEventListener("mouseover",function podswietl(){
player.style.background = "#bf8e8e"
tekst.style.color = "black"
posytion.style.color = "black"
})
ball.addEventListener("mouseout",function (){
player.style.background = 'rgb(16, 46, 29)';
tekst.style.color = "white"
posytion.style.color = "white"
})
var bojo = document.getElementById('footballField')
// listenery pozwalające na przesuwanie punktu
ball.addEventListener("mousedown", function przesuwanie(){
ball.style.background = "orange"
player.style.background = 'rgb(16, 46, 29)';
tekst.style.color = "white"
posytion.style.color = "white"
bojo.addEventListener("mousemove", function whileMove(ev){
var bojo = document.getElementById('footballField')
var bnd = ev.target.getBoundingClientRect()
// zapis od 0 - 1 w jakim procentowym miejscu boiska użytkownik kliknął
var x = ((ev.clientX - bnd.left)/bojo.offsetWidth)*100;
var y = ((ev.clientY - bnd.top)/bojo.offsetHeight)*100;
player.style.background = 'rgb(16, 46, 29)';
tekst.style.color = "white"
posytion.style.color = "white"
x = parseFloat(x) -3
y = parseFloat(y) -3
if(bojo.parentNode.querySelector(":hover")){
ball.style.left = x + "%"
ball.style.top = y + "%"
}
//var shooterX = konwerturX(ball.style.left)
//var shooterY = konwetujY(ball.style.top)
posytion.innerHTML = "x:" + konwerturX(ball.style.left) + "m " + "y:" + konwetujY(ball.style.top) + "m";
player.setAttribute('possition',[konwerturX(ball.style.left),konwetujY(ball.style.top)]);
bojo.addEventListener("mouseup", function afterUp(){
ball.style.background = pColor
bojo.removeEventListener("mousemove", whileMove)
bojo.removeEventListener("mouseup", afterUp)
})
})
bojo.addEventListener("mouseup", function reload(){
//sentQuestion();
bojo.removeEventListener("mouseup",reload)
})
})
//sentQuestion();
}
// // Wyłanie zapytania do serwera
// Wysłanie zapytania do serwera
const [data,setData] = useState([{}])
function sentQuestion() {
///Dziwny Blad
loadPlayers()
if (number_of_shooters_rev.current == 1) {
//console.log('Wysyłanie wartości: ', bodyPart, technique, actionType, shooterPossition, gameMinute, firstShot);
// Użyj backticksów zamiast zwykłych cudzysłowów
fetch(`http://127.0.0.1:5000/get_model?shooter=${shooter}&goalkeeper=${goalkeeper}&defenders=${defenders}&strickers=${stricers}&bodyPart=${bodyPart}&technique=${technique}&actionType=${actionType}&shooterPossition=${shooterPossition}&gameMinute=${gameMinute}&shot_first_time=${firstShot}&shot_one_on_one=${oneOnOne}&shot_aerial_won=${afterAirDuel}&shot_open_goal=${openGoal}&shot_follows_dribble=${afterDribbling}&shot_redirect=${redirect}`).then(
res => res.json()
).then(
data => {
setData(data);
console.log(data);
// Przenieś tę linię do środka bloku .then(), aby uniknąć błędów
let eX = data.response;
document.getElementById("ex").innerHTML = eX;
//updateXGMeter(eX);
}
).catch(error => {
console.error('Błąd:', error);
});
} else {
alert('Piłka nie jest obecnie na boisku.');
}
var ball = document.querySelector('.football');
if (ball) {
fetch("http://localhost:5173/LRegresion" + shooterX + "&" + shooterY).then(
res=> res.json()
).then(
data => {
setData(data)
console.log(data)
}
)
eX = data.response
document.getElementById("ex").innerHTML = "Współczynnik xG: "+ eX
} else {
alert('Piłka nie jest obecnie na boisku.');
}
}
/* Funkcja dodająca listener do boiska*/
function boiskoListener(ev){
ev.preventDefault()
var bojo = document.getElementById('footballField')
var bnd = ev.target.getBoundingClientRect()
function boiskoListener(){
// zapis od 0 - 1 w jakim procentowym miejscu boiska użytkownik kliknął
var x = ((ev.clientX - bnd.left)/bojo.offsetWidth)*100;
var y = ((ev.clientY - bnd.top)/bojo.offsetHeight)*100;
var x = event.clientX - footballField.getBoundingClientRect().left;
var y = event.clientY - footballField.getBoundingClientRect().top;
shooterX = (x * 105)/600
shooterY = ((400 - y) * 69)/ 400
// Przypadek kiedy zaznaczamy strzelca
if(active_bbt == "bbt1"){
let existingBall = document.querySelector('.football');
if (!existingBall) {
var ball = document.createElement('div');
ball.className = 'football';
ball.style.left = x + 'px';
ball.style.top = y + 'px';
footballField.appendChild(ball);
} else {
alert('Możesz dodać tylko jedną piłkę!');
}
// Przypadek kiedy zaznaczamy bramkarza
} else if (active_bbt == "bbt2") {
let existingGoalkeeper = document.querySelector('.goalkeeper');
if (!existingGoalkeeper) {
var ball = document.createElement('div');
ball.className = 'goalkeeper';
ball.style.left = x + 'px';
ball.style.top = y + 'px';
footballField.appendChild(ball);
} else {
alert('Możesz dodać tylko jednego bramkarza!');
}
}
// Przypadek kiedy zaznaczamy obronce
else if(active_bbt == "bbt3"){
if(number_of_defenders <= 10){
var ball = document.createElement('div');
ball.className = 'defender';
ball.style.left = x + 'px';
ball.style.top = y + 'px';
footballField.appendChild(ball);
number_of_defenders = number_of_defenders + 1} else {alert("zbyt duza liczba obronców")}
}else if(active_bbt == "bbt4"){
// Przypadek kiedy zaznaczamy napastnika
if(number_of_strikers <= 10){
var ball = document.createElement('div');
ball.className = 'striker';
ball.style.left = x + 'px';
ball.style.top = y + 'px';
footballField.appendChild(ball);
number_of_strikers = number_of_strikers + 1
}else{alert("zbyt duza liczba obroncow")}}
var ball = document.createElement('div');
ball.className = "football";
ball.style.left = x + "%"
ball.style.top = y + "%"
//dodanie zawodnika do listy oraz punktu do mapy w zaleznosci od aktywnosci przycisku 1,2,3 lub 4
if(active_bbt=="bbt1"){
if(number_of_shooters_rev.current < 1 ){
addPlayer(0,ball)
bojo.appendChild(ball)
ball.style.background = "#fc0303"
}else{alert("mozesz dodac tylko jednego strzelca")}
}else if(active_bbt == "bbt2"){
if ( number_of_goalkeepers_rev.current < 1){
addPlayer(1,ball)
bojo.appendChild(ball)
ball.style.background = "#03e7fc"
}else{alert("mozesz dodac tylko jednego bramkarza")}
}else if(active_bbt == "bbt3"){
if(number_of_defenders_rev.current < 10){
addPlayer(2,ball);
bojo.appendChild(ball)
ball.style.background = "#0324fc"
}else{alert("maksymalna liczba obroncow")}
}else if(active_bbt == "bbt4"){
if(number_of_strikers_rev.current < 10){
addPlayer(3,ball);
bojo.appendChild(ball)
ball.style.background = "#fc6703"
}else{alert("maksymalna liczba napastnikow")}
}
}
// funkcja działą po utworzeniu komponentów, dodaje listenry do elementów
useEffect(()=>{
var footballField = document.getElementById('footballField');
footballField.addEventListener('contextmenu', boiskoListener,false)
footballField.addEventListener('click', boiskoListener)
document.getElementById("bbt1").addEventListener("click",function(){
changePlayer("bbt1")
@ -386,92 +226,92 @@ const handleRedirectChange = (event) => {
document.getElementById("bbt4").addEventListener("click",function(){
changePlayer("bbt4")
},false)
// document.getElementById("bbt5").addEventListener("click",function(){
// changeLeg("bbt5")
// },false)
// document.getElementById("bbt6").addEventListener("click",function(){
// changeLeg("bbt6")
// },false)
// document.getElementById("bbt7").addEventListener("click",function(){
// changeLeg("bbt7")
// },false)
// document.getElementById("bbt8").addEventListener("click",function(){
// changeLeg("bbt8")
// },false)
},[]);
/*zwracany komponent zawierajacy boisko*/
return (
<div>
<body>
<div className="container">
{/* Listy zwijane */}
<div className="top-bar" id = "top-bar">
<div className="top-bar">
{/* new version */}
<div className="dropdown">
<button onClick={() => setIsOpen(!isOpen)} className="dropbtn">
Część ciała
</button>
{isOpen && (
<div className="cho-dropdown_body_part">
<a a href="#">Noga Prawa</a>
<a a href="#">Noga Lewa</a>
<a a href="#">Głowa</a>
<a a href="#">Inna</a>
</div>
)}
</div>
<form className="dropdown" id = "bodyPartList">
<select className="dropbtn"
onChange={event => {setBodyPart(event.target.value);
//sentQuestion()
}}
defaultValue={bodyPart}>
<option value = "Right Foot">Noga Prawa</option>
<option value = "Left Foot">Noga Lewa</option>
<option value = "Head">Głowa</option>
<option value = "Other" >Inna</option>
</select>
</form>
{/* old version */}
{/* <div className="ChoosingPlayer">
<button className="cho-shooter" id = "bbt5">Noga Prawa</button>
<button className="cho-goalkeeper"id = "bbt6">Noga Lewa</button>
<button className="cho-defence" id = "bbt7">Głowa</button>
<button className="cho-atack" id = "bbt8">Inna</button>
</div> */}
<div className="dropdown">
<button onClick={toggleDropdown} className="dropbtn">Technika strzału</button>
{isOpen && (
<div className="cho-dropdown_technique_name">
<a href="#"> Zwykły </a>
<a href="#"> Wolej </a>
<a href="#"> Półwolej </a>
<a href="#"> Lob </a>
<a href="#"> Szczupak </a>
<a href="#"> Kopnięcie z góry </a>
<a href="#"> Piętka </a>
</div>
)}
</div>
<form className="dropdown" id = "shootTypeList">
<select className="dropbtn" onChange={event => {setTechnique(event.target.value);
//sentQuestion()
}}
defaultValue = {technique}>
<option value="Normal"> Zwykły </option>
<option value = "Volley"> Wolej </option>
<option value = "Half Volley"> Półwolej </option>
<option value = "Lob"> Lob </option>
<option value = "Diving Header"> Szczupak </option>
<option value = "Overhead Kick"> Kopnięcie z góry </option>
<option value = "Backheel"> Piętka </option>
</select>
</form>
<div className="dropdown">
<button onClick={toggleDropdown} className="dropbtn">Typ akcji</button>
{isOpen && (
<div className="cho-dropdown_type_name">
<a href="#"> Atak Pozycyjny </a>
<a href="#"> Rzut Wolny </a>
<a href="#"> Rzut Karny </a>
<a href="#"> Rzut Rozny </a>
<a href="#"> Rozpoczęcie </a>
</div>
)}
</div>
<form className="dropdown" id = "actionTypeList" onChange={event => {setActionType(event.target.value);
//sentQuestion()
}}
defaultValue={technique}>
<select className="dropbtn">
<option value = "Open Play"> Atak Pozycyjny </option>
<option value = "Free Kick"> Rzut Wolny </option>
<option value = "Penalty"> Rzut Karny </option>
<option value= "Corner"> Rzut Rozny </option>
</select>
</form>
<form className="dropdown" id = "possitionList"
onChange={event => {setPossition(event.target.value);
//sentQuestion()
}}
defaultValue={shooterPossition}>
<select className="dropbtn">
<option value="Right Center Forward">Prawy Środkowy Napastnik</option>
<option value="Left Center Forward">Lewy Środkowy Napastnik</option>
<option value="Secondary Striker">Drugi Napastnik</option>
<option value="Center Forward">Środkowy Napastnik</option>
<option value="Center Midfield">Środkowy Pomocnik</option>
<option value="Left Center Midfield">Lewy Środkowy Pomocnik</option>
<option value="Right Center Midfield">Prawy Środkowy Pomocnik</option>
<option value="Left Midfield">Lewy Pomocnik</option>
<option value="Center Attacking Midfield">Środkowy Ofensywny Pomocnik</option>
<option value="Left Defensive Midfield">Lewy Defensywny Pomocnik</option>
<option value="Left Attacking Midfield">Lewy Ofensywny Pomocnik</option>
<option value="Right Attacking Midfield">Prawy Ofensywny Pomocnik</option>
<option value="Right Defensive Midfield">Prawy Defensywny Pomocnik</option>
<option value="Center Defensive Midfield">Środkowy Defensywny Pomocnik</option>
<option value="Right Midfield">Prawy Pomocnik</option>
<option value="Left Wing Back">Lewy Pomocnik Skrzydłowy</option>
<option value="Left Wing">Lewe Skrzydło</option>
<option value="Right Wing">Prawe Skrzydło</option>
<option value="Right Wing Back">Prawy Pomocnik Skrzydłowy</option>
<option value="Center Back">Środkowy Obrońca</option>
<option value="Left Center Back">Lewy Środkowy Obrońca</option>
<option value="Right Center Back">Prawy Środkowy Obrońca</option>
<option value="Right Back">Prawy Obrońca</option>
<option value="Left Back">Lewy Obrońca</option>
<option value="Goalkeeper">Bramkarz</option>
</select>
</form>
<div className="dropdown">
<button onClick={toggleDropdown} className="dropbtn">Pozycja strzelającego</button>
{isOpen && (
<div className="cho-dropdown_position_name">
<a href="#"> Bramkarz </a>
<a href="#"> Obrońca </a>
<a href="#"> Pomocnik </a>
<a href="#"> Napastnik </a>
</div>
)}
</div>
<div className="cho-minute">
<label htmlFor="gameMinute" className="label-large"></label>
@ -486,49 +326,51 @@ const handleRedirectChange = (event) => {
/>
</div>
</div>
<div className="main-content" id = "field">
<div className="player-list" id = "list" >
</div>
<div className="field" id="footballField">
<div className="field-pic"></div>
<div className="main-content" id = "field">
<div className="field" id="footballField">
<span className="left">
<span className="halfway-line"></span>
<span className="centre-circle"></span>
<span className="centre-mark"></span>
<span className="penalty-area"></span>
<span className="penalty-mark"></span>
<span className="penalty-arc"></span>
<span className="goal-area"></span>
<span className="corner-arc"></span>
</span>
</div>
<div className="rightMenu">
<div className="xg-meter">
<b id="ex" className="xg-value">0</b>
<span className="right">
<span className="halfway-line"></span>
<span className="centre-circle"></span>
<span className="centre-mark"></span>
<span className="penalty-area"></span>
<span className="penalty-mark"></span>
<span className="penalty-arc"></span>
<span className="goal-area"></span>
<span className="corner-arc"></span>
</span>
</div>
</div>
<div className="additional-parameters">
<h3>Parametry strzału</h3>
<label>
<input type="checkbox" id="firstShot" onChange={handleFirstShotChange} />
Pierwszy w meczu
</label>
<label>
<input type="checkbox" id="oneOnOne" onChange={handleOneOnOneChange} />
Akcja sam na sam
</label>
<label>
<input type="checkbox" id="afterAirDuel" onChange={handleAfterAirDuelChange} />
Po pojedynku powietrznym
</label>
<label>
<input type="checkbox" id="openGoal" onChange={handleOpenGoalChange} />
Na pustą bramkę
</label>
<label>
<input type="checkbox" id="afterDribbling" onChange={handleAfterDribblingChange} />
Poprzedzony dryblingiem
</label>
<label>
<input type="checkbox" id="redirect" onChange={handleRedirectChange} />
Rykoszet
</label>
</div>
</div>
</div>
{/* <div className="ChoosingPlayer">
<button className="cho-one_on_one" id = "bbt8">Sam na sam</button>
</div>
<div className="ChoosingPlayer">
<button className="cho-first_time" id = "bbt12">Pierwszy w meczu</button>
</div>
<div className="ChoosingPlayer">
<button className="cho-aerial_won" id = "bbt13">Pojedynek powietrzny</button>
</div>
<div className="ChoosingPlayer">
<button className="cho-follows_dribble" id = "bbt14">Drybling</button>
</div>
<div className="ChoosingPlayer">
<button className="cho-redirect" id = "bbt15">Rykoszet</button>
</div> */}
<div className="bottom-bar">
<button className="cho-shooter" id = "bbt1">Strzelec</button>
@ -538,8 +380,13 @@ const handleRedirectChange = (event) => {
<button className="reset-button" onClick={resetField}>Reset</button>
<button className="info-button" onClick={sentQuestion}>xG</button>
</div>
<div>
<b id = "ex" className="Ex">
</b>
</div>
</div>
</body>
);
};

View File

@ -3,7 +3,6 @@ import React from 'react'
const Loader = () => {
return (
<div>Loader</div>
)
}

View File

@ -2,8 +2,8 @@ import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { styles } from "../style";
import { logo} from "../assets";
import { navLinks } from "../constants";
import { logo, menu, close } from "../assets";
const Navbar = () => {
const [active, setActive] = useState("");
@ -48,6 +48,20 @@ const Navbar = () => {
</span>
</Link>
<ul className='list-none hidden sm:flex flex-row gap-10'>
{navLinks.map((nav) => (
<li
key={nav.id}
className={`${
active === nav.title ? "text-white" : "text-secondary"
} hover:text-white text-[18px] font-medium cursor-pointer`}
onClick={() => setActive(nav.title)}
>
<a href={`#${nav.id}`}>{nav.title}</a>
</li>
))}
</ul>
</div>
</nav>
);

View File

@ -1,7 +1,257 @@
import {
mobile,
backend,
creator,
web,
javascript,
typescript,
html,
css,
reactjs,
redux,
tailwind,
nodejs,
mongodb,
git,
figma,
docker,
meta,
starbucks,
tesla,
shopify,
carrent,
jobit,
tripguide,
threejs,
} from "../assets";
export { };
export const navLinks = [
];
const services = [
{
title: "Web Developer",
icon: web,
},
{
title: "React Native Developer",
icon: mobile,
},
{
title: "Backend Developer",
icon: backend,
},
{
title: "Content Creator",
icon: creator,
},
];
const technologies = [
{
name: "HTML 5",
icon: html,
},
{
name: "CSS 3",
icon: css,
},
{
name: "JavaScript",
icon: javascript,
},
{
name: "TypeScript",
icon: typescript,
},
{
name: "React JS",
icon: reactjs,
},
{
name: "Redux Toolkit",
icon: redux,
},
{
name: "Tailwind CSS",
icon: tailwind,
},
{
name: "Node JS",
icon: nodejs,
},
{
name: "MongoDB",
icon: mongodb,
},
{
name: "Three JS",
icon: threejs,
},
{
name: "git",
icon: git,
},
{
name: "figma",
icon: figma,
},
{
name: "docker",
icon: docker,
},
];
const experiences = [
{
title: "React.js Developer",
company_name: "Starbucks",
icon: starbucks,
iconBg: "#383E56",
date: "March 2020 - April 2021",
points: [
"Developing and maintaining web applications using React.js and other related technologies.",
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.",
"Implementing responsive design and ensuring cross-browser compatibility.",
"Participating in code reviews and providing constructive feedback to other developers.",
],
},
{
title: "React Native Developer",
company_name: "Tesla",
icon: tesla,
iconBg: "#E6DEDD",
date: "Jan 2021 - Feb 2022",
points: [
"Developing and maintaining web applications using React.js and other related technologies.",
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.",
"Implementing responsive design and ensuring cross-browser compatibility.",
"Participating in code reviews and providing constructive feedback to other developers.",
],
},
{
title: "Web Developer",
company_name: "Shopify",
icon: shopify,
iconBg: "#383E56",
date: "Jan 2022 - Jan 2023",
points: [
"Developing and maintaining web applications using React.js and other related technologies.",
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.",
"Implementing responsive design and ensuring cross-browser compatibility.",
"Participating in code reviews and providing constructive feedback to other developers.",
],
},
{
title: "Full stack Developer",
company_name: "Meta",
icon: meta,
iconBg: "#E6DEDD",
date: "Jan 2023 - Present",
points: [
"Developing and maintaining web applications using React.js and other related technologies.",
"Collaborating with cross-functional teams including designers, product managers, and other developers to create high-quality products.",
"Implementing responsive design and ensuring cross-browser compatibility.",
"Participating in code reviews and providing constructive feedback to other developers.",
],
},
];
const testimonials = [
{
testimonial:
"I thought it was impossible to make a website as beautiful as our product, but Rick proved me wrong.",
name: "Sara Lee",
designation: "CFO",
company: "Acme Co",
image: "https://randomuser.me/api/portraits/women/4.jpg",
},
{
testimonial:
"I've never met a web developer who truly cares about their clients' success like Rick does.",
name: "Chris Brown",
designation: "COO",
company: "DEF Corp",
image: "https://randomuser.me/api/portraits/men/5.jpg",
},
{
testimonial:
"After Rick optimized our website, our traffic increased by 50%. We can't thank them enough!",
name: "Lisa Wang",
designation: "CTO",
company: "456 Enterprises",
image: "https://randomuser.me/api/portraits/women/6.jpg",
},
];
const projects = [
{
name: "Car Rent",
description:
"Web-based platform that allows users to search, book, and manage car rentals from various providers, providing a convenient and efficient solution for transportation needs.",
tags: [
{
name: "react",
color: "blue-text-gradient",
},
{
name: "mongodb",
color: "green-text-gradient",
},
{
name: "tailwind",
color: "pink-text-gradient",
},
],
image: carrent,
source_code_link: "https://github.com/",
},
{
name: "Job IT",
description:
"Web application that enables users to search for job openings, view estimated salary ranges for positions, and locate available jobs based on their current location.",
tags: [
{
name: "react",
color: "blue-text-gradient",
},
{
name: "restapi",
color: "green-text-gradient",
},
{
name: "scss",
color: "pink-text-gradient",
},
],
image: jobit,
source_code_link: "https://github.com/",
},
{
name: "Trip Guide",
description:
"A comprehensive travel booking platform that allows users to book flights, hotels, and rental cars, and offers curated recommendations for popular destinations.",
tags: [
{
name: "nextjs",
color: "blue-text-gradient",
},
{
name: "supabase",
color: "green-text-gradient",
},
{
name: "css",
color: "pink-text-gradient",
},
],
image: tripguide,
source_code_link: "https://github.com/",
},
];
export { services, technologies, experiences, testimonials, projects };

View File

@ -1,271 +1,15 @@
from joblib import load
import pandas as pd
from math import sqrt
import math
import numpy as np
import xgboost
from sklearn.preprocessing import OrdinalEncoder
# Funkcja zwraca prawdopodobieństwo zdobycia gola
def LogisticRegression_predict_proba(position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead):
# distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
def LogisticRegression_predict_proba(position_x, position_y, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead):
distance_to_goalM = sqrt(( (position_x**2) + (position_y**2)))
model = load('regresja_logistyczna.joblib')
X_new = pd.DataFrame(columns=['position_x', 'position_y', 'distance_to_goalM', 'angle','match_minute', 'Number_Intervening_Opponents','Number_Intervening_Teammates', 'isFoot', 'isHead'])
X_new.loc[len(X_new.index)] = [position_x, position_y, distance_to_goalM, angle, match_minute, Number_Intervening_Opponents, Number_Intervening_Teammates, isFoot, isHead]
return model.predict_proba(X_new)[0][1].round(2)
#xgBoost
def xgboost_predict_proba(minute=0, position_name='Center Forward', shot_body_part_name='Right Foot',
shot_technique_name='Normal', shot_type_name='Open Play', shot_first_time=False,
shot_one_on_one=False, shot_aerial_won=False,
shot_open_goal=False, shot_follows_dribble=False, shot_redirect=False, x1=0.0, y1=0.0,
number_of_players_opponents=0, number_of_players_teammates=0,
angle=0.0, distance=0.0, x_player_opponent_Goalkeeper=np.nan,
x_player_opponent_8=np.nan, x_player_opponent_1=np.nan, x_player_opponent_2=np.nan,
x_player_opponent_3=np.nan, x_player_teammate_1=np.nan, x_player_opponent_4=np.nan,
x_player_opponent_5=np.nan, x_player_opponent_6=np.nan, x_player_teammate_2=np.nan,
x_player_opponent_9=np.nan, x_player_opponent_10=np.nan, x_player_opponent_11=np.nan,
x_player_teammate_3=np.nan, x_player_teammate_4=np.nan, x_player_teammate_5=np.nan,
x_player_teammate_6=np.nan, x_player_teammate_7=np.nan, x_player_teammate_8=np.nan,
y_player_opponent_Goalkeeper=np.nan, y_player_opponent_8=np.nan,
x_player_teammate_9=np.nan, x_player_teammate_10=np.nan,
y_player_opponent_1=np.nan, y_player_opponent_2=np.nan, y_player_opponent_3=np.nan,
y_player_teammate_1=np.nan, y_player_opponent_4=np.nan, y_player_opponent_5=np.nan,
y_player_opponent_6=np.nan, y_player_teammate_2=np.nan, y_player_opponent_9=np.nan,
y_player_opponent_10=np.nan, y_player_opponent_11=np.nan, y_player_teammate_3=np.nan,
y_player_teammate_4=np.nan, y_player_teammate_5=np.nan, y_player_teammate_6=np.nan,
y_player_teammate_7=np.nan, y_player_teammate_8=np.nan, y_player_teammate_9=np.nan,
y_player_teammate_10=np.nan, x_player_opponent_7=np.nan, y_player_opponent_7=np.nan,
x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan):
model = xgboost.XGBClassifier()
model.load_model('xgboost.json')
enc = OrdinalEncoder()
enc = load('labelEncoder.joblib')
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name',
'shot_type_name', 'shot_first_time', 'shot_one_on_one',
'shot_aerial_won', 'shot_open_goal',
'shot_follows_dribble', 'shot_redirect', 'x1', 'y1',
'number_of_players_opponents', 'number_of_players_teammates',
'angle', 'distance', 'x_player_opponent_Goalkeeper',
'x_player_opponent_8', 'x_player_opponent_1', 'x_player_opponent_2',
'x_player_opponent_3', 'x_player_teammate_1', 'x_player_opponent_4',
'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2',
'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11',
'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5',
'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8',
'x_player_teammate_9', 'x_player_teammate_10',
'y_player_opponent_Goalkeeper', 'y_player_opponent_8',
'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3',
'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5',
'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9',
'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3',
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper'])
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name, shot_technique_name,
shot_type_name, shot_first_time, shot_one_on_one,
shot_aerial_won, shot_open_goal,
shot_follows_dribble, shot_redirect, x1, y1,
number_of_players_opponents, number_of_players_teammates,
angle, distance, x_player_opponent_Goalkeeper,
x_player_opponent_8, x_player_opponent_1, x_player_opponent_2,
x_player_opponent_3, x_player_teammate_1, x_player_opponent_4,
x_player_opponent_5, x_player_opponent_6, x_player_teammate_2,
x_player_opponent_9, x_player_opponent_10, x_player_opponent_11,
x_player_teammate_3, x_player_teammate_4, x_player_teammate_5,
x_player_teammate_6, x_player_teammate_7, x_player_teammate_8,
x_player_teammate_9, x_player_teammate_10,
y_player_opponent_Goalkeeper, y_player_opponent_8,
y_player_opponent_1, y_player_opponent_2, y_player_opponent_3,
y_player_teammate_1, y_player_opponent_4, y_player_opponent_5,
y_player_opponent_6, y_player_teammate_2, y_player_opponent_9,
y_player_opponent_10, y_player_opponent_11, y_player_teammate_3,
y_player_teammate_4, y_player_teammate_5, y_player_teammate_6,
y_player_teammate_7, y_player_teammate_8, y_player_teammate_9,
y_player_teammate_10, x_player_opponent_7, y_player_opponent_7,
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper]
X_new[['position_name',
'shot_technique_name',
'shot_type_name',
'shot_body_part_name']] = enc.transform(X_new[['position_name', 'shot_technique_name', 'shot_type_name', 'shot_body_part_name']], )
X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']] = X_new[['minute',
'position_name',
'shot_technique_name',
'shot_type_name',
'number_of_players_opponents',
'number_of_players_teammates',
'shot_body_part_name']].astype(int)
# X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']] = X_new[['minute',
# 'position_name',
# 'shot_technique_name',
# 'shot_type_name',
# 'number_of_players_opponents',
# 'number_of_players_teammates',
# 'shot_body_part_name']].astype('category')
X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']] = X_new[['shot_first_time',
'shot_one_on_one',
'shot_aerial_won',
'shot_open_goal',
'shot_follows_dribble',
'shot_redirect']].astype(int)
print(X_new)
print(X_new.dtypes)
return model.predict_proba(X_new)[0][1].round(3)
#XgBoost_2
def xgboost_predict_proba_v2(shooter,goalkeeper,teamMatesList,opponentsList, minute,position_name,shot_body_part_name,
shot_technique_name,shot_type_name,shot_first_time,shot_aerial_won,shot_open_goal,
shot_follows_dribble,shot_redirect):
model = load('xgboost.joblib')
X_new = pd.DataFrame(columns=['minute', 'position_name', 'shot_body_part_name',
'shot_technique_name','shot_type_name', 'shot_first_time',
'shot_one_on_one','shot_aerial_won',
'shot_open_goal','shot_follows_dribble', 'shot_redirect',
'x1', 'y1','number_of_players_opponents',
'number_of_players_teammates','angle', 'distance',
'x_player_opponent_Goalkeeper', 'x_player_opponent_8',
'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3',
'x_player_opponent_4','x_player_opponent_5', 'x_player_opponent_6',
'x_player_teammate_2','x_player_opponent_9', 'x_player_opponent_10',
'x_player_opponent_11','x_player_teammate_1',
'x_player_teammate_3', 'x_player_teammate_4','x_player_teammate_5',
'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8',
'x_player_teammate_9', 'x_player_teammate_10',
'y_player_opponent_Goalkeeper', 'y_player_opponent_8',
'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3',
'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5',
'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9',
'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3',
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper'])
shooter = konwertujDoListy(shooter)
teamMatesList = konwertujDoListy(teamMatesList)
opponentsList = konwertujDoListy(opponentsList)
goalkeeper = konwertujDoListy(goalkeeper)
# obliczenie katu oraz odleglosci
angle = loc2angle(x = shooter[0], y = shooter[1])
print("kat: " + str(angle))
distance = loc2distance(x = shooter[0], y = shooter[1])
print("dystans: " + str(distance))
#Sortowanie list zawodnikow
teamMatesList = sortNearestToShooter(teamMatesList,shooter= shooter)
opponentsList = sortNearestToShooter(opponentsList, shooter=shooter)
# Obliczenie ilosci zawosników
teamMatesList = zmienWMaciez(teamMatesList)
opponentsList = zmienWMaciez(opponentsList)
# DO ROZBUDOWY
number_of_players_opponents = 3
number_of_players_teammates = 3
# Bramkarz
x_player_opponent_Goalkeeper = goalkeeper[0]
y_player_opponent_Goalkeeper = goalkeeper[1]
# Uproszczona funkcja trzeba rozbudowac
shot_one_on_one = True if number_of_players_opponents == 1 else False
# TeamMate goalkeppe
x_player_teammate_Goalkeeper = np.nan
y_player_teammate_Goalkeeper = np.nan
#Reszta Zawodnikow
X_new.loc[len(X_new.index)] = [minute, position_name, shot_body_part_name,
shot_technique_name,shot_type_name, shot_first_time,
shot_one_on_one,shot_aerial_won,
shot_open_goal,shot_follows_dribble, shot_redirect,
shooter[0], shooter[1],number_of_players_opponents,
number_of_players_teammates,angle, distance,
x_player_opponent_Goalkeeper, opponentsList[8][0],
opponentsList[0][0], opponentsList[1][0], opponentsList[2][0],
opponentsList[3][0], opponentsList[4][0], opponentsList[5][0],
opponentsList[6][0], opponentsList[7][0], teamMatesList[8][0],
opponentsList[9][0], opponentsList[10][0],
teamMatesList[0][0], teamMatesList[1][0], teamMatesList[2][0],
teamMatesList[3][0], teamMatesList[4][0], teamMatesList[5][0],
teamMatesList[6][0], teamMatesList[7][0],teamMatesList[8][0],
teamMatesList[9][0],
y_player_opponent_Goalkeeper,
opponentsList[0][1], opponentsList[1][1], opponentsList[2][1],
opponentsList[3][1], opponentsList[4][1],opponentsList[5][1],
opponentsList[6][1], opponentsList[7][1], opponentsList[8][1],
opponentsList[9][1], opponentsList[10][1],
teamMatesList[0][1],teamMatesList[1][1], teamMatesList[2][1],
teamMatesList[4][1],teamMatesList[5][1], teamMatesList[6][1], teamMatesList[7][1],
teamMatesList[8][1], teamMatesList[9][1],
x_player_teammate_Goalkeeper, y_player_teammate_Goalkeeper]
categorical_columns = ['position_name', 'shot_technique_name', 'shot_type_name', 'number_of_players_opponents', 'number_of_players_teammates', 'shot_body_part_name'] # list all your object columns here
# X_new = pd.get_dummies(X_new, columns=categorical_columns)
X_new[categorical_columns] = X_new[categorical_columns].astype('category')
return model.predict_proba(X_new)[0][1].round(2)
# Pomocnicze Funkcje
# trzeba uzupelnic
def sortNearestToShooter(playerList, shooter):
return playerList
def loc2distance(x, y):
return math.sqrt(x**2 + (y - 34)**2)
def loc2locdistance(x1, y1, x2, y2):
return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)
def loc2angle(x, y):
rads = math.atan(7.32 * x / (x**2 + (y - 34)**2 - (7.32/2)**2))
rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads)
return deg
# zamiana stringa odzielonego ',' na liste
def konwertujDoListy(listaString):
listaString = listaString.split(",")
listaFloat = []
for elem in listaString:
listaFloat.append(float(elem))
return listaFloat
#Zamiana listy w formie [1x,1y,2x,2y,3x,3y...] do postaci maciezy [xi, yi]
def zmienWMaciez(lista):
maciez = []
for i in range(0,len(lista),2):
player = [lista[i],lista[i+1]]
maciez.append(player)
if(len(maciez) < 10):
for i in range(len(maciez),11,1):
maciez.append([np.nan,np.nan])
return maciez
#kolejne modele

View File

@ -1,48 +0,0 @@
from modele import zmienWMaciez,xgboost_predict_proba_v2,konwertujDoListy
#zmien maciez test
'''
lista = [2,3,43,12,323,12,23,43,54,90]
print(zmienWMaciez(lista))
lista = zmienWMaciez(lista)
print(lista[3][0])
print(lista[3][1])
print(lista[0][0])
'''
'''
string = "49.27,49.73,48.49,34.75,19.95,28.44"
string = konwertujDoListy(string)
print(string)
print(string[3])
string = zmienWMaciez(string)
print(string)
'''
'''
a = ['minute', 'position_name', 'shot_body_part_name', 'shot_technique_name',
'shot_type_name', 'shot_first_time', 'shot_one_on_one',
'shot_aerial_won', 'shot_deflected', 'shot_open_goal',
'shot_follows_dribble', 'shot_redirect', 'x1', 'y1',
'number_of_players_opponents', 'number_of_players_teammates',
'angle', 'distance', 'x_player_opponent_Goalkeeper',
'x_player_opponent_1', 'x_player_opponent_2','x_player_opponent_3', 'x_player_opponent_4',
'x_player_opponent_5', 'x_player_opponent_6', 'x_player_teammate_2',
'x_player_opponent_9', 'x_player_opponent_10', 'x_player_opponent_11','x_player_teammate_1'
'x_player_teammate_3', 'x_player_teammate_4', 'x_player_teammate_5',
'x_player_teammate_6', 'x_player_teammate_7', 'x_player_teammate_8',
'x_player_teammate_9', 'x_player_teammate_10',
'y_player_opponent_Goalkeeper', 'y_player_opponent_8',
'y_player_opponent_1', 'y_player_opponent_2', 'y_player_opponent_3',
'y_player_teammate_1', 'y_player_opponent_4', 'y_player_opponent_5',
'y_player_opponent_6', 'y_player_teammate_2', 'y_player_opponent_9',
'y_player_opponent_10', 'y_player_opponent_11', 'y_player_teammate_3',
'y_player_teammate_4', 'y_player_teammate_5', 'y_player_teammate_6',
'y_player_teammate_7', 'y_player_teammate_8', 'y_player_teammate_9',
'y_player_teammate_10', 'x_player_opponent_7', 'y_player_opponent_7',
'x_player_teammate_Goalkeeper', 'y_player_teammate_Goalkeeper',
'shot_kick_off']
print(len(a))
'''

View File

@ -1,286 +1,37 @@
from flask import Flask, request, jsonify
from flask import Flask
from flask_cors import CORS
from modele.modele import LogisticRegression_predict_proba, xgboost_predict_proba, xgboost_predict_proba_v2
import numpy as np
import math
from modele.modele import LogisticRegression_predict_proba
app = Flask(__name__)
CORS(app)
app.config['CORS_HEADERS'] = 'Content-Type'
# model Api
@app.route("/members")
def members():
return{"members":["Member1","Member2","Member3"]}
# zapytanie o regresje logistyczną na podstawie pozycji piłki
# @app.route("/LRegresion<x>&<y>")
@app.route("/get_model", methods = ['GET'])
def get_model():
# Pozycja strzelca
shooter = request.args.get('shooter')
print("wprowadzone dane:")
print("strzelec: " + shooter)
@app.route("/LRegresion<x>&<y>")
def LRegresion(x,y):
if shooter[0] is None and shooter[1] is None:
return jsonify({"error": "Brak wymaganych parametrów"}), 400
# Elementy z list: czesc ciała,rodzaj uderzenia,pozycja strzelca oraz typ akcji
x = int(x[0:2])
y = int(y[0:2])
body_part = request.args.get('bodyPart')
technique = request.args.get('technique')
acionType = request.args.get('actionType')
minute = request.args.get('gameMinute')
position_name = request.args.get('shooterPossition')
gameMinute = request.args.get('gameMinute')
shot_first_time = request.args.get('shot_first_time')
shot_one_on_one = request.args.get('shot_one_on_one')
shot_aerial_won = request.args.get('shot_aerial_won')
shot_open_goal = request.args.get('shot_open_goal')
shot_follows_dribble = request.args.get('shot_follows_dribble')
shot_redirect = request.args.get('shot_redirect')
shooter_x, shooter_y = shooter.split(',')
shooter_x = float(shooter_x)
shooter_y = float(shooter_y)
print("minuta: ", minute)
print("pozycja x1 strzelca: ", shooter_x)
print("pozycja y1 strzelca: ", shooter_y)
print("czesc ciala: " + body_part)
print("technika: " + technique)
print("typ akcji: " + acionType)
# lista atakujacy oraz obroncy
def konwertujDoListy(listaString):
listaString = listaString.split(",")
listaFloat = []
for elem in listaString:
listaFloat.append(float(elem))
return listaFloat
def zmienWMaciez(lista):
maciez = []
for i in range(0,len(lista),2):
player = [float(lista[i]),float(lista[i+1])]
maciez.append(player)
if(len(maciez) < 10):
for i in range(len(maciez),11,1):
maciez.append([np.nan,np.nan])
return maciez
obroncy = request.args.get('defenders')
atakujacy = request.args.get('strickers')
print("wspolrzedne obroncow: ", obroncy)
if obroncy == "":
obroncy_macierz = [[np.nan, np.nan]]
else:
obroncy_lista = konwertujDoListy(obroncy)
obroncy_macierz = zmienWMaciez(obroncy_lista)
if atakujacy == "":
atakujacy_macierz = [[np.nan, np.nan]]
else:
atakujacy_lista = konwertujDoListy(atakujacy)
atakujacy_macierz = zmienWMaciez(atakujacy_lista)
if gameMinute == "":
gameMinute = 1.0 # to change
print("wspolrzedne obroncow: ", obroncy)
print("wspolrzedne atakujacych: ", atakujacy)
def euclidean_distance(point1, point2):
"""Calculate the Euclidean distance between two points."""
return math.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2)
def sort_coordinates_by_distance(coordinates, reference_point):
"""Sort a list of coordinates based on Euclidean distance from a reference point.
Coordinates with NaN values are placed at the end of the list.
"""
def distance_or_inf(coord):
"""Helper function to handle coordinates with NaN values."""
if hasattr(coord, '__iter__') and len(coord) >= 2:
if np.isnan(coord[0]) or np.isnan(coord[1]):
return float('inf') # Set distance to infinity for NaN coordinates
return euclidean_distance(coord, reference_point)
return float('inf') # Set distance to infinity for non-iterable coordinates
sorted_coordinates = sorted(coordinates, key=distance_or_inf)
if(len(sorted_coordinates) < 10):
for i in range(len(sorted_coordinates),11,1):
sorted_coordinates.append([np.nan,np.nan])
return sorted_coordinates
# POSORTOWANI OBRONCY I ATAKUJACY
posortowani_obroncy = sort_coordinates_by_distance(obroncy_macierz, [shooter_x, shooter_y])
posortowani_atakujacy = sort_coordinates_by_distance(atakujacy_macierz, [shooter_x, shooter_y])
print("Posortowani obroncy: ", posortowani_obroncy)
print("Posortowani atakujacy: ", posortowani_atakujacy)
number_of_players_opponents = float(np.sum(~np.isnan(posortowani_obroncy).all(axis=1)))
number_of_players_teammates = float(np.sum(~np.isnan(posortowani_atakujacy).all(axis=1)))
print("Liczba obroncow:", number_of_players_opponents)
print("Liczba atakujacych:", number_of_players_teammates)
## add angle, match minutes and number of players
def loc2angle(x, y):
rads = math.atan(7.32 * x / (x**2 + (y - 34)**2 - (7.32/2)**2))
rads = math.pi + rads if rads < 0 else rads
deg = math.degrees(rads)
return deg
def loc2distance(x, y):
return math.sqrt(x**2 + (y - 34)**2)
angle = loc2angle(x = shooter_x, y = shooter_y)
dist = loc2distance(x = shooter_x, y = shooter_y)
# BRAMKARZ
goalkepper = request.args.get('goalkeeper')
if goalkepper == "null":
goalkepper_x, goalkepper_y = np.nan, np.nan
else:
goalkepper_x, goalkepper_y = goalkepper.split(',')
goalkepper_x = float(goalkepper_x)
goalkepper_y = float(goalkepper_y)
print("bramkarz:", goalkepper_x, goalkepper_y)
if shot_first_time == 'true':
shot_first_time = True
else:
shot_first_time = False
if shot_one_on_one == 'true':
shot_one_on_one = True
else:
shot_one_on_one = False
if shot_aerial_won == 'true':
shot_aerial_won = True
else:
shot_aerial_won = False
if shot_open_goal == 'true':
shot_open_goal = True
else:
shot_open_goal = False
if shot_follows_dribble == 'true':
shot_follows_dribble = True
else:
shot_follows_dribble = False
if shot_redirect == 'true':
shot_redirect = True
else:
shot_redirect = False
#### CHECKLIST
print('CHECKLISTA')
print('shot_first_time', shot_first_time)
print('shot_one_on_one', shot_one_on_one)
print('shot_aerial_won', shot_aerial_won)
print('shot_open_goal', shot_open_goal)
print('shot_follows_dribble', shot_follows_dribble)
print('shot_redirect', shot_redirect)
# MODEL XGBOOST
response = xgboost_predict_proba(minute=int(gameMinute), #minute=0,
position_name=position_name,
shot_body_part_name=body_part,
shot_technique_name=technique,
shot_type_name=acionType,
shot_first_time=shot_first_time,
shot_one_on_one=shot_one_on_one,
shot_aerial_won=shot_aerial_won,
shot_open_goal=shot_open_goal,
shot_follows_dribble=shot_follows_dribble,
shot_redirect=shot_redirect,
x1=shooter_x, y1=shooter_y,
number_of_players_opponents=number_of_players_opponents,
number_of_players_teammates=number_of_players_teammates,
angle=angle, distance=dist,
x_player_opponent_Goalkeeper=goalkepper_x, y_player_opponent_Goalkeeper=goalkepper_y,
x_player_opponent_1=posortowani_obroncy[0][0], y_player_opponent_1=posortowani_obroncy[0][1],
x_player_opponent_2=posortowani_obroncy[1][0], y_player_opponent_2=posortowani_obroncy[1][1],
x_player_opponent_3=posortowani_obroncy[2][0], y_player_opponent_3=posortowani_obroncy[2][1],
x_player_opponent_4=posortowani_obroncy[3][0], y_player_opponent_4=posortowani_obroncy[3][1],
x_player_opponent_5=posortowani_obroncy[4][0], y_player_opponent_5=posortowani_obroncy[4][1],
x_player_opponent_6=posortowani_obroncy[5][0], y_player_opponent_6=posortowani_obroncy[5][1],
x_player_opponent_7=posortowani_obroncy[6][0], y_player_opponent_7=posortowani_obroncy[6][1],
x_player_opponent_8=posortowani_obroncy[7][0], y_player_opponent_8=posortowani_obroncy[7][1],
x_player_opponent_9=posortowani_obroncy[8][0], y_player_opponent_9=posortowani_obroncy[8][1],
x_player_opponent_10=posortowani_obroncy[9][0], y_player_opponent_10=posortowani_obroncy[9][1],
x_player_teammate_Goalkeeper=np.nan, y_player_teammate_Goalkeeper=np.nan,
x_player_teammate_1=posortowani_atakujacy[0][0], y_player_teammate_1=posortowani_atakujacy[0][1],
x_player_teammate_2=posortowani_atakujacy[1][0], y_player_teammate_2=posortowani_atakujacy[1][1],
x_player_teammate_3=posortowani_atakujacy[2][0], y_player_teammate_3=posortowani_atakujacy[2][1],
x_player_teammate_4=posortowani_atakujacy[3][0], y_player_teammate_4=posortowani_atakujacy[3][1],
x_player_teammate_5=posortowani_atakujacy[4][0], y_player_teammate_5=posortowani_atakujacy[4][1],
x_player_teammate_6=posortowani_atakujacy[5][0], y_player_teammate_6=posortowani_atakujacy[5][1],
x_player_teammate_7=posortowani_atakujacy[6][0], y_player_teammate_7=posortowani_atakujacy[6][1],
x_player_teammate_8=posortowani_atakujacy[7][0], y_player_teammate_8=posortowani_atakujacy[7][1],
x_player_teammate_9=posortowani_atakujacy[8][0], y_player_teammate_9=posortowani_atakujacy[8][1],
x_player_teammate_10=posortowani_atakujacy[9][0], y_player_teammate_10=posortowani_atakujacy[9][1])
# response = xgboost_predict_proba(shooter = shooter,
# opponentsList = opponentsList, teamMatesList = teamMatesList, minute = 20, position_name = position_name, shot_body_part_name = body_part, shot_technique_name = technique,
# shot_type_name = acionType, shot_first_time = False,
# shot_aerial_won = False, shot_deflected = False, shot_open_goal = False,
# shot_follows_dribble = False, shot_redirect = False, shot_kick_off = False, goalkeeper= goalkepper
# )
#print(response)
res = str(response)
#return {"response":res}
return jsonify({"response":res})
""""
def get_model():
# x = int(x[0:2])
# y = int(y[0:2])
shooter = request.args.get('shooter')
shooter = konwertujDoListy(shooter)
print("wprowadzone dane:")
print("x strzelca: " + str(shooter[0]))
print("y strzelca: " + str(shooter[1]))
## change model on xgboost
## add angle, match minutes and number of players
angle = loc2angle(x = shooter[0], y = shooter[1])
dist = loc2distance(x = shooter[0], y = shooter[1])
if shooter[0] is None and shooter[1] is None:
return jsonify({"error": "Brak wymaganych parametrów"}), 400
response = LogisticRegression_predict_proba(position_x=shooter[0],
position_y=shooter[1],
distance_to_goalM = dist,
angle = angle,
response = LogisticRegression_predict_proba(position_x=x,
position_y=y,
angle = 13.67,
match_minute=13,
Number_Intervening_Opponents=3,
Number_Intervening_Teammates=0,
isFoot=1,
isHead=0)
print(x)
print(y)
print(response)
return {"response":[str(response)]}
#print(response)
res = str(response)
#return {"response":res}
return jsonify({"response":res})
# uruchomienie serwera
"""
if __name__ == "__main__":
app.run(debug = True)

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -4,55 +4,20 @@
@tailwind components;
@tailwind utilities;
.Ex {
display: block; /* Może być inline-block, jeśli preferujesz */
margin: 20px auto; /* Centralnie i z marginesem */
padding: 10px;
background-color: #4CAF50; /* Przykładowy kolor tła */
color: white; /* Kolor tekstu */
text-align: center;
border-radius: 5px; /* Lekko zaokrąglone rogi */
font-size: 20px; /* Duża, czytelna czcionka */
font-weight: bold; /* Pogrubienie dla lepszej widoczności */
width: 100%; /* Poszerzone pole */
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.5); /* Cień dla dodatkowej głębi */
/* Opcjonalnie, można dodać gradient tła dla większego efektu */
background-image: linear-gradient(to right, #32CD32 , #4CAF50);
transition: transform 0.3s ease; /* Delikatna animacja */
}
.Ex:hover {
transform: scale(1.10); /* Efekt powiększenia przy najechaniu */
}
.xg-meter {
width: 200px;
height: 100px; /* Zmiana wysokości, aby pasowała do proporcji bramki */
display: flex;
align-items: center;
justify-content: center;
text-align: center;
color: white;
font-size: 48px;
font-weight: bold;
background: url('assets/bramka.jpeg') no-repeat center center; /* Tło z obrazem bramki */
background-size: cover; /* Dopasowanie obrazu do rozmiaru elementu */
border-radius: 10px; /* Opcjonalnie, dla zaokrąglonych rogów */
}
.xg-value {
display: block;
background: rgba(0, 0, 0, 0.5); /* Półprzezroczyste tło dla lepszej czytelności tekstu */
padding: 5px 10px; /* Dodanie odstępu */
border-radius: 5px; /* Zaokrąglone rogi dla tekstu */
}
/* Funkcja JavaScript będzie sterować stopniem gradientu */
.Ex{
display: block; /* Może być inline-block, jeśli preferujesz */
margin: 20px auto; /* Centralnie i z marginesem */
padding: 10px;
background-color: #4CAF50; /* Przykładowy kolor tła */
color: white; /* Kolor tekstu */
text-align: center;
border-radius: 5px; /* Lekko zaokrąglone rogi */
font-size: 20px; /* Duża, czytelna czcionka */
font-weight: bold; /* Pogrubienie dla lepszej widoczności */
width: 50%; /* Dostosuj szerokość zgodnie z potrzebami */
/* Dodatkowe style, takie jak cienie, mogą być dodane */
}
body {
margin: 50px;
display: grid;
@ -61,67 +26,42 @@
grid-template-rows: auto;
grid-template-columns: auto auto auto;
}
.container {
display: flex;
flex-direction: column;
align-items: baseline;
justify-content: space-between;
align-items: center;
justify-content: space-between;
position: relative;
font-size: 7px;
margin: 5px;
margin-top: 5vh ;
width: 100%;
margin: 50 px;
}
.field-pic{
content:url(assets/bojo.png);
height: inherit;
width: inherit;
}
.field-pic img{
max-width: 100%;
max-height: 100%;
}
.container span {
display: block;
}
.main-content {
display: flex;
justify-content: space-between;
align-items: center;
}
.player{
width: inherit;
height: 8vh;
background-color: rgb(16, 46, 29);
--line: 0.3em solid white;
border: var(--line);
}
.main-content {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
}
.field {
--line: 0.3em solid white;
border: var(--line);
position: relative;
overflow: hidden;
width: 50vw;
height: calc(50vw*68/105);
width: inherit;
height: inherit;
z-index: 1;
margin: 0;
background-image: url("img_tree.gif");
background-color: #cccccc;
background-color:green;
width: 120em;
height: 80em;
justify-content: space-between;
}
.subMenu {
display: grid;
grid-template-rows: auto auto auto;
@ -132,41 +72,153 @@
background-color: #f0f0f0; /* Example background color */
z-index: 1000; /* Ensure it stays on top of other content */
}
.player-list {
background-color: rgb(61, 38, 38);
width: 13vw;
height: calc(50vw*68/105);
overflow: scroll;
font-size: 12px; /* Example font size - adjust as needed */
}
.top-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
width: 60vw; /* Dostosuj szerokość zgodnie z potrzebami */
width: 100%; /* Dostosuj szerokość zgodnie z potrzebami */
/* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */
z-index: 2;
}
.bottom-bar {
display: flex;
justify-content: space-between; /* Rozmieszcza przyciski równomiernie */
align-items: center;
padding: 10px;
width: 50vw; /* Dostosuj szerokość zgodnie z potrzebami */
width: 100%; /* Dostosuj szerokość zgodnie z potrzebami */
/* Możesz dodać dodatkowe style, jak tło, obramowanie itp. */
}
.halfway-line {
width: 60em;
height: 80em;
border-right: var(--line);
}
.centre-circle,
.penalty-arc {
width: 20em;
height: 20em;
border: var(--line);
border-radius: 50%;
position: absolute;
top: 30em;
}
.centre-circle {
left: calc((120em - 20em - 0.3em) / 2);
}
.centre-mark {
width: 2em;
height: 2em;
background-color: white;
border-radius: 50%;
position: absolute;
top: calc(80em / 2 - 1em);
left: calc(120em / 2 - 1em + 0.3em / 2);
}
.penalty-mark {
width: 2em;
height: 2em;
background-color: white;
border-radius: 50%;
position: absolute;
top: calc(80em / 2 - 1em);
left: calc(12em - 2em / 2);
}
.penalty-area {
width: 18em;
height: 44em;
border: var(--line);
position: absolute;
top: calc((80em - 44em) / 2);
left: -0.3em;
background-color: green;
}
.penalty-arc {
left: calc(12em - 20em / 2);
z-index: -1;
}
.goal-area {
width: 6em;
height: 20em;
border: var(--line);
position: absolute;
top: calc((80em - 20em) / 2);
left: -0.3em;
}
.corner-arc {
border: 1px solid blue;
position: absolute;
}
.corner-arc::after,
.corner-arc::before {
content: '';
position: absolute;
width: 5em;
height: 5em;
border: 0.3em solid white;
border-radius: 50%;
}
.corner-arc::before {
top: 0;
left: 0;
}
.corner-arc::after {
bottom: 0;
right: 0;
}
.right {
position: absolute;
top: 0px;
left: 50%;
transform: rotateY(180deg);
}
.football {
width: 2em;
height: 2em;
background-color: black;
border-radius: 50%;
position: absolute
position: absolute;
}
.defender{
width: 2em;
height: 2em;
background-color: red;
border-radius: 50%;
position: absolute;
}
.striker{
width: 2em;
height: 2em;
background-color: blue;
border-radius: 50%;
position: absolute;
}
.goalkeeper{
width: 2em;
height: 2em;
background-color: yellow;
border-radius: 50%;
position: absolute;
}
.reset-button {
position: relative;
margin: 5px;
@ -238,7 +290,7 @@
color: #000000;
font-size: 16px;
}
.cho-first_time {
position: relative;
padding: 10px;
@ -275,38 +327,7 @@
color: #000000;
font-size: 16px;
}
.additional-parameters {
position: relative; /* Or absolute, depending on layout */
right: 0;
top: 30%; /* Adjusted to a higher position */
width: 250px; /* Increased width */
background-color: #000000;
padding: 15px; /* Increased padding */
border: 1px solid #ddd;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
z-index: 100; /* To ensure it stays on top */
color: #ffffff; /* Optional: change text color for better visibility on dark background */
}
.additional-parameters h3 {
margin-top: 0;
font-size: 18px; /* Increased font size for heading */
}
.additional-parameters label {
display: flex; /* Updated to flex for better alignment */
align-items: center; /* Aligns checkbox and label text vertically */
margin-bottom: 10px; /* Increased spacing between checkboxes */
font-size: 16px; /* Increased font size for labels */
}
.additional-parameters input[type="checkbox"] {
margin-right: 10px; /* Adds spacing between checkbox and label text */
}
/* DROPDOWNS */
/* Style the dropdown button */
.dropbtn {
@ -322,13 +343,13 @@
.dropbtn:hover, .dropbtn:focus {
background-color: #3e8e41;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
}
.cho-dropdown_body_part {
display: none;
position: absolute;
@ -337,7 +358,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.cho-dropdown_body_part a{
color: black;
padding: 12px 16px;
@ -345,15 +366,15 @@
display: block;
font-size: 16px;
}
/* Change color of dropdown links on hover */
.cho-dropdown_body_part a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_body_part {
display: block;
}
.cho-dropdown_position_name {
display: none;
position: absolute;
@ -362,7 +383,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.cho-dropdown_position_name a {
color: black;
padding: 12px 16px;
@ -370,15 +391,15 @@
display: block;
font-size: 16px;
}
/* Change color of dropdown links on hover */
.cho-dropdown_position_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_position_name {
display: block;
}
.cho-dropdown_technique_name {
position: relative;
display: none;
@ -388,7 +409,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.cho-dropdown_technique_name a {
color: black;
padding: 12px 16px;
@ -396,15 +417,15 @@
display: block;
font-size: 16px;
}
/* Change color of dropdown links on hover */
.cho-dropdown_technique_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_technique_name {
display: block;
}
.cho-dropdown_type_name {
display: none;
position: absolute;
@ -413,7 +434,7 @@
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.cho-dropdown_type_name a {
color: black;
padding: 12px 16px;
@ -421,16 +442,16 @@
display: block;
font-size: 16px;
}
/* Change color of dropdown links on hover */
.cho-dropdown_type_name a:hover {background-color: #f1f1f1}
/* Show the dropdown menu on hover */
.dropdown:hover .cho-dropdown_type_name {
display: block;
}
/* MANUAL INPUT */
.cho-minute {
margin-top: 10px;
@ -643,5 +664,5 @@
-2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
}
}

BIN
data/.DS_Store vendored

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

BIN
notebooks/.DS_Store vendored

Binary file not shown.

View File

@ -11,33 +11,33 @@ library(purrr)
# code and data from https://github.com/Dato-Futbol/xg-model
get_shots <- function(file_path, name_detail, save_files = F){
players <- fromJSON("data/players.json")
shots <- fromJSON(file_path) %>%
filter(subEventName == "Shot")
tags <- tibble(tags = shots$tags) %>%
hoist(tags,
hoist(tags,
tags_id = "id") %>%
unnest_wider(tags_id, names_sep = "")
tags2 <- tags %>%
mutate(is_goal = ifelse(rowSums(. == "101", na.rm = T) > 0, 1, 0),
is_blocked = ifelse(rowSums(. == "2101", na.rm = T) > 0, 1, 0),
is_CA = ifelse(rowSums(. == "1901", na.rm = T) > 0, 1, 0), # is countre attack
body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
body_part = ifelse(rowSums(. == "401", na.rm = T) > 0, "left",
ifelse(rowSums(. == "402", na.rm = T) > 0, "right",
ifelse(rowSums(. == "403", na.rm = T) > 0, "head/body", "NA"))))
pos <- tibble(positions = shots$positions) %>%
hoist(positions,
hoist(positions,
y = "y",
x = "x") %>%
unnest_wider(y, names_sep = "") %>%
unnest_wider(x, names_sep = "") %>%
dplyr::select(-c(x2, y2))
shots_ok <- shots %>%
dplyr::select(matchId, teamId, playerId, eventSec, matchPeriod) %>%
bind_cols(pos, tags2) %>%
@ -46,14 +46,14 @@ get_shots <- function(file_path, name_detail, save_files = F){
left_join(players %>%
dplyr::select(c("wyId", "foot")), by = c("playerId" = "wyId")) %>%
mutate(league = name_detail)
if(save_files){
write_rds(shots, paste0("shots", name_detail, ".rds"))
write_rds(tags2, paste0("tags2", name_detail, ".rds"))
write_rds(pos, paste0("pos", name_detail, ".rds"))
write_rds(shots_ok, paste0("unblocked_shots", name_detail, ".rds"))
}
shots_ok
}
# shotsEN <- get_shots("data/events/events_England.json", "EN")
@ -63,12 +63,12 @@ get_shots <- function(file_path, name_detail, save_files = F){
# shotsGE <- get_shots("data/events/events_Germany.json", "GE")
# shotsFR <- get_shots("data/events/events_France.json", "FR")
# shotsEC <- get_shots("data/events/events_European_Championship.json", "EC")
#
#
# shots <- shotsEN %>%
# bind_rows(shotsFR, shotsGE, shotsIT, shotsSP, shotsWC, shotsEC)
get_final_data <- function(data) {
data <- data %>% select(eventSec, y1, x1, is_goal, is_blocked, is_CA, body_part, foot)
data$x1 <- (100 - data$x1) * 105/100
data$y1 <- data$y1 * data$y1/100
@ -77,7 +77,7 @@ get_final_data <- function(data) {
data <- data %>% mutate(distance = sqrt( (100 - x1)^2 + (34 - y1)^2),
minute = round(eventSec / 60),
eventSec = round(eventSec))
data
}
@ -89,14 +89,14 @@ get_final_data <- function(data) {
get_data <- function(event_path, info_path) {
events <- read.csv(event_path)
info <- read.csv(info_path)
events <- merge(events, info[, c('id_odsp', 'country', 'date')], by = 'id_odsp', all.x = TRUE)
data <- subset(events, event_type == 1)
data_final <- data %>% select(sort_order, time, shot_place, shot_outcome, is_goal, location, bodypart, assist_method, situation,
fast_break)
data_final
}
# data2 <- get_data(event_path = "data/events.csv", info_path = "data/ginf.csv")
@ -114,7 +114,7 @@ loc2angle <- function(x, y) {
# distance to goal
loc2distance <- function(x, y) {
sqrt(x^2 + (y - 34)^2)
sqrt(x^2 + y^2)
}
# distance between two points on the pitch
@ -124,18 +124,18 @@ loc2locdistance <- function(x1, y1, x2, y2) {
get_shots2 <- function(json_file) {
data <- fromJSON(json_file) %>% filter(type$name == "Shot") %>% dplyr::select(c(minute, position, location, shot))
df_temp <- do.call(rbind, lapply(data$location, function(loc) c(120, 80) - loc))
colnames(df_temp) <- c("x1", "y1")
data$x1 <- df_temp[,1]
data$y1 <- df_temp[,2]
data$shot$freeze_frame <- Map(function(ff, x1, y1) {
ff$x1 <- yd_to_m(x1)
ff$y1 <- yd_to_m(y1)
return(ff)
},
},
data$shot$freeze_frame, data$x1, data$y1)
tryCatch({
@ -148,17 +148,17 @@ get_shots2 <- function(json_file) {
df <- df %>% mutate(teammate = ifelse(teammate, "teammate", "opponent"),
distance = loc2locdistance(x1 = x, y1 = y, x2 = x1, y2 = y1)) %>%
arrange(distance)
groups_count <- df %>% group_by(teammate) %>% count() %>% as.data.frame()
if ( !("opponent" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "opponent", n = 0)
} else if ( !("teammate" %in% groups_count$teammate) ) {
groups_count <- groups_count %>% add_row(teammate = "teammate", n = 0)
}
na_df <- as.data.frame(matrix("na", nrow = 21 - nrow(df), ncol = ncol(df)))
colnames(na_df) <- colnames(df)
na_df$teammate <- rep(c("opponent", "teammate"), c(11, 10) - groups_count$n)
dff <- rbind(df, na_df)
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number(distance)) %>% ungroup() %>%
@ -170,9 +170,9 @@ get_shots2 <- function(json_file) {
dff <- as.data.frame(matrix("na", nrow = 21, ncol = 3))
colnames(dff) <- c("x", "y", "teammate")
dff$teammate <- rep(c("opponent", "teammate"), c(11, 10))
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
select(-c(teammate, rown)) %>%
dff <- dff %>% group_by(teammate) %>% mutate(rown = row_number()) %>% ungroup() %>%
mutate(position_teammate = paste(teammate, rown, sep = "_")) %>%
select(-c(teammate, rown)) %>%
mutate(x = ifelse(x == "na", NA, x),
y = ifelse(x == "na", NA, y))
}
@ -181,7 +181,7 @@ get_shots2 <- function(json_file) {
# %>%
# stop("123")
wider_df <- dff %>%
pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
pivot_wider(names_from = position_teammate, values_from = c(x, y), names_sep = "_player_") %>%
mutate(across(everything(), as.numeric))
wider_df
# wider_df <- apply(wider_df, MARGIN = 2, unlist)
@ -193,7 +193,7 @@ get_shots2 <- function(json_file) {
print(paste("An error occurred:", e$message))
})
df_players_location <- df_players_location %>% t()
tryCatch({ # TODO reduce error cases
data$number_of_players_opponents <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric
@ -213,12 +213,12 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
tryCatch({ # TODO reduce error cases
data$number_of_players_teammates <- mapply(function(sublist, x1_threshold) {
# Extracting the first location value and converting it to numeric
first_location_values <- sapply(sublist$location, function(loc) as.numeric(loc[1]))
if ("teammate" %in% names(sublist)) {
# Filtering and counting
res <- sum(sublist$teammate & first_location_values > x1_threshold) # error here
@ -233,71 +233,71 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
data$shot <- data$shot %>% select(-freeze_frame, -statsbomb_xg, -key_pass_id)
data$shot$body_part <- data$shot$body_part %>% select(-id)
data$shot$technique <- data$shot$technique %>% select(-id)
data$shot$type <- data$shot$type %>% select(-id)
data$position <- data$position %>% select(-id)
data$shot <- data$shot %>% select(-end_location)
tryCatch({ # TODO reduce error cases
if ("one_on_one" %in% colnames(data$shot)) {
data[is.na(data$shot$one_on_one), ]$shot$one_on_one <- FALSE
} else {
data$shot$one_on_one <- FALSE
}
if ("first_time" %in% colnames(data$shot)) {
data[is.na(data$shot$first_time), ]$shot$first_time <- FALSE
} else {
data$shot$first_time <- FALSE
}
if ("aerial_won" %in% colnames(data$shot)) {
data[is.na(data$shot$aerial_won), ]$shot$aerial_won <- FALSE
} else {
data$shot$aerial_won <- FALSE
}
if ("saved_to_post" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_to_post), ]$shot$saved_to_post <- FALSE
} else {
data$shot$saved_to_post <- FALSE
}
if ("deflected" %in% colnames(data$shot)) {
data[is.na(data$shot$deflected), ]$shot$deflected <- FALSE
} else {
data$shot$deflected <- FALSE
}
if ("saved_off_target" %in% colnames(data$shot)) {
data[is.na(data$shot$saved_off_target), ]$shot$saved_off_target <- FALSE
} else {
data$shot$saved_off_target <- FALSE
}
if ("open_goal" %in% colnames(data$shot)) {
data[is.na(data$shot$open_goal), ]$shot$open_goal <- FALSE
} else {
data$shot$open_goal <- FALSE
}
if ("follows_dribble" %in% colnames(data$shot)) {
data[is.na(data$shot$follows_dribble), ]$shot$follows_dribble <- FALSE
} else {
data$shot$follows_dribble <- FALSE
}
if ("redirect" %in% colnames(data$shot)) {
data[is.na(data$shot$redirect), ]$shot$redirect <- FALSE
} else {
data$shot$redirect <- FALSE
}
if ("kick_off" %in% colnames(data$kick_off)) {
data[is.na(data$shot$kick_off), ]$shotf$kick_off <- FALSE
} else {
@ -308,21 +308,21 @@ get_shots2 <- function(json_file) {
# handle the error
print(paste("An error occurred:", e$message))
})
data <- data %>% mutate(is_goal = ifelse(shot$outcome$id == 97, 1, 0),
x1 = yd_to_m(x1) %>% round(., digits = 1),
y1 = yd_to_m(y1) %>% round(., digits = 1),
angle = loc2angle(x1, y1) %>% round(., digits = 1),
distance = loc2distance(x = x1, y = y1)) %>%
distance = loc2distance(x = x1, y = y1)) %>%
select(-location)
data$shot$outcome <- data$shot$outcome %>% select(-id)
data <- data %>% unnest(shot, names_sep = "_") %>%
unnest(position, names_sep = "_") %>%
unnest(shot_type, names_sep = "_") %>%
data <- data %>% unnest(shot, names_sep = "_") %>%
unnest(position, names_sep = "_") %>%
unnest(shot_type, names_sep = "_") %>%
unnest(shot_outcome, names_sep = "_") %>%
unnest(shot_technique, names_sep = "_") %>%
unnest(shot_technique, names_sep = "_") %>%
unnest(shot_body_part, names_sep = "_")
data <- cbind(data, df_players_location)
data
}
@ -338,12 +338,12 @@ skimr::skim(combined_data)
data3_final <- combined_data %>% select(-c(shot_outcome_name,
shot_saved_off_target,
shot_saved_to_post,
kick_off)) %>%
kick_off)) %>%
mutate(shot_kick_off = ifelse(is.na(shot_kick_off), FALSE, shot_kick_off))
pattern <- "^(x_player_|y_player_).*$"
cols <- names(data3_final)[grepl(pattern, names(data3_final))]
data_final <- data3_final %>% unnest(all_of(cols))
skimr::skim(data_final)
write_csv(data_final, file = "data/final_data.csv")
#df_test <- read.csv("data/final_data.csv", nrows = 10000)
# df_test <- read.csv("data/final_data.csv", nrows = 100)
##################### The fourth dataset ##############################

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long