Initial commit

This commit is contained in:
Maxime 2015-07-02 22:16:59 +00:00 committed by Maxime Beauchemin
commit 68c5a48c1f
12 changed files with 7437 additions and 0 deletions

6
README.md Normal file
View File

@ -0,0 +1,6 @@
Panoramix
=========
Panoramix is a web UI for Druid.io
![img](https://descubrirlahistoria.es/wp-content/uploads/2014/03/panoramix.jpg)

132
app.py Normal file
View File

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

6
requirements.txt Normal file
View File

@ -0,0 +1,6 @@
pydruid
python-dateutil
flask
pandas
wtforms
flask-bootstrap

6487
static/bootstrap-theme.css vendored Normal file

File diff suppressed because it is too large Load Diff

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

207
static/main.css Normal file
View File

@ -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 */

View File

@ -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;
}

1
static/select2.min.css vendored Normal file

File diff suppressed because one or more lines are too long

2
static/select2.min.js vendored Normal file

File diff suppressed because one or more lines are too long

BIN
static/serpe.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -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 %}

View File

@ -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 %}