Upload index.html
Browse files- index.html +11 -6
index.html
CHANGED
|
@@ -474,6 +474,8 @@
|
|
| 474 |
.region-sheet .region-manager-note{display:grid;grid-template-columns:1fr 1fr;gap:11px;margin-top:10px}
|
| 475 |
.region-sheet .region-manager-note>div{padding:11px 13px;background:#f7f9fd;border:1px solid #e0e6f1;border-radius:7px;color:#324062;font-size:11px;line-height:1.55}
|
| 476 |
.region-sheet .region-manager-note strong{display:block;margin-bottom:5px;color:#131c68}
|
|
|
|
|
|
|
| 477 |
.region-sheet .region-small{color:#5f6a8a;font-size:10px;line-height:1.5}
|
| 478 |
@media(max-width:1160px){.region-sheet .region-panel-grid{grid-template-columns:1fr 1fr}.region-sheet .region-detail-grid{grid-template-columns:1fr}.region-sheet .region-comparison-svg{height:220px}}
|
| 479 |
@media(max-width:720px){.region-sheet .region-panel-grid,.region-sheet .region-manager-note{grid-template-columns:1fr}.region-sheet .region-wordmark{display:block}.region-sheet .region-heading-title{font-size:24px}}
|
|
@@ -1733,7 +1735,7 @@ function regionReportData(code){
|
|
| 1733 |
// Per locatie wordt een bezoekdag gedefinieerd als locatie + cliënt + kalenderdag,
|
| 1734 |
// identiek aan calculateImported/getReportData van de locatierapportage.
|
| 1735 |
const seenVisits=new Set(),byMonth=new Map(period.months.map(x=>[x,0])),byWeek=[0,0,0,0,0,0,0],monthClientSets=new Map(period.months.map(x=>[x,new Set()]));
|
| 1736 |
-
const regionClients=new Set(),activeClients=new Set(),visitedDays=new Set(),daysByClient=new Map();
|
| 1737 |
const perSite=new Map(def.sites.map(s=>[s,{name:s,visits:0,clientIds:new Set(),activeIds:new Set(),firstByClient:new Map(),intake:0}]));
|
| 1738 |
const firstInRegion=new Map();
|
| 1739 |
function recordFirst(map,id,date){if(!map.has(id)||date<map.get(id))map.set(id,date);}
|
|
@@ -1752,6 +1754,8 @@ function regionReportData(code){
|
|
| 1752 |
for(const r of inPeriod){
|
| 1753 |
const site=perSite.get(regionCanonical(r.site));if(!site)continue;
|
| 1754 |
regionClients.add(r.id);site.clientIds.add(r.id);
|
|
|
|
|
|
|
| 1755 |
const key=JSON.stringify([r.site,r.id,r.date]);if(seenVisits.has(key))continue;
|
| 1756 |
seenVisits.add(key);site.visits++;
|
| 1757 |
const mk=r.date.slice(0,7);byMonth.set(mk,(byMonth.get(mk)||0)+1);
|
|
@@ -1774,6 +1778,7 @@ function regionReportData(code){
|
|
| 1774 |
return {code,region:def.name,definedSites:def.sites,period,available,locations,months,byWeek,
|
| 1775 |
unique:regionClients.size,active:activeClients.size,newIntake,visits,daysWithScans:visitedDays.size,
|
| 1776 |
averagePerDay:visitedDays.size?visits/visitedDays.size:0,
|
|
|
|
| 1777 |
overlappingClients:locations.reduce((s,l)=>s+l.unique,0)-regionClients.size,
|
| 1778 |
historyLoaded:importedData.historyLoaded,checks,
|
| 1779 |
sourceYear:REPORT_YEAR};
|
|
@@ -1806,12 +1811,12 @@ function buildRegionReport(d){
|
|
| 1806 |
<div class="region-wordmark"><span class="region-reakt">Reakt</span><small>Werken aan je toekomst</small></div>
|
| 1807 |
<div class="region-title-tag">ORCHESTRA NEXT · REGION INTELLIGENCE</div>
|
| 1808 |
<div class="region-heading-title">Regiomonitor ${escapeHTML(d.region)}</div>
|
| 1809 |
-
<p class="region-heading-sub">Inloopvoorzieningen ·
|
| 1810 |
-
<div class="region-meta"><span><b>Rapportage:</b> ${escapeHTML(q.label)}</span><span><b>Peildatum:</b> ${readableDate(q.peildatum)}</span><span><b>Locaties:</b> ${avail.found.length} van ${d.definedSites.length} beschikbaar</span><span><b>Status:</b>
|
| 1811 |
${avail.missing.length?`<div class="region-cover-warning"><b>Onvolledige regioregistratie.</b> Geen bruikbare scans aangetroffen voor: ${escapeHTML(avail.missing.join(', '))}. Deze locaties staan in de vergelijking als ‘*’; hun nulwaarden betekenen niet dat er geen bezoekers waren. De regiocijfers zijn uitsluitend gebaseerd op locaties die in het ingelezen bestand voorkomen.</div>`:''}
|
| 1812 |
${!d.historyLoaded?'<div class="region-cover-warning"><b>Historie 2025 ontbreekt.</b> Nieuwe instroom is voorlopig: eerder geregistreerde bezoekers kunnen ten onrechte als nieuw meetellen.</div>':''}
|
| 1813 |
<div class="report-kpi-grid">${cards}</div>
|
| 1814 |
-
<div class="region-rule"><strong>Regioberekening:</strong> cliënten worden op regioniveau één keer geteld, ook als ze meerdere locaties bezoeken. Bezoekdagen zijn de optelsom van de afzonderlijke unieke bezoekdagen per locatie.
|
| 1815 |
<div class="region-panel-grid">
|
| 1816 |
<section class="report-panel"><h2>Bezoekdagen per maand</h2><div class="chart-box">${reportChartLine(mon,m.map(x=>x.visits))}</div></section>
|
| 1817 |
<section class="report-panel"><h2>Nieuwe instroom per maand</h2><div class="chart-box">${reportChartBars(mon,m.map(x=>x.newIntake),'#288e28')}</div></section>
|
|
@@ -1823,9 +1828,9 @@ function buildRegionReport(d){
|
|
| 1823 |
</div>
|
| 1824 |
<div class="region-manager-note">
|
| 1825 |
<div><strong>Managementinzicht</strong>In ${escapeHTML(q.label)} registreerden de beschikbare locaties in ${escapeHTML(d.region)} gezamenlijk ${nf(d.visits)} bezoekdagen bij ${nf(d.unique)} verschillende cliënten. Gemiddeld ${d.averagePerDay.toLocaleString('nl-NL',{minimumFractionDigits:1,maximumFractionDigits:1})} bezoekdagen per kalenderdag met registratie (${nf(d.daysWithScans)} dagen). ${nf(d.newIntake)} cliënten waren nieuw in de regio${d.historyLoaded?' op basis van 2025 en 2026':' binnen de beschikbare historie van 2026'}.</div>
|
| 1826 |
-
<div><strong>
|
| 1827 |
</div>
|
| 1828 |
-
<div class="report-foot"><span>Bron: browser-lokaal ingelezen scangegevens 2026${d.historyLoaded?' met historie 2025':''}.
|
| 1829 |
}
|
| 1830 |
function openRegionReport(){
|
| 1831 |
try{
|
|
|
|
| 474 |
.region-sheet .region-manager-note{display:grid;grid-template-columns:1fr 1fr;gap:11px;margin-top:10px}
|
| 475 |
.region-sheet .region-manager-note>div{padding:11px 13px;background:#f7f9fd;border:1px solid #e0e6f1;border-radius:7px;color:#324062;font-size:11px;line-height:1.55}
|
| 476 |
.region-sheet .region-manager-note strong{display:block;margin-bottom:5px;color:#131c68}
|
| 477 |
+
.region-sheet .region-average-number{font-size:29px;line-height:1.3;font-weight:850;color:#5822c7;margin:3px 0 7px;font-variant-numeric:tabular-nums}
|
| 478 |
+
.region-sheet .region-average-number span{font-size:12px;font-weight:650;color:#465579}
|
| 479 |
.region-sheet .region-small{color:#5f6a8a;font-size:10px;line-height:1.5}
|
| 480 |
@media(max-width:1160px){.region-sheet .region-panel-grid{grid-template-columns:1fr 1fr}.region-sheet .region-detail-grid{grid-template-columns:1fr}.region-sheet .region-comparison-svg{height:220px}}
|
| 481 |
@media(max-width:720px){.region-sheet .region-panel-grid,.region-sheet .region-manager-note{grid-template-columns:1fr}.region-sheet .region-wordmark{display:block}.region-sheet .region-heading-title{font-size:24px}}
|
|
|
|
| 1735 |
// Per locatie wordt een bezoekdag gedefinieerd als locatie + cliënt + kalenderdag,
|
| 1736 |
// identiek aan calculateImported/getReportData van de locatierapportage.
|
| 1737 |
const seenVisits=new Set(),byMonth=new Map(period.months.map(x=>[x,0])),byWeek=[0,0,0,0,0,0,0],monthClientSets=new Map(period.months.map(x=>[x,new Set()]));
|
| 1738 |
+
const regionClients=new Set(),activeClients=new Set(),visitedDays=new Set(),daysByClient=new Map(),uniqueClientsByDay=new Map();
|
| 1739 |
const perSite=new Map(def.sites.map(s=>[s,{name:s,visits:0,clientIds:new Set(),activeIds:new Set(),firstByClient:new Map(),intake:0}]));
|
| 1740 |
const firstInRegion=new Map();
|
| 1741 |
function recordFirst(map,id,date){if(!map.has(id)||date<map.get(id))map.set(id,date);}
|
|
|
|
| 1754 |
for(const r of inPeriod){
|
| 1755 |
const site=perSite.get(regionCanonical(r.site));if(!site)continue;
|
| 1756 |
regionClients.add(r.id);site.clientIds.add(r.id);
|
| 1757 |
+
if(!uniqueClientsByDay.has(r.date))uniqueClientsByDay.set(r.date,new Set());
|
| 1758 |
+
uniqueClientsByDay.get(r.date).add(r.id);
|
| 1759 |
const key=JSON.stringify([r.site,r.id,r.date]);if(seenVisits.has(key))continue;
|
| 1760 |
seenVisits.add(key);site.visits++;
|
| 1761 |
const mk=r.date.slice(0,7);byMonth.set(mk,(byMonth.get(mk)||0)+1);
|
|
|
|
| 1778 |
return {code,region:def.name,definedSites:def.sites,period,available,locations,months,byWeek,
|
| 1779 |
unique:regionClients.size,active:activeClients.size,newIntake,visits,daysWithScans:visitedDays.size,
|
| 1780 |
averagePerDay:visitedDays.size?visits/visitedDays.size:0,
|
| 1781 |
+
averageClientsPerDay:uniqueClientsByDay.size?[...uniqueClientsByDay.values()].reduce((total,ids)=>total+ids.size,0)/uniqueClientsByDay.size:0,
|
| 1782 |
overlappingClients:locations.reduce((s,l)=>s+l.unique,0)-regionClients.size,
|
| 1783 |
historyLoaded:importedData.historyLoaded,checks,
|
| 1784 |
sourceYear:REPORT_YEAR};
|
|
|
|
| 1811 |
<div class="region-wordmark"><span class="region-reakt">Reakt</span><small>Werken aan je toekomst</small></div>
|
| 1812 |
<div class="region-title-tag">ORCHESTRA NEXT · REGION INTELLIGENCE</div>
|
| 1813 |
<div class="region-heading-title">Regiomonitor ${escapeHTML(d.region)}</div>
|
| 1814 |
+
<p class="region-heading-sub">Inloopvoorzieningen · vergelijking van locaties</p>
|
| 1815 |
+
<div class="region-meta"><span><b>Rapportage:</b> ${escapeHTML(q.label)}</span><span><b>Peildatum:</b> ${readableDate(q.peildatum)}</span><span><b>Locaties:</b> ${avail.found.length} van ${d.definedSites.length} beschikbaar</span><span><b>Status:</b> Actief</span></div>
|
| 1816 |
${avail.missing.length?`<div class="region-cover-warning"><b>Onvolledige regioregistratie.</b> Geen bruikbare scans aangetroffen voor: ${escapeHTML(avail.missing.join(', '))}. Deze locaties staan in de vergelijking als ‘*’; hun nulwaarden betekenen niet dat er geen bezoekers waren. De regiocijfers zijn uitsluitend gebaseerd op locaties die in het ingelezen bestand voorkomen.</div>`:''}
|
| 1817 |
${!d.historyLoaded?'<div class="region-cover-warning"><b>Historie 2025 ontbreekt.</b> Nieuwe instroom is voorlopig: eerder geregistreerde bezoekers kunnen ten onrechte als nieuw meetellen.</div>':''}
|
| 1818 |
<div class="report-kpi-grid">${cards}</div>
|
| 1819 |
+
<div class="region-rule"><strong>Regioberekening:</strong> cliënten worden op regioniveau één keer geteld, ook als ze meerdere locaties bezoeken. Bezoekdagen zijn de optelsom van de afzonderlijke unieke bezoekdagen per locatie.</div>
|
| 1820 |
<div class="region-panel-grid">
|
| 1821 |
<section class="report-panel"><h2>Bezoekdagen per maand</h2><div class="chart-box">${reportChartLine(mon,m.map(x=>x.visits))}</div></section>
|
| 1822 |
<section class="report-panel"><h2>Nieuwe instroom per maand</h2><div class="chart-box">${reportChartBars(mon,m.map(x=>x.newIntake),'#288e28')}</div></section>
|
|
|
|
| 1828 |
</div>
|
| 1829 |
<div class="region-manager-note">
|
| 1830 |
<div><strong>Managementinzicht</strong>In ${escapeHTML(q.label)} registreerden de beschikbare locaties in ${escapeHTML(d.region)} gezamenlijk ${nf(d.visits)} bezoekdagen bij ${nf(d.unique)} verschillende cliënten. Gemiddeld ${d.averagePerDay.toLocaleString('nl-NL',{minimumFractionDigits:1,maximumFractionDigits:1})} bezoekdagen per kalenderdag met registratie (${nf(d.daysWithScans)} dagen). ${nf(d.newIntake)} cliënten waren nieuw in de regio${d.historyLoaded?' op basis van 2025 en 2026':' binnen de beschikbare historie van 2026'}.</div>
|
| 1831 |
+
<div class="region-daily-average"><strong>Gemiddeld aantal cliënten per dag</strong><div class="region-average-number">${d.averageClientsPerDay.toLocaleString('nl-NL',{minimumFractionDigits:1,maximumFractionDigits:1})} <span>cliënten per dag</span></div><div>Iedere cliënt telt per kalenderdag maximaal één keer mee binnen de hele regio, ook bij bezoek aan meerdere locaties. Berekend over ${nf(d.daysWithScans)} dagen met geregistreerde bezoeken in de gekozen rapportageperiode.</div></div>
|
| 1832 |
</div>
|
| 1833 |
+
<div class="report-foot"><span>Bron: browser-lokaal ingelezen scangegevens 2026${d.historyLoaded?' met historie 2025':''}.</span><span>ORCHESTRA NEXT v9 · ${escapeHTML(d.region)}</span></div>`;
|
| 1834 |
}
|
| 1835 |
function openRegionReport(){
|
| 1836 |
try{
|