The Markdown format¶
A data story is a Markdown file. The story editor writes it for you, but you can also write or tweak one by hand. This page shows the building blocks. Every example is a working one for the Wikidata profile.
Let the editor write the hard parts
The JSON inside map, graph, embed and music blocks is checked strictly by
SHMARQL. The easiest way to get it right is to make the node in the editor,
then Export and copy the block from story.md. The examples below are
complete, minimal starting points.
Front matter¶
---
title: Vermeer in Wikidata
description: Where the paintings of Johannes Vermeer are today.
keywords: [Vermeer, Wikidata]
language: en
license: CC BY 4.0
lodeon:
htmlMeta:
description: Where the paintings of Johannes Vermeer are today.
openGraph:
title: Vermeer in Wikidata
type: article
jsonLd:
"@context": https://schema.org
"@type": ScholarlyArticle
headline: Vermeer in Wikidata
---
title is the page title. Everything under lodeon: goes into the page
head: htmlMeta as <meta name=…> tags, openGraph as
<meta property="og:…"> tags, and jsonLd as a
<script type="application/ld+json"> block. The editor fills all of this from
the metadata panel. The lodeon: section also marks the page as a data story.
SPARQL Query: shmarql¶
```shmarql {title="Paintings by Johannes Vermeer" kg="wikidata"}
SELECT ?painting ?paintingLabel WHERE {
?painting wdt:P170 wd:Q41264 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
LIMIT 20
```
kgis the profile name. Without it, the default profile is used and the table is made on the server.titleis shown above the table.- The query runs in the reader's browser, through the read-only
/api/sparql/<kg>.
Plotly Visualization: lodeon-visualization¶
The body is JSON. The runtime only needs a Plotly figure (data, layout,
config):
```lodeon-visualization {title="Paintings per painter"}
{
"renderer": "plotly",
"figure": {
"data": [{"type": "bar",
"x": ["Rembrandt", "Jan Steen", "Frans Hals", "Pieter de Hooch", "Johannes Vermeer"],
"y": [751, 482, 307, 201, 36]}],
"layout": {"height": 360, "yaxis": {"title": {"text": "Paintings"}}}
}
}
```
The editor stores more: the source (sourceMode sparql, csv, tsv or
url, with the query or data), chartType, the column mapping, the editable
plotlyDataJson/layoutJson/configJson and the table data. That is what
lets you edit the chart again later.
RAWGraphs Visualization: lodeon-rawgraphs¶
```lodeon-rawgraphs {title="A chart from RAWGraphs"}
{
"renderer": "rawgraphs",
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"60\"><rect width=\"120\" height=\"40\" fill=\"#0072B2\"/></svg>"
}
```
Readers see the svg. The editor also stores the RAWGraphs projectJson and
a summary, so the chart can be rendered again from the project.
Leaflet Map: lodeon-leaflet¶
```lodeon-leaflet {title="Two museums"}
{
"renderer": "leaflet",
"featureCollection": {
"type": "FeatureCollection",
"features": [
{"type": "Feature", "geometry": {"type": "Point", "coordinates": [4.885278, 52.36]},
"properties": {"label": "Rijksmuseum", "resource": "http://www.wikidata.org/entity/Q190804", "category": "Amsterdam"}},
{"type": "Feature", "geometry": {"type": "Point", "coordinates": [4.314306, 52.080389]},
"properties": {"label": "Mauritshuis", "resource": "http://www.wikidata.org/entity/Q221092", "category": "The Hague"}}
]
},
"tileLayerId": "openStreetMap",
"height": 420,
"initialView": "fitBounds",
"center": [52.2, 4.6],
"zoom": 8,
"fitBoundsMaxZoom": 12,
"clustering": {"enabled": false, "disableAtZoom": null, "showCoverageOnHover": true,
"spiderfyOnMaxZoom": true, "spiderfyDistanceMultiplier": 1.5},
"legend": {"enabled": true, "position": "bottomRight", "title": "City"},
"popupFields": ["label", "resource", "category"],
"markerStyle": {"radius": 7, "color": "#005A8D", "fillColor": "#0072B2", "fillOpacity": 0.8, "weight": 2},
"caption": "Two museums with paintings by Vermeer."
}
```
- GeoJSON coordinates are longitude, latitude;
centeris latitude, longitude (as in Leaflet). tileLayerIdmust be one of the map backgrounds in the LODEON settings (openStreetMapby default).initialViewisfitBounds(zoom to the data) orconfigured(usecenterandzoom).- Features carry their own data. The map doesn't run a query when it is read.
Graph Explorer: lodeon-graph-explorer¶
```lodeon-graph-explorer {title="Around Vermeer"}
{
"renderer": "graphExplorer",
"knowledgeGraphProfileId": "wikidata",
"items": [{"iri": "http://www.wikidata.org/entity/Q41264", "label": "Johannes Vermeer"}],
"direction": "outgoing",
"depth": 1,
"maxNodes": 60,
"maxEdgesPerNode": 25,
"showLiterals": false,
"height": 520
}
```
The graph is fetched live from /api/explorer/<profile>/expand each time the
page is read, starting from the items.
IIIF Object: lodeon-iiif¶
By URL (one manifest or info.json per line in url):
```lodeon-iiif {title="Rembrandt, Portrait of Eleazar Swalmius"}
{
"renderer": "iiif",
"sourceMode": "url",
"url": "https://iiif.kmska.be/iiif/2/968/manifest.json",
"viewMode": "single",
"height": 520
}
```
From a query, run live through the profile. The query returns ?manifest (or
?imageInfo), and optionally ?label and ?resource:
```lodeon-iiif {title="Paintings in the SMK"}
{
"renderer": "iiif",
"sourceMode": "sparql",
"knowledgeGraphProfileId": "wikidata",
"query": "SELECT ?resource ?label ?manifest WHERE { ?resource wdt:P170 wd:Q5598 ; wdt:P6108 ?manifest . FILTER(STRSTARTS(STR(?manifest), \"https://api.smk.dk/\")) SERVICE wikibase:label { bd:serviceParam wikibase:language \"en\". ?resource rdfs:label ?label . } } LIMIT 10",
"resultMapping": {"manifest": "manifest", "imageInfo": "imageInfo", "label": "label", "resource": "resource"},
"viewMode": "gallery",
"galleryReferenceStrip": "horizontal"
}
```
Embed Remote Content: lodeon-embed¶
```lodeon-embed {title="A map from the Wikidata Query Service"}
{
"renderer": "iframe",
"url": "https://query.wikidata.org/embed.html#%23defaultView%3AMap%0ASELECT%20%3Fm%20%3Fc%20WHERE%20%7B%20%3Fp%20wdt%3AP170%20wd%3AQ41264%20%3B%20wdt%3AP195%20%3Fm%20.%20%3Fm%20wdt%3AP625%20%3Fc%20%7D",
"aspectRatio": "16:9",
"caption": "Collections with paintings by Vermeer."
}
```
- The URL's origin must be in
nodes.embed.allowedOrigins, or the block shows a warning instead. Thesandboxandallowof the frame also come from those settings, not from the block. - For a gallery, add
"urls": […](or"items": [{"url": …, "label": …}]),"viewMode": "gallery"and"galleryReferenceStrip": "horizontal","vertical"or"none". aspectRatiois16:9,4:3,1:1, … orcustomtogether with"height": <pixels>.
Music Notation: lodeon-verovio¶
```lodeon-verovio {title="Frère Jacques"}
{
"renderer": "verovio",
"items": [
{
"id": "frere-jacques",
"data": "@clef:G-2\n@keysig:\n@timesig:4/4\n@data:4'CDEC/CDEC/EF2G/4EF2G/",
"format": "pae",
"label": "Frère Jacques",
"resource": "http://www.wikidata.org/entity/Q825728",
"resourceLabel": "Frère Jacques (nursery rhyme)",
"bindings": {},
"status": {"state": "ready", "messages": []}
}
],
"viewMode": "single",
"selectedItemId": "frere-jacques",
"documentLayout": "responsive",
"initialZoom": 1,
"paginatedPageHeight": 1400,
"visibleMetadataFields": [],
"playback": {"tempoMultiplier": 1, "loop": false, "volume": 0.8},
"compare": {"aItemId": null, "bItemId": null, "synchronizedZoom": true, "aZoom": 1, "bZoom": 1,
"playbackMode": "a", "loopSequence": false, "tempoMultiplier": 1,
"targetKey": null, "showTransposed": false},
"caption": ""
}
```
format is pae (Plaine & Easie)
or mei (MEI). viewMode is single,
list, grouped (by resource) or compare (two items side by side, set
with compare.aItemId and compare.bItemId).
Media Asset¶
Media assets are plain Markdown or HTML pointing into the story's assets/
folder:
[](https://commons.wikimedia.org/wiki/File:La_ronda_de_noche,_por_Rembrandt_van_Rijn.jpg)
The Night Watch. Rembrandt van Rijn, The Night Watch, 1642, Public domain
<audio controls src="assets/audio/interview.mp3"></audio>
<video controls src="assets/videos/tour.mp4"></video>
The editor adds a caption line from the asset's metadata, and with extended metadata switched on a collapsible table with all fields.
Story Metadata¶
The Story Metadata node becomes an HTML block, made from the project metadata when the Markdown is written:
<section class="tile lodeon-story-metadata" aria-label="About this story">
<dl>
<dt><strong>Author:</strong></dt>
<dd><strong>Josiah Carberry</strong>, …</dd>
<dt><strong>License:</strong></dt>
<dd>CC BY 4.0</dd>
</dl>
</section>
Ordinary Markdown¶
Everything from writing documentation pages works
in stories too: headings, lists, tables, quotes, images, /// blocks and
```sparql code blocks with a ▶ run link.