Einfaches Markdown-Panel
In diesem ersten Beispiel geht es nur darum, das Vorgehen zu zeigen.
Dashboard als Vorlage
Als einfaches Beispiel, das keine Datenabfragen macht, kann ein Dashboard mit einem oder mehreren Makrdown-Panels verwendet werden. In der Praxis werden Dashboards, die nur Markdown-Panels enthalten, wohl nur selten gebraucht, aber das Vorgehen lässt sich daran gut zeigen und die Beispiele lassen sich einfach nachvollziehen. Hier der Screenshot der interaktiv erstellten Dashboardvorlage für das erste Beispiel:

Dieses Dashboard wird nun exportiert und als blog_beispiel1.ndjson gespeichert.
Inputdatei mit Variablen
Da sonst auch json-Dateien verwendet werden, bietet es sich an, die Variablen ebenfalls in einer neuen json-Datei blog_beispiel1_vars.json zu definieren. Es empfiehlt sich, auch den Titel resp. Namen des Dashboards – in diesem Beispiel steht «title»: «Blog_Beispiel1» in der ndjson-Datei – in der Inputdatei zu definieren und dabei einen neuen Namen zu wählen, damit man beim Import das ursprüngliche Dashboard nicht gleich überschreibt, falls keine neue Id generiert wird.
Hier ein Beispiel des Dateiinhaltes, in dem alle Texte des Markdown-Panels definiert sind:
{
"markdown": {
"title": "Markdown_Titel",
"textzeilen": ["Textzeile1", "Textzeile2","😃"]
},
"dashboard_title": "generiertes_dashboard_blog_beispiel1"
}
Umformen der ndjson-Datei mit dem Dashboard
Danach macht man am besten eine Kopie der Datei mit dem Dashboard, hier mit dem Namen blog_beispiel1.j2.
Die Zeile mit der Dashboarddefinition kopiert man nun in eine weitere, neue Datei blog_beispiel1.json, um sie besser editieren zu können. Diese neue Datei öffnet man in VSCode und formatiert sie mit <ctrl><alt><b>
(vscode-json: Beautify). Zudem können an Kommata Zeilenumbrüche und die Zeichenfolge ——> angehängt werden, um eine bessere Übersicht zu bekommen. Die Zeilenumbrüche und die Zeichenfolge lassen sich später wieder einfach entfernen.
Der Teil der Datei mit der Definition des Markdown-Panels sieht dann etwa wie folgt aus:
...
"panelsJSON": "[{\"type\":\"visualization\",
------>\"gridData\":{\"x\":0,
------>\"y\":0,
------>\"w\":20,
------>\"h\":9,
------>\"i\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\"},
------>\"panelIndex\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\",
------>\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},
------>\"savedVis\":{\"id\":\"\",
------>\"title\":\"\",
------>\"description\":\"\",
------>\"type\":\"markdown\",
------>\"params\":{\"fontSize\":12,
------>\"openLinksInNewTab\":false,
------>\"markdown\":\"# Markdown_Titel\\n\\nTextzeile1\\n\\nTextzeile 2\\n\\n😃\"},
------>\"uiState\":{},
------>\"data\":{\"aggs\":[],
------>\"searchSource\":{\"query\":{\"query\":\"\",
------>\"language\":\"kuery\"},\"filter\":[]}}}}}]",
"timeRestore": false,
],
"timeRestore": false,
"title": "Blog_Beispiel1",
"version": 2
},
…
Achtung, die Backslashes vor den Anführungs- und Schlusszeichen und vor Backslashes müssen nach dem Umformen der Datei noch vorhanden sein.
Einfügen von jinja2 Elementen
Jetzt können in der Datei blog_beispiel1.json Referenzen auf die Variablen aus der Inputdatei eingefügt werden. Die Dokumentation zu jinja2 ist wie schon zuvor angegeben auf folgender Webseite zu finden: https://jinja.palletsprojects.com/en/stable/templates/. Um den Wert eines Elementes der Inputdatei einzufügen, genügt es, den Namen der Variable in doppelten geschweiften Klammern anzugeben.
"markdown": "# Markdown_Titel\n\nTextzeile1\n\nTextzeile 2\n\n😃"
muss dazu für die obige Inputdatei wie folgt angepasst werden:
"markdown": "# {{ markdown.title }}\n\n{{ markdown.textzeilen.0 }}\n\n{{ markdown.textzeilen.1 }}\n\n{{ markdown.textzeilen.2 }}"
markdown.textzeilen
ist als Array definiert und mit den Zahlen kann auf die einzelnen Arrayelemente zugegriffen werden. Die Zeile mit dem Dashboardnamen (gegen Ende der Datei vor der Versionsangabe) wird dann noch wie folgt definiert:
"title": "{{ dashboard_title }}",
Dashboard-Id löschen
Jetzt muss man noch die Dashboard-Id in blog_beispiel1.json löschen, da man sonst möglicherweise einen Konflikt mit dem ursprünglichen Dashboard und dem mit neuem Namen generierten Dashboard bekommt. Die Id steht gegen Ende der Datei nach der Angabe created_at
:
"created_at": "2024-11-26T16:56:50.240Z",
"id": "2d77705c-912a-4730-a565-242f6ae43475",
Man kann einfach die Zeile mit der Id löschen.
Formatieren als ndjson-Template
Zuerst müssen die eingefügten Zeilenumbrüche und Zeichenfolgen mit einem entsprechenden Replace all im Editor wieder gelöscht werden.
Mit der Tastenkombination <ctrl><alt><u>
(vscode-json: Uglify) kann jetzt das json in blog_beisiel1.json wieder auf eine einzelne Zeile geschrieben werden.
Mit dieser Zeile ersetzt man die ursprüngliche Zeile in blog_beisiel1.j2 und erhält so ein Template, um das Dashboard, das interaktiv erstellt wurde, neu zu generieren.
Dashboard generieren und importieren
Auf der Kommandozeile generiert man nun das neue Dashboard:
jinjanate blog_beispiel1.j2 blog_beispiel1_vars.json -o generiertes_dashboard_blog_beispiel1.ndjson
In Elastic kann nun unter dem Menüpunkt «Management → Stack Management → Saved Objects» die neu generierte Dateien generiertes_dashboard_blog_beispiel1.ndjson importiert werden. Es sollte zum Import die Option «Create new objects with random Ids» ausgewählt werden. So erhält man am wenigsten Konflikte, bekommt aber allenfalls mehrere Objekte mit demselben Namen, bei denen man die alten Versionen löschen kann. Da muss man schauen, welche Variante am einfachsten ist und ob eventuell die Ids oben nicht gelöscht werden sollen.
Wenn man beim Import eine Meldung folgender Art bekommt « ‹generiertes_dashboard_blog_beispiel› conflicts with an existing object.», so hat man ein Problem mit Ids und dem neuen Dashboardnamen.
Das neu importierte Dashboard sieht dann genau so aus wie die Vorlage im Screenshot oben.
Mehrere Markdown Panels generieren
Ausgangspunkt ist dieselbe Vorlage wie in Beispiel 1.
Inputdatei mit Variablen
Die Inputdatei wird mit Angaben für mehrere Markdown-Panels erweitert. Neben dem Text für die Panels wird auch die Position und Grösse definiert. Hier die Beispieldatei blog_beispiel2_vars.json:
{
"markdown": [
{
"title": "Swissmakers",
"textzeilen": [
"Aus Freude an Technik",
"Engeneering / Security / Consulting",
"swissmakers.ch 😊"
],
"position": [4,0],
"groesse": [20,8]
},
{
"title": "Codeatelier",
"textzeilen": [
"Wir bauen deine digitale Zukunft",
"Webdesign 🟢 SEO 🟢 Webapps 🟢 Webshops",
"codeatelier.ch 😃"
],
"position": [9,9],
"groesse": [25,8]
},
{
"title": "Swissmakers",
"textzeilen": [
"Ihre ITC-Spezialistinnen und -Spezialisten",
"Engeneering, Linux und Netzsicherheit",
"swissmakers.ch 👍"
],
"position": [0,18],
"groesse": [35,8]
}
],
"dashboard_title": "generiertes_dashboard_blog_beispiel2"
}
Umformen der ndjson-Datei mit dem Dashboard
Wie in Beispiel 1 sollte man die Datei blog_beispiel2.j2 umformen, damit sie einfacher zu ändern ist. Damit man mehrere Markdown-Panels erhält, kann man im jinja2-Template in panelsJSON die Angaben für die Panels wiederholen. Im mit eckigen Klammern begrenzten Teil nach panelsJSON wiederholt man den ganzen Teil von {\"type\":\"visualization\",
bis zu \"filter\":[]}}}}}
wobei zwischen diesen Definitionen der Panels jeweils ein Komma als Trennzeichen von Array-Elementen eingefügt werden muss. Am Ende des Arrays darf aber kein Komma mehr stehen. Das Ganze kann in einer ersten Variante direkt im Editor gemacht werden und sieht dann wie folgt aus:
"panelsJSON": "[{\"type\":\"visualization\",
------>\"gridData\":{\"x\":0,
------>\"y\":0,
------>\"w\":20,
------>\"h\":9,
------>\"i\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\"},
------>\"panelIndex\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\",
------>\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},
------>\"savedVis\":{\"id\":\"\",
------>\"title\":\"\",
------>\"description\":\"\",
------>\"type\":\"markdown\",
------>\"params\":{\"fontSize\":12,
------>\"openLinksInNewTab\":false,
------>\"markdown\":\"# Markdown_Titel\\n\\nTextzeile1\\n\\nTextzeile 2\\n\\n😃\"},
------>\"uiState\":{},
------>\"data\":{\"aggs\":[],
------>\"searchSource\":{\"query\":{\"query\":\"\",
------>\"language\":\"kuery\"},
------>\"filter\":[]}}}}},
------>{\"type\":\"visualization\",
------>\"gridData\":{\"x\":0,
------>\"y\":0,
------>\"w\":20,
------>\"h\":9,
------>\"i\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\"},
------>\"panelIndex\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\",
------>\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},
------>\"savedVis\":{\"id\":\"\",
------>\"title\":\"\",
------>\"description\":\"\",
------>\"type\":\"markdown\",
------>\"params\":{\"fontSize\":12,
------>\"openLinksInNewTab\":false,
------>\"markdown\":\"# Markdown_Titel\\n\\nTextzeile1\\n\\nTextzeile 2\\n\\n😃\"},
------>\"uiState\":{},
------>\"data\":{\"aggs\":[],
------>\"searchSource\":{\"query\":{\"query\":\"\",
------>\"language\":\"kuery\"},
------>\"filter\":[]}}}}},
------>{\"type\":\"visualization\",
------>\"gridData\":{\"x\":0,
… …
------>\"language\":\"kuery\"},
------>\"filter\":[]}}}}}]",
"timeRestore": false,
"title": "Blog_Beispiel2",
"version": 2
},
"coreMigrationVersion": "8.8.0",
Löschen der Panel-Indices
Ein Panel bekommt in Kibana einen Index-Wert. Diese müssen (ausser dem ersten) gelöscht werden, resp. es darf nicht mehrmals derselbe Index vorkommen, sonst überschreiben sich die Panels. Folgende Zeilen in der Datei blog_beispiel2.j2 müssen also noch gelöscht werden:
-----→\"panelIndex\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\",
Auch die Dashboard-Id sollte am besten wieder gelöscht werden.
Einfügen von jinja2 Elementen
Analog Beispiel 1 können nun die Variablen aus der Inputdatei eingefügt werden. Man hat dabei eine Array-Ebene mehr als im ersten Beispiel und neben den Texten sind auch noch die Positionen und die Grösse der Panels anzugeben. Auszugsweise sieht das dann so aus:
"panelsJSON": "[{\"type\":\"visualization\",
------>\"gridData\":{\"x\":{{ markdown.0.position.0 }},
------>\"y\":{{ markdown.0.position.1 }},
------>\"w\":{{ markdown.0.groesse.0 }},
------>\"h\":{{ markdown.0.groesse.1 }},
… …
------>\"markdown\":\"# {{ markdown.0.title }}\\n\\n{{ markdown.0.textzeilen.0 }}\\n\\n{{ markdown.0.textzeilen.1 }}\\n\\n{{ markdown.0.textzeilen.2 }}\"},
… …
Für die weiteren zwei Panels heisst es dann {{ markdown.1. … }}
und {{ markdown.2. … }}
.
Auch der Name des Dashboards muss noch angepasst werden:
"title":"{{ dashboard_title }}"
Weitere Schritte
Analog Beispiel 1 muss die Datei blog_beispiel2.j2 wieder als ndjson formatiert werden.
Dann kann das Dashboard generiert werden mit dem Befehl:
jinjanate blog_beispiel2.j2 blog_beispiel2_vars.json -o generiertes_dashboard_blog_beispiel2.ndjson
Das generierte Dashboard wird wiederum mit der Option «Create new objects with random Ids» importiert. Das Resultat sieht man im folgenden Screenshot:

Generieren von mehreren Panels in einer Schleife
Das Dashboard aus Beispiel 2 lässt sich auch etwas eleganter generieren. Anstelle der Aneinanderreihung der Markdown-Panels im jinja2-Template können die Panels in Beispiel 3 in einer Schleife generiert werden. Diese Lösung bietet mehr Flexibilität.
Als Inputdatei mit Variablen wird vorerst eine Kopie blog_beispiel3_vars.json der Inputdatei von Beispiel 2 gebraucht, in der nur der Name resp. Titel des Dashboards auf generiertes_dashboard_blog_beispiel3 angepasst worden ist.
blog_beispiel3.json ist wieder die umformatierte Datei mit dem ursprünglich interaktiv erstellten Dashboard, in die nun jinja2-Elemente eingefügt werden. Die Datei ist vorerst eine Kopie von blog_beispiel1.json, die nur die Definition eines Markdown-Panels enthält, nicht die Datei mit den drei Panels aus Beispiel 2. Hier nun der entsprechende Teil der Datei mit den neuen jinja2-Elementen:
"panelsJSON": "[{% for item in markdown %}{\"type\":\"visualization\",
------->\"gridData\":{\"x\":{{ markdown[loop.index0]['position'][0] }},
------->\"y\":{{ markdown[loop.index0]['position'][1] }},
------->\"w\":{{ markdown[loop.index0]['groesse'][0] }},
------->\"h\":{{ markdown[loop.index0]['groesse'][1] }},
------->\"i\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\"},
------->\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},
------->\"savedVis\":{\"id\":\"\",
------->\"title\":\"\",
------->\"description\":\"\",
------->\"type\":\"markdown\",
------->\"params\":{\"fontSize\":12,
------->\"openLinksInNewTab\":false,
------->\"markdown\":\"# {{ markdown[loop.index0]['title'] }}\\n\\n{{ markdown[loop.index0]['textzeilen'][0] }}\\n\\n{{ markdown[loop.index0]['textzeilen'][1] }}\\n\\n{{ markdown[loop.index0]['textzeilen'][2] }}\"},
------->\"uiState\":{},
------->\"data\":{\"aggs\":[],
------->\"searchSource\":{\"query\":{\"query\":\"\",
------->\"language\":\"kuery\"},
------->\"filter\":[]}}}}}{% if loop.index != loop.length %},{% endif %}
{% endfor %}]",
"timeRestore": false,
"title": "{{ dashboard_title }}",
"version": 2
},
In jinja2 kann eine Schleife mit den folgenden Elementen definiert werden:
{% for item in markdown %}
{% endfor %}
Für jedes Element im Array markdown in der Inputdatei wird dann der ganze Teil innerhalb der Schleife wiederholt. Damit erhält man die drei Paneldefinitionen im Output.
Wie beim Anpassen der Datei für Beispiel 2 muss man beachten, dass die Paneldefinitionen in einem json-Array stehen, zwischen dessen Elementen ein Komma stehen muss, aber am Ende des Arrays darf kein Komma mehr stehen. Dies kann mit einer Bedingung in jinja2 erreicht werden:
{% if loop.index != loop.length %},{% endif %}
Wenn der Schleifenindex noch nicht gleich der Anzahl Schleifen ist, so wird das Komma zwischen der if-Bedingung und dem {% endif %}
in den Output geschrieben, aber beim letzten Schleifendurchgang nicht mehr.
Für die Angabe der Arrayelemente aus der Inputdatei wird hier eine alternative Syntax verwendet, bei der die Array-Ebenen nicht durch Punkte getrennt sind wie es in Beispiel 1 und Beispiel 2 gebraucht wurde, sondern in eckigen Klammern angegeben werden. loop.index0
ist eine Variable, die innerhalb einer for-Schleife zur Verfügung steht und die angibt, in welchem Durchgang der Schleife man ist, wenn mit 0 zu zählen begonnen wird, um Unterschied zur oben verwendeten Variable loop.index
, bei der mit 1 zu zählen begonnen wird. Die Namensteile ohne Anführungs- und Schlusszeichen sind jinja2-Variablen, deren Wert dort eingesetzt wird, jene in Anführungs- und Schlusszeichen sind die Namen aus dem json in der Inputdatei. Anführungs- und Schlusszeichen sind also wichtig und müssen korrekt gesetzt sein.
Wie in den anderen Beispielen muss nun die Datei umformatiert und als ganzes Template blog_beispiel3.j2 gespeichert werden.
Der Befehl
jinjanate blog_beispiel3.j2 blog_beispiel3_vars.json -o generiertes_dashboard_blog_beispiel3.ndjson
generiert dann ein Dashboard, das genau so aussieht wie jenes in Beispiel 2.
Neue Inputdatei mit Variablen
Mit der Schleife im Template ist Beispiel 3 nun viel flexibler als Beispiel 2. Es genügt, die Inputdatei anzupassen, um unterschiedlich viele Markdown-Panels im Dashboard zu generieren. Es können natürlich auch verschiedene Inputdateien mit demselben Template verwendet werden, z.B. für verschiedene Stages (dev, preprod, prod) etc.
Hier eine neue Inputdatei:
{
"markdown": [
{
"title": "**Swissmakers**",
"textzeilen": [
"Aus Freude an Technik",
"Engeneering / Security / Consulting",
"swissmakers.ch 😊"
],
"position": [0,0],
"groesse": [15,8]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Einfach Top!",
"swissmakers.ch 😊 👍 💪 👍 😄",
""
],
"position": [18,0],
"groesse": [15,8]
},
{
"title": "**Codeatelier**",
"textzeilen": [
"Wir bauen deine digitale Zukunft",
"Webdesign 🟢 SEO 🟢 Webapps 🟢 Webshops",
"codeatelier.ch 😃"
],
"position": [9,9],
"groesse": [18,8]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Ihre ITC-Spezialistinnen und -Spezialisten",
"Engeneering, Linux und Netzsicherheit",
"swissmakers.ch 👍"
],
"position": [0,18],
"groesse": [18,8]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Ihre ITC-Expertinnen und -Experten",
"für ihre Private Cloud basierend auf Nextcloud",
"swissmakers.ch 👍"
],
"position": [18,18],
"groesse": [18,8]
}
],
"dashboard_title": "generiertes_dashboard_blog_beispiel3_b"
}
Ohne weitere Anpassungen wird daraus mit demselben Template das folgende Dashboard generiert:

Automatisches Anordnen von Panels
In Beispiel 4 geht es darum, ein paar weitere Möglichkeiten von jinja2-Templates zu zeigen und Panels im Dashboard automatisch in Zeilen und Spalten anzuordnen.
Es wird eine feste Anzahl von Markdown-Panels verwendet, die je nach der gewünschten Anzahl Panels im Dashboard wiederholt werden.
Inputdatei mit Variablen
Als Inputdatei mit Variablen wird eine Kopie der Inputdatei von Beispiel 3 verwendet. Grösse und Position der Markdown-Panels werden aber für alle Panels einheitlich gesetzt und ausserhalb des markdown-Arrays im json-File definiert. Dort wird auch die gewünschte Anzahl Markdown-Panels und die Anzahl Spalten für die Panels im Dashboard angegeben. Die Breite der Panels ist kleiner definiert als in den vorangehenden Beispielen, weil die Panels sonst in Kibana automatisch etwas anders angeordnet werden, da sie nicht wie eigentlich gewünscht Platz finden im Dashboard.
Die Inputdatei blog_beispiel4_vars.json sieht wie folgt aus:
{
"hoehe": 8,
"breite": 10,
"spalten": 4,
"anzahl": 20,
"markdown": [
{
"title": "**Swissmakers**",
"textzeilen": [
"Aus Freude an Technik",
"Engeneering / Security / Consulting",
"swissmakers.ch 😊"
]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Einfach Top!",
"swissmakers.ch 😊 👍 💪 👍 😄",
""
]
},
{
"title": "**Codeatelier**",
"textzeilen": [
"Wir bauen deine digitale Zukunft",
"Webdesign 🟢 SEO 🟢 Webapps 🟢 Webshops",
"codeatelier.ch 😃"
]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Ihre ITC-Spezialistinnen und -Spezialisten",
"Engeneering, Linux und Netzsicherheit",
"swissmakers.ch 👍"
]
},
{
"title": "**Swissmakers**",
"textzeilen": [
"Ihre ITC-Expertinnen und -Experten",
"für ihre Private Cloud basierend auf Nextcloud",
"swissmakers.ch 👍"
]
}
],
"dashboard_title": "generiertes_dashboard_blog_beispiel4"
}
Generieren und anordnen der Panels
blog_beispiel4.json ist wieder die umformatierte Datei mit dem ursprünglich interaktiv erstellten Dashboard.
Für das Beispiel 4 ist noch der Panel-Titel ausgeschaltet und die Schriftgrösse etwas verkleinert worden.
"optionsJSON": "{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":true}",
------→\"params\":{\"fontSize\":10,
In blog_beispiel4.json werden nun wiederum jinja2-Elemente eingefügt. Hier nun der entsprechende Teil der Datei mit den teilweise neuen jinja2-Elementen:
"panelsJSON": "{% set global = namespace(row = 0) %}[{% for i in range(0, anzahl - 1) %}{\"type\":\"visualization\",
------->\"gridData\":{\"x\":{{ (i) % spalten * breite }},
------->\"y\":{{ hoehe * global.row }}{% if (i + 1) % spalten == 0 %}{% set global.row = global.row + 1 %}{% endif %},
------->\"w\":{{ breite }},
------->\"h\":{{ hoehe }},
------->\"i\":\"09747f18-d4b6-4cb0-a25e-63abf3a9cce8\"},
------->\"embeddableConfig\":{\"enhancements\":{\"dynamicActions\":{\"events\":[]}},
------->\"savedVis\":{\"id\":\"\",
------->\"title\":\"\",
------->\"description\":\"\",
------->\"type\":\"markdown\",
------->\"params\":{\"fontSize\":10,
------->\"openLinksInNewTab\":false,
------->\"markdown\":\"# {{ markdown[i % markdown|length]['title'] }}\\n\\n{{ markdown[i % markdown|length]['textzeilen'][0] }}\\n\\n{{ markdown[i % markdown|length]['textzeilen'][1] }}\\n\\n{{ markdown[i % markdown|length]['textzeilen'][2] }}\"},
------->\"uiState\":{},
------->\"data\":{\"aggs\":[],
------->\"searchSource\":{\"query\":{\"query\":\"\",
------->\"language\":\"kuery\"},
------->\"filter\":[]}}}}}{% if loop.index != loop.length %},{% endif %}{% endfor %}]",
Die insgesamt 20 Markdown-Panels «anzahl»: 20
sollen in Zeilen mit je 4 Panels «spalten»: 4
angeordnet werden. Dazu wird die Hilfsvariable row
definiert, in der die Zeile für das Panel steht und mit der dann die y-Position berechnet wird. row
wird mit dem Wert 0 initialisiert:
{% set global = namespace(row = 0) %}
Die Schleife über die Panels wird etwas anders definiert als zuvor:
{% for i in range(0, anzahl) %}
Man hat so die Schleifenvariable i, die von 0 bis anzahl
-1, im Beispiel also von 0 bis 29, läuft. Die obere Grenze anzahl
in der range-Funktion wird von der Funktion nicht zurück geliefert, man muss also anzahl
und nicht anzahl
– 1 als obere Grenze angeben. Am Ende der Schleife hat man wieder die Bedingung wegen den Kommata zwischen den Paneldefinitionen aber nicht am Ende das Arrays:
{% if loop.index != loop.length %},{% endif %}
%
ist in Jinja2 der Modulo-Operator, der den Rest einer ganzzahligen Division angibt. Damit lassen sich die jeweiligen x-Positionen der Panels berechnen:
{{ (i) % spalten * breite }}
Beim Zugriff auf die Elemente des markdown-Arrays in der Inputdatei wird ebenfalls der Modulo-Operator zusammen mit der Laufvariable i
verwendet, um nach dem letzten Array-Element wieder auf das erste zuzugreifen:
{{ markdown[i % markdown|length]['title'] }}
Mit dem Filter length
in markdown|length
erhält man die Anzahl Elemente im Array markdown
, die man hier braucht.
Wie in den anderen Beispielen muss nun die Datei umformatiert und als ganzes Template blog_beispiel4.j2 gespeichert werden.
Der Befehl
jinjanate blog_beispiel4.j2 blog_beispiel4_vars.json -o generiertes_dashboard_blog_beispiel4.ndjson
generiert nun folgendes Dashboard, in dem die Markdown-Panels wiederholt werden und regelmässig in 4 Spalten angeordnet sind:

Dashboards mit Elastic-Daten
Sie kennen nun erste Beispiele. Erkunden Sie die Möglichkeit der Dashboard-Generierung mit Elastic-Beispieldaten in einigen Wochen in unserem nächsten Teil dieses Blogbeitrags.
Natürlich können Sie jederzeit auf Swissmakers zukommen für Unterstützung bei der Erstellung professioneller Kibana-Dashboards.