RubenvanGemeren commited on
Commit
2be0ad4
·
1 Parent(s): 88cd236

Updated ui with new graph

Browse files
Files changed (2) hide show
  1. app.py +75 -69
  2. templates/players.html +112 -36
app.py CHANGED
@@ -16,107 +16,113 @@ except:
16
  project = hopsworks.login()
17
  fs = project.get_feature_store()
18
 
19
- players = fs.get_feature_group("fpl_predictions")
20
 
21
- player_df = players.read()
22
 
23
- player_data = player_df.to_json(orient="records")
24
 
25
- players = json.loads(player_data)
26
 
27
- for player in players:
28
- if player["predicted_score"] != None:
29
- player["predicted_score"] = round(player["predicted_score"])
30
 
31
  # Mock data (replace with actual database query or file read)
32
  sample_players = [
33
  {
34
- "firstname": "Harry",
35
- "lastname": "Kane",
36
- "club": "Tottenham",
37
- "position": "ST",
38
- "points": 100,
39
- "5latestGws": [
40
- {"gameweek": 21, "total_points": 10, "predicted_points": 8},
41
- {"gameweek": 20, "total_points": 7, "predicted_points": 6},
42
- {"gameweek": 19, "total_points": 13, "predicted_points": 10},
43
- {"gameweek": 18, "total_points": 5, "predicted_points": 4},
44
- {"gameweek": 17, "total_points": 11, "predicted_points": 9},
45
  ],
46
- "nextGwPrediction": 7,
47
  },
48
  {
49
- "firstname": "Erling",
50
- "lastname": "Haaland",
51
- "club": "Man City",
52
- "position": "ST",
53
- "points": 120,
54
- "5latestGws": [
55
- {"gameweek": 21, "total_points": 15, "predicted_points": 12},
56
- {"gameweek": 20, "total_points": 9, "predicted_points": 11},
57
- {"gameweek": 19, "total_points": 8, "predicted_points": 10},
58
- {"gameweek": 18, "total_points": 12, "predicted_points": 13},
59
- {"gameweek": 17, "total_points": 14, "predicted_points": 13},
60
  ],
61
- "nextGwPrediction": 8,
62
  },
63
  {
64
- "firstname": "Bukayo",
65
- "lastname": "Saka",
66
- "club": "Arsenal",
67
- "position": "MID",
68
- "points": 80,
69
- "5latestGws": [
70
- {"gameweek": 21, "total_points": 7, "predicted_points": 6},
71
- {"gameweek": 20, "total_points": 6, "predicted_points": 7},
72
- {"gameweek": 19, "total_points": 9, "predicted_points": 8},
73
- {"gameweek": 18, "total_points": 10, "predicted_points": 9},
74
- {"gameweek": 17, "total_points": 8, "predicted_points": 8},
75
  ],
76
- "nextGwPrediction": 6,
77
  },
78
  {
79
- "firstname": "Marcus",
80
- "lastname": "Rashford",
81
- "club": "Man United",
82
- "position": "MID",
83
- "points": 90,
84
- "5latestGws": [
85
- {"gameweek": 21, "total_points": 12, "predicted_points": 10},
86
- {"gameweek": 20, "total_points": 10, "predicted_points": 9},
87
- {"gameweek": 19, "total_points": 11, "predicted_points": 10},
88
- {"gameweek": 18, "total_points": 14, "predicted_points": 12},
89
- {"gameweek": 17, "total_points": 13, "predicted_points": 11},
90
  ],
91
- "nextGwPrediction": 9,
92
  },
93
  {
94
- "firstname": "Mohamed",
95
- "lastname": "Salah",
96
- "club": "Liverpool",
97
- "position": "MID",
98
- "points": 70,
99
- "5latestGws": [
100
- {"gameweek": 21, "total_points": 8, "predicted_points": 7},
101
- {"gameweek": 20, "total_points": 6, "predicted_points": 8},
102
- {"gameweek": 19, "total_points": 7, "predicted_points": 9},
103
- {"gameweek": 18, "total_points": 11, "predicted_points": 10},
104
- {"gameweek": 17, "total_points": 9, "predicted_points": 8},
105
  ],
106
- "nextGwPrediction": 7,
107
  },
108
  ]
