INHOUDSOPGAVE


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:


ManierWat je krijgtGeschikt voor
Volledig portaalZoeken, filteren, datasets, nieuws en richtlijnenEen aparte "Open data"-pagina
Losse component (tab-modus)Eén kaart, tabel, grafiek, scorekaart of metadata van één datasetEen kaartje of grafiek in een nieuwsbericht of themapagina
DashboardEen raster van meerdere componenten, samengesteld in de dashboard-beheeromgevingEen 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.js en assets/style.css weg, naast de versies met hash. Verwijs altijd naar deze vaste namen, dan hoeft de externe site na een update niets aan te passen.
  • Zet url en website altijd expliciet. Zonder url leidt het component het adres af van de pagina waarop het staat — op een gemeentesite is dat het verkeerde domein. Zonder website vraagt het component de portaalnaam op bij de backend (via PORTAL_HOSTS) en valt anders terug op een standaardportaal.
  • Het element moet in de DOM staan voordat het script draait. Het script leest url en website van het eerste <data-portaal> op de pagina. Met type="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/width wordt het element 100vh × 100vw, oftewel schermvullend. Geef in een contentpagina dus altijd een maat mee, bijvoorbeeld height="500px" width="100%".
  • Eenmalige herlaadactie. Bij het allereerste bezoek haalt het component de huisstijl op (…/style.css van het portaal), bewaart die in localStorage en 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)


AttribuutVoorbeeldBetekenis
urlhttps://kaartviewer.gemeente.nlBasisadres van de KaartViewer-omgeving, zonder slash aan het eind. Verplicht op externe sites.
websitePortaalGemeenteNaam van het portaal (de bookmark) in de KaartViewer. Bepaalt welke datasets, huisstijl en teksten je krijgt.
datasetenergielabelsAttribuutnaam van de dataset. Meerdere datasets scheid je met ;. Zonder dataset toon je het volledige portaal.
tabkaartWelk paneel je toont; zet het component in tab-modus. Zie de volgende sectie.
typebarGrafiektype bij tab="grafiek".
height, width400px, 100%CSS-maat van het component. Standaard 100vh × 100vw. calc(…) mag.
title, subtitleEnergielabels per buurtTitel boven een grafiek of scorekaart (niet bij de tabel).
initFilterenergielabel;A;B|buurtnaam;CentrumFilter bij het laden: attribuut;waarde1;waarde2, groepen gescheiden door | (EN). Ruimtelijk: geom;<WKT in RD> met filterGeomType="intersects".
standalonetrueKoppeling met andere componenten op de pagina: false (gekoppeld, standaard), true (los), datasetOnly (alleen met dezelfde dataset).
classmijn-kaartjeExtra CSS-klasse op het buitenste element (scorekaart).



Per paneel de belangrijkste opties


PaneelBelangrijkste 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.


tabToontExtra verplicht
kaartInteractieve kaart met legenda en infopaneel—
grafiekEen grafiek, scorekaart of schuifregelaartype en meestal theme
tabelDoorzoekbare tabel met de records—
metadataBeschrijving van de dataset—
databronnenDownloads en API-documentatie—
dashboardKaart, grafiek en tabel samen—
dashboard2Kaart, infopaneel en tabel samen—
infoAlleen 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.


AdresToont
/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


WatMechanismeUitzetten
Filters (klik in grafiek, toggle in scorekaart, filterAttribute op de kaart)BroadcastChannel met de naam data_portal_channelstandalone="true", of standalone="datasetOnly" om alleen met dezelfde dataset te koppelen
Zoom en uitsnede van kaartenEen window-event, los van standalonemapSyncZoom="false" per kaart
Geselecteerd object in het infopaneelBroadcastChannelstandalone="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.



ParameterWaardenEffect
pagehome, dataset, guidelines, newsWelke pagina van het portaal open staat
datasetattribuutnaamOpent die dataset direct
tabkaart, tabel, grafiek, metadata, databronnen, dashboard, dashboard2, infoActieve weergave binnen de dataset
websiteportaalnaamOverschrijft 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)


ParameterVerbergt
hideFilterFilterpaneel
hidePagesPaginamenu (home, nieuws, richtlijnen)
hideBreadCrumbsKruimelpad
hideTitleTitel van de dataset
hideTabsTabbladbalk van de dataset
hideTabMetadata, hideTabTable, hideTabMap, hideTabChart, hideTabExport, hideTabDashboardDat ene tabblad
hideMapBarWerkbalk van de kaart
hideChartSettingsInstellingen boven de grafiek
hideFeedbackFeedbackknop


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.css en de lettertypen worden geserveerd met Access-Control-Allow-Origin. Een type="module"-script van een ander domein laadt anders niet.
  • ☐ De API (/admin/rest/…) stuurt al Access-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:


DirectiveToevoegen
script-srchttps://kaartviewer.gemeente.nl
style-srchttps://kaartviewer.gemeente.nl en 'unsafe-inline'
connect-srchttps://kaartviewer.gemeente.nl
img-srchttps: data: blob: (kaarttegels komen van meerdere diensten, zoals PDOK)
font-srchttps://kaartviewer.gemeente.nl data:
frame-srchttps://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


SymptoomOorzaakOplossing
Leeg vlak, geen fout in de consoleOnbekende tab-waarde, bijvoorbeeld map of exporterenGebruik een waarde uit de tabel bij Tab-modus
Verkeerde datasets of huisstijlwebsite ontbreekt of is verkeerd gespeldZet website expliciet op elk element
Requests gaan naar het domein van de gemeente (404)url ontbreekt op het eerste elementZet url op elk element, in elk geval op het eerste
Console: CORS of blocked by CORS policy bij index.jsAssets zonder Access-Control-Allow-OriginHeader toevoegen op de KaartViewer-server
Console: Refused to load … Content Security PolicyCSP van de gemeentesiteDomein toevoegen, zie checklist
Pagina springt naar een inlogschermDataset is niet publiek (403)Dataset publiek maken of een andere kiezen
Pagina herlaadt één keer bij het eerste bezoekHuisstijl wordt in localStorage gezetNormaal gedrag; daarna niet meer
Gemeentesite ziet er anders uit na toevoegenGlobale CSS uit style.cssIframe gebruiken of style.css weglaten
Component is schermvullendGeen height/width opgegevenMaten meegeven
Filters springen tussen niet-gerelateerde componentenStandaard koppeling via BroadcastChannelstandalone="true" of "datasetOnly"
Kaarten bewegen samen terwijl dat niet moetZoomsynchronisatie staat standaard aanmapSyncZoom="false"
Leeg iframe met dashboardFraming geblokkeerd door de serverframe-ancestors/X-Frame-Options aanpassen