# Psikogram — Ringkasan Seluruh Test

## Tujuan
Halaman yang menampilkan ringkasan visual dan tekstual dari seluruh hasil tes (PAPIKOSTIK, DISC, Ishihara, WPT, Matrix Assessment) dalam satu tampilan.

## Data Flow

```
RptestController::store()
  ├── $test1Data  ← getTest1Data($applicant)
  ├── $test2Data  ← getTest2Data($applicant)
  ├── $test3Data  ← getTest3Data($applicant)
  ├── $test4Data  ← getTest4Data($applicant)
  └── $psikogramData  ← getPsikogramData($test1Data, $test4Data, $posisi)
        ↓
  compact(...) → result.blade.php
        ↓
  @include('report.rptest.partials.psikogram')
```

### `getPsikogramData($test1Data, $test4Data, $posisi)`

Method baru (v2) yang menghitung **Matrix Assessment** — 14 aspek psikologi dari `ref_psikogram`:

1. **Input**: PAPI code scores dari test1 (20 kode A-Z), WPT kategori dari test4
2. **Load** `ref_psikogram` (distinct by aspek → 14 unique rows)
3. **Load** `vacancies_ideal_score` per vacancy position (jika ada)
4. **Per aspek**:
   - Row 1 (Kecerdasan Umum): semua formula null → pakai WPT kategori langsung
   - Row 2-14: **evaluasi formula PHP** dari kolom `sr`/`r`/`c_minus`/`c`/`c_plus`/`t`/`st`
     - Variable `$A`..`$Z` diganti dengan nilai PAPI code score (`jumlah`)
     - Contoh: `round(($C + $D + $R) / 3) == 4` akan di-`eval()` dengan nilai aktual
   - Kategori yang terpenuhi → `&#10004;` + `aktual` rank (1-7)
5. **Nilai** = `(aktual / ideal) * persen / pembagian_aspek`
6. **Total Nilai** = sum seluruh nilai
7. **Job Fit** = `(total_nilai / max_possible) * 100` (persentase)

### Struktur Data Return `$psikogramData`

```php
[
    'aspek_items' => [
        [
            'no' => string,           // a, b, c, ... per grup kategori_aspek
            'aspek' => string,        // 'Kecerdasan Umum', 'Gaya Kerja', ...
            'deskripsi' => string,
            'kategori_aspek' => string, // 'Intelektual', 'Sikap Kerja', ...
            'sr' => string,           // '&#10004;' atau ''
            'r' => string,
            'c_minus' => string,
            'c' => string,
            'c_plus' => string,
            't' => string,
            'st' => string,
            'aktual' => int,           // 0-7 (rank kategori yang terpenuhi)
            'ideal' => int,            // dari vacancies_ideal_score atau ref_psikogram.nilai_ideal
            'persen' => float,
            'pembagian_aspek' => int,
            'nilai' => float,          // nilai kontribusi ke total
        ],
        // ... 14 items
    ],
    'total_nilai' => float,
    'max_possible' => float,
    'job_fit_persen' => float,
]
```

## Komponen View

### Screen View
| Section | Source | Visual Element |
|---------|--------|----------------|
| PAPIKOSTIK | `$test1Data['codes']` + `$test1Data['radar_values']` | ECharts Radar Chart + tabel scrollable 20 code |
| DISC | `$test2Data['grafik']` + `$test2Data['karakter']` | 3 ECharts Line Chart (Most/Least/Change) + 3 card karakter |
| Ishihara | `$test3Data['total_benar']` / `total_salah` / `hasil_akhir` | Card dengan warna dinamis |
| WPT | `$test4Data['score']` / `kategori` / `kesimpulan` | Card score (count) + badge kategori |
| **Matrix Assessment** | `$psikogramData['aspek_items']` | Tabel 14 aspek × 7 kategori + Ideal + Nilai + Total + Job Fit |

### Print View
Tampilan cetak satu halaman berisi:
- Logo + identitas kandidat
- Tabel PAPIKOSTIK (Code, Score, Description)
- Tabel DISC (3 baris x 5 kolom D/I/S/C/*)
- 3 label karakter (Mask / Core / Mirror)
- Tabel ringkasan ISHIHARA + WPT
- **Tabel Matrix Assessment** (14 aspek × 7 kategori + Total Nilai + Job Fit)

## ECharts yang Digunakan

### Radar Chart (PAPIKOSTIK)
- Container: `#chartPsikogramTest1`
- 20 indikator (N, G, A, L, P, I, T, V, S, B, O, X, C, D, R, Z, E, K, F, W)
- K/Z memiliki max negatif (ditampilkan merah di radar)
- Responsive terhadap resize window

### Line Charts (DISC)
- Containers: `#chartPsikogramMost`, `#chartPsikogramLeast`, `#chartPsikogramChange`
- Sumbu X: D, I, S, C
- Sumbu Y: -8 s/d 8
- Masing-masing mewakili grafik Most, Least, Change

## Catatan
- ECharts CDN di-load via `@push('js')` di akhir partial
- Tab psikogram di `result.blade.php` menggunakan ID `#psikogram` sesuai dengan `data-bs-target`
- Styling print menggunakan class `.print-only` / `.screen-only` — konsisten dengan partial lain
- `vacancies_ideal_score` saat ini kosong — fallback ke `ref_psikogram.nilai_ideal`
