mirror of https://github.com/apache/superset.git
Initial commit
This commit is contained in:
commit
447eefc79b
|
@ -0,0 +1,132 @@
|
||||||
|
from pydruid import client
|
||||||
|
from pydruid.utils.filters import Dimension
|
||||||
|
from dateutil.parser import parse
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from flask import Flask, render_template, request
|
||||||
|
from flask_bootstrap import Bootstrap
|
||||||
|
import json
|
||||||
|
from wtforms import Form, SelectMultipleField, SelectField, TextField
|
||||||
|
import pandas as pd
|
||||||
|
pd.set_option('display.max_colwidth', -1)
|
||||||
|
|
||||||
|
ROW_LIMIT = 10000
|
||||||
|
PORT = 8088
|
||||||
|
query = client.PyDruid("http://10.181.47.80:8080", 'druid/v2')
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
Bootstrap(app)
|
||||||
|
|
||||||
|
def latest_metadata(datasource):
|
||||||
|
max_time = query.time_boundary(datasource=datasource)[0]['result']['maxTime']
|
||||||
|
max_time = parse(max_time)
|
||||||
|
intervals = (max_time - timedelta(seconds=1)).isoformat() + '/'
|
||||||
|
intervals += max_time.isoformat()
|
||||||
|
return query.segment_metadata(
|
||||||
|
datasource=datasource,
|
||||||
|
intervals=intervals)[-1]['columns']
|
||||||
|
|
||||||
|
@app.route("/datasource/<datasource>/")
|
||||||
|
def datasource(datasource):
|
||||||
|
|
||||||
|
metadata = latest_metadata(datasource)
|
||||||
|
grain = ['all', 'none', 'minute', 'hour', 'day']
|
||||||
|
since_l = {
|
||||||
|
'1hour': timedelta(hours=1),
|
||||||
|
'1day': timedelta(days=1),
|
||||||
|
'7days': timedelta(days=7),
|
||||||
|
'28days': timedelta(days=28),
|
||||||
|
'all': timedelta(days=365*100)
|
||||||
|
}
|
||||||
|
limits = [0, 5, 10, 25, 50, 100, 500]
|
||||||
|
limit = request.args.get("limit")
|
||||||
|
try:
|
||||||
|
limit = int(limit)
|
||||||
|
if limit not in limits:
|
||||||
|
limits.append(limit)
|
||||||
|
limits = sorted(limits)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
class QueryForm(Form):
|
||||||
|
groupby = SelectMultipleField(
|
||||||
|
'Group by', choices=[(m, m) for m in sorted(metadata.keys())])
|
||||||
|
granularity = SelectField(
|
||||||
|
'Granularity', choices=[(g, g) for g in grain])
|
||||||
|
since = SelectField(
|
||||||
|
'Since', choices=[(s, s) for s in since_l.keys()])
|
||||||
|
limit = SelectField(
|
||||||
|
'Limit', choices=[(s, s) for s in limits])
|
||||||
|
flt_col_1 = SelectField(
|
||||||
|
'Filter 1', choices=[(m, m) for m in sorted(metadata.keys())])
|
||||||
|
flt_op_1 = SelectField(
|
||||||
|
'Filter 1', choices=[(m, m) for m in ['==', 'in', '<', '>']])
|
||||||
|
flt_eq_1 = TextField("Super")
|
||||||
|
|
||||||
|
groupby = request.args.getlist("groupby") or []
|
||||||
|
granularity = request.args.get("granularity")
|
||||||
|
limit = int(request.args.get("limit", ROW_LIMIT)) or ROW_LIMIT
|
||||||
|
since = request.args.get("since", "all")
|
||||||
|
from_dttm = (datetime.now() - since_l[since]).isoformat()
|
||||||
|
|
||||||
|
# Building filters
|
||||||
|
i = 1
|
||||||
|
filters = []
|
||||||
|
while True:
|
||||||
|
col = request.args.get("flt_col_" + str(i))
|
||||||
|
op = request.args.get("flt_op_" + str(i))
|
||||||
|
eq = request.args.get("flt_eq_" + str(i))
|
||||||
|
print (col,op,eq)
|
||||||
|
if col and op and eq:
|
||||||
|
filters.append(Dimension(col)==eq)
|
||||||
|
filters = Dimension(col)==eq
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
|
print filters
|
||||||
|
|
||||||
|
results=[]
|
||||||
|
results = query.groupby(
|
||||||
|
datasource=datasource,
|
||||||
|
granularity=granularity or 'all',
|
||||||
|
intervals=from_dttm + '/' + datetime.now().isoformat(),
|
||||||
|
dimensions=groupby,
|
||||||
|
aggregations={"count": client.doublesum("count")},
|
||||||
|
filter=filters,
|
||||||
|
limit_spec={
|
||||||
|
"type": "default",
|
||||||
|
"limit": limit,
|
||||||
|
"columns": [{
|
||||||
|
"dimension" : "count",
|
||||||
|
"direction" : "descending",
|
||||||
|
},],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
df = query.export_pandas()
|
||||||
|
if df is not None and not df.empty:
|
||||||
|
df = df.sort(df.columns[0], ascending=False)
|
||||||
|
if granularity == 'all':
|
||||||
|
del df['timestamp']
|
||||||
|
|
||||||
|
table = df.to_html(
|
||||||
|
classes=["table", "table-striped", 'table-bordered'], index=False)
|
||||||
|
else:
|
||||||
|
table = None
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
'panoramix/datasource.html',
|
||||||
|
table=table,
|
||||||
|
datasource=datasource,
|
||||||
|
latest_metadata=json.dumps(
|
||||||
|
metadata,
|
||||||
|
sort_keys=True,
|
||||||
|
indent=2),
|
||||||
|
results=json.dumps(
|
||||||
|
results,
|
||||||
|
sort_keys=True,
|
||||||
|
indent=2),
|
||||||
|
form=QueryForm(request.args),
|
||||||
|
)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app.debug = True
|
||||||
|
app.run(host='0.0.0.0', port=PORT)
|
|
@ -0,0 +1,6 @@
|
||||||
|
pydruid
|
||||||
|
python-dateutil
|
||||||
|
flask
|
||||||
|
pandas
|
||||||
|
wtforms
|
||||||
|
flask-bootstrap
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -0,0 +1,207 @@
|
||||||
|
body { padding-top: 70px; }
|
||||||
|
a.navbar-brand span {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
nav{
|
||||||
|
-webkit-box-shadow: 0px 3px 3px #AAA;
|
||||||
|
-moz-box-shadow: 0px 3px 3px #AAA;
|
||||||
|
box-shadow: 0px 3px 3px #AAA;
|
||||||
|
z-index:999;
|
||||||
|
}
|
||||||
|
a.navbar-brand {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
td>span.glyphicon{
|
||||||
|
padding-left: 3px;
|
||||||
|
padding-top: 3px;
|
||||||
|
}
|
||||||
|
button.btn {
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.rich_doc {
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 1px solid #dddddd;
|
||||||
|
background: white;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.status_square {
|
||||||
|
width:10px;
|
||||||
|
height:10px;
|
||||||
|
border:1px solid grey;
|
||||||
|
display:inline-block;
|
||||||
|
padding-left: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
div.squares{
|
||||||
|
float:right;
|
||||||
|
font-size: 1;
|
||||||
|
}
|
||||||
|
div.task_row{
|
||||||
|
}
|
||||||
|
span.success{
|
||||||
|
background-color:green;
|
||||||
|
}
|
||||||
|
span.up_for_retry{
|
||||||
|
background-color:yellow;
|
||||||
|
}
|
||||||
|
span.started{
|
||||||
|
background-color:lime;
|
||||||
|
}
|
||||||
|
span.error{
|
||||||
|
background-color:red;
|
||||||
|
}
|
||||||
|
span.queued{
|
||||||
|
background-color:gray;
|
||||||
|
}
|
||||||
|
.tooltip-inner {
|
||||||
|
text-align:left !important;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
input#execution_date {
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
table.highlighttable{
|
||||||
|
width: 100%;
|
||||||
|
table-layout:fixed;
|
||||||
|
}
|
||||||
|
div.linenodiv {
|
||||||
|
padding-right: 1px !important;
|
||||||
|
}
|
||||||
|
.linenos {
|
||||||
|
width: 50px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
div.linenodiv pre {
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
color: #AAA;
|
||||||
|
background-color: #FCFCFC;
|
||||||
|
text-align:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
overflow: auto;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
pre code {
|
||||||
|
overflow-wrap: normal;
|
||||||
|
white-space: pre;
|
||||||
|
}
|
||||||
|
input, select {
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sql {
|
||||||
|
border: 1px solid #CCC;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.ace_editor div {
|
||||||
|
font: inherit!important
|
||||||
|
}
|
||||||
|
#ace_container {
|
||||||
|
margin: 10px 0px;
|
||||||
|
}
|
||||||
|
#sql_ace {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.no-wrap {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
div.form-inline{
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body div.panel {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
.blur {
|
||||||
|
filter:url(#blur-effect-1);
|
||||||
|
}
|
||||||
|
div.legend_item {
|
||||||
|
-moz-border-radius: 5px/5px;
|
||||||
|
-webkit-border-radius: 5px 5px;
|
||||||
|
border-radius: 5px/5px;
|
||||||
|
float:right;
|
||||||
|
margin: 0px 10px 0px 0px;
|
||||||
|
padding:0px 5px;
|
||||||
|
border:solid 2px grey;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
div.legend_circle{
|
||||||
|
-moz-border-radius: 10px/10px;
|
||||||
|
-webkit-border-radius: 10px 10px;
|
||||||
|
border-radius: 10px/10px;
|
||||||
|
width:15px;
|
||||||
|
height:15px;
|
||||||
|
border:1px solid grey;
|
||||||
|
float:left;
|
||||||
|
margin-top: 2px;
|
||||||
|
margin-right: 0px;
|
||||||
|
}
|
||||||
|
div.square {
|
||||||
|
width:12px;
|
||||||
|
height:12px;
|
||||||
|
float: right;
|
||||||
|
margin-top: 2px;
|
||||||
|
border:1px solid black;
|
||||||
|
}
|
||||||
|
.btn:active, .btn.active {
|
||||||
|
box-shadow: inset 0 6px 6px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hll { background-color: #ffffcc }
|
||||||
|
.c { color: #408080; font-style: italic } /* Comment */
|
||||||
|
.err { border: 1px solid #FF0000 } /* Error */
|
||||||
|
.k { color: #008000; font-weight: bold } /* Keyword */
|
||||||
|
.o { color: #666666 } /* Operator */
|
||||||
|
.cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||||
|
.cp { color: #BC7A00 } /* Comment.Preproc */
|
||||||
|
.c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||||
|
.cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||||
|
.gd { color: #A00000 } /* Generic.Deleted */
|
||||||
|
.ge { font-style: italic } /* Generic.Emph */
|
||||||
|
.gr { color: #FF0000 } /* Generic.Error */
|
||||||
|
.gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||||
|
.gi { color: #00A000 } /* Generic.Inserted */
|
||||||
|
.go { color: #888888 } /* Generic.Output */
|
||||||
|
.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||||
|
.gs { font-weight: bold } /* Generic.Strong */
|
||||||
|
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||||
|
.gt { color: #0044DD } /* Generic.Traceback */
|
||||||
|
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||||
|
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||||
|
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||||
|
.kp { color: #008000 } /* Keyword.Pseudo */
|
||||||
|
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||||
|
.kt { color: #B00040 } /* Keyword.Type */
|
||||||
|
.m { color: #666666 } /* Literal.Number */
|
||||||
|
.s { color: #BA2121 } /* Literal.String */
|
||||||
|
.na { color: #7D9029 } /* Name.Attribute */
|
||||||
|
.nb { color: #008000 } /* Name.Builtin */
|
||||||
|
.nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||||
|
.no { color: #880000 } /* Name.Constant */
|
||||||
|
.nd { color: #AA22FF } /* Name.Decorator */
|
||||||
|
.ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||||
|
.ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||||
|
.nf { color: #0000FF } /* Name.Function */
|
||||||
|
.nl { color: #A0A000 } /* Name.Label */
|
||||||
|
.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||||
|
.nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||||
|
.nv { color: #19177C } /* Name.Variable */
|
||||||
|
.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||||
|
.w { color: #bbbbbb } /* Text.Whitespace */
|
||||||
|
.mb { color: #666666 } /* Literal.Number.Bin */
|
||||||
|
.mf { color: #666666 } /* Literal.Number.Float */
|
||||||
|
.mh { color: #666666 } /* Literal.Number.Hex */
|
||||||
|
.mi { color: #666666 } /* Literal.Number.Integer */
|
||||||
|
.mo { color: #666666 } /* Literal.Number.Oct */
|
||||||
|
.sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||||
|
.sc { color: #BA2121 } /* Literal.String.Char */
|
||||||
|
.sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||||
|
.s2 { color: #BA2121 } /* Literal.String.Double */
|
|
@ -0,0 +1,495 @@
|
||||||
|
/*! Select2 Bootstrap 3 CSS v1.4.6 | MIT License | github.com/t0m/select2-bootstrap-css */
|
||||||
|
/**
|
||||||
|
* Reset Bootstrap 3 .form-control styles which - if applied to the
|
||||||
|
* original <select>-element the Select2-plugin may be run against -
|
||||||
|
* are copied to the .select2-container.
|
||||||
|
*
|
||||||
|
* 1. Overwrite .select2-container's original display:inline-block
|
||||||
|
* with Bootstrap 3's default for .form-control, display:block;
|
||||||
|
* courtesy of @juristr (@see https://github.com/fk/select2-bootstrap-css/pull/1)
|
||||||
|
*/
|
||||||
|
.select2-container.form-control {
|
||||||
|
background: transparent;
|
||||||
|
box-shadow: none;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
/* 1 */
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust Select2 inputs to fit Bootstrap 3 default .form-control appearance.
|
||||||
|
*/
|
||||||
|
.select2-container .select2-choices .select2-search-field input,
|
||||||
|
.select2-container .select2-choice,
|
||||||
|
.select2-container .select2-choices {
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
border-color: #cccccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #555555;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
background-color: white;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-search input {
|
||||||
|
border-color: #cccccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #555555;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
|
background-color: white;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container .select2-choices .select2-search-field input {
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust Select2 input heights to match the Bootstrap default.
|
||||||
|
*/
|
||||||
|
.select2-container .select2-choice {
|
||||||
|
height: 34px;
|
||||||
|
line-height: 1.42857;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Multi Select2's height which - depending on how many elements have been selected -
|
||||||
|
* may grown higher than their initial size.
|
||||||
|
*/
|
||||||
|
.select2-container.select2-container-multi.form-control {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Bootstrap 3 control sizing classes
|
||||||
|
* @see http://getbootstrap.com/css/#forms-control-sizes
|
||||||
|
*/
|
||||||
|
.select2-container.input-sm .select2-choice,
|
||||||
|
.input-group-sm .select2-container .select2-choice {
|
||||||
|
height: 30px;
|
||||||
|
line-height: 1.5;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.input-lg .select2-choice,
|
||||||
|
.input-group-lg .select2-container .select2-choice {
|
||||||
|
height: 46px;
|
||||||
|
line-height: 1.33333;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field input {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.input-sm .select2-choices .select2-search-field input,
|
||||||
|
.input-group-sm .select2-container-multi .select2-choices .select2-search-field input {
|
||||||
|
height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.input-lg .select2-choices .select2-search-field input,
|
||||||
|
.input-group-lg .select2-container-multi .select2-choices .select2-search-field input {
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust height and line-height for .select2-search-field amd multi-select Select2 widgets.
|
||||||
|
*
|
||||||
|
* 1. Class repetition to address missing .select2-chosen in Select2 < 3.3.2.
|
||||||
|
*/
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field input {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-chosen,
|
||||||
|
.select2-choice > span:first-child,
|
||||||
|
.select2-container .select2-choices .select2-search-field input {
|
||||||
|
padding: 6px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-sm .select2-chosen,
|
||||||
|
.input-group-sm .select2-chosen,
|
||||||
|
.input-sm .select2-choice > span:first-child,
|
||||||
|
.input-group-sm .select2-choice > span:first-child,
|
||||||
|
.input-sm .select2-choices .select2-search-field input,
|
||||||
|
.input-group-sm .select2-choices .select2-search-field input {
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-lg .select2-chosen,
|
||||||
|
.input-group-lg .select2-chosen,
|
||||||
|
.input-lg .select2-choice > span:first-child,
|
||||||
|
.input-group-lg .select2-choice > span:first-child,
|
||||||
|
.input-lg .select2-choices .select2-search-field input,
|
||||||
|
.input-group-lg .select2-choices .select2-search-field input {
|
||||||
|
padding: 10px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.input-sm .select2-choices .select2-search-choice,
|
||||||
|
.input-group-sm .select2-container-multi .select2-choices .select2-search-choice {
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi.input-lg .select2-choices .select2-search-choice,
|
||||||
|
.input-group-lg .select2-container-multi .select2-choices .select2-search-choice {
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the single Select2's dropdown arrow button appearance.
|
||||||
|
*
|
||||||
|
* 1. For Select2 v.3.3.2.
|
||||||
|
*/
|
||||||
|
.select2-container .select2-choice .select2-arrow,
|
||||||
|
.select2-container .select2-choice div {
|
||||||
|
border-left: none;
|
||||||
|
background: none;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open .select2-choice .select2-arrow,
|
||||||
|
.select2-dropdown-open .select2-choice div {
|
||||||
|
border-left-color: transparent;
|
||||||
|
background: none;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the dropdown arrow button icon position for the single-select Select2 elements
|
||||||
|
* to make it line up vertically now that we increased the height of .select2-container.
|
||||||
|
*
|
||||||
|
* 1. Class repetition to address missing .select2-chosen in Select2 v.3.3.2.
|
||||||
|
*/
|
||||||
|
.select2-container .select2-choice .select2-arrow b,
|
||||||
|
.select2-container .select2-choice div b {
|
||||||
|
background-position: 0 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open .select2-choice .select2-arrow b,
|
||||||
|
.select2-dropdown-open .select2-choice div b {
|
||||||
|
background-position: -18px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.input-sm .select2-choice .select2-arrow b,
|
||||||
|
.input-group-sm .select2-container .select2-choice .select2-arrow b,
|
||||||
|
.select2-container.input-sm .select2-choice div b,
|
||||||
|
.input-group-sm .select2-container .select2-choice div b {
|
||||||
|
background-position: 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open.input-sm .select2-choice .select2-arrow b,
|
||||||
|
.input-group-sm .select2-dropdown-open .select2-choice .select2-arrow b,
|
||||||
|
.select2-dropdown-open.input-sm .select2-choice div b,
|
||||||
|
.input-group-sm .select2-dropdown-open .select2-choice div b {
|
||||||
|
background-position: -18px 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container.input-lg .select2-choice .select2-arrow b,
|
||||||
|
.input-group-lg .select2-container .select2-choice .select2-arrow b,
|
||||||
|
.select2-container.input-lg .select2-choice div b,
|
||||||
|
.input-group-lg .select2-container .select2-choice div b {
|
||||||
|
background-position: 0 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open.input-lg .select2-choice .select2-arrow b,
|
||||||
|
.input-group-lg .select2-dropdown-open .select2-choice .select2-arrow b,
|
||||||
|
.select2-dropdown-open.input-lg .select2-choice div b,
|
||||||
|
.input-group-lg .select2-dropdown-open .select2-choice div b {
|
||||||
|
background-position: -18px 9px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Bootstrap's validation states and change Select2's border colors and focus states.
|
||||||
|
* Apply .has-warning, .has-danger or .has-succes to #select2-drop to match Bootstraps' colors.
|
||||||
|
*/
|
||||||
|
.has-warning .select2-choice,
|
||||||
|
.has-warning .select2-choices {
|
||||||
|
border-color: #8a6d3b;
|
||||||
|
}
|
||||||
|
.has-warning .select2-container-active .select2-choice,
|
||||||
|
.has-warning .select2-container-multi.select2-container-active .select2-choices {
|
||||||
|
border-color: #66512c;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
|
||||||
|
}
|
||||||
|
.has-warning.select2-drop-active {
|
||||||
|
border-color: #66512c;
|
||||||
|
}
|
||||||
|
.has-warning.select2-drop-active.select2-drop.select2-drop-above {
|
||||||
|
border-top-color: #66512c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-error .select2-choice,
|
||||||
|
.has-error .select2-choices {
|
||||||
|
border-color: #a94442;
|
||||||
|
}
|
||||||
|
.has-error .select2-container-active .select2-choice,
|
||||||
|
.has-error .select2-container-multi.select2-container-active .select2-choices {
|
||||||
|
border-color: #843534;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
|
||||||
|
}
|
||||||
|
.has-error.select2-drop-active {
|
||||||
|
border-color: #843534;
|
||||||
|
}
|
||||||
|
.has-error.select2-drop-active.select2-drop.select2-drop-above {
|
||||||
|
border-top-color: #843534;
|
||||||
|
}
|
||||||
|
|
||||||
|
.has-success .select2-choice,
|
||||||
|
.has-success .select2-choices {
|
||||||
|
border-color: #3c763d;
|
||||||
|
}
|
||||||
|
.has-success .select2-container-active .select2-choice,
|
||||||
|
.has-success .select2-container-multi.select2-container-active .select2-choices {
|
||||||
|
border-color: #2b542c;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
|
||||||
|
}
|
||||||
|
.has-success.select2-drop-active {
|
||||||
|
border-color: #2b542c;
|
||||||
|
}
|
||||||
|
.has-success.select2-drop-active.select2-drop.select2-drop-above {
|
||||||
|
border-top-color: #2b542c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make Select2's active-styles - applied to .select2-container when the widget receives focus -
|
||||||
|
* fit Bootstrap 3's .form-element:focus appearance.
|
||||||
|
*/
|
||||||
|
.select2-container-active .select2-choice,
|
||||||
|
.select2-container-multi.select2-container-active .select2-choices {
|
||||||
|
border-color: #66afe9;
|
||||||
|
outline: none;
|
||||||
|
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
||||||
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
||||||
|
-webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||||
|
-o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||||
|
transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-active {
|
||||||
|
border-color: #66afe9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-drop-auto-width,
|
||||||
|
.select2-drop.select2-drop-above.select2-drop-active {
|
||||||
|
border-top-color: #66afe9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select2 widgets in Bootstrap Input Groups
|
||||||
|
*
|
||||||
|
* When Select2 widgets are combined with other elements using Bootstrap 3's
|
||||||
|
* "Input Group" component, we don't want specific edges of the Select2 container
|
||||||
|
* to have a border-radius.
|
||||||
|
*
|
||||||
|
* In Bootstrap 2, input groups required a markup where these style adjustments
|
||||||
|
* could be bound to a CSS-class identifying if the additional elements are appended,
|
||||||
|
* prepended or both.
|
||||||
|
*
|
||||||
|
* Bootstrap 3 doesn't rely on these classes anymore, so we have to use our own.
|
||||||
|
* Use .select2-bootstrap-prepend and .select2-bootstrap-append on a Bootstrap 3 .input-group
|
||||||
|
* to let the contained Select2 widget know which edges should not be rounded as they are
|
||||||
|
* directly followed by another element.
|
||||||
|
*
|
||||||
|
* @see http://getbootstrap.com/components/#input-groups
|
||||||
|
*/
|
||||||
|
.input-group.select2-bootstrap-prepend [class^="select2-choice"] {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group.select2-bootstrap-append [class^="select2-choice"] {
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open [class^="select2-choice"] {
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
border-bottom-right-radius: 4px !important;
|
||||||
|
border-bottom-left-radius: 4px !important;
|
||||||
|
background: white;
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
.input-group.select2-bootstrap-prepend .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-left-radius: 0 !important;
|
||||||
|
border-top-left-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.input-group.select2-bootstrap-append .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-right-radius: 0 !important;
|
||||||
|
border-top-right-radius: 0 !important;
|
||||||
|
}
|
||||||
|
.input-group.input-group-sm.select2-bootstrap-prepend .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-right-radius: 3px !important;
|
||||||
|
}
|
||||||
|
.input-group.input-group-lg.select2-bootstrap-prepend .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-right-radius: 6px !important;
|
||||||
|
}
|
||||||
|
.input-group.input-group-sm.select2-bootstrap-append .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-left-radius: 3px !important;
|
||||||
|
}
|
||||||
|
.input-group.input-group-lg.select2-bootstrap-append .select2-dropdown-open.select2-drop-above [class^="select2-choice"] {
|
||||||
|
border-bottom-left-radius: 6px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust Select2's choices hover and selected styles to match Bootstrap 3's default dropdown styles.
|
||||||
|
*/
|
||||||
|
.select2-results .select2-highlighted {
|
||||||
|
color: white;
|
||||||
|
background-color: #337ab7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust alignment of Bootstrap 3 buttons in Bootstrap 3 Input Groups to address
|
||||||
|
* Multi Select2's height which - depending on how many elements have been selected -
|
||||||
|
* may grown higher than their initial size.
|
||||||
|
*/
|
||||||
|
.select2-bootstrap-append .select2-container-multiple,
|
||||||
|
.select2-bootstrap-append .input-group-btn,
|
||||||
|
.select2-bootstrap-append .input-group-btn .btn,
|
||||||
|
.select2-bootstrap-prepend .select2-container-multiple,
|
||||||
|
.select2-bootstrap-prepend .input-group-btn,
|
||||||
|
.select2-bootstrap-prepend .input-group-btn .btn {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make Multi Select2's choices match Bootstrap 3's default button styles.
|
||||||
|
*/
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice {
|
||||||
|
color: #555555;
|
||||||
|
background: white;
|
||||||
|
border-color: #cccccc;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select2-container-multi .select2-choices .select2-search-choice-focus {
|
||||||
|
background: #ebebeb;
|
||||||
|
border-color: #adadad;
|
||||||
|
color: #333333;
|
||||||
|
-webkit-box-shadow: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Multi Select2's choice close-button vertical alignment.
|
||||||
|
*/
|
||||||
|
.select2-search-choice-close {
|
||||||
|
margin-top: -7px;
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust the single Select2's clear button position (used to reset the select box
|
||||||
|
* back to the placeholder value and visible once a selection is made
|
||||||
|
* activated by Select2's "allowClear" option).
|
||||||
|
*/
|
||||||
|
.select2-container .select2-choice abbr {
|
||||||
|
top: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjust "no results" and "selection limit" messages to make use
|
||||||
|
* of Bootstrap 3's default "Alert" style.
|
||||||
|
*
|
||||||
|
* @see http://getbootstrap.com/components/#alerts-default
|
||||||
|
*/
|
||||||
|
.select2-results .select2-no-results,
|
||||||
|
.select2-results .select2-searching,
|
||||||
|
.select2-results .select2-selection-limit {
|
||||||
|
background-color: #fcf8e3;
|
||||||
|
color: #8a6d3b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address disabled Select2 styles.
|
||||||
|
*
|
||||||
|
* 1. For Select2 v.3.3.2.
|
||||||
|
* 2. Revert border-left:0 inherited from Select2's CSS to prevent the arrow
|
||||||
|
* from jumping when switching from disabled to enabled state and vice versa.
|
||||||
|
*/
|
||||||
|
.select2-container.select2-container-disabled .select2-choice,
|
||||||
|
.select2-container.select2-container-disabled .select2-choices {
|
||||||
|
cursor: not-allowed;
|
||||||
|
background-color: #eeeeee;
|
||||||
|
border-color: #cccccc;
|
||||||
|
}
|
||||||
|
.select2-container.select2-container-disabled .select2-choice .select2-arrow,
|
||||||
|
.select2-container.select2-container-disabled .select2-choice div,
|
||||||
|
.select2-container.select2-container-disabled .select2-choices .select2-arrow,
|
||||||
|
.select2-container.select2-container-disabled .select2-choices div {
|
||||||
|
background-color: transparent;
|
||||||
|
border-left: 1px solid transparent;
|
||||||
|
/* 2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Address Select2's loading indicator position - which should not stick
|
||||||
|
* to the right edge of Select2's search input.
|
||||||
|
*
|
||||||
|
* 1. in .select2-search input
|
||||||
|
* 2. in Multi Select2's .select2-search-field input
|
||||||
|
* 3. in the status-message of infinite-scroll with remote data (@see http://ivaynberg.github.io/select2/#infinite)
|
||||||
|
*
|
||||||
|
* These styles alter Select2's default background-position of 100%
|
||||||
|
* and supply the new background-position syntax to browsers which support it:
|
||||||
|
*
|
||||||
|
* 1. Android, Safari < 6/Mobile, IE<9: change to a relative background-position of 99%
|
||||||
|
* 2. Chrome 25+, Firefox 13+, IE 9+, Opera 10.5+: use the new CSS3-background-position syntax
|
||||||
|
*
|
||||||
|
* @see http://www.w3.org/TR/css3-background/#background-position
|
||||||
|
*
|
||||||
|
* @todo Since both Select2 and Bootstrap 3 only support IE8 and above,
|
||||||
|
* we could use the :after-pseudo-element to display the loading indicator.
|
||||||
|
* Alternatively, we could supply an altered loading indicator image which already
|
||||||
|
* contains an offset to the right.
|
||||||
|
*/
|
||||||
|
.select2-search input.select2-active,
|
||||||
|
.select2-container-multi .select2-choices .select2-search-field input.select2-active,
|
||||||
|
.select2-more-results.select2-active {
|
||||||
|
background-position: 99%;
|
||||||
|
/* 4 */
|
||||||
|
background-position: right 4px center;
|
||||||
|
/* 5 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To support Select2 pre v3.4.2 in combination with Bootstrap v3.2.0,
|
||||||
|
* ensure that .select2-offscreen width, height and position can not be overwritten.
|
||||||
|
*
|
||||||
|
* This adresses changes in Bootstrap somewhere after the initial v3.0.0 which -
|
||||||
|
* in combination with Select2's pre-v3.4.2 CSS missing the "!important" after
|
||||||
|
* the following rules - allow Bootstrap to overwrite the latter, which results in
|
||||||
|
* the original <select> element Select2 is replacing not be properly being hidden
|
||||||
|
* when used in a "Bootstrap Input Group with Addon".
|
||||||
|
**/
|
||||||
|
.select2-offscreen,
|
||||||
|
.select2-offscreen:focus {
|
||||||
|
width: 1px !important;
|
||||||
|
height: 1px !important;
|
||||||
|
position: absolute !important;
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
|
@ -0,0 +1,62 @@
|
||||||
|
{% extends "bootstrap/base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Panoramix - A Druid UI{% endblock %}
|
||||||
|
{% block html_attribs %} lang="en"{% endblock %}
|
||||||
|
|
||||||
|
{% block styles %}
|
||||||
|
{{super()}}
|
||||||
|
<link rel="stylesheet" href="{{url_for('.static', filename='bootstrap-theme.css')}}">
|
||||||
|
<link rel="stylesheet" href="{{url_for('.static', filename='main.css')}}">
|
||||||
|
<link rel="stylesheet" href="{{url_for('.static', filename='select2.min.css')}}">
|
||||||
|
<link rel="stylesheet" href="{{url_for('.static', filename='select2-bootstrap.css')}}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block navbar %}
|
||||||
|
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<!-- Brand and toggle get grouped for better mobile display -->
|
||||||
|
<div class="navbar-header">
|
||||||
|
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||||
|
<span class="sr-only">Toggle navigation</span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a class="navbar-brand" href="#">Panoramix</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||||
|
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
|
||||||
|
<li class="dropdown">
|
||||||
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a href="#">Action</a></li>
|
||||||
|
<li><a href="#">Another action</a></li>
|
||||||
|
<li><a href="#">Something else here</a></li>
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
<li><a href="#">Separated link</a></li>
|
||||||
|
<li role="separator" class="divider"></li>
|
||||||
|
<li><a href="#">One more separated link</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="nav navbar-nav navbar-right">
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div><!-- /.navbar-collapse -->
|
||||||
|
</div><!-- /.container-fluid -->
|
||||||
|
</nav>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script src="{{url_for('.static', filename='select2.min.js')}}"></script>
|
||||||
|
<script>
|
||||||
|
$( document ).ready(function() {
|
||||||
|
$(".select2").select2();
|
||||||
|
$(".select2_tags").select2({tags: true});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{% extends "panoramix/base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h3>{{ datasource }}</h3>
|
||||||
|
<form method="GET">
|
||||||
|
<div>{{ form.granularity.label }}: {{ form.granularity(class_="form-control select2") }}</div>
|
||||||
|
<div>{{ form.since.label }}: {{ form.since(class_="form-control select2") }}</div>
|
||||||
|
<div>{{ form.groupby.label }}: {{ form.groupby(class_="form-control select2") }}</div>
|
||||||
|
<div>{{ form.limit.label }}: {{ form.limit(class_="form-control select2_tags") }}</div>
|
||||||
|
<hr>
|
||||||
|
<h4>Filters</h4>
|
||||||
|
<div>
|
||||||
|
<span style="width: 100px;">{{ form.flt_col_1(class_="form-control select2") }}</span>
|
||||||
|
<span>{{ form.flt_op_1(class_="form-control select2 input-sm") }}</span>
|
||||||
|
<span>{{ form.flt_eq_1(class_="form-control") }}</span>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<input type="submit" class="btn btn-primary">
|
||||||
|
</form><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-9">
|
||||||
|
|
||||||
|
<h3>Tabular Data</h3>
|
||||||
|
{{ table|safe }}
|
||||||
|
|
||||||
|
<h3>Results</h3>
|
||||||
|
<pre>
|
||||||
|
{{ results }}
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<h3>Latest Segment Metadata</h3>
|
||||||
|
<pre>
|
||||||
|
{{ latest_metadata }}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue