File size: 36,290 Bytes
7611efd
 
 
 
 
8192462
7611efd
 
c7404c6
7611efd
4b7a3ab
 
 
8192462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1731e10
4b7a3ab
1731e10
8192462
 
 
1731e10
8192462
 
 
 
 
 
 
4b7a3ab
8192462
 
 
 
4b7a3ab
8192462
 
4b7a3ab
 
8192462
 
4b7a3ab
 
 
 
 
8192462
 
 
 
 
 
 
4b7a3ab
8192462
 
 
 
 
 
 
 
 
 
 
4b7a3ab
 
8192462
4b7a3ab
8192462
 
 
 
 
 
 
4b7a3ab
3cada53
 
8192462
 
4b7a3ab
 
 
 
8192462
4b7a3ab
 
 
 
8192462
 
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8192462
4b7a3ab
 
 
8192462
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3cada53
7611efd
 
 
c7404c6
8192462
4b7a3ab
 
1731e10
 
 
 
 
 
 
 
 
 
 
 
4b7a3ab
1731e10
4b7a3ab
 
 
 
 
 
8b1309e
4b7a3ab
 
 
1731e10
4b7a3ab
 
 
 
 
 
8b1309e
4b7a3ab
 
1731e10
4b7a3ab
 
1731e10
 
3437071
04f8c0a
8192462
 
1731e10
 
3437071
04f8c0a
1731e10
c7404c6
7611efd
4b7a3ab
c7404c6
4b7a3ab
7dc7fcc
4b7a3ab
 
 
 
d747267
66f8eac
 
 
 
4b7a3ab
 
 
 
 
 
 
 
 
 
 
d747267
66f8eac
 
 
 
 
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
66f8eac
 
 
 
 
4b7a3ab
 
 
 
 
7dc7fcc
 
 
 
 
 
691b9d4
66f8eac
6f3c545
c8c725b
66f8eac
 
7dc7fcc
 
 
 
 
 
 
 
 
 
 
691b9d4
66f8eac
6f3c545
66f8eac
 
7dc7fcc
 
 
 
 
 
 
 
 
 
 
 
66f8eac
 
6f3c545
66f8eac
 
 
7dc7fcc
 
 
 
 
8ea0adc
 
 
 
 
 
 
66f8eac
 
6f3c545
66f8eac
 
8ea0adc
 
 
 
c8c725b
 
 
7611efd
4b7a3ab
 
c7404c6
4b7a3ab
c7404c6
 
4b7a3ab
8192462
4b7a3ab
8192462
 
 
 
4b7a3ab
7611efd
 
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7611efd
 
 
4b7a3ab
 
 
 
 
 
15836e0
 
 
 
4b7a3ab
15836e0
 
4b7a3ab
 
 
 
 
 
8ea0adc
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
 
 
7611efd
4b7a3ab
 
 
 
7611efd
 
 
c7404c6
4b7a3ab
 
c7404c6
4b7a3ab
 
c7404c6
 
8192462
4b7a3ab
c7404c6
 
7611efd
c7404c6
4b7a3ab
7611efd
 
4b7a3ab
7611efd
8192462
7611efd
4b7a3ab
7611efd
 
4b7a3ab
3cada53
c7404c6
 
4b7a3ab
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
04f8c0a
4b7a3ab
 
 
04f8c0a
4b7a3ab
 
629dc95
4b7a3ab
 
df81100
4b7a3ab
 
3437071
4b7a3ab
 
04f8c0a
4b7a3ab
 
 
04f8c0a
 
4b7a3ab
 
 
 
 
 
 
 
04f8c0a
4b7a3ab
3437071
 
7611efd
 
c7404c6
3cada53
1014fd4
04f8c0a
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Boston Scientific Dashboard</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css"/>
    <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        /* [MISMO CSS QUE ANTES - OMITIDO POR BREVEDAD] */
         /* Paleta de colores corporativa */
         :root {
            --primary-blue: #0057b8;
            --secondary-blue: #003f7f;
            --light-gray: #f4f4f4;
            --dark-gray: #333;
            --highlight-yellow: #FFD700;
            --danger-red: #FF0000;
            --success-green: #008000;
        }

        /* Estilos generales */
        body {
            font-family: Arial, sans-serif;
            background-color: var(--light-gray);
            color: var(--dark-gray);
            margin: 0;
            padding: 0;
        }

        h1 {
            text-align: center;
            color: var(--primary-blue);
            margin: 20px 0;
        }


        /*CAMBIO COLUMNAS*/

        /* Contenedor principal con grid */
        .dashboard {
            display: grid;
            grid-template-columns: 1fr 2fr 1fr;/*1fr;*/
            grid-template-rows: auto auto auto;
            gap: 20px;
            padding: 20px;
        }

        /* Controles */
        #controls {
            grid-column: 1 / -1; /* Hacer que los controles ocupen todo el ancho */
            display: flex;
            justify-content: center;
            align-items: center;
            background: white;
            padding: 15px; /* Aumentado padding */
            border-radius: 10px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            margin-bottom: 20px; /* Añadido margen inferior */
            flex-wrap: wrap; /* Permitir que los controles pasen a la siguiente línea si no caben */
        }

        #controls label {
             margin: 0 5px 0 15px; /* Ajuste de margen para etiquetas */
        }

        #controls select {
            padding: 8px;
            font-size: 16px;
            border: 2px solid var(--primary-blue);
            border-radius: 5px;
            background: white;
            color: var(--dark-gray);
            cursor: pointer;
            margin: 5px; /* Añadido margen alrededor de los selectores */
        }

        /* Estilos del mapa */
        #map {
            height: 500px;
            width: 100%;
            border-radius: 10px;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
        }

        /* Contenedor de gráficos */
        .chart-container { /* Este contenedor ya no se usa directamente para los gráficos principales */
            /* display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 20px; */
        }

        .chart-box {
            background: white;
            padding: 20px;
            border-radius: 10px;
            box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
            /* Los canvas dentro del chart-box se manejarán individualmente o por defecto */
        }

        canvas {
            width: 100%;
            /* Altura ajustada para mejor visualización cuando hay varios */
            height: auto; /* Permitir que el contenedor defina la altura o usar ratio */
            max-height: 250px; /* Limitar altura máxima si es necesario */
            margin-bottom: 15px; /* Espacio entre gráficos dentro del mismo chart-box */
        }
        .chart-box canvas:last-child {
             margin-bottom: 0; /* Quitar margen inferior al último canvas */
        }


        /* Responsive */
        @media (max-width: 1200px) { /* Ajuste para pantallas medianas/grandes */
             .dashboard {
                grid-template-columns: 1fr 1fr; /* 2 columnas */
                grid-template-rows: auto auto auto;
            }
             #map {
                 grid-column: 1 / -1; /* Mapa ocupa todo el ancho */
                 grid-row: 2; /* Mapa en la segunda fila */
             }
            .chart-box:nth-of-type(1) { /* Primer contenedor de gráficos */
                 grid-column: 1 / 2;
                 grid-row: 3;
            }
            .chart-box:nth-of-type(2) { /* Segundo contenedor de gráficos */
                 grid-column: 2 / 3;
                 grid-row: 3;
            }
             #controls {
                 grid-row: 1; /* Controles en la primera fila */
             }
        }

        @media (max-width: 768px) {
            .dashboard {
                grid-template-columns: 1fr; /* 1 columna */
                grid-template-rows: auto auto auto auto; /* Una fila para cada elemento principal */
            }
             #map, .chart-box, #controls {
                 grid-column: 1 / -1; /* Todos ocupan el ancho completo */
             }
             #controls { grid-row: 1; }
             #map { grid-row: 2; }
             .chart-box:nth-of-type(1) { grid-row: 3; } /* Primer chart-box */
             .chart-box:nth-of-type(2) { grid-row: 4; } /* Segundo chart-box */

             #controls {
                 flex-direction: column; /* Apilar controles verticalmente */
                 align-items: stretch; /* Estirar elementos */
             }
             #controls label {
                 margin: 10px 0 5px 0; /* Ajustar margen para layout vertical */
             }
             #controls select {
                 width: 100%; /* Ocupar todo el ancho disponible */
                 box-sizing: border-box; /* Incluir padding/border en el ancho */
             }
        }
    </style>
