提交 a5b22d5b 编写于 作者: V Vlad Ilyushchenko

grid column auto-width

上级 7b28dbf1
......@@ -5,28 +5,20 @@
~ | |_| | |_| | __/\__ \ |_| |_| | |_) |
~ \__\_\\__,_|\___||___/\__|____/|____/
~
~ The MIT License (MIT)
~ Copyright (c) 2014-2016 Appsicle
~
~ Copyright (C) 2016 Appsicle
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ Permission is hereby granted, free of charge, to any person obtaining a
~ copy of this software and associated documentation files (the "Software"),
~ to deal in the Software without restriction, including without limitation
~ the rights to use, copy, modify, merge, publish, distribute, sublicense,
~ and/or sell copies of the Software, and to permit persons to whom the
~ Software is furnished to do so, subject to the following conditions:
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ The above copyright notice and this permission notice shall be included in
~ all copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
~ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
~ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
~ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
~ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
~ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
~ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--><!--suppress HtmlUnknownTag --><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>QuestDB - Console</title><link rel="apple-touch-icon" href="apple-touch-icon.png"><!-- Place favicon.ico in the root directory --><link rel="stylesheet" href="styles/qdb.css"><script type="text/javascript">history.pushState(null, null, 'index.html');
window.addEventListener('popstate', function () {
history.pushState(null, null, 'index.html');
});</script></head><body class="pace-done"><div id="wrapper"><nav class="navbar-default navbar-static-side" role="navigation"><div class="sidebar-collapse"><ul class="nav metismenu" id="side-menu"><li class="nav-header"><div class="dropdown profile-element"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><span class="clear"><h3>QuestDB</h3></span></a></div><div class="logo-element">QDB</div></li><li><a id="sql-editor" href="#"><i class="fa fa-table"></i> <span class="nav-label">SQL Console</span></a></li><li><a id="file-upload" href="#"><i class="fa fa-upload"></i> <span class="nav-label">Data import</span></a></li><li><a href="#"><i class="fa fa-pie-chart"></i> <span class="nav-label">Analytics</span></a></li></ul></div></nav><div id="page-wrapper" class="gray-bg"><div class="row border-bottom"><nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0"><div class="navbar-header"><a class="navbar-minimalize minimalize-styl-2 btn btn-primary" href="#"><i class="fa fa-bars"></i></a></div><ul class="nav navbar-top-links navbar-right"><li><span class="m-r-sm text-muted welcome-message">Welcome to QuestDB Console</span></li><li><a href="#"><i class="fa fa-sign-out"></i> Log out</a></li></ul></nav></div><div class="row wrapper border-bottom white-bg page-heading js-sql-panel"><div class="col-lg-10"><h3>SQL Console</h3></div></div><div class="wrapper wrapper-content js-sql-panel"><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div class="m-b-sm"><div class="btn-group pull-right"><button class="btn btn-white btn-sm"><i class="fa fa-arrow-left"></i></button></div><button class="btn btn-white btn-sm m-r-sm js-query-run"><i class="fa fa-play"></i>&nbsp;&nbsp;Run</button> <button class="btn btn-white btn-sm"><i class="fa fa-copy"></i></button> <button class="btn btn-white btn-sm"><i class="fa fa-scissors"></i></button> <button class="btn btn-white btn-sm m-r-sm"><i class="fa fa-clipboard"></i></button> <button class="btn btn-white btn-sm"><i class="fa fa-paragraph"></i></button></div><div id="sqlEditor" class="editor border-rounded-top-half"></div><div class="query-progress-spinner js-query-spinner"></div><div class="query-message query-message-ok js-query-message-panel"><div class="col-lg-2 query-time"><i class="fa fa-clock-o"></i><div class="js-query-time">-</div></div><div class="col-lg-10 js-query-message-text"></div></div></div></div></div></div><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div id="grid"></div></div></div></div></div></div><div class="row wrapper border-bottom white-bg page-heading js-import-panel"><div class="col-lg-10"><h3>Data import</h3></div></div><div class="wrapper wrapper-content js-import-panel"><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div id="dragTarget" class="drag-target drag-idle"><h2>Drag files here to import</h2></div><div class="m-b-sm"><button id="btnImportClearSelected" class="btn btn-white btn-sm" disabled="disabled"><i class="fa fa-remove"></i>Clear</button> <button id="btnRetry" class="btn btn-white btn-sm" title disabled="disabled"><i class="fa fa-upload"></i></button> <button id="btnImportCancel" class="btn btn-white btn-sm" title disabled="disabled"><i class="fa fa-stop"></i></button></div><div id="import-file-list"></div></div></div></div></div><div class="row" id="import-detail"><div class="col-lg-12"><div class="js-import-editor"><div class="ibox"><div class="ibox-content"><div class="row"><div class="col-lg-12"><div class="stats-switcher-viewport"><div class="stats-switcher"><div class="row vertical-align import-imported-table"><div class="col-xs-3"><i class="fa fa-table fa-2x"></i></div><div class="col-xs-9 text-right"><h3 class="font-bold js-import-tab-name">ABCD</h3></div></div><div class="import-stats"><div class="import-imported-stats pull-right"><i class="fa fa-thumbs-o-down"></i>&nbsp;<span class="js-rejected-row-count">1023003</span> rows</div><div class="import-imported-stats"><i class="fa fa-thumbs-o-up"></i>&nbsp;<span class="js-imported-row-count">15000000</span> rows</div></div></div></div></div><div class="row"><div class="col-lg-12"><div class="import-stats-chart"><div class="import-rejected pull-right"></div><div class="import-imported"></div></div></div></div><div class="row"><div class="col-lg-12"><div class="grid"><div class="ud-header-row"><div class="ud-header gh-1"><i class="fa fa-hashtag"></i></div><div class="ud-header gh-2">Column name</div><div class="ud-header gh-3">Type</div><div class="ud-header gh-4">Errors</div></div><div class="ud-canvas"><!--<div class="ud-row" style="top: 0">--><!--<div class="ud-cell gc-1 g-other js-g-row">1</div>--><!--<div class="ud-cell gc-2 g-other">location</div>--><!--<div class="ud-cell gc-3 g-type">STRING</div>--><!--<div class="ud-cell gc-4 g-other">10</div>--><!--<div class="ud-cell gc-5 g-other">0</div>--><!--</div>--><!--<div class="ud-row" style="top: 35px">--><!--<div class="ud-cell gc-1 g-other">2</div>--><!--<div class="ud-cell gc-2 g-other"><i--><!--class="fa fa-exclamation-triangle g-warning"></i>price--><!--</div>--><!--<div class="ud-cell gc-3 g-type">DOUBLE</div>--><!--<div class="ud-cell gc-4 g-other">8</div>--><!--<div class="ud-cell gc-5 g-other">1400</div>--><!--</div>--></div></div></div></div></div></div></div></div><div class="panel panel-danger js-import-error"><div class="panel-heading">Import failed</div><div class="panel-body"><div class="col-sm-7 js-message">Server rejected file due to unsupported file format.</div><div class="col-sm-5 ud-btn-group js-import-error-btn-group"><form method="get"><label><input type="radio" name="importAction" value="append" class="js-btn-append"> Append</label><label><input type="radio" name="importAction" value="overwrite" class="js-btn-overwrite"> Overwrite</label><label><input type="radio" name="importAction" value="cancel" class="js-btn-cancel"> Cancel</label></form></div></div></div></div></div></div><div class="footer"><div><strong>Copyright</strong> Appsicle Ltd. &copy; 2014-2016</div></div></div></div><script src="scripts/qdb.js"></script></body></html>
\ No newline at end of file
});</script></head><body class="pace-done"><div id="wrapper"><nav class="navbar-default navbar-static-side" role="navigation"><div class="sidebar-collapse"><ul class="nav metismenu" id="side-menu"><li class="nav-header"><div class="dropdown profile-element"><a data-toggle="dropdown" class="dropdown-toggle" href="#"><span class="clear"><h3>QuestDB</h3></span></a></div><div class="logo-element">QDB</div></li><li><a id="sql-editor" href="#"><i class="fa fa-table"></i> <span class="nav-label">SQL Console</span></a></li><li><a id="file-upload" href="#"><i class="fa fa-upload"></i> <span class="nav-label">Data import</span></a></li><li><a href="#"><i class="fa fa-pie-chart"></i> <span class="nav-label">Analytics</span></a></li></ul></div></nav><div id="page-wrapper" class="gray-bg"><div class="row border-bottom"><nav class="navbar navbar-static-top" role="navigation" style="margin-bottom: 0"><div class="navbar-header"><a class="navbar-minimalize minimalize-styl-2 btn btn-primary" href="#"><i class="fa fa-bars"></i></a></div><ul class="nav navbar-top-links navbar-right"><li><span class="m-r-sm text-muted welcome-message">Welcome to QuestDB Console</span></li><li><a href="#"><i class="fa fa-sign-out"></i> Log out</a></li></ul></nav></div><div class="row wrapper border-bottom white-bg page-heading js-sql-panel"><div class="col-lg-10"><h3>SQL Console</h3></div></div><div class="wrapper wrapper-content js-sql-panel"><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div class="m-b-sm"><div class="btn-group pull-right"><button class="btn btn-white btn-sm"><i class="fa fa-arrow-left"></i></button></div><button class="btn btn-white btn-sm m-r-sm js-query-run"><i class="fa fa-play"></i>&nbsp;&nbsp;Run</button> <button class="btn btn-white btn-sm"><i class="fa fa-copy"></i></button> <button class="btn btn-white btn-sm"><i class="fa fa-scissors"></i></button> <button class="btn btn-white btn-sm m-r-sm"><i class="fa fa-clipboard"></i></button> <button class="btn btn-white btn-sm"><i class="fa fa-paragraph"></i></button></div><div id="sqlEditor" class="editor border-rounded-top-half"></div><div class="query-progress-spinner js-query-spinner"></div><div class="query-message query-message-ok js-query-message-panel"><div class="col-lg-2 query-time"><i class="fa fa-clock-o"></i><div class="js-query-time">-</div></div><div class="col-lg-10 js-query-message-text"></div></div></div></div></div></div><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div id="grid"><div class="qg-header-row"></div><div class="qg-viewport"><div class="qg-canvas"></div></div></div></div></div></div></div></div><div class="row wrapper border-bottom white-bg page-heading js-import-panel"><div class="col-lg-10"><h3>Data import</h3></div></div><div class="wrapper wrapper-content js-import-panel"><div class="row"><div class="col-lg-12"><div class="ibox"><div class="ibox-content"><div id="dragTarget" class="drag-target drag-idle"><h2>Drag files here to import</h2></div><div class="m-b-sm"><button id="btnImportClearSelected" class="btn btn-white btn-sm" disabled="disabled"><i class="fa fa-remove"></i>Clear</button> <button id="btnRetry" class="btn btn-white btn-sm" title disabled="disabled"><i class="fa fa-upload"></i></button> <button id="btnImportCancel" class="btn btn-white btn-sm" title disabled="disabled"><i class="fa fa-stop"></i></button></div><div id="import-file-list"></div></div></div></div></div><div class="row" id="import-detail"><div class="col-lg-12"><div class="js-import-editor"><div class="ibox"><div class="ibox-content"><div class="row"><div class="col-lg-12"><div class="stats-switcher-viewport"><div class="stats-switcher"><div class="row vertical-align import-imported-table"><div class="col-xs-3"><i class="fa fa-table fa-2x"></i></div><div class="col-xs-9 text-right"><h3 class="font-bold js-import-tab-name">ABCD</h3></div></div><div class="import-stats"><div class="import-imported-stats pull-right"><i class="fa fa-thumbs-o-down"></i>&nbsp;<span class="js-rejected-row-count">1023003</span> rows</div><div class="import-imported-stats"><i class="fa fa-thumbs-o-up"></i>&nbsp;<span class="js-imported-row-count">15000000</span> rows</div></div></div></div></div><div class="row"><div class="col-lg-12"><div class="import-stats-chart"><div class="import-rejected pull-right"></div><div class="import-imported"></div></div></div></div><div class="row"><div class="col-lg-12"><div class="grid"><div class="ud-header-row"><div class="ud-header gh-1"><i class="fa fa-hashtag"></i></div><div class="ud-header gh-2">Column name</div><div class="ud-header gh-3">Type</div><div class="ud-header gh-4">Errors</div></div><div class="ud-canvas"><!--<div class="ud-row" style="top: 0">--><!--<div class="ud-cell gc-1 g-other js-g-row">1</div>--><!--<div class="ud-cell gc-2 g-other">location</div>--><!--<div class="ud-cell gc-3 g-type">STRING</div>--><!--<div class="ud-cell gc-4 g-other">10</div>--><!--<div class="ud-cell gc-5 g-other">0</div>--><!--</div>--><!--<div class="ud-row" style="top: 35px">--><!--<div class="ud-cell gc-1 g-other">2</div>--><!--<div class="ud-cell gc-2 g-other"><i--><!--class="fa fa-exclamation-triangle g-warning"></i>price--><!--</div>--><!--<div class="ud-cell gc-3 g-type">DOUBLE</div>--><!--<div class="ud-cell gc-4 g-other">8</div>--><!--<div class="ud-cell gc-5 g-other">1400</div>--><!--</div>--></div></div></div></div></div></div></div></div><div class="panel panel-danger js-import-error"><div class="panel-heading">Import failed</div><div class="panel-body"><div class="col-sm-7 js-message">Server rejected file due to unsupported file format.</div><div class="col-sm-5 ud-btn-group js-import-error-btn-group"><form method="get"><label><input type="radio" name="importAction" value="append" class="js-btn-append"> Append</label><label><input type="radio" name="importAction" value="overwrite" class="js-btn-overwrite"> Overwrite</label><label><input type="radio" name="importAction" value="cancel" class="js-btn-cancel"> Cancel</label></form></div></div></div></div></div></div><div class="footer"><div><strong>Copyright</strong> Appsicle Ltd. &copy; 2014-2016</div></div></div></div><script src="scripts/qdb.js"></script></body></html>
\ No newline at end of file
......@@ -27,7 +27,8 @@
'use strict';
$.fn.grid = function () {
var defaults = {
minColumnWidth: 60
minColumnWidth: 60,
rowHeight: 28
};
var $style;
var div = $(this);
......@@ -36,11 +37,13 @@
var header;
var colMax;
var data;
var totalWidth = -1;
var stretched = 0;
// viewport height
var vp = 400;
// row height in px
var rh = 30;
var rh = defaults.rowHeight;
// virtual row count in grid
var r;
// max virtual y (height) of grid canvas
......@@ -67,7 +70,7 @@
h = 10000000;
}
M = Math.ceil(yMax / h);
canvas.css('height', h);
canvas.css('height', h === 0 ? 1 : h);
}
function renderRow(row) {
......@@ -126,45 +129,96 @@
canvas = div.find('.qg-canvas');
}
function createCss() {
$style = $('<style type="text/css" rel="stylesheet"/>').appendTo($('head'));
function getColumnAlignment(i) {
switch (data.columns[i].type) {
case 'STRING':
case 'SYMBOL':
return 'text-align: left;';
default:
return '';
}
}
var rules = [];
var sum = 0;
function generatePxWidth(rules) {
for (var i = 0; i < colMax.length; i++) {
var w = Math.max(defaults.minColumnWidth, colMax[i] * 8 + 8);
rules.push('.qg-w' + i + '{width:' + w + 'px;}');
sum += w;
rules.push('.qg-w' + i + '{width:' + colMax[i] + 'px;' + getColumnAlignment(i) + '}');
}
rules.push('.qg-r{width:' + sum + 'px;}');
rules.push('.qg-canvas{width:' + sum + 'px;}');
rules.push('.qg-r{width:' + totalWidth + 'px;}');
rules.push('.qg-canvas{width:' + totalWidth + 'px;}');
stretched = 2;
}
if ($style[0].styleSheet) { // IE
$style[0].styleSheet.cssText = rules.join(' ');
} else {
$style[0].appendChild(document.createTextNode(rules.join(' ')));
function generatePctWidth(rules) {
for (var i = 0; i < colMax.length; i++) {
rules.push('.qg-w' + i + '{width:' + colMax[i] * 100 / totalWidth + '%;' + getColumnAlignment(i) + '}');
}
rules.push('.qg-r{width:100%;}');
rules.push('.qg-canvas{width:100%;}');
stretched = 1;
}
function createCss() {
if (data) {
var viewportWidth = viewport.width();
var f = null;
if (totalWidth < viewportWidth && stretched !== 1) {
f = generatePctWidth;
} else if (totalWidth > viewportWidth && stretched !== 2) {
f = generatePxWidth;
}
if (f) {
if ($style) {
$style.remove();
}
$style = $('<style type="text/css" rel="stylesheet"/>').appendTo($('head'));
var rules = [];
f(rules);
rules.push('.qg-c{height:' + rh + 'px;}');
if ($style[0].styleSheet) { // IE
$style[0].styleSheet.cssText = rules.join(' ');
} else {
$style[0].appendChild(document.createTextNode(rules.join(' ')));
}
}
}
}
function computeColumnWidths() {
colMax = [];
var i, k;
var i, k, w;
totalWidth = 0;
for (i = 0; i < data.columns.length; i++) {
var c = data.columns[i];
$('<div class="qg-header qg-w' + i + '">' + c.name + '</div>').appendTo(header);
colMax.push(c.name.length * 1.2);
var col = $('<div class="qg-header qg-w' + i + '">' + c.name + '</div>').appendTo(header);
switch (c.type) {
case 'STRING':
case 'SYMBOL':
col.addClass('qg-header-l');
break;
}
w = Math.max(defaults.minColumnWidth, Math.ceil(c.name.length * 8 * 1.2 + 8));
colMax.push(w);
totalWidth += w;
}
var max = data.result.length > 100 ? 100 : data.result.length;
for (i = 0; i < max; i++) {
var row = data.result[i];
var sum = 0;
for (k = 0; k < row.length; k++) {
var cell = row[k];
var str = cell !== null ? cell.toString() : 'null';
colMax[k] = Math.max(str.length, colMax[k]);
w = Math.max(defaults.minColumnWidth, str.length * 8 + 8);
colMax[k] = Math.max(w, colMax[k]);
sum += colMax[k];
}
totalWidth = Math.max(totalWidth, sum);
}
console.log('computed: ' + totalWidth);
}
function clear() {
......@@ -179,12 +233,16 @@
header.empty();
canvas.empty();
rows = {};
stretched = 0;
data = null;
}
function resizeViewport() {
var t = viewport[0].getBoundingClientRect().top;
vp = Math.round((window.innerHeight - t)) - 90;
viewport.css('height', vp);
createCss();
viewportScroll(true);
}
function resizeDiv() {
......@@ -218,12 +276,12 @@
//noinspection JSUnusedLocalSymbols
function update(x, m) {
data = m.r;
clear();
data = m.r;
addRows(data.result.length);
computeColumnWidths();
createCss();
resize();
viewport[0].scrollTop = 0;
viewportScroll(true);
}
......
......@@ -77,7 +77,7 @@
function qq() {
abortActive();
requestParams.query = qry.q;
requestParams.limit = '0,10000';
requestParams.limit = '0,1000';
requestParams.withCount = false;
time = new Date().getTime();
hActiveRequest = $.get('/js', requestParams).done(handleServerResponse).fail(handleServerError);
......
......@@ -50,6 +50,10 @@
text-align: right;
}
.qg-header-l {
text-align: left;
}
.qg-viewport {
overflow: auto;
}
......@@ -61,8 +65,13 @@
.qg-c {
display: inline-block;
padding: 3px;
padding: 4px 3px;
overflow: hidden;
text-overflow: ellipsis;
text-align: right;
}
.qg-c:hover {
padding: 2px 1px;
border: 2px solid #afb7c7;
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册