diff --git a/superset/assets/javascripts/explore/stores/controls.jsx b/superset/assets/javascripts/explore/stores/controls.jsx index 1e543a201..da6ff386a 100644 --- a/superset/assets/javascripts/explore/stores/controls.jsx +++ b/superset/assets/javascripts/explore/stores/controls.jsx @@ -655,6 +655,7 @@ export const controls = { type: 'SelectControl', label: 'Entity', default: null, + validators: [v.nonEmpty], description: 'This define the element to be plotted on the chart', mapStateToProps: state => ({ choices: (state.datasource) ? state.datasource.gb_cols : [], @@ -761,7 +762,9 @@ export const controls = { type: 'SelectControl', freeForm: true, label: 'Table Timestamp Format', - default: 'smart_date', + default: '%Y-%m-%d %H:%M:%S', + validators: [v.nonEmpty], + clearable: false, choices: D3_TIME_FORMAT_OPTIONS, description: 'Timestamp Format', }, diff --git a/superset/assets/javascripts/explore/stores/visTypes.js b/superset/assets/javascripts/explore/stores/visTypes.js index 5322680f6..3bc7fd626 100644 --- a/superset/assets/javascripts/explore/stores/visTypes.js +++ b/superset/assets/javascripts/explore/stores/visTypes.js @@ -183,6 +183,9 @@ const visTypes = { y_axis_format: { label: 'Left Axis Format', }, + x_axis_format: { + choices: D3_TIME_FORMAT_OPTIONS, + }, }, }, @@ -211,6 +214,13 @@ const visTypes = { }, sections.NVD3TimeSeries[1], ], + controlOverrides: { + x_axis_format: { + choices: D3_TIME_FORMAT_OPTIONS, + default: control => + control.choices && control.choices.length > 0 ? [control.choices[0][0]] : null, + }, + }, }, compare: { @@ -475,9 +485,8 @@ const visTypes = { label: null, controlSetRows: [ ['metric'], - ['compare_lag'], - ['compare_suffix'], - ['y_axis_format'], + ['compare_lag', 'compare_suffix'], + ['y_axis_format', null], ], }, ], diff --git a/superset/assets/visualizations/big_number.js b/superset/assets/visualizations/big_number.js index 51b08bffa..f0c3950a2 100644 --- a/superset/assets/visualizations/big_number.js +++ b/superset/assets/visualizations/big_number.js @@ -1,6 +1,6 @@ import d3 from 'd3'; import d3tip from 'd3-tip'; -import { formatDate } from '../javascripts/modules/dates'; +import { d3FormatPreset, d3TimeFormatPreset } from '../javascripts/modules/utils'; import './big_number.css'; import '../stylesheets/d3tip.css'; @@ -12,8 +12,9 @@ function bigNumberVis(slice, payload) { const fd = slice.formData; const json = payload.data; - const f = d3.format(fd.y_axis_format); + const f = d3FormatPreset(fd.y_axis_format); const fp = d3.format('+.1%'); + const formatDate = d3TimeFormatPreset('smart_date'); const width = slice.width(); const height = slice.height(); const svg = div.append('svg'); @@ -138,7 +139,7 @@ function bigNumberVis(slice, payload) { const yAxis = d3.svg.axis() .scale(scaleY) .orient('left') - .tickFormat(d3.format(fd.y_axis_format)) + .tickFormat(f) .tickValues(valueExt); g.call(yAxis); diff --git a/superset/assets/visualizations/nvd3_vis.js b/superset/assets/visualizations/nvd3_vis.js index b4ccc71b3..736de78f5 100644 --- a/superset/assets/visualizations/nvd3_vis.js +++ b/superset/assets/visualizations/nvd3_vis.js @@ -331,7 +331,7 @@ function nvd3Vis(slice, payload) { chart.x2Axis.tickFormat(xAxisFormatter); height += 30; } - if (chart.xAxis && chart.xAxis.tickFormat) { + if (isTimeSeries && chart.xAxis && chart.xAxis.tickFormat) { chart.xAxis.tickFormat(xAxisFormatter); } diff --git a/superset/assets/visualizations/table.js b/superset/assets/visualizations/table.js index be1a82c62..82b030586 100644 --- a/superset/assets/visualizations/table.js +++ b/superset/assets/visualizations/table.js @@ -3,8 +3,7 @@ import 'datatables-bootstrap3-plugin/media/css/datatables-bootstrap3.css'; import 'datatables.net'; import dt from 'datatables.net-bs'; -import { fixDataTableBodyHeight } from '../javascripts/modules/utils'; -import { timeFormatFactory, formatDate } from '../javascripts/modules/dates'; +import { fixDataTableBodyHeight, d3TimeFormatPreset } from '../javascripts/modules/utils'; import './table.css'; const $ = require('jquery'); @@ -14,7 +13,6 @@ dt(window, $); function tableVis(slice, payload) { const container = $(slice.selector); const fC = d3.format('0,000'); - let timestampFormatter; const data = payload.data; const fd = slice.formData; @@ -35,11 +33,7 @@ function tableVis(slice, payload) { maxes[metrics[i]] = d3.max(col(metrics[i])); } - if (fd.table_timestamp_format === 'smart_date') { - timestampFormatter = formatDate; - } else if (fd.table_timestamp_format !== undefined) { - timestampFormatter = timeFormatFactory(fd.table_timestamp_format); - } + const tsFormatter = d3TimeFormatPreset(fd.table_timestamp_format); const div = d3.select(slice.selector); div.html(''); @@ -70,8 +64,8 @@ function tableVis(slice, payload) { const val = row[c]; let html; const isMetric = metrics.indexOf(c) >= 0; - if (c === 'timestamp') { - html = timestampFormatter(val); + if (c === '__timestamp') { + html = tsFormatter(val); } if (typeof (val) === 'string') { html = `${val}`; diff --git a/superset/viz.py b/superset/viz.py index 9e7f8be2d..75cb4113b 100755 --- a/superset/viz.py +++ b/superset/viz.py @@ -352,9 +352,6 @@ class TableViz(BaseViz): columns=list(df.columns), ) - def json_dumps(self, obj): - return json.dumps(obj, default=utils.json_iso_dttm_ser) - class PivotTableViz(BaseViz): @@ -650,15 +647,16 @@ class BubbleViz(NVD3Viz): def query_obj(self): form_data = self.form_data d = super(BubbleViz, self).query_obj() - d['groupby'] = list({ - form_data.get('series'), + d['groupby'] = [ form_data.get('entity') - }) + ] + if form_data.get('series'): + d['groupby'].append(form_data.get('series')) self.x_metric = form_data.get('x') self.y_metric = form_data.get('y') self.z_metric = form_data.get('size') self.entity = form_data.get('entity') - self.series = form_data.get('series') + self.series = form_data.get('series') or self.entity d['row_limit'] = form_data.get('limit') d['metrics'] = [ @@ -666,7 +664,7 @@ class BubbleViz(NVD3Viz): self.x_metric, self.y_metric, ] - if not all(d['metrics'] + [self.entity, self.series]): + if not all(d['metrics'] + [self.entity]): raise Exception("Pick a metric for x, y and size") return d