109
 
 
 
 
 
 
 
110
 
111
  @app.route("/test")
112
  def test():
113
- return players
114
 
115
 
116
  @app.route("/")
117
  def index():
118
  """Render the main page."""
119
- return render_template("players.html", players=players)
120
 
121
 
122
  @app.route("/api/players", methods=["POST", "GET"])
 
16
  project = hopsworks.login()
17
  fs = project.get_feature_store()
18
 
19
+ # players = fs.get_feature_group("fpl_predictions")
20
 
21
+ # player_df = players.read()
22
 
23
+ # player_data = player_df.to_json(orient="records")
24
 
25
+ # players = json.loads(player_data)
26
 
27
+ # for player in players:
28
+ # if player["predicted_score"] != None:
29
+ # player["predicted_score"] = round(player["predicted_score"])
30
 
31
  # Mock data (replace with actual database query or file read)
32
  sample_players = [
33
  {
34
+ "first_name": "Harry",
35
+ "second_name": "Kane",
36
+ "position": "Midfielder",
37
+ "team": "Tottenham",
38
+ "total_points": 100,
39
+ "latest_predictions": [
40
+ {"gameweek": 21, "total_points": 18, "predicted_points": 15},
41
+ {"gameweek": 20, "total_points": 12, "predicted_points": 8},
42
+ {"gameweek": 19, "total_points": 9, "predicted_points": 5},
43
+ {"gameweek": 18, "total_points": 5, "predicted_points": 7},
44
+ {"gameweek": 17, "total_points": 11, "predicted_points": 7},
45
  ],
46
+ "predicted_score": 7,
47
  },
48
  {
49
+ "first_name": "Harry2",
50
+ "second_name": "Kane2",
51
+ "position": "Midfielder",
52
+ "team": "Tottenham",
53
+ "total_points": 100,
54
+ "latest_predictions": [
55
+ {"gameweek": 21, "total_points": 10, "predicted_points": 8},
56
+ {"gameweek": 20, "total_points": 5, "predicted_points": 8},
57
+ {"gameweek": 19, "total_points": 13, "predicted_points": 15},
58
+ {"gameweek": 18, "total_points": 5, "predicted_points": 7},
59
+ {"gameweek": 17, "total_points": 14, "predicted_points": 18},
60
  ],
61
+ "predicted_score": 7,
62
  },
63
  {
64
+ "first_name": "Harry3",
65
+ "second_name": "Kane3",
66
+ "position": "Midfielder",
67
+ "team": "Tottenham",
68
+ "total_points": 100,
69
+ "latest_predictions": [
70
+ {"gameweek": 21, "total_points": 14, "predicted_points": 11},
71
+ {"gameweek": 20, "total_points": 8, "predicted_points": 4},
72
+ {"gameweek": 19, "total_points": 11, "predicted_points": 7},
73
+ {"gameweek": 18, "total_points": 6, "predicted_points": 8},
74
+ {"gameweek": 17, "total_points": 12, "predicted_points": 9},
75
  ],
76
+ "predicted_score": 7,
77
  },
78
  {
79
+ "first_name": "Harry4",
80
+ "second_name": "Kane4",
81
+ "position": "Midfielder",
82
+ "team": "Tottenham",
83
+ "total_points": 100,
84
+ "latest_predictions": [
85
+ {"gameweek": 21, "total_points": 10, "predicted_points": 8},
86
+ {"gameweek": 20, "total_points": 7, "predicted_points": 6},
87
+ {"gameweek": 19, "total_points": 13, "predicted_points": 10},
88
+ {"gameweek": 18, "total_points": 5, "predicted_points": 4},
89
+ {"gameweek": 17, "total_points": 11, "predicted_points": 9},
90
  ],
91
+ "predicted_score": 7,
92
  },
93
  {
94
+ "first_name": "Harry5",
95
+ "second_name": "Kane5",
96
+ "position": "Midfielder",
97
+ "team": "Tottenham",
98
+ "total_points": 100,
99
+ "latest_predictions": [
100
+ {"gameweek": 21, "total_points": 10, "predicted_points": 8},
101
+ {"gameweek": 20, "total_points": 7, "predicted_points": 6},
102
+ {"gameweek": 19, "total_points": 13, "predicted_points": 10},
103
+ {"gameweek": 18, "total_points": 5, "predicted_points": 4},
104
+ {"gameweek": 17, "total_points": 11, "predicted_points": 9},
105
  ],
106
+ "predicted_score": 7,
107
  },
108
  ]
109
 
110
+ # Format the latest_predictions for each player
111
+ for player in sample_players:
112
+ player["latest_predictions_str"] = ", ".join(
113
+ [f"GW{pred['gameweek']}: {pred['total_points']} pts (Pred: {pred['predicted_points']} pts)" for pred in player["latest_predictions"]]
114
+ )
115
+
116
 
117
  @app.route("/test")
118
  def test():
119
+ return "test"
120
 
121
 
122
  @app.route("/")
123
  def index():
124
  """Render the main page."""
125
+ return render_template("players.html", players=sample_players, current_gameweek=20)
126
 
127
 
128
  @app.route("/api/players", methods=["POST", "GET"])
templates/players.html CHANGED
@@ -3,24 +3,18 @@
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>FPL Player Points</title>
7
  <script src="https://unpkg.com/htmx.org"></script>
8
  <link rel="stylesheet" href="/static/styles.css" />
9
- <!-- Include Bootstrap CSS -->
10
- <link
11
- href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
12
- rel="stylesheet"
13
- />
14
- <!-- Include DataTables CSS -->
15
- <link
16
- href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css"
17
- rel="stylesheet"
18
- />
19
  </head>
20
  <body>
21
  <div class="container">
22
- <h1 class="my-4">FPL Player Points</h1>
23
-
24
  <!-- Player Table -->
25
  <table id="player-table" class="display compact">
26
  <thead class="thead-dark">
@@ -41,40 +35,122 @@
41
  <td>{{ player.team }}</td>
42
  <td>{{ player.total_points }}</td>
43
  <td>
44
- <!-- <table class="inner-table">
45
- <tr>
46
- <th>Gameweek</th>
47
- <th>Points</th>
48
- <th>Predicted Points</th>
49
- </tr>
50
- {% for gw in player['5latestGws'] %}
51
- <tr>
52
- <td>{{ gw['gameweek'] }}</td>
53
- <td>{{ gw['total_points'] }}</td>
54
- <td>{{ gw['predicted_points'] }}</td>
55
- </tr>
56
- {% endfor %}
57
- </table> -->
58
- </td>
59
  <td>{{ player.predicted_score }}</td>
60
  </tr>
61
  {% endfor %}
62
  </tbody>
63
  </table>
 
64
  </div>
65
 
66
  <!-- Include jQuery -->
67
- <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
68
- <!-- Include DataTables JS -->
69
- <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
70
- <!-- Include Bootstrap JS and dependencies -->
71
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
72
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
 
 
 
73
 
74
  <script>
75
- $(document).ready(function() {
76
- $('#player-table').DataTable();
77
- });
78
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  </body>
80
  </html>
 
3
  <head>
4
  <meta charset="UTF-8" />
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>FPL Player Points for week {{ current_gameweek }}</title>
7
  <script src="https://unpkg.com/htmx.org"></script>
8
  <link rel="stylesheet" href="/static/styles.css" />
9
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"/>
10
+ <link rel="stylesheet" href="https://cdn.datatables.net/2.2.0/css/dataTables.dataTables.css" />
11
+ <link rel="stylesheet" href="https://cdn.datatables.net/select/2.1.0/css/select.dataTables.css">
12
+ <link rel="stylesheet" href="https://code.highcharts.com/css/highcharts.css"/>
 
 
 
 
 
 
13
  </head>
14
  <body>
15
  <div class="container">
16
+ <h1 class="my-4" style="padding-bottom: 6%;">FPL Player Points</h1>
17
+ <h2 class="my-4">Gameweek {{ current_gameweek }}</h2>
18
  <!-- Player Table -->
19
  <table id="player-table" class="display compact">
20
  <thead class="thead-dark">
 
35
  <td>{{ player.team }}</td>
36
  <td>{{ player.total_points }}</td>
37
  <td>
38
+ {% for prediction in player.latest_predictions %}
39
+ <div>Gameweek {{ prediction.gameweek }}: {{ prediction.total_points }} points (Predicted: {{ prediction.predicted_points }} points)</div>
40
+ {% endfor %}
41
+ </td>
 
 
 
 
 
 
 
 
 
 
 
