OUAREDAEK commited on
Commit
a0be42c
·
verified ·
1 Parent(s): d3bef47

Upload templates/index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. templates/index.html +780 -1247
templates/index.html CHANGED
@@ -319,545 +319,373 @@ button:disabled {
319
  line-height: 1.5;
320
  }
321
 
322
- /* ================= ONGLET 2: DASHBOARD ÉTUDIANT ================= */
323
  #tab-dashboard .manifest-item {
324
  background: linear-gradient(135deg, #f9fbe7, #f0f4c3);
325
- padding: 20px;
326
  border-radius: 12px;
327
  border-left: 6px solid #cddc39;
328
  margin: 15px 0;
329
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
 
330
  }
331
 
332
  .manifest-item b {
333
  color: #689f38;
334
  }
335
 
336
- /* ================= COMPÉTENCES ================= */
337
- .bar {
338
- background: #f5f5f5;
339
- border-radius: 12px;
340
- height: 22px;
341
- margin: 8px 0 20px;
342
- overflow: hidden;
343
- box-shadow: inset 0 2px 5px rgba(0,0,0,0.1);
344
- }
345
-
346
- .fill {
347
- height: 100%;
348
- border-radius: 12px;
349
- color: white;
350
- font-size: 13px;
351
- text-align: right;
352
- padding-right: 12px;
353
- line-height: 22px;
354
- font-weight: 600;
355
- transition: width 0.5s ease;
356
- position: relative;
357
- overflow: hidden;
358
- }
359
-
360
- .fill::after {
361
- content: '';
362
- position: absolute;
363
- top: 0;
364
- left: 0;
365
- right: 0;
366
- bottom: 0;
367
- background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3));
368
- }
369
-
370
- /* ================= RADAR ================= */
371
- #radar-container {
372
- display: flex;
373
- flex-wrap: wrap;
374
- gap: 30px;
375
- margin: 20px auto;
376
- align-items: flex-start;
377
- }
378
-
379
- #radar {
380
- flex: 1;
381
- min-width: 500px;
382
- max-width: 500px;
383
  background: white;
384
- border-radius: 15px;
385
- padding: 20px;
386
- box-shadow: 0 5px 20px rgba(0,0,0,0.08);
387
  border: 1px solid #e0e0e0;
 
388
  }
389
 
390
- /* ================= GRILLE DES MÉTRIQUES RADAR ================= */
391
- .radar-metrics-grid {
392
  display: grid;
393
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
394
- gap: 20px;
395
- margin: 25px 0;
396
- }
397
-
398
- .metric-card {
399
- background: white;
400
- border-radius: 12px;
401
- padding: 20px;
402
- box-shadow: 0 4px 12px rgba(0,0,0,0.08);
403
- border-left: 5px solid #1976D2;
404
- transition: transform 0.3s, box-shadow 0.3s;
405
- display: flex;
406
- flex-direction: column;
407
- align-items: center;
408
- text-align: center;
409
  }
410
 
411
- .metric-card:hover {
412
- transform: translateY(-5px);
413
- box-shadow: 0 8px 20px rgba(0,0,0,0.12);
 
 
 
414
  }
415
 
416
- .metric-icon {
417
- font-size: 32px;
418
- margin-bottom: 10px;
419
  }
420
 
421
- .metric-name {
 
422
  font-weight: 600;
423
  color: #333;
424
  margin-bottom: 8px;
425
- font-size: 16px;
 
426
  }
427
 
428
- .metric-value {
429
- font-size: 28px;
430
- font-weight: bold;
431
- color: #1976D2;
 
432
  margin: 5px 0;
433
  }
434
 
435
- .metric-value.high {
436
- color: #43A047;
437
- }
438
-
439
- .metric-value.medium {
440
- color: #FB8C00;
441
- }
442
-
443
- .metric-value.low {
444
- color: #E53935;
445
- }
446
-
447
- .metric-description {
448
- font-size: 13px;
449
- color: #666;
450
- margin-top: 8px;
451
- line-height: 1.4;
452
- }
453
-
454
- /* ================= PANEL MÉTACOGNITION ================= */
455
- .metacognition-panel {
456
- flex: 1;
457
- min-width: 400px;
458
- max-width: 600px;
459
- background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
460
- padding: 25px;
461
- border-radius: 15px;
462
- border-left: 6px solid #FF9800;
463
- box-shadow: 0 5px 20px rgba(0,0,0,0.08);
464
  }
465
 
466
- .metacognition-header {
 
467
  display: flex;
468
- align-items: center;
469
  gap: 15px;
470
- margin-bottom: 20px;
471
- padding-bottom: 15px;
472
- border-bottom: 2px solid rgba(255, 152, 0, 0.2);
 
 
 
473
  }
474
 
475
- .metacognition-icon {
476
- font-size: 32px;
477
- background: #FF9800;
478
- color: white;
479
- width: 60px;
480
- height: 60px;
481
- border-radius: 50%;
482
  display: flex;
483
  align-items: center;
484
- justify-content: center;
485
- box-shadow: 0 4px 12px rgba(255, 152, 0, 0.3);
486
- }
487
-
488
- .metacognition-header h4 {
489
- color: #FF9800;
490
- margin: 0;
491
- font-size: 20px;
492
- }
493
-
494
- .metacognition-content {
495
- display: flex;
496
- flex-direction: column;
497
- gap: 20px;
498
  }
499
 
500
- .metacognition-message {
501
- background: white;
502
- padding: 18px;
503
- border-radius: 12px;
504
- font-size: 15px;
505
- line-height: 1.6;
506
- border: 2px solid #FFE0B2;
507
  }
508
 
509
- .metacognition-message strong {
510
- color: #FF9800;
511
- display: block;
512
- margin-bottom: 8px;
513
- font-size: 16px;
514
- }
515
 
516
- .metacognition-questions {
 
517
  background: white;
518
- padding: 20px;
519
  border-radius: 12px;
520
- border: 2px solid #FFE0B2;
521
- }
522
-
523
- .metacognition-questions h5 {
524
- color: #FF9800;
525
- margin-top: 0;
526
- margin-bottom: 15px;
527
- font-size: 16px;
528
- }
529
-
530
- .metacognition-questions ul {
531
- margin: 0;
532
- padding-left: 20px;
533
- }
534
-
535
- .metacognition-questions li {
536
- margin-bottom: 10px;
537
- color: #555;
538
- line-height: 1.5;
539
- font-size: 14px;
540
  }
541
 
542
- .metacognition-questions li:last-child {
543
- margin-bottom: 0;
 
544
  }
545
 
546
- /* Message bot radar */
547
- .radar-bot-message {
548
  background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
549
- padding: 20px;
550
- border-radius: 15px;
551
- margin: 20px 0;
552
- border-left: 6px solid #1976D2;
553
- box-shadow: 0 4px 12px rgba(25, 118, 210, 0.1);
554
- animation: fadeIn 0.5s ease-in;
555
  }
556
 
557
- .radar-bot-header {
558
  display: flex;
559
  align-items: center;
560
- gap: 12px;
561
- margin-bottom: 15px;
562
  }
563
 
564
- .radar-bot-icon {
565
- font-size: 28px;
566
  background: #1976D2;
567
  color: white;
568
- width: 50px;
569
- height: 50px;
570
  border-radius: 50%;
571
  display: flex;
572
  align-items: center;
573
  justify-content: center;
574
  }
575
 
576
- .radar-bot-title {
577
- font-size: 18px;
578
  font-weight: 600;
579
  color: #1976D2;
580
  margin: 0;
581
  }
582
 
583
- .radar-bot-content {
584
- font-size: 16px;
585
- line-height: 1.6;
586
  color: #333;
587
  margin: 0;
588
  }
589
 
590
- .radar-bot-insights {
591
  background: white;
592
- padding: 15px;
593
- border-radius: 10px;
594
- margin-top: 15px;
595
  border: 1px solid #E3F2FD;
596
  }
597
 
598
- .radar-insight-item {
599
  display: flex;
600
  align-items: center;
601
- gap: 10px;
602
- margin-bottom: 8px;
603
- padding: 8px 12px;
604
  border-radius: 6px;
605
  background: #F5F5F5;
606
- transition: all 0.3s;
607
  }
608
 
609
- .radar-insight-item:hover {
610
- background: #E3F2FD;
611
- transform: translateX(5px);
612
- }
613
-
614
- .radar-insight-icon {
615
- font-size: 20px;
616
- width: 30px;
617
- text-align: center;
618
- }
619
-
620
- .radar-insight-text {
621
- flex-grow: 1;
622
- font-size: 14px;
623
  }
624
 
625
- /* Légende radar */
626
- .radar-legend {
627
- display: flex;
628
- justify-content: center;
629
- gap: 25px;
630
- margin: 15px 0 25px 0;
631
- flex-wrap: wrap;
632
- padding: 15px;
633
  background: white;
634
  border-radius: 10px;
635
- border: 1px solid #e0e0e0;
636
- box-shadow: 0 2px 8px rgba(0,0,0,0.05);
 
 
 
637
  }
638
 
639
- .legend-item {
640
- display: flex;
641
- align-items: center;
642
- gap: 10px;
643
- padding: 8px 15px;
644
- background: #f8f9fa;
645
- border-radius: 8px;
646
- font-size: 14px;
647
- font-weight: 500;
648
- transition: transform 0.2s;
649
  }
650
 
651
- .legend-item:hover {
652
- transform: translateY(-2px);
653
- box-shadow: 0 3px 10px rgba(0,0,0,0.1);
654
  }
655
 
656
- .legend-color {
657
- width: 20px;
658
- height: 20px;
659
- border-radius: 4px;
660
- border: 2px solid white;
661
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
662
  }
663
 
664
- .legend-low {
665
- background: linear-gradient(135deg, #e53935, #f44336);
 
 
 
666
  }
667
 
668
- .legend-medium {
669
- background: linear-gradient(135deg, #fb8c00, #ff9800);
670
- }
671
 
672
- .legend-high {
673
- background: linear-gradient(135deg, #43a047, #4caf50);
 
 
 
674
  }
675
 
676
- #radar-list {
677
- list-style: none;
678
- padding: 0;
 
 
 
679
  margin: 15px 0;
680
- display: grid;
681
- grid-template-columns: repeat(2, 1fr);
682
- gap: 10px;
683
- }
684
-
685
- #radar-list li {
686
- background: #f8f9fa;
687
- padding: 10px 15px;
688
- border-radius: 8px;
689
- font-size: 13px;
690
- border-left: 4px solid #1976D2;
691
- transition: all 0.3s;
692
- display: flex;
693
- justify-content: space-between;
694
- align-items: center;
695
  }
696
 
697
- #radar-list li:hover {
698
- background: #e3f2fd;
699
- transform: translateX(5px);
700
- }
701
-
702
- #radar-list li .value {
703
- font-weight: bold;
704
- color: #1976D2;
705
- font-size: 14px;
706
- }
707
-
708
- /* ================= HEATMAP ENRICHIE ================= */
709
- .heatmap-analysis {
710
- background: white;
711
- padding: 20px;
712
- border-radius: 15px;
713
- box-shadow: 0 5px 20px rgba(0,0,0,0.08);
714
- border: 1px solid #e0e0e0;
715
- margin: 10px auto;
716
  }
717
 
718
- .analysis-controls {
719
  display: flex;
720
  align-items: center;
721
- gap: 15px;
722
- margin-bottom: 20px;
723
- padding: 15px;
724
  background: #f8f9fa;
725
- border-radius: 12px;
726
  }
727
 
728
- .analysis-controls label {
729
  font-weight: 600;
730
  color: #1976D2;
 
731
  }
732
 
733
- .analysis-controls select {
734
- padding: 10px 20px;
735
- border-radius: 8px;
736
  border: 2px solid #1976D2;
737
  background: white;
738
  color: #333;
739
  font-weight: 500;
740
  cursor: pointer;
741
- transition: all 0.3s;
742
  flex-grow: 1;
743
- max-width: 300px;
744
  }
745
 
746
- .analysis-controls select:hover {
747
- border-color: #2196F3;
748
- box-shadow: 0 0 0 3px rgba(33, 150, 243, 0.1);
 
749
  }
750
 
751
- #heatmap {
 
752
  background: white;
753
- border-radius: 15px;
754
  padding: 15px;
755
- box-shadow: 0 5px 20px rgba(0,0,0,0.08);
756
  border: 1px solid #e0e0e0;
757
- margin: 10px auto;
758
- cursor: crosshair;
759
- }
760
-
761
- .enriched-legend {
762
- display: grid;
763
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
764
- gap: 20px;
765
- margin: 20px 0;
766
- padding: 20px;
767
- background: #f8f9fa;
768
- border-radius: 12px;
769
  }
770
 
771
- .legend-section h5 {
772
  color: #1976D2;
773
- margin-bottom: 15px;
774
- font-size: 16px;
775
  display: flex;
776
  align-items: center;
777
- gap: 8px;
778
  }
779
 
780
- .legend-grid {
781
  display: grid;
782
  grid-template-columns: repeat(3, 1fr);
783
- gap: 10px;
784
  }
785
 
786
- .legend-item-small {
787
  display: flex;
788
  align-items: center;
789
- gap: 8px;
790
- font-size: 13px;
791
  }
792
 
793
- .legend-color-small {
794
- width: 20px;
795
- height: 20px;
796
  border-radius: 4px;
797
  border: 2px solid white;
798
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
799
  }
800
 
801
- .persistence-indicators {
 
 
 
 
 
 
 
 
 
802
  display: flex;
803
  flex-direction: column;
804
- gap: 12px;
 
805
  }
806
 
807
- .indicator {
808
  display: flex;
809
  align-items: center;
810
- gap: 10px;
811
- padding: 10px 15px;
812
  background: white;
813
- border-radius: 8px;
814
- font-size: 14px;
815
- border-left: 4px solid #1976D2;
816
  }
817
 
818
- .indicator-dot {
819
- width: 12px;
820
- height: 12px;
821
  border-radius: 50%;
822
  }
823
 
824
- .persistence-analysis {
825
- background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
826
- padding: 20px;
827
- border-radius: 12px;
828
- margin-top: 20px;
829
- border-left: 6px solid #1976D2;
830
- }
831
-
832
- .persistence-analysis h5 {
833
- color: #1976D2;
834
- margin-top: 0;
835
- margin-bottom: 15px;
836
- font-size: 16px;
837
- display: flex;
838
- align-items: center;
839
- gap: 8px;
840
  }
841
 
842
- .persistence-analysis > div {
843
- margin-bottom: 10px;
844
- padding: 10px;
845
  background: white;
846
- border-radius: 8px;
847
  border-left: 3px solid #1976D2;
848
  }
849
 
850
- .persistence-analysis strong {
851
- color: #333;
852
- margin-right: 10px;
853
- }
854
-
855
- .recommendation-box {
856
- background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
857
- border-left-color: #43A047 !important;
858
- padding: 15px;
859
- }
860
-
861
  /* ================= ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION ================= */
862
  #tab-evaluation #reflagent {
863
  background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
