mirror of https://github.com/apache/superset.git
Merge pull request #120 from mistercrunch/sliceinfo
Slice information can be displayed in dashboard
This commit is contained in:
commit
ef612ed66c
1
TODO.md
1
TODO.md
|
@ -20,6 +20,7 @@ List of TODO items for Panoramix
|
||||||
An example of a layer might be "holidays" or "site outages", ...
|
An example of a layer might be "holidays" or "site outages", ...
|
||||||
* **Worth doing? User defined groups:** People could define mappings in the UI of say "Countries I follow" and apply it to different datasets. For now, this is done by writing CASE-WHEN-type expression which is probably good enough.
|
* **Worth doing? User defined groups:** People could define mappings in the UI of say "Countries I follow" and apply it to different datasets. For now, this is done by writing CASE-WHEN-type expression which is probably good enough.
|
||||||
|
|
||||||
|
|
||||||
## Easy-ish fix
|
## Easy-ish fix
|
||||||
* datasource in explore mode could be a dropdown
|
* datasource in explore mode could be a dropdown
|
||||||
* Create a set of slices and dashboard on top of the World Bank dataset that ship with load_examples
|
* Create a set of slices and dashboard on top of the World Bank dataset that ship with load_examples
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 43df8de3a5f4
|
||||||
|
Revises: 7dbf98566af7
|
||||||
|
Create Date: 2016-01-18 23:43:16.073483
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '43df8de3a5f4'
|
||||||
|
down_revision = '7dbf98566af7'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column('dashboards', sa.Column('json_metadata', sa.Text(), nullable=True))
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column('dashboards', 'json_metadata')
|
|
@ -0,0 +1,21 @@
|
||||||
|
"""empty message
|
||||||
|
|
||||||
|
Revision ID: 7dbf98566af7
|
||||||
|
Revises: 8e80a26a31db
|
||||||
|
Create Date: 2016-01-17 22:00:23.640788
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '7dbf98566af7'
|
||||||
|
down_revision = '8e80a26a31db'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects import mysql
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
op.add_column('slices', sa.Column('description', sa.Text(), nullable=True))
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column('slices', 'description')
|
|
@ -66,6 +66,7 @@ class Slice(Model, AuditMixinNullable):
|
||||||
datasource_name = Column(String(2000))
|
datasource_name = Column(String(2000))
|
||||||
viz_type = Column(String(250))
|
viz_type = Column(String(250))
|
||||||
params = Column(Text)
|
params = Column(Text)
|
||||||
|
description = Column(Text)
|
||||||
|
|
||||||
table = relationship(
|
table = relationship(
|
||||||
'SqlaTable', foreign_keys=[table_id], backref='slices')
|
'SqlaTable', foreign_keys=[table_id], backref='slices')
|
||||||
|
@ -88,6 +89,10 @@ class Slice(Model, AuditMixinNullable):
|
||||||
form_data=d)
|
form_data=d)
|
||||||
return viz
|
return viz
|
||||||
|
|
||||||
|
@property
|
||||||
|
def description_markeddown(self):
|
||||||
|
return utils.markdown(self.description)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def datasource_id(self):
|
def datasource_id(self):
|
||||||
return self.table_id or self.druid_datasource_id
|
return self.table_id or self.druid_datasource_id
|
||||||
|
@ -154,6 +159,7 @@ class Dashboard(Model, AuditMixinNullable):
|
||||||
position_json = Column(Text)
|
position_json = Column(Text)
|
||||||
description = Column(Text)
|
description = Column(Text)
|
||||||
css = Column(Text)
|
css = Column(Text)
|
||||||
|
json_metadata = Column(Text)
|
||||||
slug = Column(String(255), unique=True)
|
slug = Column(String(255), unique=True)
|
||||||
slices = relationship(
|
slices = relationship(
|
||||||
'Slice', secondary=dashboard_slices, backref='dashboards')
|
'Slice', secondary=dashboard_slices, backref='dashboards')
|
||||||
|
@ -165,6 +171,10 @@ class Dashboard(Model, AuditMixinNullable):
|
||||||
def url(self):
|
def url(self):
|
||||||
return "/panoramix/dashboard/{}/".format(self.slug or self.id)
|
return "/panoramix/dashboard/{}/".format(self.slug or self.id)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def metadata_dejson(self):
|
||||||
|
return json.loads(self.json_metadata)
|
||||||
|
|
||||||
def dashboard_link(self):
|
def dashboard_link(self):
|
||||||
return '<a href="{self.url}">{self.dashboard_title}</a>'.format(self=self)
|
return '<a href="{self.url}">{self.dashboard_title}</a>'.format(self=self)
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,18 @@ html>body{
|
||||||
margin-left: 365px;
|
margin-left: 365px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.slice_description{
|
||||||
|
padding: 8px;
|
||||||
|
margin: 5px;
|
||||||
|
border: 1px solid #DDD;
|
||||||
|
background-color: #F8F8F8;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slice_info{
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
.padded{
|
.padded{
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -23,7 +34,7 @@ html>body{
|
||||||
}
|
}
|
||||||
|
|
||||||
.slice_container {
|
.slice_container {
|
||||||
height: 100%;
|
//height: 100%;
|
||||||
}
|
}
|
||||||
.container-fluid {
|
.container-fluid {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
|
@ -106,7 +106,13 @@ var px = (function() {
|
||||||
return token.width();
|
return token.width();
|
||||||
},
|
},
|
||||||
height: function(){
|
height: function(){
|
||||||
return token.height() - 25;
|
var others = 0;
|
||||||
|
var widget = container.parents('.widget');
|
||||||
|
var slice_description = widget.find('.slice_description');
|
||||||
|
if (slice_description.is(":visible"))
|
||||||
|
others += widget.find('.slice_description').height() + 25;
|
||||||
|
others += widget.find('.slice_header').height();
|
||||||
|
return widget.height() - others;
|
||||||
},
|
},
|
||||||
render: function() {
|
render: function() {
|
||||||
$('.btn-group.results span').attr('disabled','disabled');
|
$('.btn-group.results span').attr('disabled','disabled');
|
||||||
|
@ -416,9 +422,17 @@ var px = (function() {
|
||||||
}).data('gridster');
|
}).data('gridster');
|
||||||
$("div.gridster").css('visibility', 'visible');
|
$("div.gridster").css('visibility', 'visible');
|
||||||
$("#savedash").click(function() {
|
$("#savedash").click(function() {
|
||||||
|
var expanded_slices = {};
|
||||||
|
$.each($(".slice_info"), function(i, d){
|
||||||
|
var widget = $(this).parents('.widget');
|
||||||
|
var slice_description = widget.find('.slice_description');
|
||||||
|
if(slice_description.is(":visible"))
|
||||||
|
expanded_slices[$(d).attr('slice_id')] = true;
|
||||||
|
});
|
||||||
var data = {
|
var data = {
|
||||||
positions: gridster.serialize(),
|
positions: gridster.serialize(),
|
||||||
css: $("#dash_css").val()
|
css: $("#dash_css").val(),
|
||||||
|
expanded_slices: expanded_slices,
|
||||||
};
|
};
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
@ -432,6 +446,13 @@ var px = (function() {
|
||||||
var li = $(this).parents("li");
|
var li = $(this).parents("li");
|
||||||
gridster.remove_widget(li);
|
gridster.remove_widget(li);
|
||||||
});
|
});
|
||||||
|
$(".slice_info").click(function(){
|
||||||
|
var widget = $(this).parents('.widget');
|
||||||
|
var slice_description = widget.find('.slice_description');
|
||||||
|
slice_description.slideToggle(500, function(){
|
||||||
|
widget.find('.refresh').click();
|
||||||
|
});
|
||||||
|
});
|
||||||
$("table.slice_header").mouseover(function() {
|
$("table.slice_header").mouseover(function() {
|
||||||
$(this).find("td.icons nobr").show();
|
$(this).find("td.icons nobr").show();
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,7 +6,7 @@ function viz_nvd3(slice) {
|
||||||
$.getJSON(slice.jsonEndpoint(), function(payload) {
|
$.getJSON(slice.jsonEndpoint(), function(payload) {
|
||||||
var fd = payload.form_data;
|
var fd = payload.form_data;
|
||||||
var viz_type = fd.viz_type;
|
var viz_type = fd.viz_type;
|
||||||
var f = d3.format('.4s');
|
var f = d3.format('.3s');
|
||||||
nv.addGraph(function() {
|
nv.addGraph(function() {
|
||||||
if (viz_type === 'line') {
|
if (viz_type === 'line') {
|
||||||
if (fd.show_brush) {
|
if (fd.show_brush) {
|
||||||
|
@ -49,6 +49,7 @@ function viz_nvd3(slice) {
|
||||||
} else if (viz_type === 'pie') {
|
} else if (viz_type === 'pie') {
|
||||||
chart = nv.models.pieChart()
|
chart = nv.models.pieChart()
|
||||||
chart.showLegend(fd.show_legend);
|
chart.showLegend(fd.show_legend);
|
||||||
|
chart.valueFormat(f);
|
||||||
if (fd.donut) {
|
if (fd.donut) {
|
||||||
chart.donut(true);
|
chart.donut(true);
|
||||||
chart.donutLabelsOutside(true);
|
chart.donutLabelsOutside(true);
|
||||||
|
@ -99,8 +100,13 @@ function viz_nvd3(slice) {
|
||||||
chart.showLegend(fd.show_legend);
|
chart.showLegend(fd.show_legend);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make space for labels on right
|
var height = slice.height();
|
||||||
//chart.height($(".chart").height() - 50).margin({"right": 50});
|
if(chart.hasOwnProperty("x2Axis")) {
|
||||||
|
height += 30;
|
||||||
|
}
|
||||||
|
chart.height(height);
|
||||||
|
slice.container.css('height', height + 'px');
|
||||||
|
|
||||||
if ((viz_type === "line" || viz_type === "area") && fd.rich_tooltip) {
|
if ((viz_type === "line" || viz_type === "area") && fd.rich_tooltip) {
|
||||||
chart.useInteractiveGuideline(true);
|
chart.useInteractiveGuideline(true);
|
||||||
}
|
}
|
||||||
|
@ -122,7 +128,9 @@ function viz_nvd3(slice) {
|
||||||
else if (fd.x_axis_format !== undefined) {
|
else if (fd.x_axis_format !== undefined) {
|
||||||
chart.xAxis.tickFormat(px.timeFormatFactory(fd.x_axis_format));
|
chart.xAxis.tickFormat(px.timeFormatFactory(fd.x_axis_format));
|
||||||
}
|
}
|
||||||
if (fd.contribution || fd.num_period_compare) {
|
if (chart.yAxis !== undefined)
|
||||||
|
chart.yAxis.tickFormat(d3.format('.3s'));
|
||||||
|
if (fd.contribution || fd.num_period_compare || viz_type == 'compare') {
|
||||||
chart.yAxis.tickFormat(d3.format('.3p'));
|
chart.yAxis.tickFormat(d3.format('.3p'));
|
||||||
if (chart.y2Axis != undefined) {
|
if (chart.y2Axis != undefined) {
|
||||||
chart.y2Axis.tickFormat(d3.format('.3p'));
|
chart.y2Axis.tickFormat(d3.format('.3p'));
|
||||||
|
@ -140,15 +148,9 @@ function viz_nvd3(slice) {
|
||||||
d3.select(slice.selector).append("svg")
|
d3.select(slice.selector).append("svg")
|
||||||
.datum(payload.data)
|
.datum(payload.data)
|
||||||
.transition().duration(500)
|
.transition().duration(500)
|
||||||
|
.attr('height', height)
|
||||||
.call(chart);
|
.call(chart);
|
||||||
|
|
||||||
// if it is a two axis chart, rescale it down just a little so it fits in the div.
|
|
||||||
if(chart.hasOwnProperty("x2Axis")) {
|
|
||||||
two_axis_chart = $(slice.selector + " > svg");
|
|
||||||
w = two_axis_chart.width();
|
|
||||||
h = two_axis_chart.height();
|
|
||||||
two_axis_chart.get(0).setAttribute('viewBox', '0 0 '+w+' '+(h+30));
|
|
||||||
}
|
|
||||||
return chart;
|
return chart;
|
||||||
});
|
});
|
||||||
slice.done(payload);
|
slice.done(payload);
|
||||||
|
|
|
@ -79,13 +79,13 @@ px.registerViz('table', function(slice) {
|
||||||
paging: false,
|
paging: false,
|
||||||
searching: form_data.include_search,
|
searching: form_data.include_search,
|
||||||
});
|
});
|
||||||
slice.container.find('.tooltip').remove();
|
|
||||||
// Sorting table by main column
|
// Sorting table by main column
|
||||||
if (form_data.metrics.length > 0) {
|
if (form_data.metrics.length > 0) {
|
||||||
var main_metric = form_data.metrics[0];
|
var main_metric = form_data.metrics[0];
|
||||||
datatable.column(data.columns.indexOf(main_metric)).order( 'desc' ).draw();
|
datatable.column(data.columns.indexOf(main_metric)).order( 'desc' ).draw();
|
||||||
}
|
}
|
||||||
slice.done(json);
|
slice.done(json);
|
||||||
|
slice.container.parents('.widget').find('.tooltip').remove();
|
||||||
}).fail(function(xhr){
|
}).fail(function(xhr){
|
||||||
slice.error(xhr.responseText);
|
slice.error(xhr.responseText);
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,25 +91,35 @@ body {
|
||||||
<nobr class="icons">
|
<nobr class="icons">
|
||||||
<a><i class="fa fa-arrows drag"></i></a>
|
<a><i class="fa fa-arrows drag"></i></a>
|
||||||
<a class="refresh"><i class="fa fa-refresh"></i></a>
|
<a class="refresh"><i class="fa fa-refresh"></i></a>
|
||||||
<a class="bug" data-slice_id="{{ slice.id }}" data-toggle="tooltip" title="console.log(this.slice);"><i class="fa fa-bug"></i></a>
|
|
||||||
</nobr>
|
</nobr>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="text-center header"><nobr>{{ slice.slice_name }}</nobr></div>
|
<div class="text-center header">
|
||||||
|
<nobr>
|
||||||
|
{{ slice.slice_name }}
|
||||||
|
{% if slice.description %}
|
||||||
|
<i class="fa fa-info-circle slice_info" slice_id="{{ slice.id }}"></i>
|
||||||
|
{% endif %}
|
||||||
|
</nobr>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="icons text-right">
|
<td class="icons text-right">
|
||||||
<nobr>
|
<nobr>
|
||||||
<a href="{{ slice.slice_url }}"><i class="fa fa-play"></i></a>
|
<a href="{{ slice.slice_url }}"><i class="fa fa-play"></i></a>
|
||||||
<a href="{{ slice.edit_url }}"><i class="fa fa-gear"></i></a>
|
<a href="{{ slice.edit_url }}"><i class="fa fa-edit"></i></a>
|
||||||
<a class="closeslice"><i class="fa fa-close"></i></a>
|
<a class="closeslice"><i class="fa fa-close"></i></a>
|
||||||
</br>
|
</br>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div id="{{ viz.token }}" class="token" style="height: 100%;">
|
<div class="slice_description bs-callout bs-callout-default" style="{{ 'display: none;' if "{}".format(slice.id) not in dashboard.metadata_dejson.expanded_slices }}">
|
||||||
|
{{ slice.description_markeddown | safe }}
|
||||||
|
</div>
|
||||||
|
<input type="hidden" slice_id="{{ slice.id }}" value="false">
|
||||||
|
<div id="{{ viz.token }}" class="token">
|
||||||
<img src="{{ url_for("static", filename="img/loading.gif") }}" class="loading" alt="loading">
|
<img src="{{ url_for("static", filename="img/loading.gif") }}" class="loading" alt="loading">
|
||||||
<div class="slice_container" id="{{ viz.token }}_con" style="height: 100%; width: 100%;"></div>
|
<div class="slice_container" id="{{ viz.token }}_con"></div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -131,9 +141,6 @@ body {
|
||||||
$('#filters').click( function(){
|
$('#filters').click( function(){
|
||||||
alert(dashboard.readFilters());
|
alert(dashboard.readFilters());
|
||||||
});
|
});
|
||||||
$('a.bug').click( function(){
|
|
||||||
console.log(dashboard.getSlice($(this).data('slice_id')));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -42,11 +42,16 @@
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
<span>{{ form.get_field("viz_type")(class_="select2") }}</span>
|
<span>{{ form.get_field("viz_type")(class_="select2") }}</span>
|
||||||
<span class="alert alert-info" title="Slice Name" data-toggle="tooltip">{{ viz.form_data.slice_name }}
|
{% if slice %}
|
||||||
<a class="" href="/slicemodelview/edit/{{ viz.form_data.slice_id }}" data-toggle="tooltip" title="Edit Slice metadata">
|
<span class="alert alert-info" title="Slice" data-toggle="tooltip">{{ slice.slice_name }}
|
||||||
<i class="fa fa-edit"></i>
|
<a class="" href="/slicemodelview/edit/{{ slice.id }}" data-toggle="tooltip" title="Edit Slice metadata">
|
||||||
</a>
|
{% if slice.description %}
|
||||||
</span>
|
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="bottom" title="{{ slice.description }}"></i>
|
||||||
|
{% endif %}
|
||||||
|
<i class="fa fa-edit"></i>
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
<div class="btn-group results pull-right" role="group">
|
<div class="btn-group results pull-right" role="group">
|
||||||
<a role="button" tabindex="0" class="btn btn-default" id="shortner" title="Short URL" data-toggle="popover" data-trigger="focus">
|
<a role="button" tabindex="0" class="btn btn-default" id="shortner" title="Short URL" data-toggle="popover" data-trigger="focus">
|
||||||
<i class="fa fa-link"></i>
|
<i class="fa fa-link"></i>
|
||||||
|
@ -160,7 +165,7 @@
|
||||||
{% include 'appbuilder/flash.html' %}
|
{% include 'appbuilder/flash.html' %}
|
||||||
<div
|
<div
|
||||||
id="{{ viz.token }}"
|
id="{{ viz.token }}"
|
||||||
class="viz slice {{ viz.viz_type }}"
|
class="widget viz slice {{ viz.viz_type }}"
|
||||||
data-slice="{{ viz.json_data }}"
|
data-slice="{{ viz.json_data }}"
|
||||||
style="height: 700px;">
|
style="height: 700px;">
|
||||||
<img src="{{ url_for("static", filename="img/loading.gif") }}" class="loading" alt="loading">
|
<img src="{{ url_for("static", filename="img/loading.gif") }}" class="loading" alt="loading">
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{% if viz.form_data.get("json") == "true" %}
|
{% if viz.form_data.get("json") == "true" %}
|
||||||
{{ viz.get_json() }}
|
{{ viz.get_json() }}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
{% if viz.request.args.get("standalone") == "true" %}
|
{% if viz.request.args.get("standalone") == "true" %}
|
||||||
{% extends 'panoramix/standalone.html' %}
|
{% extends 'panoramix/standalone.html' %}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -22,4 +23,5 @@
|
||||||
<script src="{{ url_for('static', filename=js) }}"></script>
|
<script src="{{ url_for('static', filename=js) }}"></script>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -205,9 +205,12 @@ class SliceModelView(PanoramixModelView, DeleteMixin):
|
||||||
'slice_link', 'viz_type', 'datasource_type',
|
'slice_link', 'viz_type', 'datasource_type',
|
||||||
'datasource', 'created_by', 'changed_on_']
|
'datasource', 'created_by', 'changed_on_']
|
||||||
edit_columns = [
|
edit_columns = [
|
||||||
'slice_name', 'viz_type', 'druid_datasource',
|
'slice_name', 'description', 'viz_type', 'druid_datasource',
|
||||||
'table', 'dashboards', 'params']
|
'table', 'dashboards', 'params']
|
||||||
base_order = ('changed_on','desc')
|
base_order = ('changed_on','desc')
|
||||||
|
description_columns = {
|
||||||
|
'description': Markup("The content here can be displayed as widget headers in the dashboard view. Supports <a href='https://daringfireball.net/projects/markdown/'>markdown</a>"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
appbuilder.add_view(
|
appbuilder.add_view(
|
||||||
|
@ -222,7 +225,8 @@ class DashboardModelView(PanoramixModelView, DeleteMixin):
|
||||||
datamodel = SQLAInterface(models.Dashboard)
|
datamodel = SQLAInterface(models.Dashboard)
|
||||||
list_columns = ['dashboard_link', 'created_by', 'changed_by', 'changed_on_']
|
list_columns = ['dashboard_link', 'created_by', 'changed_by', 'changed_on_']
|
||||||
edit_columns = [
|
edit_columns = [
|
||||||
'dashboard_title', 'slug', 'slices', 'position_json', 'css']
|
'dashboard_title', 'slug', 'slices', 'position_json', 'css',
|
||||||
|
'json_metadata']
|
||||||
add_columns = edit_columns
|
add_columns = edit_columns
|
||||||
base_order = ('changed_on','desc')
|
base_order = ('changed_on','desc')
|
||||||
description_columns = {
|
description_columns = {
|
||||||
|
@ -434,6 +438,15 @@ class Panoramix(BaseView):
|
||||||
payload,
|
payload,
|
||||||
status=status,
|
status=status,
|
||||||
mimetype="application/csv")
|
mimetype="application/csv")
|
||||||
|
|
||||||
|
slice_id = request.args.get("slice_id")
|
||||||
|
slc = None
|
||||||
|
if slice_id:
|
||||||
|
slc = (
|
||||||
|
db.session.query(models.Slice)
|
||||||
|
.filter_by(id=request.args.get("slice_id"))
|
||||||
|
.first()
|
||||||
|
)
|
||||||
if request.args.get("json") == "true":
|
if request.args.get("json") == "true":
|
||||||
status = 200
|
status = 200
|
||||||
if config.get("DEBUG"):
|
if config.get("DEBUG"):
|
||||||
|
@ -451,9 +464,11 @@ class Panoramix(BaseView):
|
||||||
mimetype="application/json")
|
mimetype="application/json")
|
||||||
else:
|
else:
|
||||||
if config.get("DEBUG"):
|
if config.get("DEBUG"):
|
||||||
resp = self.render_template("panoramix/viz.html", viz=obj)
|
resp = self.render_template(
|
||||||
|
"panoramix/viz.html", viz=obj, slice=slc)
|
||||||
try:
|
try:
|
||||||
resp = self.render_template("panoramix/viz.html", viz=obj)
|
resp = self.render_template(
|
||||||
|
"panoramix/viz.html", viz=obj, slice=slc)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if config.get("DEBUG"):
|
if config.get("DEBUG"):
|
||||||
raise(e)
|
raise(e)
|
||||||
|
@ -490,6 +505,9 @@ class Panoramix(BaseView):
|
||||||
dash = session.query(Dash).filter_by(id=dashboard_id).first()
|
dash = session.query(Dash).filter_by(id=dashboard_id).first()
|
||||||
dash.slices = [o for o in dash.slices if o.id in slice_ids]
|
dash.slices = [o for o in dash.slices if o.id in slice_ids]
|
||||||
dash.position_json = json.dumps(data['positions'], indent=4)
|
dash.position_json = json.dumps(data['positions'], indent=4)
|
||||||
|
dash.json_metadata = json.dumps({
|
||||||
|
'expanded_slices': data['expanded_slices'],
|
||||||
|
}, indent=4)
|
||||||
dash.css = data['css']
|
dash.css = data['css']
|
||||||
session.merge(dash)
|
session.merge(dash)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
Loading…
Reference in New Issue