42
  <td>{{ player.predicted_score }}</td>
43
  </tr>
44
  {% endfor %}
45
  </tbody>
46
  </table>
47
+ <canvas id="myChart"></canvas>
48
  </div>
49
 
50
  <!-- Include jQuery -->
51
+ <script src="https://code.jquery.com/jquery-3.7.1.js"></script>
52
+ <script src="https://cdn.datatables.net/2.2.0/js/dataTables.js"></script>
 
 
53
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.5.4/dist/umd/popper.min.js"></script>
54
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
55
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
56
+ <script src="https://cdn.datatables.net/select/2.1.0/js/dataTables.select.js"></script>
57
+ <script src="https://cdn.datatables.net/select/2.1.0/js/select.dataTables.js"></script>
58
 
59
  <script>
60
+ $(document).ready(function() {
61
+ const table = new DataTable('#player-table');
62
+
63
+ // Function to generate random colors
64
+ function getRandomColor() {
65
+ const letters = '0123456789ABCDEF';
66
+ let color = '#';
67
+ for (let i = 0; i < 6; i++) {
68
+ color += letters[Math.floor(Math.random() * 16)];
69
+ }
70
+ return color;
71
+ }
72
+
73
+ // Function to generate chart data for a single player
74
+ function generateChart(player) {
75
+ // Extract gameweeks and points data
76
+ const gameweeks = player.latest_predictions.map(prediction => prediction.gameweek);
77
+ const totalPointsData = player.latest_predictions.map(prediction => prediction.total_points);
78
+ const predictedPointsData = player.latest_predictions.map(prediction => prediction.predicted_points);
79
+
80
+ // Prepare datasets for the chart
81
+ const datasets = [
82
+ {
83
+ label: `${player.first_name} ${player.second_name} - Total Points`,
84
+ data: totalPointsData,
85
+ borderColor: getRandomColor(),
86
+ backgroundColor: 'rgba(0, 123, 255, 0.3)', // Transparent fill color
87
+ fill: '+1' // Fill the area between total and predicted points
88
+ },
89
+ {
90
+ label: `${player.first_name} ${player.second_name} - Predicted Points`,
91
+ data: predictedPointsData,
92
+ borderColor: getRandomColor(),
93
+ fill: false // No fill for predicted points line
94
+ }
95
+ ];
96
+
97
+ return { labels: gameweeks, datasets: datasets };
98
+ }
99
+
100
+ // Function to render the chart
101
+ function renderChart(player) {
102
+ const chartData = generateChart(player);
103
+
104
+ // Destroy any existing chart before creating a new one
105
+ if (window.myChart) {
106
+ if (window.myChart instanceof Chart) {
107
+ window.myChart.destroy();
108
+ }
109
+ }
110
+
111
+ // Create a new chart
112
+ const ctx = document.getElementById('myChart').getContext('2d');
113
+ window.myChart = new Chart(ctx, {
114
+ type: 'line',
115
+ data: {
116
+ labels: chartData.labels,
117
+ datasets: chartData.datasets
118
+ },
119
+ options: {
120
+ scales: {
121
+ y: {
122
+ beginAtZero: true
123
+ }
124
+ }
125
+ }
126
+ });
127
+ }
128
+
129
+ // Handle click event on the DataTable rows
130
+ $('#player-table tbody').on('click', 'tr', function() {
131
+ // Get the player's data from the DataTable
132
+ const rowData = table.row(this).data();
133
+
134
+ console.log('Row data:', rowData[0]);
135
+
136
+ // Assuming `playersData` contains all players' data
137
+ const selectedPlayer = playersData.find(player => (player.first_name + " " + player.second_name) === rowData[0]);
138
+
139
+ console.log('Selected player');
140
+ if (selectedPlayer) {
141
+ console.log('Selected player:', selectedPlayer);
142
+ renderChart(selectedPlayer);
143
+ }
144
+ });
145
+
146
+ // Players data injected from the backend
147
+ const playersData = JSON.parse('{{ players | tojson | safe }}');
148
+
149
+ });
150
+ </script>
151
+
152
+
153
+
154
+
155
  </body>
156
  </html>