@@ -1075,19 +903,6 @@ textarea:focus {
1075
  padding: 20px;
1076
  }
1077
 
1078
- #radar-container {
1079
- flex-direction: column;
1080
- }
1081
-
1082
- #radar, .metacognition-panel {
1083
- min-width: 100%;
1084
- max-width: 100%;
1085
- }
1086
-
1087
- .enriched-legend {
1088
- grid-template-columns: 1fr;
1089
- }
1090
-
1091
  .tabs {
1092
  flex-direction: column;
1093
  }
@@ -1118,50 +933,40 @@ textarea:focus {
1118
  justify-content: center;
1119
  }
1120
 
1121
- .analysis-controls {
1122
- flex-direction: column;
1123
- align-items: stretch;
1124
- }
1125
-
1126
- .radar-legend {
1127
  flex-direction: column;
1128
- align-items: center;
1129
  gap: 10px;
1130
  }
1131
 
1132
- #radar-list {
1133
- grid-template-columns: 1fr;
1134
- }
1135
-
1136
- .legend-grid {
1137
- grid-template-columns: repeat(2, 1fr);
1138
  }
1139
 
1140
- .metacognition-icon {
1141
- width: 50px;
1142
- height: 50px;
1143
- font-size: 26px;
1144
  }
1145
 
1146
- .metacognition-header h4 {
1147
- font-size: 18px;
1148
  }
1149
 
1150
- .persistence-indicators {
1151
  flex-direction: column;
 
 
1152
  }
1153
 
1154
- .gdpr-options {
1155
- flex-direction: column;
1156
- gap: 10px;
1157
  }
1158
 
1159
- .gdpr-option {
1160
- min-width: 100%;
 
1161
  }
1162
 
1163
- .radar-metrics-grid {
1164
- grid-template-columns: 1fr;
1165
  }
1166
  }
1167
 
