INHOUDSOPGAVE
- Inleiding
- Snelstart
- Attributen van het data-portaal tag
- Tab-modus: één weergave van een dataset
- Dashboard insluiten
- Meerdere componenten op één pagina
- URL-parameters en zichtbaarheidsvlaggen
- Styling, toegang en hosting
- Volledig voorbeeld en probleemoplossing
Inleiding
Deze handleiding is voor webbeheerders en ontwikkelaars van een externe website (bijvoorbeeld een gemeente) die data vanuit Dataportaal willen tonen. Je hebt geen build-tools nodig: het component wordt als kant-en-klaar script geladen vanaf de KaartViewer-server. Dataportaal is één Web Component, <data-portaal>, dat je met twee regels HTML in elke website plaatst, ook in een gemeentesite. Hetzelfde element kan het complete portaal tonen, of één losse kaart, tabel, grafiek of scorekaart van een dataset.
Er zijn drie manieren om dit te integreren:
| Manier | Wat je krijgt | Geschikt voor |
|---|---|---|
| Volledig portaal | Zoeken, filteren, datasets, nieuws en richtlijnen | Een aparte "Open data"-pagina |
| Losse component (tab-modus) | Eén kaart, tabel, grafiek, scorekaart of metadata van één dataset | Een kaartje of grafiek in een nieuwsbericht of themapagina |
| Dashboard | Een raster van meerdere componenten, samengesteld in de dashboard-beheeromgeving | Een monitor of wijkdashboard zonder zelf HTML te schrijven |
Dashboards gebruiken intern precies hetzelfde <data-portaal>-element; alles wat hieronder over attributen staat geldt dus ook voor dashboardtegels.
Snelstart
Neem een stylesheet, een script en het element op; vervang https://kaartviewer.gemeente.nl door het adres van jullie KaartViewer-omgeving.
<!-- 1. In de <head> -->
<link rel="stylesheet" href="https://kaartviewer.gemeente.nl/dataportaal/assets/style.css">
<script type="module" src="https://kaartviewer.gemeente.nl/dataportaal/assets/index.js"></script>
<!-- 2. Op de plek waar het portaal moet komen -->
<data-portaal
url="https://kaartviewer.gemeente.nl"
website="PortaalGemeente"
height="800px"
width="100%">
</data-portaal>
Dit toont het volledige portaal. Voor één losse kaart of grafiek voeg je dataset en tab toe (zie Tab-modus: één weergave van een dataset ).
Er zijn een aantal dingen waar je op moet letten:
- Vaste bestandsnamen. De build schrijft altijd ook
assets/index.jsenassets/style.cssweg, naast de versies met hash. Verwijs altijd naar deze vaste namen, dan hoeft de externe site na een update niets aan te passen. - Zet
urlenwebsitealtijd expliciet. Zonderurlleidt het component het adres af van de pagina waarop het staat — op een gemeentesite is dat het verkeerde domein. Zonderwebsitevraagt het component de portaalnaam op bij de backend (viaPORTAL_HOSTS) en valt anders terug op een standaardportaal. - Het element moet in de DOM staan voordat het script draait. Het script leest
urlenwebsitevan het eerste<data-portaal>op de pagina. Mettype="module"en het element in de HTML gaat dat vanzelf goed. Voeg je het element via JavaScript of een CMS-blok toe, plaats het element dan eerst en laad het script daarna. - Hoogte en breedte. Zonder
height/widthwordt het element100vh×100vw, oftewel schermvullend. Geef in een contentpagina dus altijd een maat mee, bijvoorbeeldheight="500px" width="100%". - Eenmalige herlaadactie. Bij het allereerste bezoek haalt het component de huisstijl op (
…/style.cssvan het portaal), bewaart die inlocalStorageen herlaadt de pagina één keer. Daarna niet meer. Houd hier rekening mee bij formulieren of analytics op dezelfde pagina.
Attributen van het data-portaal tag
Alle configuratie gaat via HTML-attributen op het element, er is geen JavaScript-API nodig. Waarden zijn altijd tekst, dus ook booleans schrijf je als "true" of "false".
Algemeen (elk type)
| Attribuut | Voorbeeld | Betekenis |
|---|---|---|
url | https://kaartviewer.gemeente.nl | Basisadres van de KaartViewer-omgeving, zonder slash aan het eind. Verplicht op externe sites. |
website | PortaalGemeente | Naam van het portaal (de bookmark) in de KaartViewer. Bepaalt welke datasets, huisstijl en teksten je krijgt. |
dataset | energielabels | Attribuutnaam van de dataset. Meerdere datasets scheid je met ;. Zonder dataset toon je het volledige portaal. |
tab | kaart | Welk paneel je toont; zet het component in tab-modus. Zie de volgende sectie. |
type | bar | Grafiektype bij tab="grafiek". |
height, width | 400px, 100% | CSS-maat van het component. Standaard 100vh × 100vw. calc(…) mag. |
title, subtitle | Energielabels per buurt | Titel boven een grafiek of scorekaart (niet bij de tabel). |
initFilter | energielabel;A;B|buurtnaam;Centrum | Filter bij het laden: attribuut;waarde1;waarde2, groepen gescheiden door | (EN). Ruimtelijk: geom;<WKT in RD> met filterGeomType="intersects". |
standalone | true | Koppeling met andere componenten op de pagina: false (gekoppeld, standaard), true (los), datasetOnly (alleen met dezelfde dataset). |
class | mijn-kaartje | Extra CSS-klasse op het buitenste element (scorekaart). |
Per paneel de belangrijkste opties
| Paneel | Belangrijkste attributen |
|---|---|
Kaart (tab="kaart") | showMapHeader, legend (false of een afbeeldings-URL), legendOnly, showLayerToggle, mapStyle, filterOnZoom, mapSyncZoom, zoomToFilter, initBBox (RD: minX,minY,maxX,maxY), filterAttribute, showInfo, infoOnly, infoOnlyText |
Staaf / lijn / cirkel / ring (type="bar", bar_horizontal, line, pie, doughnut) | theme (groeperingsattribuut), themesPerBar, value, valueX (lijn), valueOnly, sumAttribute, chartLegend, valueInChart, percentage, zeroValueText, playButton, resetButton |
Meter (type="gauge") | theme, value, valueOnly, percentage, hideTotal, zeroValueText |
Scorekaart (type="scorecard") | theme, value, top, sort, sum, average, calculation, plusAllValues, hideTotal, filterSwitch, scorecardSearchBar, keepList |
Schuifregelaar (type="slider") | theme, extraThemes, value, maxLabels, sliderFormat, playButton |
Tabel (tab="tabel") | columns (kolommen gescheiden door ;, in die volgorde) |
De volledige referentie, met standaardwaarden en formaten per attribuut, staat op de KaartViewer-server zelf: …/dataportaal/dataportaal-options.txt, en met live voorbeelden in …/dataportaal/dataportaal-combinaties.html. Die bestanden worden bij elke build meegeleverd en zijn daarmee altijd in lijn met de geïnstalleerde versie.
Tab-modus: één weergave van een dataset
Met dataset en tab samen toont het component alleen één specifieke weergave, zonder menu, zoekbalk of kruimelpad. Het element blijft onzichtbaar tot de dataset geladen is, zodat de bezoeker geen half opgebouwd scherm ziet.
tab | Toont | Extra verplicht |
|---|---|---|
kaart | Interactieve kaart met legenda en infopaneel | — |
grafiek | Een grafiek, scorekaart of schuifregelaar | type en meestal theme |
tabel | Doorzoekbare tabel met de records | — |
metadata | Beschrijving van de dataset | — |
databronnen | Downloads en API-documentatie | — |
dashboard | Kaart, grafiek en tabel samen | — |
dashboard2 | Kaart, infopaneel en tabel samen | — |
info | Alleen het infopaneel | — |
Let op de volgende waarden: het is kaart, niet map, en databronnen, niet exporteren. Een onbekende waarde geeft geen foutmelding maar een leeg vlak.
Voorbeelden
Kaart van één buurt, compact en zonder kopbalk:
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="kaart"
showMapHeader="false"
initFilter="buurtnaam;Centrum" zoomToFilter="true"
height="400px" width="100%">
</data-portaal>
Staafdiagram per energielabel, met waarden in de balken:
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="bar"
theme="energielabel" title="Woningen per energielabel"
chartLegend="false" valueInChart="true"
height="350px" width="100%">
</data-portaal>
Scorekaart met de top 5, waarop de bezoeker kan filteren:
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="scorecard"
theme="buurtnaam" top="5" sort="desc" filterSwitch="true"
title="Buurten met de meeste labels"
height="300px" width="100%">
</data-portaal>
Tabel met alleen twee kolommen:
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="tabel"
columns="buurtnaam;energielabel"
height="500px" width="100%">
</data-portaal>
De waarden voor dataset, theme, columns en initFilter zijn attribuutnamen uit de KaartViewer-beheeromgeving. Vraag ze op bij de beheerder, of lees ze af uit de adresbalk van het volledige portaal (?dataset=…).
Dashboard insluiten
Een dashboard stel je samen in de beheeromgeving op https://kaartviewer.gemeente.nl/dashboard/admin.html en publiceer je daar. Op de externe site neem je het vervolgens op via een iframe, of je bouwt het raster zelf na met losse componenten.
| Adres | Toont |
|---|---|
/dashboard/ | Overzicht van alle gepubliceerde dashboards en menu's |
/dashboard/index.html?id=<dashboard-id> | Eén dashboard, schermvullend |
/dashboard/index.html?menu=<menu-id> | Een navigatiebalk met de dashboards uit dat menu |
Optie A: iframe (aanbevolen)
<iframe
src="https://kaartviewer.gemeente.nl/dashboard/index.html?id=3f2a9c1e"
title="Dashboard energietransitie"
style="width:100%; height:800px; border:0;">
</iframe>
Het dashboard draait dan volledig geïsoleerd: geen conflict met de huisstijl van de gemeentesite en geen gedeelde filters met andere componenten op de pagina. De tegels schalen mee met de iframe, want hun maten zijn berekend in vw/vh van het iframe-venster. Geef het iframe altijd een title voor schermlezers (WCAG 2.1).
De KaartViewer-server moet framing vanaf het gemeentedomein toestaan. Staat er een X-Frame-Options- of frame-ancestors-header die dat blokkeert, dan blijft het iframe leeg; voor de backend-API regel je dit met CSP_FRAME_ANCESTORS in de .env.
Optie B: zelf nabouwen met losse componenten
Wil je het dashboard in de opmaak van de eigen site, zet dan de losse <data-portaal>-elementen in een eigen CSS-grid. De attributen per tegel lees je af in het tegelpaneel van de dashboard-beheeromgeving: het zijn precies de attributen uit deze handleiding.
<div style="display:grid; grid-template-columns:2fr 1fr; gap:10px; height:700px;">
<data-portaal url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="kaart" height="700px" width="100%"></data-portaal>
<div style="display:grid; grid-template-rows:1fr 1fr; gap:10px;">
<data-portaal url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="pie" theme="energielabel"
height="345px" width="100%"></data-portaal>
<data-portaal url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="scorecard" theme="buurtnaam"
filterSwitch="true" height="345px" width="100%"></data-portaal>
</div>
</div>
Het nadeel is dat wijzigingen in de beheeromgeving niet vanzelf doorkomen; je past de HTML zelf aan.
Gebruik op de externe site alleen gepubliceerde dashboards. Een concept-dashboard is via ?id= wel op te vragen, maar staat niet in het overzicht en kan nog veranderen.
Meerdere componenten op één pagina
Zet zoveel <data-portaal>-elementen op een pagina als je wilt; het script laad je maar één keer. Standaard zijn ze aan elkaar gekoppeld: een klik in een grafiek filtert ook de kaart en de tabel.
Eén portaal per pagina. url en website worden gelezen van het eerste <data-portaal> op de pagina, en de huisstijl wordt per portaal één keer geladen. Combineer dus geen componenten uit twee verschillende portalen of KaartViewer-omgevingen op dezelfde pagina; gebruik daarvoor een iframe.
Hoe de koppeling werkt
| Wat | Mechanisme | Uitzetten |
|---|---|---|
Filters (klik in grafiek, toggle in scorekaart, filterAttribute op de kaart) | BroadcastChannel met de naam data_portal_channel | standalone="true", of standalone="datasetOnly" om alleen met dezelfde dataset te koppelen |
| Zoom en uitsnede van kaarten | Een window-event, los van standalone | mapSyncZoom="false" per kaart |
| Geselecteerd object in het infopaneel | BroadcastChannel | standalone="true" |
Handige combinaties:
- Kaart met
filterAttribute="buurtnaam"+ scorekaart per buurt: klik op een pand, de rest van de pagina toont die buurt. - Kaart met
zoomToFilter="true": de kaart zoomt naar het resultaat van een filter uit een grafiek of scorekaart. tab="kaart" infoOnly="true"naast een gewone kaart: een apart infopaneel dat de aangeklikte feature toont.
Let op: synchronisatie over browsertabbladen
Een BroadcastChannel werkt voor het hele domein, niet per pagina. Heeft een bezoeker twee tabbladen van de gemeentesite open met gekoppelde componenten, dan filteren die elkaar ook. Zet standalone="true" op componenten die niets met de rest te maken hebben, zoals een los kaartje in een nieuwsbericht.
URL-parameters en zichtbaarheidsvlaggen
Het component leest parameters uit de adresbalk van de pagina waarop het staat, op een externe site uit de URL van de gemeentepagina. Zo kun je vanaf een andere pagina direct naar een dataset linken, of onderdelen van het volledige portaal verbergen.
In het volledige portaal schrijft het component page, dataset en tab ook terug in de adresbalk (zonder herladen). Een bezoeker kan de URL daardoor delen en komt dan op dezelfde plek uit.
| Parameter | Waarden | Effect |
|---|---|---|
page | home, dataset, guidelines, news | Welke pagina van het portaal open staat |
dataset | attribuutnaam | Opent die dataset direct |
tab | kaart, tabel, grafiek, metadata, databronnen, dashboard, dashboard2, info | Actieve weergave binnen de dataset |
website | portaalnaam | Overschrijft het portaal, alleen als het website-attribuut ontbreekt |
Voorbeeld: https://www.gemeente.nl/open-data?page=dataset&dataset=energielabels&tab=kaart.
Onderdelen verbergen (waarde 1)
| Parameter | Verbergt |
|---|---|
hideFilter | Filterpaneel |
hidePages | Paginamenu (home, nieuws, richtlijnen) |
hideBreadCrumbs | Kruimelpad |
hideTitle | Titel van de dataset |
hideTabs | Tabbladbalk van de dataset |
hideTabMetadata, hideTabTable, hideTabMap, hideTabChart, hideTabExport, hideTabDashboard | Dat ene tabblad |
hideMapBar | Werkbalk van de kaart |
hideChartSettings | Instellingen boven de grafiek |
hideFeedback | Feedbackknop |
Deze vlaggen zijn vooral bedoeld voor deel-links naar het volledige portaal. Voor een vaste embed op de eigen site is tab-modus met attributen voorspelbaarder: attributen staan in de HTML en veranderen niet mee met de URL.
Styling, toegang en hosting
Huisstijl
De binnenkant van elk component zit in een Shadow DOM. CSS van de gemeentesite komt daar niet in, en andersom lekt de interne opmaak niet naar buiten. Kleuren, logo en lettertype van het portaal stel je in de KaartViewer-beheeromgeving in; het component haalt die op als …/admin/rest/openapi/<website>/style.css.
Uitzondering is dataportaal/assets/style.css uit de snelstart. Dat bestand bevat Bootstrap, OpenLayers, Font Awesome en de lettertypen, en werkt op de hele pagina. Het kan knoppen, koppen en formulieren van de gemeentesite veranderen. Test de pagina na het toevoegen; conflicteert het, gebruik dan een iframe (zie Optie A: iframe (aanbevolen) ) of laat het bestand weg en controleer of iconen en lettertypen nog goed zijn.
Van buitenaf bepaal je alleen de maat (height, width) en de rand eromheen. Voorbeeld voor een kaartje met afgeronde hoeken:
data-portaal { display: block; border: 1px solid #e5e7eb; border-radius: 12px; overflow: hidden; }Alleen openbare data
Op een extern domein is de bezoeker niet ingelogd bij de KaartViewer: de API-aanroepen gaan zonder sessiecookie. Neem daarom alleen datasets op die in het portaal publiek zijn. Geeft de API een 403 terug, dan stuurt het component de hele pagina door naar het inlogscherm van de KaartViewer — dat wil je op een gemeentesite niet.
Checklist voor de KaartViewer-server:
- ☐ De site draait op HTTPS, net als de gemeentesite (anders blokkeert de browser het als mixed content).
- ☐
…/dataportaal/assets/index.js,style.cssen de lettertypen worden geserveerd metAccess-Control-Allow-Origin. Eentype="module"-script van een ander domein laadt anders niet. - ☐ De API (
/admin/rest/…) stuurt alAccess-Control-Allow-Origin: *; daar is niets extra nodig. - ☐ Het portaal (
website) heeft viewtype dataportaal of dashboard-website, anders geven sommige endpoints lege antwoorden.
Checklist voor de gemeentesite
Heeft de gemeentesite een Content-Security-Policy, voeg dan het KaartViewer-domein toe:
| Directive | Toevoegen |
|---|---|
script-src | https://kaartviewer.gemeente.nl |
style-src | https://kaartviewer.gemeente.nl en 'unsafe-inline' |
connect-src | https://kaartviewer.gemeente.nl |
img-src | https: data: blob: (kaarttegels komen van meerdere diensten, zoals PDOK) |
font-src | https://kaartviewer.gemeente.nl data: |
frame-src | https://kaartviewer.gemeente.nl (alleen bij een iframe) |
Het component bewaart de huisstijl en de taalkeuze in localStorage van de gemeentesite. Dat is functionele opslag zonder tracking. Vermeld dit zo nodig in de cookieverklaring.
Volledig voorbeeld en probleemoplossing
Een themapagina "Energietransitie" met een tekst, een gekoppelde kaart en twee grafieken:
<!doctype html>
<html lang="nl">
<head>
<meta charset="utf-8">
<title>Energietransitie – Gemeente Voorbeeld</title>
<link rel="stylesheet" href="https://kaartviewer.gemeente.nl/dataportaal/assets/style.css">
<script type="module" src="https://kaartviewer.gemeente.nl/dataportaal/assets/index.js"></script>
<style>
.dp-raster { display:grid; grid-template-columns:2fr 1fr; gap:16px; }
.dp-raster data-portaal { display:block; border:1px solid #ddd; border-radius:8px; overflow:hidden; }
@media (max-width: 800px) { .dp-raster { grid-template-columns:1fr; } }
</style>
</head>
<body>
<h1>Energielabels in onze gemeente</h1>
<p>Klik op een pand om de cijfers voor die buurt te zien.</p>
<div class="dp-raster">
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="kaart"
filterAttribute="buurtnaam" zoomToFilter="true"
height="600px" width="100%">
</data-portaal>
<div>
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="doughnut"
theme="energielabel" title="Verdeling labels" resetButton="true"
height="292px" width="100%">
</data-portaal>
<data-portaal
url="https://kaartviewer.gemeente.nl" website="PortaalGemeente"
dataset="energielabels" tab="grafiek" type="scorecard"
theme="energielabel" value="A" title="Panden met label A"
height="292px" width="100%">
</data-portaal>
</div>
</div>
</body>
</html>
Probleemoplossing
| Symptoom | Oorzaak | Oplossing |
|---|---|---|
| Leeg vlak, geen fout in de console | Onbekende tab-waarde, bijvoorbeeld map of exporteren | Gebruik een waarde uit de tabel bij Tab-modus |
| Verkeerde datasets of huisstijl | website ontbreekt of is verkeerd gespeld | Zet website expliciet op elk element |
| Requests gaan naar het domein van de gemeente (404) | url ontbreekt op het eerste element | Zet url op elk element, in elk geval op het eerste |
Console: CORS of blocked by CORS policy bij index.js | Assets zonder Access-Control-Allow-Origin | Header toevoegen op de KaartViewer-server |
| Console: Refused to load … Content Security Policy | CSP van de gemeentesite | Domein toevoegen, zie checklist |
| Pagina springt naar een inlogscherm | Dataset is niet publiek (403) | Dataset publiek maken of een andere kiezen |
| Pagina herlaadt één keer bij het eerste bezoek | Huisstijl wordt in localStorage gezet | Normaal gedrag; daarna niet meer |
| Gemeentesite ziet er anders uit na toevoegen | Globale CSS uit style.css | Iframe gebruiken of style.css weglaten |
| Component is schermvullend | Geen height/width opgegeven | Maten meegeven |
| Filters springen tussen niet-gerelateerde componenten | Standaard koppeling via BroadcastChannel | standalone="true" of "datasetOnly" |
| Kaarten bewegen samen terwijl dat niet moet | Zoomsynchronisatie staat standaard aan | mapSyncZoom="false" |
| Leeg iframe met dashboard | Framing geblokkeerd door de server | frame-ancestors/X-Frame-Options aanpassen |