</head>
<body>

    <h1>Matrix - Dashboard</h1>

    <!-- Controles -->
    <div id="controls">
        <label for="category">Status:</label>
        <select id="category" onchange="updateMarkers()">
            <option value="all">All</option>
            <option value="assessment">Assessment</option>
            <option value="deployment">In Deployment</option>
            <option value="operative">Operative</option>
            <option value="paused">Paused</option>
            <option value="maintenance">Maintenance</option>
            <option value="removed">Removed</option>
        </select>

          

        <label for="monthFrom">From:</label>
        <select id="monthFrom" onchange="updateMarkers()">
            <option value="1">Jan</option>
            <option value="2">Feb</option>
            <option value="3">Mar</option>
            <!-- Podrías añadir más meses si creas más variables de datos -->
            <option value="4">Apr</option>
        </select>

          

        <label for="monthTo">To:</label>
        <select id="monthTo" onchange="updateMarkers()">
            <option value="1">Jan</option>
            <option value="2">Feb</option>
            <option value="3" selected>Mar</option> <!-- Seleccionado por defecto -->
             <!-- Podrías añadir más meses si creas más variables de datos -->
             <option value="4">Apr</option>
        </select>
    </div>

    <!-- Dashboard Grid -->
    <div class="dashboard">
        <div class="chart-box">
            <canvas id="connectionsChart"></canvas>
            <canvas id="webinarChart"></canvas>
            <canvas id="recordingChart"></canvas>
        </div>
        <div id="map"></div>
        <div class="chart-box">
            <canvas id="supportTimeChart"></canvas>
            <canvas id="webinarTime"></canvas>
            <canvas id="recordingTime"></canvas>
        </div>
    </div>


    <script>
        // --- DATOS MENSUALES DE EJEMPLO ---
        /*const locationsJan = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 11, avgSupportTime: 12, webinars: 1, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 7, avgSupportTime: 2, webinars: 1, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 1, avgSupportTime: 3, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 0, avgSupportTime: 0.5, webinars: 13, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},

            
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "deployment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0} // Cambiado a deployment
        ];
        const locationsFeb = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 21, avgSupportTime: 12, webinars: 3, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 5, avgSupportTime: 2, webinars: 6, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 13, avgSupportTime: 3, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 13, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Cambiado a maintenance
            
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},

            
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Cambiado a deployment
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}
        ];
         const locationsMar = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 13, avgSupportTime: 12, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0.5}, // Añadida grabación
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 5, avgSupportTime: 2, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 3, avgSupportTime: 3, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 1, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0}, // Cambiado a paused
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 3, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Vuelve a operative
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},

            
            
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0} // Pasa a operative con datos
        ];*/
        const locationsJan = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 11, avgSupportTime: 1, webinars: 1, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 7, avgSupportTime: 0.5, webinars: 1, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 1, avgSupportTime: 3, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 0, avgSupportTime: 0.5, webinars: 13, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 17, avgSupportTime: 1.50, webinars: 5, avgWebinarTime: 1 , recordings: 1, avgRecordingTime: 0.05},
            

          
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "deployment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0} // Cambiado a deployment
        ];
        const locationsFeb = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 21, avgSupportTime: 2, webinars: 3, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 5, avgSupportTime: 0.5, webinars: 6, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 13, avgSupportTime: 3, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 13, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Cambiado a maintenance
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 25, avgSupportTime: 0.23, webinars: 1, avgWebinarTime: 1 , recordings: 1, avgRecordingTime: 0.10},

          
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Cambiado a deployment
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}
        ];
         const locationsMar = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 13, avgSupportTime: 1, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0.5}, // Añadida grabación
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 5, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 3, avgSupportTime: 1, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 1, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0}, // Cambiado a paused
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 3, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Vuelve a operative

           
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 17, avgSupportTime: 0.32, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},

           
           
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0} // Pasa a operative con datos
        ];
          const locationsApr = [
            { name: "Ragusa", coords: [36.9257, 14.7244], category: "operative", connections: 8, avgSupportTime: 4, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0.5}, // Añadida grabación
            { name: "Seville", coords: [37.3886, -5.9823], category: "operative", connections: 4, avgSupportTime: 1.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Groningen", coords: [53.2194, 6.5665], category: "operative", connections: 5, avgSupportTime: 1.7, webinars: 4, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0},
            { name: "Cape Town", coords: [-33.9249, 18.4241], category: "operative", connections: 4, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 1 , recordings: 0, avgRecordingTime: 0}, // Cambiado a paused
            { name: "Bern", coords: [46.9481, 7.4474], category: "operative", connections: 3, avgSupportTime: 1, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Vuelve a operative
            
            
            { name: "Madrid", coords: [40.4165, -3.70256], category: "operative", connections: 12, avgSupportTime: 0.5, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},

            
            { name: "Kiel", coords: [54.3233, 10.1228], category: "removed", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Le Mans", coords: [48.0077, 0.1996], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Gdansk", coords: [54.3520, 18.6466], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Prague", coords: [50.0755, 14.4378], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0},
            { name: "Kuwait", coords: [29.3759, 47.9774], category: "assessment", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0}, // Pasa a operative con datos
            { name: "Şalālah", coords: [17.01505, 54.09237], category: "operative", connections: 0, avgSupportTime: 0, webinars: 0, avgWebinarTime: 0 , recordings: 0, avgRecordingTime: 0} // Pasa a operative con datos
      
        ];
        // Mapa y colores (sin cambios)
        var map = L.map('map').setView([50.0755, 14.4378], 3);
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
            attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);

        var categoryColors = { /* ... Mismos colores ... */
            "assessment": "#0057b8",
            "deployment": "#ff8c00", // Naranja para deployment
            "operative": "#008000",
            "paused": "#FFD700",
            "maintenance": "#FFA500",
            "removed": "#FF0000"
         };

        var markers = [];
        var chart1 = null, chart2 = null, chart3 = null, chart4 = null, chart5 = null, chart6 = null;


        /**
         * Agrega datos de múltiples datasets mensuales.
         * @param {Array<Array<Object>>} datasets - Array de datasets (ej: [locationsJan, locationsFeb]).
         * @returns {Array<Object>} - Un único dataset con valores agregados.
         */
        function aggregateMonthlyData(datasets) {
            const aggregated = {}; // Usar objeto para agrupar por nombre

            datasets.forEach(monthlyData => {
                monthlyData.forEach(location => {
                    const name = location.name;
                    if (!aggregated[name]) {
                        // Si es la primera vez que vemos esta ubicación, inicializarla
                        aggregated[name] = {
                            ...location, // Copia coords, category (la del primer mes encontrado)
                            totalConnections: 0,
                            totalSupportTime: 0,
                            totalWebinars: 0,
                            totalWebinarTime: 0,
                            totalRecordings: 0,
                            totalRecordingTime: 0,
                        };
                        // Usar la categoría del *último* mes en el rango como la representativa
                         if (datasets.length > 0) {
                             const lastMonthData = datasets[datasets.length - 1];
                             const lastLocationState = lastMonthData.find(loc => loc.name === name);
                             if (lastLocationState) {
                                 aggregated[name].category = lastLocationState.category;
                             }
                         }

                    }

                    // Acumular totales
                    aggregated[name].totalConnections += location.connections;
                    aggregated[name].totalSupportTime += location.connections * location.avgSupportTime; // Tiempo total = conexiones * promedio
                    aggregated[name].totalWebinars += location.webinars;
                    aggregated[name].totalWebinarTime += location.webinars * location.avgWebinarTime;
                    aggregated[name].totalRecordings += location.recordings;
                    aggregated[name].totalRecordingTime += location.recordings * location.avgRecordingTime;

                });
            });

            // Calcular promedios finales y formatear salida
            const finalData = Object.values(aggregated).map(loc => {
                // Evitar división por cero
                const avgSupportTime = loc.totalConnections > 0 ? (loc.totalSupportTime / loc.totalConnections) : 0;
                const avgWebinarTime = loc.totalWebinars > 0 ? (loc.totalWebinarTime / loc.totalWebinars) : 0;
                const avgRecordingTime = loc.totalRecordings > 0 ? (loc.totalRecordingTime / loc.totalRecordings) : 0;

                return {
                    ...loc, // Mantiene name, coords, category
                    connections: loc.totalConnections,
                    avgSupportTime: parseFloat(avgSupportTime.toFixed(2)), // Redondear a 2 decimales
                    webinars: loc.totalWebinars,
                    avgWebinarTime: parseFloat(avgWebinarTime.toFixed(2)),
                    recordings: loc.totalRecordings,
                    avgRecordingTime: parseFloat(avgRecordingTime.toFixed(2)),
                    // Eliminar propiedades temporales si se desea
                    // totalConnections, totalSupportTime, etc. ya no son necesarias
                };
            });

            return finalData;
        }


        function updateMarkers() {
            var selectedCategory = document.getElementById("category").value;
            var selectedMonthFrom = parseInt(document.getElementById("monthFrom").value, 10);
            var selectedMonthTo = parseInt(document.getElementById("monthTo").value, 10);

            let datasetsToCombine = [];

            // Validar rango básico
            //if (selectedMonthFrom > selectedMonthTo) {
            //     console.warn("El mes 'From' no puede ser posterior al mes 'To'. Mostrando datos solo para 'From'.");
            //     selectedMonthTo = selectedMonthFrom; // O mostrar un error/nada
            //}
            if (selectedMonthFrom > selectedMonthTo) {
                alert("Error: El mes 'From' no puede ser posterior al mes 'To'. Por favor, corrija la selección.");
                return; // Detiene la ejecución de la función aquí
            }

            // Determinar qué datasets incluir basándose en el rango (solo para meses 1, 2, 3)
            if (selectedMonthFrom <= 1 && selectedMonthTo >= 1) datasetsToCombine.push(locationsJan);
            if (selectedMonthFrom <= 2 && selectedMonthTo >= 2) datasetsToCombine.push(locationsFeb);
            if (selectedMonthFrom <= 3 && selectedMonthTo >= 3) datasetsToCombine.push(locationsMar);
            if (selectedMonthFrom <= 4 && selectedMonthTo >= 4) datasetsToCombine.push(locationsApr);
             // Añadir más 'if' si se crean locationsApr, locationsMay, etc.

            let dataToDisplay = [];
            if (datasetsToCombine.length > 0) {
                // Si hay más de un mes, agregar. Si solo hay uno, aggregateMonthlyData lo manejará.
                dataToDisplay = aggregateMonthlyData(datasetsToCombine);
            } else {
                console.log("No hay datos disponibles para el rango de meses seleccionado (1-3).");
            }

            // --- Filtrado por Categoría (se aplica DESPUÉS de agregar por mes) ---
            let filteredLocations = dataToDisplay.filter(location =>
                selectedCategory === "all" || location.category === selectedCategory
            );

            console.log(`Mostrando datos agregados de Mes ${selectedMonthFrom} a ${selectedMonthTo}. Categoría: ${selectedCategory}. Ubicaciones filtradas: ${filteredLocations.length}`);


            // --- Actualización de Mapa y Gráficos (sin cambios internos, solo usan filteredLocations) ---
            markers.forEach(marker => map.removeLayer(marker));
            markers = [];

            filteredLocations.forEach(location => {
                // Usar la categoría (posiblemente actualizada por la agregación)
                const color = categoryColors[location.category] || '#CCCCCC';
                var marker = L.circleMarker(location.coords, {
                    color: color,
                    fillColor: color,
                    fillOpacity: 0.8,
                    radius: 8
                }).bindPopup(`<b>${location.name}</b><br>Categoría: ${location.category}<br>Conexiones: ${location.connections}<br>Soporte: ${location.avgSupportTime} hrs`);

                marker.addTo(map);
                markers.push(marker);
            });

            // Ajustar vista del mapa
            if (markers.length > 1) {
                var group = new L.featureGroup(markers);
                 try { map.fitBounds(group.getBounds().pad(0.3)); } catch (e) { /*...*/ }
            } else if (markers.length === 1) {
                map.setView(markers[0].getLatLng(), 6);
            } else {
                map.setView([48, 15], 4);
            }

            // Actualizar gráficos
            updateCharts(filteredLocations);
        }

        // --- La función updateCharts permanece sin cambios ---
        function updateCharts(filteredLocations) {
             // ... (código idéntico al de la versión anterior para crear/actualizar los 6 gráficos) ...
            var cityNames = filteredLocations.map(location => location.name);

            var connectionsData = filteredLocations.map(location => location.connections);
            var avgSupportTimeData = filteredLocations.map(location => location.avgSupportTime);
            var webinarData = filteredLocations.map(location => location.webinars);
            var avgWebinarTimeData = filteredLocations.map(location => location.avgWebinarTime);
            var recordingData = filteredLocations.map(location => location.recordings);
            var avgRecordingTimeData = filteredLocations.map(location => location.avgRecordingTime);

            // Usar el color de la categoría final (después de la agregación)
            var categoryColorsData = filteredLocations.map(location => categoryColors[location.category] || '#CCCCCC');

            // Destruir gráficos existentes
            if (chart1) chart1.destroy();
            if (chart2) chart2.destroy();
            if (chart3) chart3.destroy();
            if (chart4) chart4.destroy();
            if (chart5) chart5.destroy();
            if (chart6) chart6.destroy();

            // --- Opciones comunes para gráficos (reutilizadas de la versión anterior) ---
             var commonOptions = (titleText) => ({
                 responsive: true,
                 maintainAspectRatio: false,
                 plugins: { legend: { display: false }, title: { display: true, text: titleText, font: { size: 14 }, color: '#333', padding: { top: 5, bottom: 15 } } },
                 scales: { x: { ticks: { color: '#333', font: {size: 10} }, grid: { display: false } }, y: { beginAtZero: true, ticks: { color: '#333' }, grid: { color: 'rgba(0,0,0,0.05)' } } },
                 animation: { duration: 800, easing: 'easeOutQuad' }
            });
            var commonDatasetOptions = (data, colors) => ({
                 data: data, backgroundColor: colors, borderColor: 'rgba(51, 51, 51, 0.5)', borderWidth: 1, borderRadius: 5, hoverBackgroundColor: 'rgba(0, 0, 0, 0.2)'
            });

            // --- Creación de Gráficos ---
            var ctx1 = document.getElementById('connectionsChart').getContext('2d');
            chart1 = new Chart(ctx1, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(connectionsData, categoryColorsData)] }, options: commonOptions('Total Remote connections (Selected Period)') });

            var ctx2 = document.getElementById('supportTimeChart').getContext('2d');
            chart2 = new Chart(ctx2, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(avgSupportTimeData, categoryColorsData)] }, options: commonOptions('Average Support Time (hrs/connection, Selected Period)') }); // Título ajustado

            var ctx3 = document.getElementById('webinarChart').getContext('2d');
            chart3 = new Chart(ctx3, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(webinarData, categoryColorsData)] }, options: commonOptions('Total Webinar Connections (Selected Period)') });

            var ctx4 = document.getElementById('webinarTime').getContext('2d');
            chart4 = new Chart(ctx4, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(avgWebinarTimeData, categoryColorsData)] }, options: commonOptions('Average Webinar Time (hrs/session, Selected Period)') }); // Título ajustado

            var ctx5 = document.getElementById('recordingChart').getContext('2d');
            chart5 = new Chart(ctx5, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(recordingData, categoryColorsData)] }, options: commonOptions('Total Recordings (Selected Period)') });

            var ctx6 = document.getElementById('recordingTime').getContext('2d');
            chart6 = new Chart(ctx6, { type: 'bar', data: { labels: cityNames, datasets: [commonDatasetOptions(avgRecordingTimeData, categoryColorsData)] }, options: commonOptions('Average Recording Time (hrs/recording, Selected Period)') }); // Título ajustado
        }


        // Llamada inicial
        document.addEventListener('DOMContentLoaded', function() {
            // Establecer mes 'To' por defecto (ej: Marzo = 3)
            const monthToSelect = document.getElementById('monthTo');
            monthToSelect.value = 3;
             // Establecer mes 'From' por defecto (ej: Enero = 1)
             const monthFromSelect = document.getElementById('monthFrom');
             monthFromSelect.value = 1;

            updateMarkers(); // Carga inicial con el rango por defecto (Jan-Mar)
        });

    </script>

</body>
</html>