@@ -1419,7 +1224,7 @@ textarea:focus {
1419
  </div>
1420
  </div>
1421
 
1422
- <!-- ONGLET 2: DASHBOARD ÉTUDIANT -->
1423
  <div id="tab-dashboard" class="tab-content">
1424
  <h3>📝 Manifeste étudiant</h3>
1425
  <div id="manifest-list">
@@ -1430,200 +1235,137 @@ textarea:focus {
1430
 
1431
  <h3>📊 Progression par compétence</h3>
1432
  <div id="competence-bars">
1433
- <em>Chargement des compétences...</em>
 
 
1434
  </div>
1435
 
1436
- <!-- LÉGENDE RADAR -->
1437
- <div class="radar-legend">
1438
- <div class="legend-item">
1439
- <div class="legend-color legend-low"></div>
1440
  <span>Faible (0-50%)</span>
1441
  </div>
1442
- <div class="legend-item">
1443
- <div class="legend-color legend-medium"></div>
1444
  <span>Moyen (50-70%)</span>
1445
  </div>
1446
- <div class="legend-item">
1447
- <div class="legend-color legend-high"></div>
1448
  <span>Élevé (70-100%)</span>
1449
  </div>
1450
  </div>
1451
 
1452
  <h3>🕸️ Radar – Learning Analytics</h3>
1453
 
1454
- <!-- Grille des métriques radar -->
1455
- <div class="radar-metrics-grid" id="radar-metrics-grid">
1456
- <div class="metric-card">
1457
- <div class="metric-icon">🚀</div>
1458
- <div class="metric-name">Démarrage des activités</div>
1459
- <div class="metric-value high">85%</div>
1460
- <div class="metric-description">Rapidité d'initiation des tâches</div>
1461
- </div>
1462
-
1463
- <div class="metric-card">
1464
- <div class="metric-icon">🎓</div>
1465
- <div class="metric-name">Connaissances validées</div>
1466
- <div class="metric-value high">72%</div>
1467
- <div class="metric-description">Acquis démontrés et évalués</div>
1468
- </div>
1469
-
1470
- <div class="metric-card">
1471
- <div class="metric-icon">📈</div>
1472
- <div class="metric-name">Niveau moyen de compétence</div>
1473
- <div class="metric-value medium">68%</div>
1474
- <div class="metric-description">Moyenne des compétences maîtrisées</div>
1475
- </div>
1476
-
1477
- <div class="metric-card">
1478
- <div class="metric-icon">🎯</div>
1479
- <div class="metric-name">Taux d'erreur (inversé)</div>
1480
- <div class="metric-value low">35%</div>
1481
- <div class="metric-description">Précision et attention aux détails</div>
1482
- </div>
1483
-
1484
- <div class="metric-card">
1485
- <div class="metric-icon">🏁</div>
1486
- <div class="metric-name">Achèvement des activités</div>
1487
- <div class="metric-value high">74%</div>
1488
- <div class="metric-description">Terminaison des tâches initiées</div>
1489
- </div>
1490
-
1491
- <div class="metric-card">
1492
- <div class="metric-icon">📚</div>
1493
- <div class="metric-name">Interactions avec les ressources</div>
1494
- <div class="metric-value high">80%</div>
1495
- <div class="metric-description">Utilisation des supports d'apprentissage</div>
1496
- </div>
1497
-
1498
- <div class="metric-card">
1499
- <div class="metric-icon">🔧</div>
1500
- <div class="metric-name">Domaines de compétence</div>
1501
- <div class="metric-value high">78%</div>
1502
- <div class="metric-description">Étendue des compétences couvertes</div>
1503
- </div>
1504
  </div>
1505
 
1506
- <!-- Message Bot Radar Contextuel -->
1507
- <div id="radar-bot-message" class="radar-bot-message" style="display: none;">
1508
- <div class="radar-bot-header">
1509
- <div class="radar-bot-icon">🎯</div>
1510
- <h4 class="radar-bot-title">Analyse de Profil</h4>
1511
- </div>
1512
- <p class="radar-bot-content" id="radar-bot-content">Analyse en cours...</p>
1513
- <div class="radar-bot-insights">
1514
- <div id="radar-bot-insights">
1515
- <!-- Les insights seront ajoutés dynamiquement -->
1516
- </div>
1517
- </div>
1518
- </div>
1519
-
1520
- <!-- Container Radar + Métacognition -->
1521
  <div id="radar-container">
1522
- <!-- Canvas pour le radar -->
1523
- <canvas id="radar" width="700" height="700"></canvas>
1524
-
1525
- <!-- Panel de Métacognition -->
1526
- <div class="metacognition-panel">
1527
- <div class="metacognition-header">
1528
- <div class="metacognition-icon">🧠</div>
1529
- <h4>Métacognition & Engagement</h4>
1530
- </div>
1531
-
1532
- <div class="metacognition-content">
1533
- <div class="metacognition-message" id="metacognitionMessage">
1534
- <strong>Analyse de votre engagement :</strong><br>
1535
- Votre profil d'apprentissage est en cours d'analyse...
1536
  </div>
1537
-
1538
- <div class="metacognition-questions">
1539
- <h5>Questions pour votre réflexion :</h5>
1540
- <ul id="metacognitionQuestions">
1541
- <li>Quelle est votre stratégie pour commencer une nouvelle activité ?</li>
1542
- <li>Comment gérez-vous les difficultés rencontrées ?</li>
1543
- <li>Qu'avez-vous appris sur votre manière d'apprendre ?</li>
1544
- </ul>
1545
  </div>
1546
  </div>
 
 
 
 
 
1547
  </div>
1548
  </div>
1549
 
1550
- <div id="radar-tooltip" class="tooltip"></div>
1551
-
1552
- <!-- ================= HEATMAP ENRICHIE ================= -->
1553
- <div class="heatmap-analysis">
1554
  <h3>🔥 Heatmap d'activité - Analyse de Persévérance</h3>
1555
 
1556
- <div class="analysis-controls">
1557
- <label for="persistenceMode">Mode d'analyse :</label>
1558
- <select id="persistenceMode" onchange="changePersistenceAnalysis()">
1559
- <option value="regularity">📊 Régularité du travail</option>
1560
- <option value="effortPattern">🔄 Schéma d'effort</option>
1561
- <option value="deadline"> Gestion des échéances</option>
1562
- <option value="combined">🎯 Vue combinée</option>
1563
- </select>
 
 
 
 
 
1564
  </div>
1565
 
1566
- <!-- Canvas pour le heatmap -->
1567
- <canvas id="heatmap" width="800" height="300"></canvas>
1568
-
1569
- <!-- Légende enrichie -->
1570
- <div class="enriched-legend">
1571
- <div class="legend-section">
1572
  <h5>📈 Niveaux d'activité</h5>
1573
- <div class="legend-grid">
1574
- <div class="legend-item-small">
1575
- <div class="legend-color-small" style="background:#EBEDF0;"></div>
1576
  <span>Aucune activité</span>
1577
  </div>
1578
- <div class="legend-item-small">
1579
- <div class="legend-color-small" style="background:#C6E48B;"></div>
1580
  <span>Faible activité</span>
1581
  </div>
1582
- <div class="legend-item-small">
1583
- <div class="legend-color-small" style="background:#7BC96F;"></div>
1584
- <span>Activité modérée</span>
1585
- </div>
1586
- <div class="legend-item-small">
1587
- <div class="legend-color-small" style="background:#239A3B;"></div>
1588
- <span>Activité élevée</span>
1589
- </div>
1590
- <div class="legend-item-small">
1591
- <div class="legend-color-small" style="background:#196127;"></div>
1592
- <span>Activité intense</span>
1593
- </div>
1594
- </div>
1595
- </div>
1596
-
1597
- <div class="legend-section">
1598
- <h5>🎯 Indicateurs de Persévérance</h5>
1599
- <div class="persistence-indicators">
1600
- <div class="indicator">
1601
- <span class="indicator-dot" style="background:#FF6B6B;"></span>
1602
- <span>Régularité : <strong id="regularityScore">-</strong></span>
1603
  </div>
1604
- <div class="indicator">
1605
- <span class="indicator-dot" style="background:#4ECDC4;"></span>
1606
- <span>Schéma d'effort : <strong id="effortPattern">-</strong></span>
1607
  </div>
1608
- <div class="indicator">
1609
- <span class="indicator-dot" style="background:#FFD166;"></span>
1610
- <span>Gestion échéances : <strong id="deadlineScore">-</strong></span>
1611
  </div>
1612
  </div>
1613
  </div>
1614
  </div>
1615
 
1616
- <!-- Analyse de persévérance -->
1617
- <div class="persistence-analysis" id="persistenceAnalysis">
1618
- <h5>📋 Analyse de la Persévérance</h5>
1619
- <div id="regularityAnalysis">
1620
- <strong>Régularité du travail :</strong> <span id="regularityText">Analyse en cours...</span>
1621
- </div>
1622
- <div id="patternAnalysis">
1623
- <strong>Schéma d'effort identifié :</strong> <span id="patternText">Analyse en cours...</span>
 
 
 
 
 
 
 
 
1624
  </div>
1625
- <div id="recommendation" class="recommendation-box">
1626
- <strong>🔄 Recommandations :</strong> <span id="recommendationText">Analyse en cours...</span>
 
 
 
 
 
 
 
 
 
 
 
 
1627
  </div>
1628
  </div>
1629
  </div>
@@ -1777,6 +1519,90 @@ const trustWeights = {
1777
  "SM": 0.20
1778
  };
1779
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1780
  // ================= INIT =================
1781
  document.addEventListener("DOMContentLoaded", () => {
1782
  console.log("✅ DOM chargé, initialisation...");
@@ -1876,7 +1702,6 @@ function loadScenarios() {
1876
  });
1877
  }
1878
 
1879
- // ================= CHARGER SCÉNARIO =================
1880
  // ================= CHARGER SCÉNARIO =================
1881
  function loadScenario(index) {
1882
  console.log("Chargement scénario", index);
@@ -1891,59 +1716,13 @@ function loadScenario(index) {
1891
  // Mettre à jour le manifeste
1892
  document.getElementById("manifest-list").innerHTML = `
1893
  <div class="manifest-item">
1894
- <b>Type de Manifest :</b> ${s.manifest.type}<br>
1895
  <b>Manifeste (écrit par l'étudiant) :</b> ${s.manifest.manifeste}<br>
1896
  <b>Description du Profil :</b> ${s.manifest.description}
1897
  </div>`;
1898
 
1899
- // Version minimaliste des compétences
1900
- const c = document.getElementById("competence-bars");
1901
- c.innerHTML = "";
1902
-
1903
- const columnsContainer = document.createElement("div");
1904
- columnsContainer.style.display = "flex";
1905
- columnsContainer.style.flexWrap = "wrap";
1906
- columnsContainer.style.gap = "20px";
1907
-
1908
- const columnGroups = [4, 4, 3, 3];
1909
- let currentIndex = 0;
1910
-
1911
- columnGroups.forEach((groupSize) => {
1912
- const column = document.createElement("div");
1913
- column.style.flex = "1";
1914
- column.style.minWidth = "200px";
1915
-
1916
- for (let i = 0; i < groupSize && currentIndex < s.competences.length; i++) {
1917
- const cp = s.competences[currentIndex];
1918
-
1919
- const compItem = document.createElement("div");
1920
- compItem.style.marginBottom = "15px";
1921
-
1922
- let color;
1923
- if (cp.value < 50) color = '#E53935';
1924
- else if (cp.value < 70) color = '#FB8C00';
1925
- else color = '#43A047';
1926
-
1927
- compItem.innerHTML = `
1928
- <div style="margin-bottom: 5px; font-weight: bold; font-size: 14px;">
1929
- ${cp.label}
1930
- </div>
1931
- <div style="height: 20px; background: #e0e0e0; border-radius: 10px; overflow: hidden;">
1932
- <div style="height: 100%; width: ${cp.value}%; background: ${color};
1933
- display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 12px;">
1934
- ${cp.value}%
1935
- </div>
1936
- </div>
1937
- `;
1938
-
1939
- column.appendChild(compItem);
1940
- currentIndex++;
1941
- }
1942
-
1943
- columnsContainer.appendChild(column);
1944
- });
1945
-
1946
- c.appendChild(columnsContainer);
1947
 
1948
  // Mettre à jour le radar avec les nouvelles métriques
1949
  if (s.radar && s.radar.length > 0) {
@@ -1961,20 +1740,20 @@ function loadScenario(index) {
1961
  });
1962
  }
1963
 
1964
- // Mettre à jour la grille des métriques radar
1965
- updateRadarMetricsGrid();
1966
 
1967
  // Mettre à jour le graphique radar
1968
  drawRadar();
1969
 
1970
- // Mettre à jour le message bot radar (CONTEXTUEL)
1971
- updateRadarBotMessage(s);
1972
-
1973
- // Mettre à jour le panel de métacognition
1974
- updateMetacognitionPanel(s);
1975
 
1976
- // Mettre à jour la heatmap enrichie
1977
- drawEnrichedHeatmap(s);
 
 
 
1978
 
1979
  // Mettre à jour le message ReflAgent
1980
  document.getElementById("reflagent").textContent = s.reflAgent;
@@ -1986,12 +1765,47 @@ function loadScenario(index) {
1986
  updateStats();
1987
  }
1988
 
1989
- // ================= MISE À JOUR DE LA GRILLE DES MÉTRIQUES RADAR =================
1990
- function updateRadarMetricsGrid() {
1991
- const grid = document.getElementById("radar-metrics-grid");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1992
  if (!grid) return;
1993
 
1994
- grid.innerHTML = "";
1995
 
1996
  radarMetrics.forEach(metric => {
1997
  // Déterminer la classe de couleur selon la valeur
@@ -2006,413 +1820,133 @@ function updateRadarMetricsGrid() {
2006
  else if (metric.label.includes("Connaissances")) icon = "🎓";
2007
  else if (metric.label.includes("Niveau moyen")) icon = "📈";
2008
  else if (metric.label.includes("Taux d'erreur")) icon = "🎯";
2009
- else if (metric.label.includes("Achèvement")) icon = "🏁";
2010
- else if (metric.label.includes("Interactions")) icon = "📚";
2011
- else if (metric.label.includes("Domaines")) icon = "🔧";
2012
-
2013
- // Déterminer la description
2014
- let description = "";
2015
- if (metric.label.includes("Démarrage")) description = "Rapidité d'initiation des tâches";
2016
- else if (metric.label.includes("Connaissances")) description = "Acquis démontrés et évalués";
2017
- else if (metric.label.includes("Niveau moyen")) description = "Moyenne des compétences maîtrisées";
2018
- else if (metric.label.includes("Taux d'erreur")) description = "Précision et attention aux détails";
2019
- else if (metric.label.includes("Achèvement")) description = "Terminaison des tâches initiées";
2020
- else if (metric.label.includes("Interactions")) description = "Utilisation des supports d'apprentissage";
2021
- else if (metric.label.includes("Domaines")) description = "Étendue des compétences couvertes";
2022
-
2023
- const metricCard = document.createElement("div");
2024
- metricCard.className = "metric-card";
2025
- metricCard.innerHTML = `
2026
- <div class="metric-icon">${icon}</div>
2027
- <div class="metric-name">${metric.label}</div>
2028
- <div class="metric-value ${colorClass}">${metric.value}%</div>
2029
- <div class="metric-description">${description}</div>
2030
- `;
2031
-
2032
- grid.appendChild(metricCard);
2033
- });
2034
- }
2035
-
2036
- // ================= NAVIGATION =================
2037
- document.getElementById("prevScenario").onclick = () =>
2038
- loadScenario(currentScenarioIndex - 1);
2039
-
2040
- document.getElementById("nextScenario").onclick = () =>
2041
- loadScenario(currentScenarioIndex + 1);
2042
-
2043
- function updateNavButtons() {
2044
- document.getElementById("prevScenario").disabled =
2045
- currentScenarioIndex === 0;
2046
- document.getElementById("nextScenario").disabled =
2047
- currentScenarioIndex === scenarios.length - 1;
2048
- }
2049
-
2050
- // ================= BOUTON LECTURE CROISÉE =================
2051
- document.getElementById('crossReadersBtn').onclick = () => {
2052
- console.log('Navigation vers la page de lecture croisée...');
2053
-
2054
- // Animation de transition
2055
- const reflectionDiv = document.getElementById('reflection');
2056
- if (reflectionDiv) {
2057
- reflectionDiv.style.opacity = '0.7';
2058
- reflectionDiv.style.transition = 'opacity 0.3s ease';
2059
- }
2060
-
2061
- // Redirection
2062
- setTimeout(() => {
2063
- window.location.href = 'cross_reading/cross_readers.html';
2064
- }, 300);
2065
- };
2066
-
2067
- // ================= MÉTACOGNITION =================
2068
- function updateMetacognitionPanel(scenario) {
2069
- console.log("Mise à jour du panel métacognition...");
2070
-
2071
- // Récupérer les métriques clés
2072
- const metrics = {};
2073
- radarMetrics.forEach(item => {
2074
- metrics[item.label] = item.value;
2075
- });
2076
-
2077
- // Calculer l'engagement global (moyenne des métriques d'activité)
2078
- const engagementMetrics = [
2079
- metrics["Démarrage des activités"],
2080
- metrics["Achèvement des activités"],
2081
- metrics["Interactions avec les ressources"],
2082
- metrics["Connaissances validées"]
2083
- ].filter(v => v !== undefined);
2084
-
2085
- const avgEngagement = engagementMetrics.length > 0
2086
- ? Math.round(engagementMetrics.reduce((a, b) => a + b) / engagementMetrics.length)
2087
- : 0;
2088
-
2089
- // Générer le message de métacognition
2090
- generateMetacognitionMessage(metrics, avgEngagement, scenario);
2091
- }
2092
-
2093
- function generateMetacognitionMessage(metrics, avgEngagement, scenario) {
2094
- const messageElement = document.getElementById("metacognitionMessage");
2095
- const questionsElement = document.getElementById("metacognitionQuestions");
2096
-
2097
- if (!messageElement || !questionsElement) return;
2098
-
2099
- // Générer le message personnalisé
2100
- let message = `<strong>Analyse de votre engagement :</strong><br>`;
2101
-
2102
- // Ajouter une conclusion basée sur le niveau d'engagement
2103
- if (avgEngagement >= 70) {
2104
- message += `Excellent niveau d'engagement global (${avgEngagement}%) ! Vous maintenez une participation active et régulière.`;
2105
- } else if (avgEngagement >= 40) {
2106
- message += `Niveau d'engagement modéré (${avgEngagement}%). Des ajustements pourraient optimiser votre apprentissage.`;
2107
- } else {
2108
- message += `Engagement faible (${avgEngagement}%). Pensez à identifier ce qui pourrait relancer votre motivation.`;
2109
- }
2110
-
2111
- // Mettre à jour le message
2112
- messageElement.innerHTML = message;
2113
-
2114
- // Questions fixes
2115
- const questions = [
2116
- "Quelle est votre stratégie pour commencer une nouvelle activité ?",
2117
- "Comment gérez-vous les difficultés rencontrées ?",
2118
- "Qu'avez-vous appris sur votre manière d'apprendre ?"
2119
- ];
2120
-
2121
- // Mettre à jour les questions
2122
- questionsElement.innerHTML = "";
2123
- questions.forEach(question => {
2124
- const li = document.createElement("li");
2125
- li.textContent = question;
2126
- questionsElement.appendChild(li);
2127
- });
2128
-
2129
- console.log("Panel métacognition mis à jour pour le scénario", scenario.id);
2130
- }
2131
-
2132
- // ================= MESSAGE BOT RADAR CONTEXTUEL =================
2133
- function updateRadarBotMessage(scenario) {
2134
- const radarBotMessage = document.getElementById("radar-bot-message");
2135
- const radarBotContent = document.getElementById("radar-bot-content");
2136
- const radarBotInsights = document.getElementById("radar-bot-insights");
2137
-
2138
- if (!radarBotMessage || !radarBotContent || !radarBotInsights) return;
2139
-
2140
- // Messages pour chaque profil basé sur le titre du scénario
2141
- const profileMessages = {
2142
- "Étudiant engagé": {
2143
- title: "Étudiant Engagé et Motivé",
2144
- message: "🎯 Ton engagement est impressionnant ! Tu démontres une forte volonté d'apprendre. Continue à canaliser cette énergie vers des objectifs clairs.",
2145
- insights: [
2146
- { icon: "🔥", text: "Motivation élevée et constante" },
2147
- { icon: "🎯", text: "Objectifs d'apprentissage bien définis" },
2148
- { icon: "📚", text: "Implication active dans les activités" },
2149
- { icon: "💪", text: "Persévérance face aux difficultés" }
2150
- ]
2151
- },
2152
- "Étudiant actif mais inefficace": {
2153
- title: "Étudiant Actif mais Peu Efficace",
2154
- message: "⚡ Tu es très actif, mais l'efficacité pourrait être améliorée. Concentre-toi sur la qualité plutôt que la quantité de travail.",
2155
- insights: [
2156
- { icon: "🏃", text: "Activité élevée mais peu ciblée" },
2157
- { icon: "🎯", text: "Besoin de stratégies d'apprentissage plus efficaces" },
2158
- { icon: "📊", text: "Résultats en deçà des efforts fournis" },
2159
- { icon: "🔄", text: "Optimisation des méthodes de travail nécessaire" }
2160
- ]
2161
- },
2162
- "Étudiant orienté vers le succès": {
2163
- title: "Étudiant Orienté Réussite",
2164
- message: "🏆 Tu vises l'excellence avec détermination. Ta motivation par le succès est un atout, mais attention à ne pas négliger le processus d'apprentissage.",
2165
- insights: [
2166
- { icon: "⭐", text: "Fort désir de réussite et de reconnaissance" },
2167
- { icon: "🎯", text: "Objectifs ambitieux et clairs" },
2168
- { icon: "📈", text: "Performance supérieure aux attentes" },
2169
- { icon: "⚖️", text: "Équilibre entre résultats et apprentissage à trouver" }
2170
- ]
2171
- },
2172
- "Étudiant motivé": {
2173
- title: "Étudiant Nouvellement Motivé",
2174
- message: "🚀 Ta motivation est un excellent point de départ ! Tu découvres les joies de l'apprentissage. Capitalise sur cet élan pour construire des bases solides.",
2175
- insights: [
2176
- { icon: "🌟", text: "Motivation récente et prometteuse" },
2177
- { icon: "🧱", text: "Construction des bases en cours" },
2178
- { icon: "📖", text: "Curiosité et ouverture d'esprit" },
2179
- { icon: "🌱", text: "Potentiel de croissance important" }
2180
- ]
2181
- },
2182
- "Étudiant surmotivé": {
2183
- title: "Étudiant Surmotivé",
2184
- message: "💥 Ton niveau d'investissement est exceptionnel, mais attention au risque de surmenage. L'excellence durable nécessite un rythme soutenable.",
2185
- insights: [
2186
- { icon: "⚡", text: "Investissement maximal dans toutes les activités" },
2187
- { icon: "⚠️", text: "Risque de burnout à surveiller" },
2188
- { icon: "🎯", text: "Perfectionnisme parfois excessif" },
2189
- { icon: "⚖️", text: "Équilibre vie étudiante/privée à préserver" }
2190
- ]
2191
- },
2192
- "Étudiant stratégique": {
2193
- title: "Étudiant Stratégique",
2194
- message: "♟️ Tu abordes l'apprentissage avec intelligence et planification. Tes méthodes efficaces montrent une bonne compréhension des enjeux académiques.",
2195
- insights: [
2196
- { icon: "🧠", text: "Approche réfléchie et planifiée" },
2197
- { icon: "🎯", text: "Optimisation des efforts pour des résultats maximaux" },
2198
- { icon: "📊", text: "Analyse des retours pour amélioration" },
2199
- { icon: "⚡", text: "Efficacité démontrée dans l'apprentissage" }
2200
- ]
2201
- },
2202
- "Étudiant en amélioration": {
2203
- title: "Étudiant en Phase d'Amélioration",
2204
- message: "📈 Tu progresses régulièrement et montre une belle capacité d'adaptation. Continue à identifier tes points faibles pour les transformer en forces.",
2205
- insights: [
2206
- { icon: "📈", text: "Progression constante et mesurable" },
2207
- { icon: "🔄", text: "Capacité d'adaptation et de remise en question" },
2208
- { icon: "🎯", text: "Objectifs d'amélioration clairement identifiés" },
2209
- { icon: "💪", text: "Persévérance dans l'effort d'apprentissage" }
2210
- ]
2211
- },
2212
- "Étudiant en difficulté": {
2213
- title: "Étudiant Rencontrant des Difficultés",
2214
- message: "🆘 Tu fais face à des obstacles dans ton apprentissage. C'est normal d'avoir des difficultés - l'important est d'identifier les causes et de chercher du soutien.",
2215
- insights: [
2216
- { icon: "⚠️", text: "Difficultés persistantes dans certains domaines" },
2217
- { icon: "🆘", text: "Besoin d'un soutien adapté identifié" },
2218
- { icon: "💭", text: "Réflexion sur les causes des difficultés" },
2219
- { icon: "🤝", text: "Ouverture à l'aide et au soutien" }
2220
- ]
2221
- },
2222
- "Étudiant évitant l'échec": {
2223
- title: "Étudiant Évitant l'Échec",
2224
- message: "🛡️ Tu sembles éviter les situations qui pourraient mener à l'échec. Rappelle-toi que l'échec fait partie de l'apprentissage et peut être une source de croissance.",
2225
- insights: [
2226
- { icon: "🛡️", text: "Stratégie de protection face aux risques d'échec" },
2227
- { icon: "🎯", text: "Choix de tâches sécurisantes et maîtrisées" },
2228
- { icon: "⚠️", text: "Évitement des défis perçus comme risqués" },
2229
- { icon: "🌱", text: "Potentiel de dépassement de ses limites" }
2230
- ]
2231
- },
2232
- "Étudiant à risque": {
2233
- title: "Étudiant à Risque de Décrochage",
2234
- message: "🚨 Certains indicateurs suggèrent un risque de décrochage. Il est important d'agir maintenant pour retrouver un parcours d'apprentissage stable et épanouissant.",
2235
- insights: [
2236
- { icon: "🚨", text: "Indicateurs de risque identifiés" },
2237
- { icon: "⚠️", text: "Engagement fluctuant ou en baisse" },
2238
- { icon: "🆘", text: "Besoin urgent de soutien et d'accompagnement" },
2239
- { icon: "🔍", text: "Identification des causes du désengagement" }
2240
- ]
2241
- },
2242
- "Étudiant en progression": {
2243
- title: "Étudiant en Progression Continue",
2244
- message: "📊 Tu montres une belle progression dans tes apprentissages. Continue à capitaliser sur tes réussites pour maintenir cette dynamique positive.",
2245
- insights: [
2246
- { icon: "📊", text: "Amélioration mesurable des compétences" },
2247
- { icon: "🎯", text: "Objectifs de progression atteints" },
2248
- { icon: "🚀", text: "Dynamique d'apprentissage positive" },
2249
- { icon: "💡", text: "Acquisition de nouvelles stratégies efficaces" }
2250
- ]
2251
- },
2252
- "Étudiant acceptant l'échec": {
2253
- title: "Étudiant Acceptant l'Échec",
2254
- message: "😔 Tu sembles avoir accepté certaines difficultés comme inévitables. Pourtant, chaque obstacle peut être surmonté avec la bonne approche et du soutien.",
2255
- insights: [
2256
- { icon: "😔", text: "Acceptation passive des difficultés" },
2257
- { icon: "⚠️", text: "Faible confiance dans sa capacité à progresser" },
2258
- { icon: "🔄", text: "Besoin de redynamiser la motivation" },
2259
- { icon: "🌟", text: "Potentiel non exploité identifié" }
2260
- ]
2261
- },
2262
- "Étudiant inactif": {
2263
- title: "Étudiant Inactif",
2264
- message: "⏸️ Ton activité d'apprentissage est très limitée. Le premier pas est souvent le plus difficile - commence par de petites actions pour relancer ta motivation.",
2265
- insights: [
2266
- { icon: "⏸️", text: "Activité d'apprentissage très réduite" },
2267
- { icon: "🚪", text: "Éloignement du parcours éducatif" },
2268
- { icon: "🆘", text: "Besoin d'un accompagnement renforcé" },
2269
- { icon: "🔓", text: "Potentiel de réengagement à débloquer" }
2270
- ]
2271
- },
2272
- "Étudiant non engagé": {
2273
- title: "Étudiant Non Engagé",
2274
- message: "😐 Tu sembles peu engagé dans ton parcours d'apprentissage. Identifier ce qui pourrait te motiver à nouveau serait un premier pas important.",
2275
- insights: [
2276
- { icon: "😐", text: "Faible implication dans les activités" },
2277
- { icon: "🎯", text: "Objectifs personnels à redéfinir" },
2278
- { icon: "🔄", text: "Besoin de retrouver du sens à l'apprentissage" },
2279
- { icon: "🌟", text: "Redécouverte des motivations intrinsèques" }
2280
- ]
2281
- },
2282
- "Étudiant persévérant": {
2283
- title: "Étudiant Persévérant",
2284
- message: "🏅 Ta persévérance face aux difficultés est remarquable. Continue à avancer pas à pas - chaque effort contribue à ton apprentissage à long terme.",
2285
- insights: [
2286
- { icon: "🏅", text: "Persévérance exceptionnelle face aux défis" },
2287
- { icon: "🐢", text: "Approche patiente et régulière" },
2288
- { icon: "📈", text: "Progrès constants malgré les obstacles" },
2289
- { icon: "💪", text: "Résilience et ténacité démontrées" }
2290
- ]
2291
- },
2292
- "Étudiant actif": {
2293
- title: "Étudiant Actif et Impliqué",
2294
- message: "🎉 Tu es activement engagé dans ton apprentissage avec une bonne participation. Continue à maintenir ce niveau d'implication pour maximiser tes progrès.",
2295
- insights: [
2296
- { icon: "🎉", text: "Participation active et régulière" },
2297
- { icon: "🤝", text: "Implication dans les activités collaboratives" },
2298
- { icon: "💡", text: "Contributions pertinentes et réfléchies" },
2299
- { icon: "🚀", text: "Dynamisme dans les apprentissages" }
2300
- ]
2301
- }
2302
- };
2303
-
2304
- // Récupérer le message pour le profil ou utiliser un message par défaut
2305
- const profileMessage = profileMessages[scenario.title] || {
2306
- title: "Profil d'Apprentissage",
2307
- message: "Analyse de votre profil d'apprentissage en cours...",
2308
- insights: [
2309
- { icon: "📊", text: "Évaluation des indicateurs d'apprentissage" },
2310
- { icon: "🎯", text: "Identification des forces et axes d'amélioration" },
2311
- { icon: "🚀", text: "Recommandations personnalisées" }
2312
- ]
2313
- };
2314
-
2315
- // Mettre à jour l'interface
2316
- radarBotMessage.style.display = 'block';
2317
- radarBotContent.innerHTML = `<strong>${profileMessage.title}</strong><br>${profileMessage.message}`;
2318
-
2319
- // Mettre à jour les insights
2320
- radarBotInsights.innerHTML = '';
2321
- profileMessage.insights.forEach(insight => {
2322
- const insightElement = document.createElement('div');
2323
- insightElement.className = 'radar-insight-item';
2324
- insightElement.innerHTML = `
2325
- <div class="radar-insight-icon">${insight.icon}</div>
2326
- <div class="radar-insight-text">${insight.text}</div>
2327
- `;
2328
- radarBotInsights.appendChild(insightElement);
2329
- });
2330
- }
2331
-
2332
- // ================= RADAR =================
2333
- function drawRadar() {
2334
- const canvas = document.getElementById("radar");
2335
- if (!canvas) {
2336
- console.error("Canvas radar non trouvé!");
2337
- return;
2338
- }
2339
-
2340
- const ctx = canvas.getContext("2d");
2341
- const cx = canvas.width / 2;
2342
- const cy = canvas.height / 2;
2343
- const radius = 220;
2344
- const n = radarMetrics.length;
2345
-
2346
- ctx.clearRect(0, 0, canvas.width, canvas.height);
2347
-
2348
- // Dessiner le radar
2349
- for (let i = 1; i <= 5; i++) {
2350
- ctx.beginPath();
2351
- ctx.arc(cx, cy, (radius / 5) * i, 0, 2 * Math.PI);
2352
- ctx.strokeStyle = "#e0e0e0";
2353
- ctx.stroke();
2354
- }
2355
-
2356
- // Dessiner les axes
2357
- radarMetrics.forEach((m, i) => {
2358
- const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2359
-
2360
- ctx.beginPath();
2361
- ctx.moveTo(cx, cy);
2362
- ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
2363
- ctx.strokeStyle = "#b0bec5";
2364
- ctx.stroke();
2365
-
2366
- // Labels
2367
- const tx = cx + (radius + 35) * Math.cos(angle);
2368
- const ty = cy + (radius + 35) * Math.sin(angle);
2369
-
2370
- ctx.font = "12px Arial";
2371
- ctx.fillStyle = "#000";
2372
- ctx.textAlign = angle > Math.PI / 2 || angle < -Math.PI / 2 ? "right" : "left";
2373
- ctx.textBaseline = "middle";
2374
- ctx.fillText(`${m.label} : ${m.value}%`, tx, ty);
2375
- });
2376
-
2377
- // Dessiner le polygone
2378
- ctx.beginPath();
2379
- radarMetrics.forEach((m, i) => {
2380
- const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2381
- const r = radius * (m.value / 100);
2382
- const x = cx + r * Math.cos(angle);
2383
- const y = cy + r * Math.sin(angle);
2384
- i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
2385
- });
2386
- ctx.closePath();
2387
-
2388
- ctx.fillStyle = "rgba(25,118,210,0.25)";
2389
- ctx.fill();
2390
- ctx.strokeStyle = "#1976D2";
2391
- ctx.lineWidth = 2;
2392
- ctx.stroke();
2393
-
2394
- // Dessiner les points
2395
- radarMetrics.forEach((m, i) => {
2396
- const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2397
- const r = radius * (m.value / 100);
2398
- const x = cx + r * Math.cos(angle);
2399
- const y = cy + r * Math.sin(angle);
2400
 
2401
- ctx.beginPath();
2402
- ctx.arc(x, y, 4, 0, 2 * Math.PI);
2403
- ctx.fillStyle = "#1976D2";
2404
- ctx.fill();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2405
  });
2406
  }
2407
 
2408
- // ================= HEATMAP ENRICHIE =================
2409
- function drawEnrichedHeatmap(scenario) {
2410
  const canvas = document.getElementById("heatmap");
2411
  if (!canvas) return;
2412
 
2413
  const ctx = canvas.getContext("2d");
2414
- const cellSize = 25;
2415
- const padding = 2;
2416
  const days = ["L", "M", "M", "J", "V", "S", "D"];
2417
  const weeks = 4;
2418
  const totalDays = weeks * 7;
@@ -2422,17 +1956,17 @@ function drawEnrichedHeatmap(scenario) {
2422
  // Titre enrichi
2423
  const scenarioTitles = {
2424
  1: {
2425
- title: "Vous êtes engagé mais désorganisé",
2426
  emoji: "😅",
2427
  pattern: "Effort concentré avant échéances"
2428
  },
2429
  2: {
2430
- title: "Vous êtes actif mais peu efficace",
2431
  emoji: "😰",
2432
- pattern: "Démarrage lent avec accélération tardive"
2433
  },
2434
  3: {
2435
- title: "Vous êtes autonome et stratégique",
2436
  emoji: "😊",
2437
  pattern: "Travail régulier et équilibré"
2438
  }
@@ -2444,17 +1978,17 @@ function drawEnrichedHeatmap(scenario) {
2444
  pattern: "Schéma à analyser"
2445
  };
2446
 
2447
- ctx.font = "bold 18px Arial";
2448
  ctx.fillStyle = "#1976D2";
2449
  ctx.textAlign = "center";
2450
- ctx.fillText(`${scenarioInfo.emoji} ${scenarioInfo.title}`, canvas.width / 2, 30);
2451
 
2452
- ctx.font = "14px Arial";
2453
  ctx.fillStyle = "#666";
2454
- ctx.fillText(`Schéma détecté : ${scenarioInfo.pattern}`, canvas.width / 2, 55);
2455
 
2456
  // Générer les données d'activité selon le scénario
2457
- const activityData = generatePersistenceData(scenario.id, totalDays);
2458
 
2459
  // Dessiner la heatmap
2460
  const colors = ["#EBEDF0", "#C6E48B", "#7BC96F", "#239A3B", "#196127"];
@@ -2463,8 +1997,8 @@ function drawEnrichedHeatmap(scenario) {
2463
  const week = Math.floor(day / 7);
2464
  const weekday = day % 7;
2465
 
2466
- const x = 45 + week * (cellSize * 7 + padding * 7) + weekday * (cellSize + padding);
2467
- const y = 80 + weekday * (cellSize + padding);
2468
 
2469
  const intensity = activityData[day];
2470
 
@@ -2475,42 +2009,72 @@ function drawEnrichedHeatmap(scenario) {
2475
  // Bordure avec indication des échéances (vendredi = jour important)
2476
  if (weekday === 4) { // Vendredi
2477
  ctx.strokeStyle = "#FF6B6B";
2478
- ctx.lineWidth = 2;
2479
  } else {
2480
  ctx.strokeStyle = intensity > 0 ? "#239A3B" : "#eee";
2481
- ctx.lineWidth = 1;
2482
  }
2483
  ctx.strokeRect(x, y, cellSize, cellSize);
2484
-
2485
- // Indicateur de persévérance (points colorés)
2486
- if (intensity >= 3) {
2487
- // Point rouge pour forte activité (indice possible cram)
2488
- ctx.fillStyle = intensity === 4 ? "#FF6B6B" : "#FFD166";
2489
- ctx.beginPath();
2490
- ctx.arc(x + cellSize - 5, y + 5, 3, 0, Math.PI * 2);
2491
- ctx.fill();
2492
- }
2493
  }
2494
 
2495
- // Analyser et afficher les métriques de persévérance
2496
- analyzePersistenceMetrics(activityData, scenario.id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2497
  }
2498
 
2499
- // Générer des données de persévérance selon le scénario
2500
- function generatePersistenceData(scenarioId, totalDays) {
2501
  const data = new Array(totalDays).fill(0);
2502
 
2503
  switch(scenarioId) {
2504
  case 1: // Scénario désorganisé - Effort concentré avant échéances
2505
  for (let i = 0; i < totalDays; i++) {
2506
  const weekday = i % 7;
2507
- // Effort concentré les jeudis et vendredis (jours 3 et 4)
2508
  if (weekday === 3 || weekday === 4) { // Jeudi et vendredi
2509
- data[i] = Math.floor(Math.random() * 2) + 3; // 3-4 (forte activité)
2510
  } else if (weekday === 5 || weekday === 6) { // Weekend
2511
- data[i] = Math.floor(Math.random() * 2); // 0-1 (très faible)
2512
  } else {
2513
- data[i] = Math.floor(Math.random() * 2) + 1; // 1-2 (faible)
2514
  }
2515
  }
2516
  break;
@@ -2519,11 +2083,11 @@ function generatePersistenceData(scenarioId, totalDays) {
2519
  for (let i = 0; i < totalDays; i++) {
2520
  const progress = i / totalDays;
2521
  if (progress < 0.3) {
2522
- data[i] = Math.floor(Math.random() * 2); // 0-1 (début très faible)
2523
  } else if (progress > 0.7) {
2524
- data[i] = Math.floor(Math.random() * 2) + 3; // 3-4 (fin forte)
2525
  } else {
2526
- data[i] = Math.floor(Math.random() * 2) + 1; // 1-2 (milieu faible)
2527
  }
2528
  }
2529
  break;
@@ -2531,17 +2095,15 @@ function generatePersistenceData(scenarioId, totalDays) {
2531
  case 3: // Scénario stratégique - Travail régulier
2532
  for (let i = 0; i < totalDays; i++) {
2533
  const weekday = i % 7;
2534
- // Travail régulier et équilibré toute la semaine
2535
  if (weekday === 5 || weekday === 6) { // Weekend léger
2536
  data[i] = Math.floor(Math.random() * 2); // 0-1
2537
  } else {
2538
- data[i] = Math.floor(Math.random() * 2) + 2; // 2-3 (régulier)
2539
  }
2540
  }
2541
  break;
2542
 
2543
  default:
2544
- // Pattern par défaut
2545
  for (let i = 0; i < totalDays; i++) {
2546
  data[i] = Math.floor(Math.random() * 5); // 0-4 aléatoire
2547
  }
@@ -2550,185 +2112,163 @@ function generatePersistenceData(scenarioId, totalDays) {
2550
  return data;
2551
  }
2552
 
2553
- // Analyser les métriques de persévérance
2554
- function analyzePersistenceMetrics(activityData, scenarioId) {
2555
  const totalDays = activityData.length;
2556
- const weeks = Math.ceil(totalDays / 7);
2557
 
2558
  // 1. Calculer la régularité (écart-type)
2559
  const avgActivity = activityData.reduce((a, b) => a + b, 0) / totalDays;
2560
  const variance = activityData.reduce((a, b) => a + Math.pow(b - avgActivity, 2), 0) / totalDays;
2561
  const stdDev = Math.sqrt(variance);
2562
- const regularity = Math.max(0, 100 - stdDev * 25); // Score de 0-100
2563
 
2564
  // 2. Identifier le schéma d'effort
2565
- let pattern = "Indéterminé";
2566
- let patternDescription = "";
2567
- let patternColor = "#666";
2568
 
2569
- // Analyser la distribution par semaine
2570
  const weeklyPatterns = [];
2571
- for (let w = 0; w < weeks; w++) {
2572
  const weekData = activityData.slice(w * 7, Math.min((w + 1) * 7, totalDays));
2573
  if (weekData.length < 5) continue;
2574
 
2575
  const weekAvg = weekData.reduce((a, b) => a + b, 0) / weekData.length;
2576
 
2577
- // Vérifier les patterns
2578
  if (weekData[4] > weekAvg * 1.5 && weekData[3] > weekAvg * 1.3) {
2579
- weeklyPatterns.push("deadline"); // Pic jeudi/vendredi
 
2580
  } else if (weekData[0] < weekAvg * 0.7 && weekData[4] > weekAvg * 1.2) {
2581
- weeklyPatterns.push("acceleration"); // Démarrage lent, fin forte
2582
- } else if (Math.max(...weekData) - Math.min(...weekData) < 1.5) {
2583
- weeklyPatterns.push("regular"); // Régulier
2584
- } else if (weekData[5] < weekAvg * 0.5 && weekData[6] < weekAvg * 0.5) {
2585
- weeklyPatterns.push("weekend_break"); // Pause weekend
2586
- }
2587
- }
2588
-
2589
- // Déterminer le pattern dominant
2590
- let dominantPattern = "regular"; // Par défaut
2591
- if (weeklyPatterns.length > 0) {
2592
- const patternCounts = weeklyPatterns.reduce((acc, val) => {
2593
- acc[val] = (acc[val] || 0) + 1;
2594
- return acc;
2595
- }, {});
2596
-
2597
- dominantPattern = Object.keys(patternCounts).reduce((a, b) =>
2598
- patternCounts[a] > patternCounts[b] ? a : b, "regular"
2599
- );
2600
- }
2601
-
2602
- // Associer les descriptions
2603
- const patternMap = {
2604
- "regular": {
2605
- name: "Travail régulier",
2606
- desc: "Effort équilibré tout au long de la semaine avec une bonne constance",
2607
- color: "#43A047"
2608
- },
2609
- "deadline": {
2610
- name: "Effort concentré avant échéances",
2611
- desc: "Pic d'activité marqué les jeudis et vendredis, typique du 'cramming'",
2612
- color: "#E53935"
2613
- },
2614
- "acceleration": {
2615
- name: "Accélération progressive",
2616
- desc: "Démarrage lent en début de semaine avec accélération avant les deadlines",
2617
- color: "#FB8C00"
2618
- },
2619
- "weekend_break": {
2620
- name: "Pause weekend marquée",
2621
- desc: "Activité réduite le weekend avec reprise en début de semaine",
2622
- color: "#2196F3"
2623
  }
2624
- };
2625
-
2626
- if (patternMap[dominantPattern]) {
2627
- pattern = patternMap[dominantPattern].name;
2628
- patternDescription = patternMap[dominantPattern].desc;
2629
- patternColor = patternMap[dominantPattern].color;
2630
  }
2631
 
2632
  // 3. Calculer la gestion des échéances
2633
  const deadlineDays = activityData.filter((_, index) => index % 7 === 3 || index % 7 === 4);
2634
  const nonDeadlineDays = activityData.filter((_, index) => index % 7 !== 3 && index % 7 !== 4);
2635
 
2636
- const deadlineAvg = deadlineDays.length > 0 ?
2637
- deadlineDays.reduce((a, b) => a + b, 0) / deadlineDays.length : 0;
2638
- const nonDeadlineAvg = nonDeadlineDays.length > 0 ?
2639
- nonDeadlineDays.reduce((a, b) => a + b, 0) / nonDeadlineDays.length : 0;
2640
-
2641
  let deadlineScore = 50;
2642
- if (deadlineAvg > 0 && nonDeadlineAvg > 0) {
2643
- const ratio = deadlineAvg / nonDeadlineAvg;
2644
- if (ratio > 1.5) {
2645
- deadlineScore = Math.min(100, 30 + (ratio - 1.5) * 40);
2646
- } else if (ratio < 0.8) {
2647
- deadlineScore = Math.max(0, 70 - (0.8 - ratio) * 50);
2648
- } else {
2649
- deadlineScore = 65 + Math.random() * 20;
2650
- }
2651
- }
2652
-
2653
- // Mettre à jour l'interface
2654
- document.getElementById("regularityScore").textContent = Math.round(regularity) + "%";
2655
- document.getElementById("regularityScore").style.color = regularity > 70 ? "#43A047" : regularity > 40 ? "#FB8C00" : "#E53935";
2656
-
2657
- document.getElementById("effortPattern").textContent = pattern;
2658
- document.getElementById("effortPattern").style.color = patternColor;
2659
-
2660
- document.getElementById("deadlineScore").textContent = Math.round(deadlineScore) + "%";
2661
- document.getElementById("deadlineScore").style.color = deadlineScore > 70 ? "#43A047" : deadlineScore > 40 ? "#FB8C00" : "#E53935";
2662
-
2663
- // Mettre à jour l'analyse textuelle
2664
- document.getElementById("regularityText").textContent =
2665
- regularity > 75 ? "Excellente régularité ! Travail stable et constant dans le temps" :
2666
- regularity > 60 ? "Bonne régularité avec quelques variations acceptables" :
2667
- regularity > 40 ? "Régularité moyenne, rythme de travail avec des hauts et des bas" :
2668
- "Faible régularité, rythme de travail très irrégulier avec des pics et des creux";
2669
-
2670
- document.getElementById("patternText").textContent = patternDescription;
2671
-
2672
- // Générer des recommandations personnalisées
2673
- let recommendations = [];
2674
-
2675
- if (regularity < 60) {
2676
- recommendations.push("Essayez d'établir un planning hebdomadaire fixe avec des créaux réguliers");
2677
- }
2678
-
2679
- if (dominantPattern === "deadline") {
2680
- recommendations.push("Anticipez les tâches importantes dès le début de semaine plutôt qu'en fin");
2681
- recommendations.push("Répartissez le travail sur plusieurs jours pour éviter le 'cramming'");
2682
  }
2683
 
2684
- if (dominantPattern === "acceleration") {
2685
- recommendations.push("Commencez plus tôt dans la semaine pour éviter l'accélération de dernière minute");
2686
- }
 
2687
 
2688
- if (deadlineScore < 50) {
2689
- recommendations.push("Équilibrez mieux votre effort entre les jours avec et sans échéance");
 
 
 
 
 
 
 
 
2690
  }
2691
 
2692
- if (recommendations.length === 0) {
2693
- recommendations.push("Continuez ainsi ! Votre gestion du temps est efficace et équilibrée");
 
 
 
 
 
 
 
 
 
 
 
 
2694
  }
2695
-
2696
- document.getElementById("recommendationText").textContent = recommendations.join(". ") + ".";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2697
  }
2698
 
2699
- // Changer le mode d'analyse
2700
- function changePersistenceAnalysis() {
2701
- const mode = document.getElementById("persistenceMode").value;
2702
- const currentScenario = scenarios[currentScenarioIndex];
2703
-
2704
- // Mettre à jour l'affichage selon le mode
2705
- const analysisDiv = document.getElementById("persistenceAnalysis");
2706
- const heatmapCanvas = document.getElementById("heatmap");
2707
- const ctx = heatmapCanvas.getContext("2d");
2708
-
2709
- // Effacer et redessiner avec des annotations spécifiques
2710
- drawEnrichedHeatmap(currentScenario);
2711
-
2712
- // Ajouter des annotations spécifiques au mode
2713
- ctx.font = "14px Arial";
2714
- ctx.fillStyle = "#1976D2";
2715
- ctx.textAlign = "center";
2716
 
2717
- switch(mode) {
2718
- case "regularity":
2719
- ctx.fillText("📊 Analyse de la régularité - Écart-type des activités", heatmapCanvas.width / 2, 280);
2720
- break;
2721
- case "effortPattern":
2722
- ctx.fillText("🔄 Identification du schéma d'effort dominant", heatmapCanvas.width / 2, 280);
2723
- break;
2724
- case "deadline":
2725
- ctx.fillText("⏰ Focus sur la gestion des échéances (jeudis/vendredis)", heatmapCanvas.width / 2, 280);
2726
- break;
2727
- case "combined":
2728
- ctx.fillText("🎯 Vue combinée : Régularité + Schéma + Échéances", heatmapCanvas.width / 2, 280);
2729
- break;
2730
  }
2731
- }
 
 
 
 
 
2732
 
2733
  // ================= MÉTRIQUES DE CONFIANCE =================
2734
  function initTrustStars(){
@@ -2897,7 +2437,6 @@ function initTrustSave(){
2897
  // Récupérer les informations conditionnelles
2898
  let evaluatorName = "";
2899
  let evaluatorRole = "";
2900
- let evaluatorInstitution = "";
2901
  let expertiseLevel = "";
2902
  let messageMastery = "";
2903
 
@@ -3181,50 +2720,44 @@ function showNotification(title, message, type = "info") {
3181
  }
3182
  }
3183
 
3184
- // Fonction de test
3185
- window.testTrustMetrics = function() {
3186
- console.log("=== TEST MÉTRIQUES DE CONFIANCE ===");
 
3187
 
3188
- // Tester quelques combinaisons
3189
- const tests = [
3190
- { nom: "Parfait", valeurs: { AR: 5, AE: 5, ESR: 5, SDM: 5, SM: 5 } },
3191
- { nom: "Moyen", valeurs: { AR: 3, AE: 3, ESR: 3, SDM: 3, SM: 3 } },
3192
- { nom: "Faible", valeurs: { AR: 1, AE: 2, ESR: 1, SDM: 2, SM: 1 } },
3193
- { nom: "Mixte", valeurs: { AR: 5, AE: 4, ESR: 3, SDM: 2, SM: 1 } }
3194
- ];
3195
 
3196
- tests.forEach(test => {
3197
- console.log(`\nTest: ${test.nom}`);
3198
-
3199
- // Appliquer les valeurs
3200
- for (const metric in test.valeurs) {
3201
- if (trustMetrics.hasOwnProperty(metric)) {
3202
- trustMetrics[metric] = test.valeurs[metric];
3203
- }
3204
- }
3205
-
3206
- // Calculer
3207
- const score = updateTrustBar();
3208
- console.log(`Résultat: ${score}%`);
3209
-
3210
- // Réinitialiser pour le prochain test
3211
- for (const metric in trustMetrics) {
3212
- trustMetrics[metric] = 0;
3213
- }
3214
- });
3215
 
3216
- console.log("=== FIN TESTS ===");
3217
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3218
 
3219
  // Exposer les fonctions globales
3220
  window.changePersistenceAnalysis = changePersistenceAnalysis;
3221
- window.drawEnrichedHeatmap = drawEnrichedHeatmap;
3222
  window.updateStats = updateStats;
3223
  window.showNotification = showNotification;
3224
  window.fillSampleEvaluator = fillSampleEvaluator;
3225
  window.clearEvaluatorFields = clearEvaluatorFields;
3226
- window.updateMetacognitionPanel = updateMetacognitionPanel;
3227
- window.updateRadarMetricsGrid = updateRadarMetricsGrid;
3228
  </script>
3229
 
3230
  </body>
 
319
  line-height: 1.5;
320
  }
321
 
322
+ /* ================= ONGLET 2: DASHBOARD ÉTUDIANT COMPACT ================= */
323
  #tab-dashboard .manifest-item {
324
  background: linear-gradient(135deg, #f9fbe7, #f0f4c3);
325
+ padding: 15px;
326
  border-radius: 12px;
327
  border-left: 6px solid #cddc39;
328
  margin: 15px 0;
329
  box-shadow: 0 3px 10px rgba(0,0,0,0.05);
330
+ font-size: 14px;
331
  }
332
 
333
  .manifest-item b {
334
  color: #689f38;
335
  }
336
 
337
+ /* ================= COMPÉTENCES COMPACTES ================= */
338
+ #competence-bars {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  background: white;
340
+ padding: 15px;
341
+ border-radius: 12px;
 
342
  border: 1px solid #e0e0e0;
343
+ margin: 15px 0;
344
  }
345
 
346
+ .compact-competences-grid {
 
347
  display: grid;
348
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
349
+ gap: 12px;
350
+ margin: 10px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  }
352
 
353
+ .compact-competence-item {
354
+ padding: 10px;
355
+ background: #f8f9fa;
356
+ border-radius: 8px;
357
+ border-left: 4px solid #1976D2;
358
+ transition: transform 0.2s;
359
  }
360
 
361
+ .compact-competence-item:hover {
362
+ transform: translateY(-2px);
363
+ background: #e3f2fd;
364
  }
365
 
366
+ .compact-competence-label {
367
+ font-size: 12px;
368
  font-weight: 600;
369
  color: #333;
370
  margin-bottom: 8px;
371
+ display: flex;
372
+ justify-content: space-between;
373
  }
374
 
375
+ .compact-competence-bar {
376
+ height: 10px;
377
+ background: #e0e0e0;
378
+ border-radius: 5px;
379
+ overflow: hidden;
380
  margin: 5px 0;
381
  }
382
 
383
+ .compact-competence-fill {
384
+ height: 100%;
385
+ border-radius: 5px;
386
+ color: white;
387
+ font-size: 9px;
388
+ text-align: right;
389
+ padding-right: 5px;
390
+ line-height: 10px;
391
+ font-weight: bold;
392
+ transition: width 0.5s ease;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
393
  }
394
 
395
+ /* ================= LÉGENDE RADAR COMPACTE ================= */
396
+ .compact-radar-legend {
397
  display: flex;
398
+ justify-content: center;
399
  gap: 15px;
400
+ margin: 15px 0;
401
+ flex-wrap: wrap;
402
+ padding: 10px;
403
+ background: white;
404
+ border-radius: 8px;
405
+ border: 1px solid #e0e0e0;
406
  }
407
 
408
+ .compact-legend-item {
 
 
 
 
 
 
409
  display: flex;
410
  align-items: center;
411
+ gap: 8px;
412
+ padding: 6px 10px;
413
+ background: #f8f9fa;
414
+ border-radius: 6px;
415
+ font-size: 12px;
 
 
 
 
 
 
 
 
 
416
  }
417
 
418
+ .compact-legend-color {
419
+ width: 16px;
420
+ height: 16px;
421
+ border-radius: 4px;
422
+ border: 2px solid white;
 
 
423
  }
424
 
425
+ .compact-legend-low { background: linear-gradient(135deg, #e53935, #f44336); }
426
+ .compact-legend-medium { background: linear-gradient(135deg, #fb8c00, #ff9800); }
427
+ .compact-legend-high { background: linear-gradient(135deg, #43a047, #4caf50); }
 
 
 
428
 
429
+ /* ================= RADAR COMPACT ================= */
430
+ #radar-container {
431
  background: white;
432
+ padding: 15px;
433
  border-radius: 12px;
434
+ border: 1px solid #e0e0e0;
435
+ margin: 15px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  }
437
 
438
+ #radar {
439
+ max-width: 100%;
440
+ height: auto;
441
  }
442
 
443
+ /* ================= MESSAGE BOT RADAR COMPACT ================= */
444
+ .compact-radar-bot-message {
445
  background: linear-gradient(135deg, #E3F2FD, #BBDEFB);
446
+ padding: 15px;
447
+ border-radius: 10px;
448
+ border-left: 4px solid #1976D2;
449
+ margin: 15px 0;
 
 
450
  }
451
 
452
+ .compact-radar-bot-header {
453
  display: flex;
454
  align-items: center;
455
+ gap: 10px;
456
+ margin-bottom: 10px;
457
  }
458
 
459
+ .compact-radar-bot-icon {
460
+ font-size: 20px;
461
  background: #1976D2;
462
  color: white;
463
+ width: 40px;
464
+ height: 40px;
465
  border-radius: 50%;
466
  display: flex;
467
  align-items: center;
468
  justify-content: center;
469
  }
470
 
471
+ .compact-radar-bot-title {
472
+ font-size: 16px;
473
  font-weight: 600;
474
  color: #1976D2;
475
  margin: 0;
476
  }
477
 
478
+ .compact-radar-bot-content {
479
+ font-size: 14px;
480
+ line-height: 1.5;
481
  color: #333;
482
  margin: 0;
483
  }
484
 
485
+ .compact-radar-bot-insights {
486
  background: white;
487
+ padding: 10px;
488
+ border-radius: 8px;
489
+ margin-top: 10px;
490
  border: 1px solid #E3F2FD;
491
  }
492
 
493
+ .compact-radar-insight-item {
494
  display: flex;
495
  align-items: center;
496
+ gap: 8px;
497
+ margin-bottom: 6px;
498
+ padding: 6px 10px;
499
  border-radius: 6px;
500
  background: #F5F5F5;
501
+ font-size: 12px;
502
  }
503
 
504
+ /* ================= GRILLE DES MÉTRIQUES RADAR COMPACTE ================= */
505
+ .compact-radar-metrics-grid {
506
+ display: grid;
507
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
508
+ gap: 12px;
509
+ margin: 15px 0;
 
 
 
 
 
 
 
 
510
  }
511
 
512
+ .compact-metric-card {
 
 
 
 
 
 
 
513
  background: white;
514
  border-radius: 10px;
515
+ padding: 15px;
516
+ box-shadow: 0 3px 8px rgba(0,0,0,0.08);
517
+ border-left: 4px solid #1976D2;
518
+ transition: transform 0.3s;
519
+ text-align: center;
520
  }
521
 
522
+ .compact-metric-card:hover {
523
+ transform: translateY(-3px);
524
+ box-shadow: 0 5px 15px rgba(0,0,0,0.12);
 
 
 
 
 
 
 
525
  }
526
 
527
+ .compact-metric-icon {
528
+ font-size: 24px;
529
+ margin-bottom: 8px;
530
  }
531
 
532
+ .compact-metric-name {
533
+ font-weight: 600;
534
+ color: #333;
535
+ margin-bottom: 5px;
536
+ font-size: 14px;
 
537
  }
538
 
539
+ .compact-metric-value {
540
+ font-size: 20px;
541
+ font-weight: bold;
542
+ color: #1976D2;
543
+ margin: 5px 0;
544
  }
545
 
546
+ .compact-metric-value.high { color: #43A047; }
547
+ .compact-metric-value.medium { color: #FB8C00; }
548
+ .compact-metric-value.low { color: #E53935; }
549
 
550
+ .compact-metric-description {
551
+ font-size: 11px;
552
+ color: #666;
553
+ margin-top: 5px;
554
+ line-height: 1.3;
555
  }
556
 
557
+ /* ================= HEATMAP COMPACT ================= */
558
+ .compact-heatmap-and-indicators {
559
+ background: white;
560
+ padding: 15px;
561
+ border-radius: 12px;
562
+ border: 1px solid #e0e0e0;
563
  margin: 15px 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
564
  }
565
 
566
+ .compact-heatmap-analysis {
567
+ margin-bottom: 15px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
568
  }
569
 
570
+ .compact-analysis-controls {
571
  display: flex;
572
  align-items: center;
573
+ gap: 10px;
574
+ margin-bottom: 15px;
575
+ padding: 10px;
576
  background: #f8f9fa;
577
+ border-radius: 8px;
578
  }
579
 
580
+ .compact-analysis-controls label {
581
  font-weight: 600;
582
  color: #1976D2;
583
+ font-size: 14px;
584
  }
585
 
586
+ .compact-analysis-controls select {
587
+ padding: 8px 12px;
588
+ border-radius: 6px;
589
  border: 2px solid #1976D2;
590
  background: white;
591
  color: #333;
592
  font-weight: 500;
593
  cursor: pointer;
 
594
  flex-grow: 1;
595
+ font-size: 14px;
596
  }
597
 
598
+ #heatmap {
599
+ max-width: 100%;
600
+ height: auto;
601
+ border-radius: 8px;
602
  }
603
 
604
+ /* ================= LÉGENDE HEATMAP COMPACTE ================= */
605
+ .compact-enriched-legend {
606
  background: white;
 
607
  padding: 15px;
608
+ border-radius: 10px;
609
  border: 1px solid #e0e0e0;
610
+ margin: 15px 0;
 
 
 
 
 
 
 
 
 
 
 
611
  }
612
 
613
+ .compact-legend-section h5 {
614
  color: #1976D2;
615
+ margin-bottom: 10px;
616
+ font-size: 14px;
617
  display: flex;
618
  align-items: center;
619
+ gap: 6px;
620
  }
621
 
622
+ .compact-legend-grid {
623
  display: grid;
624
  grid-template-columns: repeat(3, 1fr);
625
+ gap: 8px;
626
  }
627
 
628
+ .compact-legend-item-small {
629
  display: flex;
630
  align-items: center;
631
+ gap: 6px;
632
+ font-size: 11px;
633
  }
634
 
635
+ .compact-legend-color-small {
636
+ width: 16px;
637
+ height: 16px;
638
  border-radius: 4px;
639
  border: 2px solid white;
640
  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
641
  }
642
 
643
+ /* ================= INDICATEURS DE PERSÉVÉRANCE COMPACTS ================= */
644
+ .compact-persistence-analysis {
645
+ background: linear-gradient(135deg, #e3f2fd, #f3e5f5);
646
+ padding: 15px;
647
+ border-radius: 10px;
648
+ border-left: 4px solid #1976D2;
649
+ margin: 15px 0;
650
+ }
651
+
652
+ .compact-persistence-indicators {
653
  display: flex;
654
  flex-direction: column;
655
+ gap: 8px;
656
+ margin-bottom: 10px;
657
  }
658
 
659
+ .compact-indicator {
660
  display: flex;
661
  align-items: center;
662
+ gap: 8px;
663
+ padding: 8px 10px;
664
  background: white;
665
+ border-radius: 6px;
666
+ font-size: 12px;
667
+ border-left: 3px solid #1976D2;
668
  }
669
 
670
+ .compact-indicator-dot {
671
+ width: 10px;
672
+ height: 10px;
673
  border-radius: 50%;
674
  }
675
 
676
+ .compact-persistence-text {
677
+ font-size: 12px;
678
+ line-height: 1.4;
 
 
 
 
 
 
 
 
 
 
 
 
 
679
  }
680
 
681
+ .compact-persistence-text > div {
682
+ margin-bottom: 6px;
683
+ padding: 8px;
684
  background: white;
685
+ border-radius: 6px;
686
  border-left: 3px solid #1976D2;
687
  }
688
 
 
 
 
 
 
 
 
 
 
 
 
689
  /* ================= ONGLET 3: MESSAGE RÉFLEXIF ET ÉVALUATION ================= */
690
  #tab-evaluation #reflagent {
691
  background: linear-gradient(135deg, #e8f5e9, #c8e6c9);
 
903
  padding: 20px;
904
  }
905
 
 
 
 
 
 
 
 
 
 
 
 
 
 
906
  .tabs {
907
  flex-direction: column;
908
  }
 
933
  justify-content: center;
934
  }
935
 
936
+ .gdpr-options {
 
 
 
 
 
937
  flex-direction: column;
 
938
  gap: 10px;
939
  }
940
 
941
+ .gdpr-option {
942
+ min-width: 100%;
 
 
 
 
943
  }
944
 
945
+ .compact-competences-grid {
946
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
 
 
947
  }
948
 
949
+ .compact-radar-metrics-grid {
950
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
951
  }
952
 
953
+ .compact-radar-legend {
954
  flex-direction: column;
955
+ align-items: center;
956
+ gap: 8px;
957
  }
958
 
959
+ .compact-legend-grid {
960
+ grid-template-columns: repeat(2, 1fr);
 
961
  }
962
 
963
+ .compact-analysis-controls {
964
+ flex-direction: column;
965
+ align-items: stretch;
966
  }
967
 
968
+ .compact-persistence-indicators {
969
+ flex-direction: column;
970
  }
971
  }
972
 
 
1224
  </div>
1225
  </div>
1226
 
1227
+ <!-- ONGLET 2: DASHBOARD ÉTUDIANT COMPACT -->
1228
  <div id="tab-dashboard" class="tab-content">
1229
  <h3>📝 Manifeste étudiant</h3>
1230
  <div id="manifest-list">
 
1235
 
1236
  <h3>📊 Progression par compétence</h3>
1237
  <div id="competence-bars">
1238
+ <div id="compact-competences">
1239
+ <em>Chargement des compétences...</em>
1240
+ </div>
1241
  </div>
1242
 
1243
+ <!-- LÉGENDE RADAR COMPACTE -->
1244
+ <div class="compact-radar-legend">
1245
+ <div class="compact-legend-item">
1246
+ <div class="compact-legend-color compact-legend-low"></div>
1247
  <span>Faible (0-50%)</span>
1248
  </div>
1249
+ <div class="compact-legend-item">
1250
+ <div class="compact-legend-color compact-legend-medium"></div>
1251
  <span>Moyen (50-70%)</span>
1252
  </div>
1253
+ <div class="compact-legend-item">
1254
+ <div class="compact-legend-color compact-legend-high"></div>
1255
  <span>Élevé (70-100%)</span>
1256
  </div>
1257
  </div>
1258
 
1259
  <h3>🕸️ Radar – Learning Analytics</h3>
1260
 
1261
+ <!-- Grille des métriques radar compacte -->
1262
+ <div class="compact-radar-metrics-grid" id="compact-radar-metrics-grid">
1263
+ <!-- Les métriques seront ajoutées dynamiquement -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1264
  </div>
1265
 
1266
+ <!-- Container Radar et Bot Message -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1267
  <div id="radar-container">
1268
+ <div style="display: flex; gap: 20px; flex-wrap: wrap;">
1269
+ <!-- Message Bot Radar Compact -->
1270
+ <div class="compact-radar-bot-message" style="flex: 1; min-width: 300px;">
1271
+ <div class="compact-radar-bot-header">
1272
+ <div class="compact-radar-bot-icon">🎯</div>
1273
+ <h4 class="compact-radar-bot-title">Analyse de Profil</h4>
 
 
 
 
 
 
 
 
1274
  </div>
1275
+ <p class="compact-radar-bot-content" id="compact-radar-bot-content">Analyse en cours...</p>
1276
+ <div class="compact-radar-bot-insights">
1277
+ <div id="compact-radar-bot-insights">
1278
+ <!-- Les insights seront ajoutés dynamiquement -->
1279
+ </div>
 
 
 
1280
  </div>
1281
  </div>
1282
+
1283
+ <!-- Canvas Radar Compact -->
1284
+ <div style="flex: 1; min-width: 300px; text-align: center;">
1285
+ <canvas id="radar" width="500" height="500" style="max-width: 100%; height: auto;"></canvas>
1286
+ </div>
1287
  </div>
1288
  </div>
1289
 
1290
+ <!-- HEATMAP COMPACTE -->
1291
+ <div class="compact-heatmap-and-indicators">
 
 
1292
  <h3>🔥 Heatmap d'activité - Analyse de Persévérance</h3>
1293
 
1294
+ <div class="compact-heatmap-analysis">
1295
+ <div class="compact-analysis-controls">
1296
+ <label for="persistenceMode">Mode d'analyse :</label>
1297
+ <select id="persistenceMode" onchange="changePersistenceAnalysis()">
1298
+ <option value="regularity">📊 Régularité du travail</option>
1299
+ <option value="effortPattern">🔄 Schéma d'effort</option>
1300
+ <option value="deadline"> Gestion des échéances</option>
1301
+ <option value="combined">🎯 Vue combinée</option>
1302
+ </select>
1303
+ </div>
1304
+
1305
+ <!-- Canvas pour le heatmap -->
1306
+ <canvas id="heatmap" width="800" height="250" style="max-width: 100%; height: auto;"></canvas>
1307
  </div>
1308
 
1309
+ <!-- Légende des niveaux d'activité compacte -->
1310
+ <div class="compact-enriched-legend">
1311
+ <div class="compact-legend-section">
 
 
 
1312
  <h5>📈 Niveaux d'activité</h5>
1313
+ <div class="compact-legend-grid">
1314
+ <div class="compact-legend-item-small">
1315
+ <div class="compact-legend-color-small" style="background:#EBEDF0;"></div>
1316
  <span>Aucune activité</span>
1317
  </div>
1318
+ <div class="compact-legend-item-small">
1319
+ <div class="compact-legend-color-small" style="background:#C6E48B;"></div>
1320
  <span>Faible activité</span>
1321
  </div>
1322
+ <div class="compact-legend-item-small">
1323
+ <div class="compact-legend-color-small" style="background:#7BC96F;"></div>
1324
+ <span>Activité modérée</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1325
  </div>
1326
+ <div class="compact-legend-item-small">
1327
+ <div class="compact-legend-color-small" style="background:#239A3B;"></div>
1328
+ <span>Activité élevée</span>
1329
  </div>
1330
+ <div class="compact-legend-item-small">
1331
+ <div class="compact-legend-color-small" style="background:#196127;"></div>
1332
+ <span>Activité intense</span>
1333
  </div>
1334
  </div>
1335
  </div>
1336
  </div>
1337
 
1338
+ <!-- Analyse de persévérance compacte -->
1339
+ <div class="compact-persistence-analysis" id="compact-persistenceAnalysis">
1340
+ <h5>🎯 Indicateurs de Persévérance</h5>
1341
+ <div class="compact-persistence-indicators">
1342
+ <div class="compact-indicator">
1343
+ <span class="compact-indicator-dot" style="background:#FF6B6B;"></span>
1344
+ <span>Régularité calculée : <strong id="compact-regularityScore">-</strong></span>
1345
+ </div>
1346
+ <div class="compact-indicator">
1347
+ <span class="compact-indicator-dot" style="background:#4ECDC4;"></span>
1348
+ <span>Schéma d'effort : <strong id="compact-effortPattern">-</strong></span>
1349
+ </div>
1350
+ <div class="compact-indicator">
1351
+ <span class="compact-indicator-dot" style="background:#FFD166;"></span>
1352
+ <span>Gestion échéances : <strong id="compact-deadlineScore">-</strong></span>
1353
+ </div>
1354
  </div>
1355
+
1356
+ <div class="compact-persistence-text" style="margin-top: 10px;">
1357
+ <div style="margin-bottom: 10px;">
1358
+ <strong>Schéma d'effort :</strong>
1359
+ <div style="margin-top: 5px; padding: 8px; background: #F5F5F5; border-radius: 6px; font-size: 13px;">
1360
+ <span id="compact-patternText">Analyse en cours...</span>
1361
+ </div>
1362
+ </div>
1363
+ <div>
1364
+ <strong>Persévérance et gestion des efforts :</strong>
1365
+ <div style="margin-top: 5px; padding: 10px; background: #F8F9FA; border-radius: 6px; border-left: 3px solid #1976D2;">
1366
+ <span id="compact-regularityText">Analyse en cours...</span>
1367
+ </div>
1368
+ </div>
1369
  </div>
1370
  </div>
1371
  </div>
 
1519
  "SM": 0.20
1520
  };
1521
 
1522
+ // MAPPING PERSÉVÉRANCE PAR PROFIL
1523
+ const perseveranceProfiles = {
1524
+ "Étudiant engagé": {
1525
+ level: "Très élevée",
1526
+ interpretation: "Efforts constants et durables, persévère même face aux difficultés",
1527
+ color: "#43A047"
1528
+ },
1529
+ "Étudiant actif mais inefficace": {
1530
+ level: "Moyenne",
1531
+ interpretation: "Efforts importants mais mal régulés, persévérance peu productive",
1532
+ color: "#FB8C00"
1533
+ },
1534
+ "Étudiant orienté vers le succès": {
1535
+ level: "Élevée",
1536
+ interpretation: "Persévérance principalement guidée par l'atteinte des objectifs",
1537
+ color: "#4CAF50"
1538
+ },
1539
+ "Étudiant motivé": {
1540
+ level: "Élevée",
1541
+ interpretation: "Engagement soutenu et continuité stable de l'effort",
1542
+ color: "#4CAF50"
1543
+ },
1544
+ "Étudiant surmotivé": {
1545
+ level: "Très élevée",
1546
+ interpretation: "Effort intense, parfois excessif, avec risque de surcharge",
1547
+ color: "#43A047"
1548
+ },
1549
+ "Étudiant stratégique": {
1550
+ level: "Élevée",
1551
+ interpretation: "Effort bien dosé, persévérance optimisée selon le rendement attendu",
1552
+ color: "#4CAF50"
1553
+ },
1554
+ "Étudiant en amélioration": {
1555
+ level: "Moyenne à élevée",
1556
+ interpretation: "Efforts croissants, persévérance en cours de structuration",
1557
+ color: "#FF9800"
1558
+ },
1559
+ "Étudiant en difficulté": {
1560
+ level: "Faible",
1561
+ interpretation: "Découragement fréquent et difficulté à maintenir l'effort",
1562
+ color: "#E53935"
1563
+ },
1564
+ "Étudiant évitant l'échec": {
1565
+ level: "Moyenne",
1566
+ interpretation: "Persévérance motivée par la peur de l'échec plutôt que par l'apprentissage",
1567
+ color: "#FB8C00"
1568
+ },
1569
+ "Étudiant à risque": {
1570
+ level: "Très faible",
1571
+ interpretation: "Abandon rapide et très faible tolérance à l'effort",
1572
+ color: "#C62828"
1573
+ },
1574
+ "Étudiant en progression": {
1575
+ level: "Élevée",
1576
+ interpretation: "Efforts réguliers et de mieux en mieux maîtrisés",
1577
+ color: "#4CAF50"
1578
+ },
1579
+ "Étudiant acceptant l'échec": {
1580
+ level: "Élevée",
1581
+ interpretation: "Bonne résilience, persévère malgré les erreurs et les échecs",
1582
+ color: "#4CAF50"
1583
+ },
1584
+ "Étudiant inactif": {
1585
+ level: "Très faible",
1586
+ interpretation: "Manque d'engagement, difficulté à initier et maintenir l'effort",
1587
+ color: "#C62828"
1588
+ },
1589
+ "Étudiant non engagé": {
1590
+ level: "Faible",
1591
+ interpretation: "Manque de motivation, efforts sporadiques et peu soutenus",
1592
+ color: "#E53935"
1593
+ },
1594
+ "Étudiant persévérant": {
1595
+ level: "Élevée",
1596
+ interpretation: "Constance dans l'effort malgré les doutes et difficultés",
1597
+ color: "#4CAF50"
1598
+ },
1599
+ "Étudiant actif": {
1600
+ level: "Moyenne",
1601
+ interpretation: "Efforts soutenus mais parfois désorganisés ou mal canalisés",
1602
+ color: "#FB8C00"
1603
+ }
1604
+ };
1605
+
1606
  // ================= INIT =================
1607
  document.addEventListener("DOMContentLoaded", () => {
1608
  console.log("✅ DOM chargé, initialisation...");
 
1702
  });
1703
  }
1704
 
 
1705
  // ================= CHARGER SCÉNARIO =================
1706
  function loadScenario(index) {
1707
  console.log("Chargement scénario", index);
 
1716
  // Mettre à jour le manifeste
1717
  document.getElementById("manifest-list").innerHTML = `
1718
  <div class="manifest-item">
1719
+ <b>Type de Manifest :</b> ${s.manifest.type}<br>
1720
  <b>Manifeste (écrit par l'étudiant) :</b> ${s.manifest.manifeste}<br>
1721
  <b>Description du Profil :</b> ${s.manifest.description}
1722
  </div>`;
1723
 
1724
+ // Mettre à jour les compétences compactes
1725
+ updateCompactCompetences(s.competences);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1726
 
1727
  // Mettre à jour le radar avec les nouvelles métriques
1728
  if (s.radar && s.radar.length > 0) {
 
1740
  });
1741
  }
1742
 
1743
+ // Mettre à jour la grille des métriques radar compacte
1744
+ updateCompactRadarMetricsGrid();
1745
 
1746
  // Mettre à jour le graphique radar
1747
  drawRadar();
1748
 
1749
+ // Mettre à jour le message bot radar compact
1750
+ updateCompactRadarBotMessage(s);
 
 
 
1751
 
1752
+ // Mettre à jour la heatmap enrichie compacte
1753
+ drawCompactEnrichedHeatmap(s);
1754
+
1755
+ // Mettre à jour la persévérance spécifique au profil
1756
+ updatePerseveranceProfile(s.title);
1757
 
1758
  // Mettre à jour le message ReflAgent
1759
  document.getElementById("reflagent").textContent = s.reflAgent;
 
1765
  updateStats();
1766
  }
1767
 
1768
+ // ================= FONCTIONS POUR LA VERSION COMPACTE =================
1769
+
1770
+ // Mettre à jour les compétences compactes
1771
+ function updateCompactCompetences(competences) {
1772
+ const container = document.getElementById("compact-competences");
1773
+ if (!container) return;
1774
+
1775
+ container.innerHTML = '';
1776
+
1777
+ competences.forEach(comp => {
1778
+ // Déterminer la couleur selon la valeur
1779
+ let color;
1780
+ if (comp.value < 50) color = '#E53935';
1781
+ else if (comp.value < 70) color = '#FB8C00';
1782
+ else color = '#43A047';
1783
+
1784
+ // Créer l'élément de compétence
1785
+ const compItem = document.createElement('div');
1786
+ compItem.className = 'compact-competence-item';
1787
+ compItem.innerHTML = `
1788
+ <div class="compact-competence-label">
1789
+ <span>${comp.label}</span>
1790
+ <span>${comp.value}%</span>
1791
+ </div>
1792
+ <div class="compact-competence-bar">
1793
+ <div class="compact-competence-fill" style="width: ${comp.value}%; background: ${color};">
1794
+ ${comp.value >= 10 ? comp.value + '%' : ''}
1795
+ </div>
1796
+ </div>
1797
+ `;
1798
+
1799
+ container.appendChild(compItem);
1800
+ });
1801
+ }
1802
+
1803
+ // Mettre à jour la grille des métriques radar compacte
1804
+ function updateCompactRadarMetricsGrid() {
1805
+ const grid = document.getElementById("compact-radar-metrics-grid");
1806
  if (!grid) return;
1807
 
1808
+ grid.innerHTML = '';
1809
 
1810
  radarMetrics.forEach(metric => {
1811
  // Déterminer la classe de couleur selon la valeur
 
1820
  else if (metric.label.includes("Connaissances")) icon = "🎓";
1821
  else if (metric.label.includes("Niveau moyen")) icon = "📈";
1822
  else if (metric.label.includes("Taux d'erreur")) icon = "🎯";
1823
+ else if (metric.label.includes("Achèvement")) icon = "🏁";
1824
+ else if (metric.label.includes("Interactions")) icon = "📚";
1825
+ else if (metric.label.includes("Domaines")) icon = "🔧";
1826
+
1827
+ // Déterminer la description
1828
+ let description = "";
1829
+ if (metric.label.includes("Démarrage")) description = "Rapidité d'initiation";
1830
+ else if (metric.label.includes("Connaissances")) description = "Acquis démontrés";
1831
+ else if (metric.label.includes("Niveau moyen")) description = "Moyenne des compétences";
1832
+ else if (metric.label.includes("Taux d'erreur")) description = "Précision et attention";
1833
+ else if (metric.label.includes("Achèvement")) description = "Terminaison des tâches";
1834
+ else if (metric.label.includes("Interactions")) description = "Utilisation supports";
1835
+ else if (metric.label.includes("Domaines")) description = "Étendue couverte";
1836
+
1837
+ const metricCard = document.createElement("div");
1838
+ metricCard.className = "compact-metric-card";
1839
+ metricCard.innerHTML = `
1840
+ <div class="compact-metric-icon">${icon}</div>
1841
+ <div class="compact-metric-name">${metric.label}</div>
1842
+ <div class="compact-metric-value ${colorClass}">${metric.value}%</div>
1843
+ <div class="compact-metric-description">${description}</div>
1844
+ `;
1845
+
1846
+ grid.appendChild(metricCard);
1847
+ });
1848
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1849
 
1850
+ // Mettre à jour le message bot radar compact
1851
+ function updateCompactRadarBotMessage(scenario) {
1852
+ const radarBotContent = document.getElementById("compact-radar-bot-content");
1853
+ const radarBotInsights = document.getElementById("compact-radar-bot-insights");
1854
+
1855
+ if (!radarBotContent || !radarBotInsights) return;
1856
+
1857
+ // Messages pour chaque profil basé sur le titre du scénario
1858
+ const profileMessages = {
1859
+ "Étudiant engagé": {
1860
+ title: "Étudiant Engagé et Motivé",
1861
+ message: "🎯 Ton engagement est impressionnant ! Tu démontres une forte volonté d'apprendre.",
1862
+ insights: [
1863
+ { icon: "🔥", text: "Motivation élevée" },
1864
+ { icon: "🎯", text: "Objectifs bien définis" },
1865
+ { icon: "📚", text: "Implication active" }
1866
+ ]
1867
+ },
1868
+ "Étudiant actif mais inefficace": {
1869
+ title: "Actif mais Peu Efficace",
1870
+ message: "📊 Tu es très actif mais ton taux d'erreur est élevé. Concentre-toi sur une compétence à la fois.",
1871
+ insights: [
1872
+ { icon: "⚡", text: "Activité élevée" },
1873
+ { icon: "⚠️", text: "Erreurs fréquentes" },
1874
+ { icon: "🎯", text: "Focus nécessaire" }
1875
+ ]
1876
+ },
1877
+ "Étudiant orienté vers le succès": {
1878
+ title: "Orientation Réussite",
1879
+ message: "🏆 Tu vises l'excellence avec détermination. Ta rigueur est exemplaire.",
1880
+ insights: [
1881
+ { icon: "⭐", text: "Excellence visée" },
1882
+ { icon: "🎯", text: "Objectifs ambitieux" },
1883
+ { icon: "📈", text: "Performance supérieure" }
1884
+ ]
1885
+ },
1886
+ "Étudiant motivé": {
1887
+ title: "Nouvellement Motivé",
1888
+ message: "🚀 Ta motivation est un excellent point de départ ! Progresse étape par étape.",
1889
+ insights: [
1890
+ { icon: "🌟", text: "Motivation récente" },
1891
+ { icon: "🧱", text: "Construction des bases" },
1892
+ { icon: "📖", text: "Curiosité ouverte" }
1893
+ ]
1894
+ },
1895
+ "Étudiant surmotivé": {
1896
+ title: "Surmotivé - Attention",
1897
+ message: "💥 Ton niveau d'investissement est exceptionnel, attention au risque de surmenage.",
1898
+ insights: [
1899
+ { icon: "⚡", text: "Investissement maximal" },
1900
+ { icon: "⚠️", text: "Risque de burnout" },
1901
+ { icon: "⚖️", text: "Équilibre nécessaire" }
1902
+ ]
1903
+ },
1904
+ "Étudiant stratégique": {
1905
+ title: "Stratégique et Efficient",
1906
+ message: "♟️ Tu abordes l'apprentissage avec intelligence et planification.",
1907
+ insights: [
1908
+ { icon: "🧠", text: "Approche réfléchie" },
1909
+ { icon: "🎯", text: "Optimisation efforts" },
1910
+ { icon: "📊", text: "Analyse des retours" }
1911
+ ]
1912
+ }
1913
+ };
1914
+
1915
+ // Récupérer le message pour le profil ou utiliser un message par défaut
1916
+ const profileMessage = profileMessages[scenario.title] || {
1917
+ title: "Profil d'Apprentissage",
1918
+ message: "Analyse de votre profil d'apprentissage en cours...",
1919
+ insights: [
1920
+ { icon: "📊", text: "Évaluation indicateurs" },
1921
+ { icon: "🎯", text: "Forces et améliorations" },
1922
+ { icon: "🚀", text: "Recommandations" }
1923
+ ]
1924
+ };
1925
+
1926
+ // Mettre à jour l'interface
1927
+ radarBotContent.innerHTML = `<strong>${profileMessage.title}</strong><br>${profileMessage.message}`;
1928
+
1929
+ // Mettre à jour les insights
1930
+ radarBotInsights.innerHTML = '';
1931
+ profileMessage.insights.forEach(insight => {
1932
+ const insightElement = document.createElement('div');
1933
+ insightElement.className = 'compact-radar-insight-item';
1934
+ insightElement.innerHTML = `
1935
+ <div class="radar-insight-icon">${insight.icon}</div>
1936
+ <div class="radar-insight-text">${insight.text}</div>
1937
+ `;
1938
+ radarBotInsights.appendChild(insightElement);
1939
  });
1940
  }
1941
 
1942
+ // Dessiner la heatmap enrichie compacte
1943
+ function drawCompactEnrichedHeatmap(scenario) {
1944
  const canvas = document.getElementById("heatmap");
1945
  if (!canvas) return;
1946
 
1947
  const ctx = canvas.getContext("2d");
1948
+ const cellSize = 15;
1949
+ const padding = 1;
1950
  const days = ["L", "M", "M", "J", "V", "S", "D"];
1951
  const weeks = 4;
1952
  const totalDays = weeks * 7;
 
1956
  // Titre enrichi
1957
  const scenarioTitles = {
1958
  1: {
1959
+ title: "Engagé mais désorganisé",
1960
  emoji: "😅",
1961
  pattern: "Effort concentré avant échéances"
1962
  },
1963
  2: {
1964
+ title: "Actif mais peu efficace",
1965
  emoji: "😰",
1966
+ pattern: "Démarrage lent, accélération tardive"
1967
  },
1968
  3: {
1969
+ title: "Autonome et stratégique",
1970
  emoji: "😊",
1971
  pattern: "Travail régulier et équilibré"
1972
  }
 
1978
  pattern: "Schéma à analyser"
1979
  };
1980
 
1981
+ ctx.font = "bold 14px Arial";
1982
  ctx.fillStyle = "#1976D2";
1983
  ctx.textAlign = "center";
1984
+ ctx.fillText(`${scenarioInfo.emoji} ${scenarioInfo.title}`, canvas.width / 2, 20);
1985
 
1986
+ ctx.font = "12px Arial";
1987
  ctx.fillStyle = "#666";
1988
+ ctx.fillText(`${scenarioInfo.pattern}`, canvas.width / 2, 40);
1989
 
1990
  // Générer les données d'activité selon le scénario
1991
+ const activityData = generateCompactPersistenceData(scenario.id, totalDays);
1992
 
1993
  // Dessiner la heatmap
1994
  const colors = ["#EBEDF0", "#C6E48B", "#7BC96F", "#239A3B", "#196127"];
 
1997
  const week = Math.floor(day / 7);
1998
  const weekday = day % 7;
1999
 
2000
+ const x = 30 + week * (cellSize * 7 + padding * 7) + weekday * (cellSize + padding);
2001
+ const y = 60 + weekday * (cellSize + padding);
2002
 
2003
  const intensity = activityData[day];
2004
 
 
2009
  // Bordure avec indication des échéances (vendredi = jour important)
2010
  if (weekday === 4) { // Vendredi
2011
  ctx.strokeStyle = "#FF6B6B";
2012
+ ctx.lineWidth = 1.5;
2013
  } else {
2014
  ctx.strokeStyle = intensity > 0 ? "#239A3B" : "#eee";
2015
+ ctx.lineWidth = 0.5;
2016
  }
2017
  ctx.strokeRect(x, y, cellSize, cellSize);
 
 
 
 
 
 
 
 
 
2018
  }
2019
 
2020
+ // Analyser et afficher les métriques de persévérance compactes
2021
+ analyzeCompactPersistenceMetrics(activityData, scenario.id);
2022
+ }
2023
+
2024
+ // Mettre à jour la persévérance spécifique au profil
2025
+ function updatePerseveranceProfile(scenarioTitle) {
2026
+ const profile = perseveranceProfiles[scenarioTitle];
2027
+
2028
+ if (!profile) {
2029
+ console.warn(`Aucun profil de persévérance trouvé pour: ${scenarioTitle}`);
2030
+ return;
2031
+ }
2032
+
2033
+ // Mettre à jour l'interface
2034
+ const regularityText = document.getElementById("compact-regularityText");
2035
+ if (regularityText) {
2036
+ regularityText.innerHTML = `
2037
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 5px;">
2038
+ <div style="width: 12px; height: 12px; border-radius: 50%; background: ${profile.color};"></div>
2039
+ <strong style="color: ${profile.color};">${profile.level}</strong>
2040
+ </div>
2041
+ <div style="font-size: 12px; color: #555; line-height: 1.4;">
2042
+ ${profile.interpretation}
2043
+ </div>
2044
+ `;
2045
+ }
2046
+
2047
+ // Mettre à jour le score de régularité dans les indicateurs
2048
+ const regularityScore = document.getElementById("compact-regularityScore");
2049
+ if (regularityScore) {
2050
+ // Convertir le niveau textuel en pourcentage approximatif
2051
+ let scorePercent;
2052
+ if (profile.level.includes("Très élevée")) scorePercent = "90%";
2053
+ else if (profile.level.includes("Élevée")) scorePercent = "75%";
2054
+ else if (profile.level.includes("Moyenne")) scorePercent = "55%";
2055
+ else if (profile.level.includes("Faible")) scorePercent = "35%";
2056
+ else if (profile.level.includes("Très faible")) scorePercent = "20%";
2057
+ else scorePercent = "50%";
2058
+
2059
+ regularityScore.textContent = scorePercent;
2060
+ regularityScore.style.color = profile.color;
2061
+ }
2062
  }
2063
 
2064
+ // Générer des données de persévérance compactes
2065
+ function generateCompactPersistenceData(scenarioId, totalDays) {
2066
  const data = new Array(totalDays).fill(0);
2067
 
2068
  switch(scenarioId) {
2069
  case 1: // Scénario désorganisé - Effort concentré avant échéances
2070
  for (let i = 0; i < totalDays; i++) {
2071
  const weekday = i % 7;
 
2072
  if (weekday === 3 || weekday === 4) { // Jeudi et vendredi
2073
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2074
  } else if (weekday === 5 || weekday === 6) { // Weekend
2075
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2076
  } else {
2077
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2078
  }
2079
  }
2080
  break;
 
2083
  for (let i = 0; i < totalDays; i++) {
2084
  const progress = i / totalDays;
2085
  if (progress < 0.3) {
2086
+ data[i] = Math.floor(Math.random() * 2); // 0-1
2087
  } else if (progress > 0.7) {
2088
+ data[i] = Math.floor(Math.random() * 2) + 3; // 3-4
2089
  } else {
2090
+ data[i] = Math.floor(Math.random() * 2) + 1; // 1-2
2091
  }
2092
  }
2093
  break;
 
2095
  case 3: // Scénario stratégique - Travail régulier
2096
  for (let i = 0; i < totalDays; i++) {
2097
  const weekday = i % 7;
 
2098
  if (weekday === 5 || weekday === 6) { // Weekend léger
2099
  data[i] = Math.floor(Math.random() * 2); // 0-1
2100
  } else {
2101
+ data[i] = Math.floor(Math.random() * 2) + 2; // 2-3
2102
  }
2103
  }
2104
  break;
2105
 
2106
  default:
 
2107
  for (let i = 0; i < totalDays; i++) {
2108
  data[i] = Math.floor(Math.random() * 5); // 0-4 aléatoire
2109
  }
 
2112
  return data;
2113
  }
2114
 
2115
+ // Analyser les métriques de persévérance compactes
2116
+ function analyzeCompactPersistenceMetrics(activityData, scenarioId) {
2117
  const totalDays = activityData.length;
 
2118
 
2119
  // 1. Calculer la régularité (écart-type)
2120
  const avgActivity = activityData.reduce((a, b) => a + b, 0) / totalDays;
2121
  const variance = activityData.reduce((a, b) => a + Math.pow(b - avgActivity, 2), 0) / totalDays;
2122
  const stdDev = Math.sqrt(variance);
2123
+ const regularity = Math.max(0, 100 - stdDev * 25);
2124
 
2125
  // 2. Identifier le schéma d'effort
2126
+ let pattern = "Régulier";
2127
+ let patternDescription = "Effort équilibré toute la semaine";
 
2128
 
2129
+ // Analyser la distribution
2130
  const weeklyPatterns = [];
2131
+ for (let w = 0; w < 4; w++) {
2132
  const weekData = activityData.slice(w * 7, Math.min((w + 1) * 7, totalDays));
2133
  if (weekData.length < 5) continue;
2134
 
2135
  const weekAvg = weekData.reduce((a, b) => a + b, 0) / weekData.length;
2136
 
 
2137
  if (weekData[4] > weekAvg * 1.5 && weekData[3] > weekAvg * 1.3) {
2138
+ pattern = "Effort concentré";
2139
+ patternDescription = "Pic d'activité jeudi/vendredi";
2140
  } else if (weekData[0] < weekAvg * 0.7 && weekData[4] > weekAvg * 1.2) {
2141
+ pattern = "Accélération progressive";
2142
+ patternDescription = "Démarrage lent, fin forte";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2143
  }
 
 
 
 
 
 
2144
  }
2145
 
2146
  // 3. Calculer la gestion des échéances
2147
  const deadlineDays = activityData.filter((_, index) => index % 7 === 3 || index % 7 === 4);
2148
  const nonDeadlineDays = activityData.filter((_, index) => index % 7 !== 3 && index % 7 !== 4);
2149
 
 
 
 
 
 
2150
  let deadlineScore = 50;
2151
+ if (deadlineDays.length > 0 && nonDeadlineDays.length > 0) {
2152
+ const deadlineAvg = deadlineDays.reduce((a, b) => a + b, 0) / deadlineDays.length;
2153
+ const nonDeadlineAvg = nonDeadlineDays.reduce((a, b) => a + b, 0) / nonDeadlineDays.length;
2154
+ deadlineScore = Math.min(100, Math.max(0, (deadlineAvg / 4) * 100));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2155
  }
2156
 
2157
+ // Mettre à jour l'interface compacte
2158
+ document.getElementById("compact-regularityScore").textContent = Math.round(regularity) + "%";
2159
+ document.getElementById("compact-effortPattern").textContent = pattern;
2160
+ document.getElementById("compact-deadlineScore").textContent = Math.round(deadlineScore) + "%";
2161
 
2162
+ // Mettre à jour l'analyse textuelle compacte
2163
+ document.getElementById("compact-patternText").textContent = patternDescription;
2164
+ }
2165
+
2166
+ // ================= RADAR =================
2167
+ function drawRadar() {
2168
+ const canvas = document.getElementById("radar");
2169
+ if (!canvas) {
2170
+ console.error("Canvas radar non trouvé!");
2171
+ return;
2172
  }
2173
 
2174
+ const ctx = canvas.getContext("2d");
2175
+ const cx = canvas.width / 2;
2176
+ const cy = canvas.height / 2;
2177
+ const radius = 200;
2178
+ const n = radarMetrics.length;
2179
+
2180
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
2181
+
2182
+ // Dessiner le radar
2183
+ for (let i = 1; i <= 5; i++) {
2184
+ ctx.beginPath();
2185
+ ctx.arc(cx, cy, (radius / 5) * i, 0, 2 * Math.PI);
2186
+ ctx.strokeStyle = "#e0e0e0";
2187
+ ctx.stroke();
2188
  }
2189
+
2190
+ // Dessiner les axes
2191
+ radarMetrics.forEach((m, i) => {
2192
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2193
+
2194
+ ctx.beginPath();
2195
+ ctx.moveTo(cx, cy);
2196
+ ctx.lineTo(cx + radius * Math.cos(angle), cy + radius * Math.sin(angle));
2197
+ ctx.strokeStyle = "#b0bec5";
2198
+ ctx.stroke();
2199
+
2200
+ // Labels
2201
+ const tx = cx + (radius + 25) * Math.cos(angle);
2202
+ const ty = cy + (radius + 25) * Math.sin(angle);
2203
+
2204
+ ctx.font = "10px Arial";
2205
+ ctx.fillStyle = "#000";
2206
+ ctx.textAlign = angle > Math.PI / 2 || angle < -Math.PI / 2 ? "right" : "left";
2207
+ ctx.textBaseline = "middle";
2208
+ ctx.fillText(`${m.label.split(' ')[0]}`, tx, ty);
2209
+ });
2210
+
2211
+ // Dessiner le polygone
2212
+ ctx.beginPath();
2213
+ radarMetrics.forEach((m, i) => {
2214
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2215
+ const r = radius * (m.value / 100);
2216
+ const x = cx + r * Math.cos(angle);
2217
+ const y = cy + r * Math.sin(angle);
2218
+ i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
2219
+ });
2220
+ ctx.closePath();
2221
+
2222
+ ctx.fillStyle = "rgba(25,118,210,0.25)";
2223
+ ctx.fill();
2224
+ ctx.strokeStyle = "#1976D2";
2225
+ ctx.lineWidth = 2;
2226
+ ctx.stroke();
2227
+
2228
+ // Dessiner les points
2229
+ radarMetrics.forEach((m, i) => {
2230
+ const angle = (2 * Math.PI * i) / n - Math.PI / 2;
2231
+ const r = radius * (m.value / 100);
2232
+ const x = cx + r * Math.cos(angle);
2233
+ const y = cy + r * Math.sin(angle);
2234
+
2235
+ ctx.beginPath();
2236
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
2237
+ ctx.fillStyle = "#1976D2";
2238
+ ctx.fill();
2239
+ });
2240
  }
2241
 
2242
+ // ================= NAVIGATION =================
2243
+ document.getElementById("prevScenario").onclick = () =>
2244
+ loadScenario(currentScenarioIndex - 1);
2245
+
2246
+ document.getElementById("nextScenario").onclick = () =>
2247
+ loadScenario(currentScenarioIndex + 1);
2248
+
2249
+ function updateNavButtons() {
2250
+ document.getElementById("prevScenario").disabled =
2251
+ currentScenarioIndex === 0;
2252
+ document.getElementById("nextScenario").disabled =
2253
+ currentScenarioIndex === scenarios.length - 1;
2254
+ }
2255
+
2256
+ // ================= BOUTON LECTURE CROISÉE =================
2257
+ document.getElementById('crossReadersBtn').onclick = () => {
2258
+ console.log('Navigation vers la page de lecture croisée...');
2259
 
2260
+ // Animation de transition
2261
+ const reflectionDiv = document.getElementById('reflection');
2262
+ if (reflectionDiv) {
2263
+ reflectionDiv.style.opacity = '0.7';
2264
+ reflectionDiv.style.transition = 'opacity 0.3s ease';
 
 
 
 
 
 
 
 
2265
  }
2266
+
2267
+ // Redirection
2268
+ setTimeout(() => {
2269
+ window.location.href = 'cross_reading/cross_readers.html';
2270
+ }, 300);
2271
+ };
2272
 
2273
  // ================= MÉTRIQUES DE CONFIANCE =================
2274
  function initTrustStars(){
 
2437
  // Récupérer les informations conditionnelles
2438
  let evaluatorName = "";
2439
  let evaluatorRole = "";
 
2440
  let expertiseLevel = "";
2441
  let messageMastery = "";
2442
 
 
2720
  }
2721
  }
2722
 
2723
+ // Changer le mode d'analyse de persévérance
2724
+ function changePersistenceAnalysis() {
2725
+ const mode = document.getElementById("persistenceMode").value;
2726
+ const currentScenario = scenarios[currentScenarioIndex];
2727
 
2728
+ // Redessiner la heatmap avec le mode sélectionné
2729
+ drawCompactEnrichedHeatmap(currentScenario);
 
 
 
 
 
2730
 
2731
+ // Ajouter une annotation selon le mode
2732
+ const canvas = document.getElementById("heatmap");
2733
+ const ctx = canvas.getContext("2d");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2734
 
2735
+ ctx.font = "12px Arial";
2736
+ ctx.fillStyle = "#1976D2";
2737
+ ctx.textAlign = "center";
2738
+
2739
+ switch(mode) {
2740
+ case "regularity":
2741
+ ctx.fillText("📊 Analyse de la régularité", canvas.width / 2, canvas.height - 10);
2742
+ break;
2743
+ case "effortPattern":
2744
+ ctx.fillText("🔄 Schéma d'effort", canvas.width / 2, canvas.height - 10);
2745
+ break;
2746
+ case "deadline":
2747
+ ctx.fillText("⏰ Gestion des échéances", canvas.width / 2, canvas.height - 10);
2748
+ break;
2749
+ case "combined":
2750
+ ctx.fillText("🎯 Vue combinée", canvas.width / 2, canvas.height - 10);
2751
+ break;
2752
+ }
2753
+ }
2754
 
2755
  // Exposer les fonctions globales
2756
  window.changePersistenceAnalysis = changePersistenceAnalysis;
 
2757
  window.updateStats = updateStats;
2758
  window.showNotification = showNotification;
2759
  window.fillSampleEvaluator = fillSampleEvaluator;
2760
  window.clearEvaluatorFields = clearEvaluatorFields;
 
 
2761
  </script>
2762
 
2763
  </body>