diff --git a/webui/sql_build_query.php b/webui/sql_build_query.php index fc92c0c..0398256 100644 --- a/webui/sql_build_query.php +++ b/webui/sql_build_query.php @@ -128,7 +128,12 @@ function _get_repeated_groups($dbmeta, $sel_tabs, $sel_cols){ if (!array_key_exists($tid, $sel_tabs)) { continue; } + // if t is not an array, it cannot have repeated group + if (!is_array($t)) { + continue; + } // has repeated_goup? + echo get_class($t); if (!array_key_exists("repeated_group", $t)) { continue; } @@ -154,6 +159,7 @@ function _get_repeated_groups($dbmeta, $sel_tabs, $sel_cols){ } return($rgroups); } + function _get_sql_where_repeated($dbmeta, $sel_tabs, $sel_cols) { $rgroups = _get_repeated_groups($dbmeta, $sel_tabs, $sel_cols); // generate where conditions; tab0.col=tabn.col @@ -171,7 +177,7 @@ function _get_sql_where_repeated($dbmeta, $sel_tabs, $sel_cols) { function _get_sql_select_repeated($dbmeta, $sel_tabs, $sel_cols) { $rgroups = _get_repeated_groups($dbmeta, $sel_tabs, $sel_cols); - + $rcols = []; foreach (array_keys($rgroups) as $rg){ $gid = $rg; $tbid = $rgroups[$rg][0]["table_id"]; diff --git a/webui/www/js/results.js b/webui/www/js/results.js new file mode 100644 index 0000000..b059038 --- /dev/null +++ b/webui/www/js/results.js @@ -0,0 +1,245 @@ +var g_table = null; + +async function getTableData(selection) { + console.log(JSON.stringify(selection)) + const response = await fetch("./php/query_json.php", { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(selection), + }); + if (!response.ok) { + throw new Error(response.statusText); + } + console.log(response); + + const jsn = await response.json(); + console.log("here") + + if (!jsn.status_ok) { + throw Error(jsn.status_msg); + } + + return jsn.data; +} + +function getColDef(coldefs) { + let colCalcN = function(values, data, calcParams) { + return "n=" + values.length.toString(); + } + let colCalcAvg = function(values, data, calcParams){ + values = values.filter(e => e !== null); + const mean = values.reduce( (a,b) => a + parseFloat(b), 0) / values.length; + return "m=" + (mean).toPrecision(4); + } + let colCalcAvgSd = function(values, data, calcParams){ + values = values.filter(e => e !== null); + const n = values.length; + const mean = values.reduce( (a,b) => a + parseFloat(b), 0) / n; + const sd = Math.sqrt(values.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b, 0) / n); + return `m=${mean.toPrecision(2)} sd=${sd.toPrecision(2)}`; + } + return coldefs.map( e => { + let r = { + title: e.id, + field: e.id, + minWidth: 90 + } + if (e.idx == 0) { + r.topCalc = colCalcN; + r.bottomCalc = colCalcN; + r.minWidth = 120; + } else if (e.type == "float" || e.type == "int") { + r.topCalc = colCalcAvgSd; + r.bottomCalc = colCalcAvgSd; + r.sorter = "number"; + } + return r; + }); +}; + +function getDataSelection() { + try { + const storage = window.sessionStorage.getItem('selection'); + if (!storage) { + throw new Error("Session expired - Please select columns here.") + } + const sel = JSON.parse(storage); + return sel; + } catch (e) { + showAlertBox(AlertType.ERROR, ["Unable to get selected data.", e.toString()]); + console.log("err: " + e.toString()); + } +} + +function checkSelection(sel_cols) { + const dbmeta = JSON.parse(window.sessionStorage.getItem('dbmeta')); + // get table.type and repeated_group info from selections + const selected_tables = [...new Set(sel_cols.map(c => c.table_id))]; + const r_goups = {}; + const r_ungrouped = []; + dbmeta.tables.forEach(t => { + // selected? + if (!selected_tables.includes(t.id)) { + return; + } + if (t.sampletype != "repeated") { + return; + } + if (t.repeated_group) { + if (!r_goups.hasOwnProperty(t.repeated_group.group_id)) { + r_goups[t.repeated_group.group_id] = []; + } + r_goups[t.repeated_group.group_id].push(t.id); + } else { + r_ungrouped.push(t.id); + } + }); + const max_repeated = 2; + if (Object.keys(r_goups).length + r_ungrouped.length > max_repeated) { + const msg = [`You selected more than ${max_repeated} tables with timeseries data. NOAS will try to process your query but might fail due to the number of resulting rows. Here is a list of the problematic tables in your selection:`]; + let count = 1; + Object.keys(r_goups).forEach(k => { + if (r_goups[k].length > 1) { + msg.push(`${count}) group "${k}" (tables: ${r_goups[k].join(", ")})`); + } else { + msg.push(`${count}) table "${r_goups[k].join(", ")}"`); + } + count++; + }); + r_ungrouped.forEach(e => { + msg.push(`${count}) table "${e}"`); + count++; + }) + showAlertBox(AlertType.WARNING, msg); + } +} + +async function loadTable() { + try { + const sel = getDataSelection(); + checkSelection(sel.columns); + lcProgressInit("noasTable"); + // make db query + g_table_data = await getTableData(sel); + document.getElementById("noasTable").innerHTML = '