declare var Slick: any;
const tsvDirUrl = "../tsv/";
const eol = "\r\n";
//------------------------------------------------------------------------------
var tsvFileNames: string[];
function onTsvDirGetComplete (html: string) {
let page = $($.parseHTML(html));
let AElements = page.find("a");
tsvFileNames = [];
for (let i = 0; i < AElements.length; i++) {
let e = AElements.eq(i);
let s = e.attr("href");
if (s && s.match(/\.tsv$/)) {
tsvFileNames.push(s); }}
buildIndexPage(); }
// Input: yyyy-mm-dd-hhmm*
// Output: dd.mm.yyyy hh:mm
function formatFileNameTimestamp (s: string) : string {
let r = s.match(/^(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d)(\d\d)/);
if (!r || r.length != 6) {
return "(?)"; }
return r[3] + "." + r[2] + "." + r[1] + " " + r[4] + ":" + r[5]; }
function buildIndexPage() {
let html = "";
html += "
Messdaten-Index
" + eol;
html += '';
for (let fn of tsvFileNames) {
let ts = formatFileNameTimestamp(fn);
html += '
' + ts + "" + eol; }
html += "
";
$("body").html(html);
$(".tsvFileLink").click( function (this: Element, event: Event) {
event.preventDefault();
openTsvFile($(this).data("tsvFileName")); }); }
function requestTsvDirectory() {
$("body").html("(requesting TSV directory)");
$.get(tsvDirUrl, onTsvDirGetComplete, "text");
$("body").html("(Ajax sent)"); }
//------------------------------------------------------------------------------
var currentTsvFileName: string;
function openTsvFile (tsvFileName: string) {
currentTsvFileName = tsvFileName;
$("body").html("(opening " + tsvFileName + ")");
let tsvFileUrl = tsvDirUrl + tsvFileName;
$.get(tsvFileUrl, onTsvFileGetComplete, "text"); }
function onTsvFileGetComplete (fileData: string) {
let tsvFileRows = fileData.split(/\r?\n/);
let fieldRows: string[][] = [];
let columnCount = 0;
for (let fileRow of tsvFileRows) {
if (fileRow.length == 0) {
continue; }
const fields = fileRow.split(/\t/);
columnCount = Math.max(columnCount, fields.length);
fieldRows.push(fields); }
buildMeterDataPage(fieldRows, columnCount); }
function buildMeterDataPage (fieldRows: string[][], columnCount: number) {
let html = "";
let ts = formatFileNameTimestamp(currentTsvFileName);
html += "Messdaten " + ts + "
" + eol;
html += '';
$("body").html(html);
const firstValueColumn = 5;
const meterValues = Math.floor((columnCount - firstValueColumn) / 2);
let tableColumns: any = [
{name: "Haus", field: "busNo", id: "busNo", width: 40, sortable: true, sortCompareFunction: sortCompareNumeric },
{name: "M-Bus Adr.", field: "meterAddr", id: "meterAddr", width: 40, sortable: true, sortCompareFunction: sortCompareNumeric, cssClass: "alignRight" },
{name: "Zähler-Nr.", field: "meterId", id: "meterId", width: 80, sortable: true, sortCompareFunction: sortCompareNumeric },
{name: "Typ", field: "productName", id: "productName", width: 80, sortable: true },
{name: "Medium", field: "medium", id: "medium", width: 80, sortable: true } ];
for (let i = 0; i < meterValues; i++) {
tableColumns.push({
name: "Messwert " + (i + 1),
field: "value" + (i + 1),
id: "value" + (i + 1),
width: 85,
cssClass: "alignRight",
sortable: true,
sortCompareFunction: sortCompareNumeric });
tableColumns.push({
name: "Einheit " + (i + 1),
field: "unit" + (i + 1),
id: "unit" + (i + 1),
width: 85,
sortable: true }); }
let tableData = [];
for (let rowNo = 0; rowNo < fieldRows.length; rowNo++) {
let fields = fieldRows[rowNo];
let r: any = {
busNo: fields[0],
meterAddr: fields[1],
meterId: fields[2],
productName: fields[3],
medium: fields[4] };
for (let i = 0; i < meterValues; i++) {
let meterValue = fields[firstValueColumn + 2 * i];
let meterUnit = fields[firstValueColumn + 2 * i + 1];
if (meterValue != null) {
r["value" + (i + 1)] = meterValue;
r["unit" + (i + 1)] = meterUnit; }}
tableData.push(r); }
const tableOptions = {
multiColumnSort: true };
let container = $("#meterTable1");
container.css("height", genMeterTableHeight());
let grid = new Slick.Grid(container, tableData, tableColumns, tableOptions);
grid.onSort.subscribe(onGridSort); }
function onGridSort (event: any, args: any) {
let sortCols = args.sortCols;
// console.log("sort: " + JSON.stringify(sortCols));
let grid = args.grid;
let data = grid.getData();
data.sort((r1: any, r2: any) => compareRows(r1, r2, sortCols));
grid.invalidate(); }
function compareRows (r1: any, r2: any, sortCols: any) : number {
for (let sortCol of sortCols) {
let colDef = sortCol.sortCol;
let fieldName = colDef.field;
let sortCompareFunction = colDef.sortCompareFunction || sortCompareString;
let polarity = sortCol.sortAsc ? 1 : -1;
let v1 = r1[fieldName];
let v2 = r2[fieldName];
let comp = sortCompareFunction(v1, v2) * polarity;
if (comp) {
return comp; }}
return 0; }
function sortCompareString (s1?: string, s2?: string) : number {
if (s1 === undefined || s1 === "") {
return (s2 === undefined || s2 === "") ? 0 : 1; }
if (s2 === undefined || s2 === "") {
return -1; }
return (s1 == s2) ? 0 : (s1 > s2) ? 1 : -1; }
function sortCompareNumeric (s1?: string, s2?: string) : number {
let n1 = (s1 == "") ? NaN : Number(s1);
let n2 = (s2 == "") ? NaN : Number(s2);
if (isNaN(n1) && isNaN(n2)) {
return sortCompareString(s1, s2); }
if (isNaN(n1)) {
return 1; }
if (isNaN(n2)) {
return -1; }
return (n1 == n2) ? 0 : (n1 > n2) ? 1 : -1; }
function genMeterTableHeight() {
return ($(window).height() - 80) + "px"; }
function adjustMeterTableHeight() {
let t = $("#meterTable1");
if (t.length == 0) {
return; }
let newHeight = genMeterTableHeight();
let oldHeight = t.css("height");
if (newHeight == oldHeight) {
return; }
t.css("height", newHeight);
t.trigger("resize.slickgrid"); }
//------------------------------------------------------------------------------
var delayedWindowResizeTimerId: number|undefined;
function delayedWindowResizeEvent() {
delayedWindowResizeTimerId = undefined;
adjustMeterTableHeight(); }
function windowResizeEvent() {
if (delayedWindowResizeTimerId) {
clearTimeout(delayedWindowResizeTimerId); }
delayedWindowResizeTimerId = setTimeout(delayedWindowResizeEvent, 200); }
function init() {
$(window).resize(windowResizeEvent);
requestTsvDirectory(); }
$(init);