JANUS HTML Reporting
Bei der Projektarbeit für ein Labware LIMS - System hatte ich ein
HTML Reporting Framework
zu implementieren.
Der Labware - Client erzeugt HTML, das in Modulen wie dem Sample Folder, der Info Rule oder auch in Visual Workflows verwendet werden kann.
Was sehr früh störte, war dass mittels des Labware Clients lediglich statisches HTML generiert werden kann.
Weiterführende Links oder "Load on demand" und damit der Aufbau perfomanter und interaktiver Seiten sind ohne einen richtigen Webserver nicht möglich.
So fasste ich den Entschluss, Node.JS als frei verfügbare Server-Komponente zu verwenden. Mittels Node.JS läßt sich JavaScript auch auf der Backend - Seite verwenden. Viele Bibliotheken, die aus dem Client - Bereich bekannt sind gibt es auch als Server - Variante oder sie sind direkt kompatibel. Im Node.JS - Umfeld sind viele Bibliotheken Open Source verfügbar, was die Verwendung attraktiv macht.
Node.JS verwendet zum Publizieren von Eigenentwicklungen, aber auch zum Herunterladen von Fremdbibliotheken ein zentrales Repository namens npm.
Projektfokus
- Funktional
- HTML Report Server für Windows-Clientsysteme, in diesem Fall Labware LIMS
- Aus gegebenem Anlass: Die "JANUS Code Quality Suite " - ein "Diff-Tool" für Labware LIMS
- Grafische Visualisierung der Daten
- Technisch: Auseinandersetzung mit modernen Technologien
Backend-Komponenten
- node-oracledb und mssql für den Zugriff auf Oracle- und MSSQL-Datenbanken
- Express als http und https - Server
- Socket.IO für die Websocket - Kommunikation mit älteren Browsern wie IE8 - nicht mehr benötigt :-)
- Passport.js für die Benutzer - Authentifizierung
- mammoth , eine Bibliothek zur Konvertierung von Microsoft Word - Dokumenten in HTML
- Office.JS für Web-basierte Plugins für Microsoft Office - Produkte
Client-Komponenten
Charting
Basics
- jQuery
- Underscore
- Twitter Bootstrap
- require.js
JANUS verwendet folgende Charting - Bibliotheken:
- D3 - als "State of the art" im BigData - Umfeld
- EJS Charting - eine Bibliothek für "konvetionelles Charting" (Line/Pie/Bar/Stacked Bars...)). Siehe auch Homepage für kommerzielle Nutzung.
- plot.ly Charting - mehr als ein Wrapper für die D3 - Bibliothek...
- Oracle JET Engine z.B. für Gantt Charts
- Marvin.JS - Designing molecules on the web - fast, smart and intuitive
- jQuery Sparklines - small inline charts
SQL Worksheet
Das SQL Worksheet bietet den ersten Zugang zur Ausführung von SQL im Web - Client, darauf setzen viele andere Funktionen in JANUS auf
- Das SQL wird vom Webclient an den JANUS Server geschickt und dort ausgeführt
- Der Client visualisiert die Daten als HTML - Tabelle
Pivot-SQL und Chart
Pivot-SQL formulieren und ausführen - einen Pivot Chart generieren...
Labware LIMS Package Explorer
JANUS Code-Diff im Package Explorer. Zur Visualisierung dient hier CodeMirror. Der Code der beiden Labware-Instanzen wird mit DiffMatchPatch verglichen.
Oracle JET: Gantt Charting
Mittels Oracle JET lassen sich Daten als Gantt - Chart visualisieren...See
Gantt Charts
Interaktives Reporting
- Links der Project Tree zur Auswahl des Experimentes.
- Rechts die Experimentdaten
Sonstige Bibliotheken
Nicht nur für JANUS verwendet, sondern Teil auch anderer Web - basierter Entwicklungen und Oracle APEX - Projekte
- Oracle JET - "Oracle JET empowers developers by providing a modular open source toolkit"
- Knockout - "Simplify dynamic JavaScript UIs with Model-View / View-Model pattern"
- CodeMirror - "a versatile text editor implemented in JavaScript"
- ACE Code Editor - "The high performance code editor for the web"
- Highlight.JS - "Syntax highlighting for the Web"
- PaPaParse - "The powerful, in-browser CSV parser for big boys and girls"
- FancyTree - "Dynamic tree view plugin for jQuery"
- Viewer.JS - "Documents. On your site. Now."
- CKEditor - "Smart WYSIWYG editor components with collaborative editing"
- Google DiffMatchPath - "High-performance library in multiple languages that finds differences and matches in plain text and applies patches"
- JSZip - "JSZip is a javascript library for creating, reading and editing .zip files, with a lovely and simple API."
- QRious - "QRious is a pure JavaScript library for generating QR codes using HTML5 canvas"
- Split.JS - "Split.js is a 2kb unopinionated utility for resizeable split views"
Der npm Build - Prozess
Mittels npm lassen sich Builds automatisieren. Es wird eine Package-Datei definiert, die alle Abhängigkeiten der Software beinhaltet.Hier die package.json - Datei für JANUS.
Gestartet wird der Build aus der Konsole mittels:
npm install
MongoDB
Labware LIMS kann programmiert werden. Der Code, der dabei entsteht befindet sich in verschiedenen Tabellen wie z.B. SUBROUTINE, CALCULATION oder FORMAT_CALCULATION.
JANUS erlaubt es, in den entsprechenden Tabellen nach Code zu suchen, um z.B. die Verwendung einer bestimmten Subroutine oder einer Variablen bestimmten Namens herauszufinden.
Das ist mit SQL möglich, ist aber langsam, da nicht nur eine Tabelle auf Code hin überprüft werden muss sondern eben mehrere. MongoDB als dokumentenbasierte NoSQL Datenbank ist ideal, um Text in Objekten zu suchen.
MongoDB Data Store aufbauen
Zuerst muss der MongoDB Store aufgebaut werden, indem die Daten aus der Oracle-DB ausgelesen werden
Das geschieht durech eine SQL SELECT * - Abfrage gegen die entsprechenden Tabellen, die Treffer werden in die MongoDB persistiert.
Wir benötigen folgende Packages
- nodeoracledb
- mongodb
Volltextsuche im Store
Die Volltextsuche in einer MongoDB gestaltet sich unglaublich viel schneller als in einer relationalen Datenbank.
Die Abfrage erfolgt allerdings nicht über eine Abfragesprache wie SQL, sondern mittels des Aufrufs von bestimmten befehlen wie find(), die gegen eine Datenmenge (Collection) ausgeführt werden.
Die find() - Funktion erwartert als Parameter vorkonfigurierte JSON - Objekte mit den Abfrageparametern.
function find(database, collection, expression, callBack) {
var projection;
projection = {};
var sortObj = {"NAME": 1};
mongoClient.connect(mongoURL, function (err, db) {
if (err) throw err;
var dbo = db.db(database);
try {
dbo.collection(collection).find(expression, projection).sort(sortObj)
.toArray(function (err, result) {
if (err) throw err;
callBack(result);
db.close();
});
} catch(e){
console.log("mongo.find: error:" + expression + ":");
}
});
}
var searchExpr = "ArrayFromCSV";
var expression =
{
$text:
{
$search: "\"" + searchExpr + "\"",
$caseSensitive: false,
}
}
find("DEV", "SUBROUTINE", expression, function(result){
console.log(result);
})
Das Ganze kann dann in einer Webanwendung etwa so aussehen: