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);