saq1b commited on
Commit
662a38b
·
verified ·
1 Parent(s): a38e074

Delete templates

Browse files
Files changed (1) hide show
  1. templates/index.html +0 -504
templates/index.html DELETED
@@ -1,504 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Jailbreak Trading Data Analysis</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
9
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/cdn.min.js" defer></script>
10
- <style>
11
- [x-cloak] { display: none !important; }
12
- .chart-container {
13
- position: relative;
14
- height: 300px;
15
- width: 100%;
16
- }
17
- </style>
18
- </head>
19
- <body class="bg-gray-100 dark:bg-gray-900" x-data="{ darkMode: localStorage.getItem('darkMode') === 'true' }"
20
- x-init="$watch('darkMode', val => localStorage.setItem('darkMode', val))"
21
- :class="{ 'dark': darkMode }">
22
-
23
- <div class="min-h-screen dark:text-gray-100">
24
- <!-- Navigation -->
25
- <nav class="bg-white shadow-md dark:bg-gray-800 p-4">
26
- <div class="container mx-auto flex justify-between items-center">
27
- <div class="flex items-center space-x-2">
28
- <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-blue-600 dark:text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
29
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
30
- </svg>
31
- <h1 class="text-xl font-bold">Jailbreak Trading Analytics</h1>
32
- </div>
33
- <div class="flex items-center space-x-4">
34
- <button @click="darkMode = !darkMode" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700">
35
- <svg x-show="!darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
36
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
37
- </svg>
38
- <svg x-show="darkMode" xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
39
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
40
- </svg>
41
- </button>
42
- <a href="https://github.com" target="_blank" class="text-blue-600 dark:text-blue-400 hover:underline">GitHub</a>
43
- </div>
44
- </div>
45
- </nav>
46
-
47
- <!-- Dashboard -->
48
- <div class="container mx-auto px-4 py-6" x-data="dashboard()">
49
- <!-- Stats Overview -->
50
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-6">
51
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition hover:shadow-lg">
52
- <div class="flex items-center justify-between">
53
- <h2 class="text-lg font-semibold">Total Items</h2>
54
- <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-blue-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
55
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10" />
56
- </svg>
57
- </div>
58
- <p class="text-3xl font-bold mt-2" x-text="stats.totalItems">--</p>
59
- </div>
60
-
61
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition hover:shadow-lg">
62
- <div class="flex items-center justify-between">
63
- <h2 class="text-lg font-semibold">Total Trades</h2>
64
- <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
65
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" />
66
- </svg>
67
- </div>
68
- <p class="text-3xl font-bold mt-2" x-text="stats.totalTrades">--</p>
69
- </div>
70
-
71
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition hover:shadow-lg">
72
- <div class="flex items-center justify-between">
73
- <h2 class="text-lg font-semibold">Unique Items</h2>
74
- <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-purple-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
75
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
76
- </svg>
77
- </div>
78
- <p class="text-3xl font-bold mt-2" x-text="stats.totalCirculation">--</p>
79
- </div>
80
-
81
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 transition hover:shadow-lg">
82
- <div class="flex items-center justify-between">
83
- <h2 class="text-lg font-semibold">Avg Demand</h2>
84
- <svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-yellow-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
85
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
86
- </svg>
87
- </div>
88
- <p class="text-3xl font-bold mt-2" x-text="stats.avgDemand">--</p>
89
- </div>
90
- </div>
91
-
92
- <!-- Chart Section -->
93
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
94
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4">
95
- <h2 class="text-lg font-semibold mb-4">Top Items by Demand Multiple</h2>
96
- <div class="chart-container">
97
- <canvas id="demandChart"></canvas>
98
- </div>
99
- </div>
100
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4">
101
- <h2 class="text-lg font-semibold mb-4">Items by Type</h2>
102
- <div class="chart-container">
103
- <canvas id="typeChart"></canvas>
104
- </div>
105
- </div>
106
- </div>
107
-
108
- <!-- Data Table Section -->
109
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md mb-6">
110
- <div class="p-4 border-b dark:border-gray-700">
111
- <div class="flex flex-col md:flex-row md:items-center md:justify-between">
112
- <h2 class="text-lg font-semibold">Jailbreak Trading Data</h2>
113
- <div class="mt-3 md:mt-0 flex flex-col md:flex-row space-y-3 md:space-y-0 md:space-x-3">
114
- <div class="relative">
115
- <input
116
- type="text"
117
- placeholder="Search items..."
118
- class="pl-10 pr-4 py-2 border rounded-lg w-full dark:bg-gray-700 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
119
- x-model="searchQuery"
120
- @input="filterData()"
121
- >
122
- <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 absolute left-3 top-2.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
123
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
124
- </svg>
125
- </div>
126
- <div>
127
- <select
128
- class="py-2 px-3 border rounded-lg w-full dark:bg-gray-700 dark:border-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500"
129
- x-model="selectedType"
130
- @change="filterData()"
131
- >
132
- <option value="">All Types</option>
133
- <template x-for="type in types" :key="type">
134
- <option x-text="type"></option>
135
- </template>
136
- </select>
137
- </div>
138
- </div>
139
- </div>
140
- </div>
141
- <div class="overflow-x-auto" x-show="!loading">
142
- <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
143
- <thead class="bg-gray-50 dark:bg-gray-700">
144
- <tr>
145
- <template x-for="(column, index) in columns" :key="index">
146
- <th
147
- scope="col"
148
- class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600"
149
- @click="sortBy(column.key)"
150
- >
151
- <div class="flex items-center space-x-1">
152
- <span x-text="column.label"></span>
153
- <span class="flex flex-col">
154
- <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" :class="sortColumn === column.key && sortDirection === 'asc' ? 'text-blue-500' : 'text-gray-400'" fill="none" viewBox="0 0 24 24" stroke="currentColor">
155
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
156
- </svg>
157
- <svg xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" :class="sortColumn === column.key && sortDirection === 'desc' ? 'text-blue-500' : 'text-gray-400'" fill="none" viewBox="0 0 24 24" stroke="currentColor">
158
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
159
- </svg>
160
- </span>
161
- </div>
162
- </th>
163
- </template>
164
- </tr>
165
- </thead>
166
- <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
167
- <template x-for="(item, index) in paginatedData" :key="index">
168
- <tr class="hover:bg-gray-50 dark:hover:bg-gray-700">
169
- <td class="px-6 py-4 whitespace-nowrap text-sm font-medium" x-text="item.Name"></td>
170
- <td class="px-6 py-4 whitespace-nowrap text-sm" x-text="item.Type"></td>
171
- <td class="px-6 py-4 whitespace-nowrap text-sm text-right" x-text="formatNumber(item.TimesTraded)"></td>
172
- <td class="px-6 py-4 whitespace-nowrap text-sm text-right" x-text="formatNumber(item.UniqueCirculation)"></td>
173
- <td class="px-6 py-4 whitespace-nowrap text-sm text-right">
174
- <span
175
- class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full"
176
- :class="getDemandClass(item.DemandMultiple)"
177
- x-text="formatDecimal(item.DemandMultiple)"
178
- ></span>
179
- </td>
180
- </tr>
181
- </template>
182
- </tbody>
183
- </table>
184
- </div>
185
-
186
- <!-- Loading Spinner -->
187
- <div class="flex justify-center items-center py-10" x-show="loading">
188
- <svg class="animate-spin h-10 w-10 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
189
- <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
190
- <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
191
- </svg>
192
- </div>
193
-
194
- <!-- Pagination -->
195
- <div class="px-4 py-3 flex items-center justify-between border-t dark:border-gray-700" x-show="!loading">
196
- <div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
197
- <div>
198
- <p class="text-sm text-gray-700 dark:text-gray-300">
199
- Showing <span class="font-medium" x-text="(currentPage - 1) * pageSize + 1"></span> to
200
- <span class="font-medium" x-text="Math.min(currentPage * pageSize, filteredData.length)"></span> of
201
- <span class="font-medium" x-text="filteredData.length"></span> results
202
- </p>
203
- </div>
204
- <div>
205
- <nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
206
- <button
207
- class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-sm font-medium text-gray-500 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600"
208
- :disabled="currentPage === 1"
209
- @click="currentPage--"
210
- :class="{'opacity-50 cursor-not-allowed': currentPage === 1}"
211
- >
212
- <span class="sr-only">Previous</span>
213
- <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
214
- <path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
215
- </svg>
216
- </button>
217
- <template x-for="page in totalPages" :key="page">
218
- <button
219
- class="relative inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-sm font-medium hover:bg-gray-50 dark:hover:bg-gray-600"
220
- :class="{'bg-blue-50 dark:bg-blue-900 text-blue-600 dark:text-blue-300': currentPage === page, 'text-gray-700 dark:text-gray-300': currentPage !== page}"
221
- @click="currentPage = page"
222
- x-text="page"
223
- ></button>
224
- </template>
225
- <button
226
- class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-sm font-medium text-gray-500 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600"
227
- :disabled="currentPage === totalPages"
228
- @click="currentPage++"
229
- :class="{'opacity-50 cursor-not-allowed': currentPage === totalPages}"
230
- >
231
- <span class="sr-only">Next</span>
232
- <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
233
- <path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
234
- </svg>
235
- </button>
236
- </nav>
237
- </div>
238
- </div>
239
- </div>
240
- </div>
241
-
242
- <!-- Analytics Insights -->
243
- <div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6">
244
- <h2 class="text-lg font-semibold mb-4">Data Insights</h2>
245
- <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
246
- <div>
247
- <h3 class="font-medium mb-2">Top Demand Vehicles</h3>
248
- <ul class="space-y-2">
249
- <template x-for="(item, index) in topDemandVehicles.slice(0, 5)" :key="index">
250
- <li class="flex justify-between items-center">
251
- <span x-text="item.Name"></span>
252
- <span class="font-semibold" x-text="formatDecimal(item.DemandMultiple)"></span>
253
- </li>
254
- </template>
255
- </ul>
256
- </div>
257
- <div>
258
- <h3 class="font-medium mb-2">Most Traded Items</h3>
259
- <ul class="space-y-2">
260
- <template x-for="(item, index) in mostTradedItems.slice(0, 5)" :key="index">
261
- <li class="flex justify-between items-center">
262
- <span x-text="item.Name"></span>
263
- <span class="font-semibold" x-text="formatNumber(item.TimesTraded)"></span>
264
- </li>
265
- </template>
266
- </ul>
267
- </div>
268
- </div>
269
- </div>
270
- </div>
271
- </div>
272
-
273
- <script>
274
- function dashboard() {
275
- return {
276
- data: [],
277
- filteredData: [],
278
- loading: true,
279
- columns: [
280
- { key: 'Name', label: 'Item Name' },
281
- { key: 'Type', label: 'Type' },
282
- { key: 'TimesTraded', label: 'Times Traded' },
283
- { key: 'UniqueCirculation', label: 'Circulation' },
284
- { key: 'DemandMultiple', label: 'Demand' }
285
- ],
286
- sortColumn: 'DemandMultiple',
287
- sortDirection: 'desc',
288
- currentPage: 1,
289
- pageSize: 10,
290
- searchQuery: '',
291
- selectedType: '',
292
- types: [],
293
- stats: {
294
- totalItems: 0,
295
- totalTrades: 0,
296
- totalCirculation: 0,
297
- avgDemand: 0
298
- },
299
-
300
- init() {
301
- this.fetchData();
302
- },
303
-
304
- async fetchData() {
305
- try {
306
- const response = await fetch('/api/data');
307
- this.data = await response.json();
308
-
309
- // Extract unique types
310
- this.types = [...new Set(this.data.map(item => item.Type))];
311
-
312
- // Calculate stats
313
- this.stats.totalItems = this.data.length;
314
- this.stats.totalTrades = this.data.reduce((sum, item) => sum + item.TimesTraded, 0);
315
- this.stats.totalCirculation = this.data.reduce((sum, item) => sum + item.UniqueCirculation, 0);
316
- this.stats.avgDemand = this.formatDecimal(this.data.reduce((sum, item) => sum + item.DemandMultiple, 0) / this.data.length);
317
-
318
- this.sortData();
319
- this.filterData();
320
-
321
- // Initialize charts
322
- this.initCharts();
323
-
324
- this.loading = false;
325
- } catch (error) {
326
- console.error("Error fetching data:", error);
327
- this.loading = false;
328
- }
329
- },
330
-
331
- sortData() {
332
- const column = this.sortColumn;
333
- const direction = this.sortDirection === 'asc' ? 1 : -1;
334
-
335
- this.data.sort((a, b) => {
336
- if (typeof a[column] === 'string') {
337
- return direction * a[column].localeCompare(b[column]);
338
- } else {
339
- return direction * (a[column] - b[column]);
340
- }
341
- });
342
- },
343
-
344
- sortBy(column) {
345
- if (this.sortColumn === column) {
346
- this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
347
- } else {
348
- this.sortColumn = column;
349
- this.sortDirection = 'desc';
350
- }
351
-
352
- this.sortBy(column);
353
- this.filterData();
354
- },
355
-
356
- filterData() {
357
- this.currentPage = 1;
358
-
359
- this.filteredData = this.data.filter(item => {
360
- const matchesSearch = this.searchQuery === '' ||
361
- item.Name.toLowerCase().includes(this.searchQuery.toLowerCase()) ||
362
- item.Type.toLowerCase().includes(this.searchQuery.toLowerCase());
363
-
364
- const matchesType = this.selectedType === '' || item.Type === this.selectedType;
365
-
366
- return matchesSearch && matchesType;
367
- });
368
- },
369
-
370
- get paginatedData() {
371
- const start = (this.currentPage - 1) * this.pageSize;
372
- const end = start + this.pageSize;
373
- return this.filteredData.slice(start, end);
374
- },
375
-
376
- get totalPages() {
377
- return Math.max(1, Math.ceil(this.filteredData.length / this.pageSize));
378
- },
379
-
380
- formatNumber(num) {
381
- return num.toLocaleString();
382
- },
383
-
384
- formatDecimal(num) {
385
- return Number(num).toFixed(2);
386
- },
387
-
388
- getDemandClass(value) {
389
- if (value >= 5) return 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200';
390
- if (value >= 3) return 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-200';
391
- if (value >= 2) return 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200';
392
- return 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200';
393
- },
394
-
395
- get topDemandVehicles() {
396
- return [...this.data]
397
- .filter(item => item.Type === 'Vehicle')
398
- .sort((a, b) => b.DemandMultiple - a.DemandMultiple);
399
- },
400
-
401
- get mostTradedItems() {
402
- return [...this.data].sort((a, b) => b.TimesTraded - a.TimesTraded);
403
- },
404
-
405
- initCharts() {
406
- // Chart for top demand items
407
- const topItems = [...this.data]
408
- .sort((a, b) => b.DemandMultiple - a.DemandMultiple)
409
- .slice(0, 10);
410
-
411
- new Chart(document.getElementById('demandChart'), {
412
- type: 'bar',
413
- data: {
414
- labels: topItems.map(item => item.Name),
415
- datasets: [{
416
- label: 'Demand Multiple',
417
- data: topItems.map(item => item.DemandMultiple),
418
- backgroundColor: 'rgba(59, 130, 246, 0.8)',
419
- borderColor: 'rgb(59, 130, 246)',
420
- borderWidth: 1
421
- }]
422
- },
423
- options: {
424
- indexAxis: 'y',
425
- responsive: true,
426
- maintainAspectRatio: false,
427
- plugins: {
428
- legend: {
429
- display: false
430
- },
431
- tooltip: {
432
- callbacks: {
433
- label: function(context) {
434
- return `Demand: ${context.raw.toFixed(2)}`;
435
- }
436
- }
437
- }
438
- },
439
- scales: {
440
- x: {
441
- grid: {
442
- color: 'rgba(156, 163, 175, 0.1)'
443
- }
444
- },
445
- y: {
446
- grid: {
447
- display: false
448
- }
449
- }
450
- }
451
- }
452
- });
453
-
454
- // Chart for item types distribution
455
- const typeData = {};
456
- this.data.forEach(item => {
457
- if (!typeData[item.Type]) {
458
- typeData[item.Type] = 0;
459
- }
460
- typeData[item.Type]++;
461
- });
462
-
463
- const typeLabels = Object.keys(typeData);
464
- const typeCounts = Object.values(typeData);
465
-
466
- const colors = [
467
- 'rgba(59, 130, 246, 0.8)',
468
- 'rgba(16, 185, 129, 0.8)',
469
- 'rgba(245, 158, 11, 0.8)',
470
- 'rgba(239, 68, 68, 0.8)',
471
- 'rgba(139, 92, 246, 0.8)',
472
- 'rgba(236, 72, 153, 0.8)'
473
- ];
474
-
475
- new Chart(document.getElementById('typeChart'), {
476
- type: 'pie',
477
- data: {
478
- labels: typeLabels,
479
- datasets: [{
480
- data: typeCounts,
481
- backgroundColor: colors.slice(0, typeLabels.length),
482
- borderColor: 'rgba(255, 255, 255, 0.5)',
483
- borderWidth: 2
484
- }]
485
- },
486
- options: {
487
- responsive: true,
488
- maintainAspectRatio: false,
489
- plugins: {
490
- legend: {
491
- position: 'bottom',
492
- labels: {
493
- padding: 20
494
- }
495
- }
496
- }
497
- }
498
- });
499
- }
500
- };
501
- }
502
- </script>
503
- </body>
504
- </html>