Fix for Not Grouped By on Table View (#544)

* fix for default metric in table visualization

* better location for form override; covers all parameters

* remove dead code, use items instead of iteritems for python 3
This commit is contained in:
George Ke 2016-06-01 22:59:06 -07:00 committed by Maxime Beauchemin
parent 849063c797
commit cb384d051b
3 changed files with 466 additions and 352 deletions

View File

@ -129,122 +129,151 @@ class FormFactory(object):
default_groupby = gb_cols[0] if gb_cols else None
group_by_choices = self.choicify(gb_cols)
# Pool of all the fields that can be used in Caravel
self.field_dict = {
'viz_type': SelectField(
'Viz',
default='table',
choices=[(k, v.verbose_name) for k, v in viz_types.items()],
description="The type of visualization to display"),
'metrics': SelectMultipleSortableField(
'Metrics', choices=datasource.metrics_combo,
default=[default_metric],
description="One or many metrics to display"),
'metric': SelectField(
'Metric', choices=datasource.metrics_combo,
default=default_metric,
description="Chose the metric"),
'stacked_style': SelectField(
'Chart Style', choices=self.choicify(
['stack', 'stream', 'expand']),
default='stack',
description=""),
'linear_color_scheme': SelectField(
'Color Scheme', choices=self.choicify([
field_data = {
'viz_type': (SelectField, {
"label": "Viz",
"default": 'table',
"choices": [(k, v.verbose_name) for k, v in viz_types.items()],
"description": "The type of visualization to display"
}),
'metrics': (SelectMultipleSortableField, {
"label": "Metrics",
"choices": datasource.metrics_combo,
"default": [default_metric],
"description": "One or many metrics to display"
}),
'metric': (SelectField, {
"label": "Metric",
"choices": datasource.metrics_combo,
"default": default_metric,
"description": "Choose the metric"
}),
'stacked_style': (SelectField, {
"label": "Chart Style",
"choices": self.choicify(['stack', 'stream', 'expand']),
"default": 'stack',
"description": ""
}),
'linear_color_scheme': (SelectField, {
"label": "Color Scheme",
"choices": self.choicify([
'fire', 'blue_white_yellow', 'white_black',
'black_white']),
default='blue_white_yellow',
description=""),
'normalize_across': SelectField(
'Normalize Across', choices=self.choicify([
"default": 'blue_white_yellow',
"description": ""
}),
'normalize_across': (SelectField, {
"label": "Normalize Across",
"choices": self.choicify([
'heatmap', 'x', 'y']),
default='heatmap',
description=(
"default": 'heatmap',
"description": (
"Color will be rendered based on a ratio "
"of the cell against the sum of across this "
"criteria")),
'horizon_color_scale': SelectField(
'Color Scale', choices=self.choicify([
'series', 'overall', 'change']),
default='series',
description="Defines how the color are attributed."),
'canvas_image_rendering': SelectField(
'Rendering', choices=(
"criteria")
}),
'horizon_color_scale': (SelectField, {
"label": "Color Scale",
"choices": self.choicify(['series', 'overall', 'change']),
"default": 'series',
"description": "Defines how the color are attributed."
}),
'canvas_image_rendering': (SelectField, {
"label": "Rendering",
"choices": (
('pixelated', 'pixelated (Sharp)'),
('auto', 'auto (Smooth)'),
),
default='pixelated',
description=(
"default": 'pixelated',
"description": (
"image-rendering CSS attribute of the canvas object that "
"defines how the browser scales up the image")),
'xscale_interval': SelectField(
'XScale Interval', choices=self.choicify(range(1, 50)),
default='1',
description=(
"defines how the browser scales up the image")
}),
'xscale_interval': (SelectField, {
"label": "XScale Interval",
"choices": self.choicify(range(1, 50)),
"default": '1',
"description": (
"Number of step to take between ticks when "
"printing the x scale")),
'yscale_interval': SelectField(
'YScale Interval', choices=self.choicify(range(1, 50)),
default='1',
description=(
"printing the x scale")
}),
'yscale_interval': (SelectField, {
"label": "YScale Interval",
"choices": self.choicify(range(1, 50)),
"default": '1',
"description": (
"Number of step to take between ticks when "
"printing the y scale")),
'bar_stacked': BetterBooleanField(
'Stacked Bars',
default=False,
description=""),
'include_series': BetterBooleanField(
'Include Series',
default=False,
description="Include series name as an axis"),
'secondary_metric': SelectField(
'Color Metric', choices=datasource.metrics_combo,
default=default_metric,
description="A metric to use for color"),
'country_fieldtype': SelectField(
'Country Field Type',
default='cca2',
choices=(
"printing the y scale")
}),
'bar_stacked': (BetterBooleanField, {
"label": "Stacked Bars",
"default": False,
"description": ""
}),
'include_series': (BetterBooleanField, {
"label": "Include Series",
"default": False,
"description": "Include series name as an axis"
}),
'secondary_metric': (SelectField, {
"label": "Color Metric",
"choices": datasource.metrics_combo,
"default": default_metric,
"description": "A metric to use for color"
}),
'country_fieldtype': (SelectField, {
"label": "Country Field Type",
"default": 'cca2',
"choices": (
('name', 'Full name'),
('cioc', 'code International Olympic Committee (cioc)'),
('cca2', 'code ISO 3166-1 alpha-2 (cca2)'),
('cca3', 'code ISO 3166-1 alpha-3 (cca3)'),
),
description=(
"description": (
"The country code standard that Caravel should expect "
"to find in the [country] column")),
'groupby': SelectMultipleSortableField(
'Group by',
choices=self.choicify(datasource.groupby_column_names),
description="One or many fields to group by"),
'columns': SelectMultipleSortableField(
'Columns',
choices=self.choicify(datasource.groupby_column_names),
description="One or many fields to pivot as columns"),
'all_columns': SelectMultipleSortableField(
'Columns',
choices=self.choicify(datasource.column_names),
description="Columns to display"),
'all_columns_x': SelectField(
'X',
choices=self.choicify(datasource.column_names),
description="Columns to display"),
'all_columns_y': SelectField(
'Y',
choices=self.choicify(datasource.column_names),
description="Columns to display"),
'druid_time_origin': FreeFormSelectField(
'Origin',
choices=(
"to find in the [country] column")
}),
'groupby': (SelectMultipleSortableField, {
"label": "Group by",
"choices": self.choicify(datasource.groupby_column_names),
"description": "One or many fields to group by"
}),
'columns': (SelectMultipleSortableField, {
"label": "Columns",
"choices": self.choicify(datasource.groupby_column_names),
"description": "One or many fields to pivot as columns"
}),
'all_columns': (SelectMultipleSortableField, {
"label": "Columns",
"choices": self.choicify(datasource.column_names),
"description": "Columns to display"
}),
'all_columns_x': (SelectField, {
"label": "X",
"choices": self.choicify(datasource.column_names),
"description": "Columns to display"
}),
'all_columns_y': (SelectField, {
"label": "Y",
"choices": self.choicify(datasource.column_names),
"description": "Columns to display"
}),
'druid_time_origin': (FreeFormSelectField, {
"label": "Origin",
"choices": (
('', 'default'),
('now', 'now'),
),
default='',
description=(
"default": '',
"description": (
"Defines the origin where time buckets start, "
"accepts natural dates as in 'now', 'sunday' or '1970-01-01'")),
'granularity': FreeFormSelectField(
'Time Granularity', default="one day",
choices=self.choicify([
"accepts natural dates as in 'now', 'sunday' or '1970-01-01'")
}),
'granularity': (FreeFormSelectField, {
"label": "Time Granularity",
"default": "one day",
"choices": self.choicify([
'all',
'5 seconds',
'30 seconds',
@ -255,36 +284,42 @@ class FormFactory(object):
'1 day',
'7 days',
]),
description=(
"description": (
"The time granularity for the visualization. Note that you "
"can type and use simple natural language as in '10 seconds', "
"'1 day' or '56 weeks'")),
'domain_granularity': SelectField(
'Domain', default="month",
choices=self.choicify([
"'1 day' or '56 weeks'")
}),
'domain_granularity': (SelectField, {
"label": "Domain",
"default": "month",
"choices": self.choicify([
'hour',
'day',
'week',
'month',
'year',
]),
description=(
"The time unit used for the grouping of blocks")),
'subdomain_granularity': SelectField(
'Subdomain', default="day",
choices=self.choicify([
"description": (
"The time unit used for the grouping of blocks")
}),
'subdomain_granularity': (SelectField, {
"label": "Subdomain",
"default": "day",
"choices": self.choicify([
'min',
'hour',
'day',
'week',
'month',
]),
description=(
"description": (
"The time unit for each block. Should be a smaller unit than "
"domain_granularity. Should be larger or equal to Time Grain")),
'link_length': FreeFormSelectField(
'Link Length', default="200",
choices=self.choicify([
"domain_granularity. Should be larger or equal to Time Grain")
}),
'link_length': (FreeFormSelectField, {
"label": "Link Length",
"default": "200",
"choices": self.choicify([
'10',
'25',
'50',
@ -294,10 +329,12 @@ class FormFactory(object):
'200',
'250',
]),
description="Link length in the force layout"),
'charge': FreeFormSelectField(
'Charge', default="-500",
choices=self.choicify([
"description": "Link length in the force layout"
}),
'charge': (FreeFormSelectField, {
"label": "Charge",
"default": "-500",
"choices": self.choicify([
'-50',
'-75',
'-100',
@ -309,32 +346,41 @@ class FormFactory(object):
'-2500',
'-5000',
]),
description="Charge in the force layout"),
'granularity_sqla': SelectField(
'Time Column',
default=datasource.main_dttm_col or datasource.any_dttm_col,
choices=self.choicify(datasource.dttm_cols),
description=(
"description": "Charge in the force layout"
}),
'granularity_sqla': (SelectField, {
"label": "Time Column",
"default": datasource.main_dttm_col or datasource.any_dttm_col,
"choices": self.choicify(datasource.dttm_cols),
"description": (
"The time column for the visualization. Note that you "
"can define arbitrary expression that return a DATETIME "
"column in the table editor. Also note that the "
"filter bellow is applied against this column or "
"expression")),
'resample_rule': FreeFormSelectField(
'Resample Rule', default='',
choices=self.choicify(('1T', '1H', '1D', '7D', '1M', '1AS')),
description=("Pandas resample rule")),
'resample_how': FreeFormSelectField(
'Resample How', default='',
choices=self.choicify(('', 'mean', 'sum', 'median')),
description=("Pandas resample how")),
'resample_fillmethod': FreeFormSelectField(
'Resample Fill Method', default='',
choices=self.choicify(('', 'ffill', 'bfill')),
description=("Pandas resample fill method")),
'since': FreeFormSelectField(
'Since', default="7 days ago",
choices=self.choicify([
"expression")
}),
'resample_rule': (FreeFormSelectField, {
"label": "Resample Rule",
"default": '',
"choices": self.choicify(('1T', '1H', '1D', '7D', '1M', '1AS')),
"description": ("Pandas resample rule")
}),
'resample_how': (FreeFormSelectField, {
"label": "Resample How",
"default": '',
"choices": self.choicify(('', 'mean', 'sum', 'median')),
"description": ("Pandas resample how")
}),
'resample_fillmethod': (FreeFormSelectField, {
"label": "Resample Fill Method",
"default": '',
"choices": self.choicify(('', 'ffill', 'bfill')),
"description": ("Pandas resample fill method")
}),
'since': (FreeFormSelectField, {
"label": "Since",
"default": "7 days ago",
"choices": self.choicify([
'1 hour ago',
'12 hours ago',
'1 day ago',
@ -343,22 +389,25 @@ class FormFactory(object):
'90 days ago',
'1 year ago'
]),
description=(
"description": (
"Timestamp from filter. This supports free form typing and "
"natural language as in '1 day ago', '28 days' or '3 years'")),
'until': FreeFormSelectField(
'Until', default="now",
choices=self.choicify([
"natural language as in '1 day ago', '28 days' or '3 years'")
}),
'until': (FreeFormSelectField, {
"label": "Until",
"default": "now",
"choices": self.choicify([
'now',
'1 day ago',
'7 days ago',
'28 days ago',
'90 days ago',
'1 year ago'])
),
'max_bubble_size': FreeFormSelectField(
'Max Bubble Size', default="25",
choices=self.choicify([
}),
'max_bubble_size': (FreeFormSelectField, {
"label": "Max Bubble Size",
"default": "25",
"choices": self.choicify([
'5',
'10',
'15',
@ -367,27 +416,28 @@ class FormFactory(object):
'75',
'100',
])
),
'whisker_options': FreeFormSelectField(
'Whisker/outlier options', default="Tukey",
description=(
}),
'whisker_options': (FreeFormSelectField, {
"label": "Whisker/outlier options",
"default": "Tukey",
"description": (
"Determines how whiskers and outliers are calculated."),
choices=self.choicify([
"choices": self.choicify([
'Tukey',
'Min/max (no outliers)',
'2/98 percentiles',
'9/91 percentiles',
])
),
'treemap_ratio': DecimalField(
'Ratio',
default=0.5 * (1 + math.sqrt(5)), # d3 default, golden ratio
description='Target aspect ratio for treemap tiles.',
),
'number_format': FreeFormSelectField(
'Number format',
default='.3s',
choices=[
}),
'treemap_ratio': (DecimalField, {
"label": "Ratio",
"default": 0.5 * (1 + math.sqrt(5)), # d3 default, golden ratio
"description": 'Target aspect ratio for treemap tiles.',
}),
'number_format': (FreeFormSelectField, {
"label": "Number format",
"default": '.3s',
"choices": [
('.3s', '".3s" | 12.3k'),
('.3%', '".3%" | 1234543.210%'),
('.4r', '".4r" | 12350'),
@ -395,109 +445,130 @@ class FormFactory(object):
('+,', '"+," | +12,345.4321'),
('$,.2f', '"$,.2f" | $12,345.43'),
],
description="D3 format syntax for numbers "
"https://github.com/mbostock/\n"
"d3/wiki/Formatting"),
'row_limit':
FreeFormSelectField(
'Row limit',
default=config.get("ROW_LIMIT"),
choices=self.choicify(
[10, 50, 100, 250, 500, 1000, 5000, 10000, 50000])),
'limit':
FreeFormSelectField(
'Series limit',
choices=self.choicify(self.series_limits),
default=50,
description=(
"Limits the number of time series that get displayed")),
'rolling_type': SelectField(
'Rolling',
default='None',
choices=[(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']],
description=(
"description": "D3 format syntax for numbers "
"https: //github.com/mbostock/\n"
"d3/wiki/Formatting"
}),
'row_limit': (FreeFormSelectField, {
"label": 'Row limit',
"default": config.get("ROW_LIMIT"),
"choices": self.choicify(
[10, 50, 100, 250, 500, 1000, 5000, 10000, 50000])
}),
'limit': (FreeFormSelectField, {
"label": 'Series limit',
"choices": self.choicify(self.series_limits),
"default": 50,
"description": (
"Limits the number of time series that get displayed")
}),
'rolling_type': (SelectField, {
"label": "Rolling",
"default": 'None',
"choices": [(s, s) for s in ['None', 'mean', 'sum', 'std', 'cumsum']],
"description": (
"Defines a rolling window function to apply, works along "
"with the [Periods] text box")),
'rolling_periods': IntegerField(
'Periods',
validators=[validators.optional()],
description=(
"with the [Periods] text box")
}),
'rolling_periods': (IntegerField, {
"label": "Periods",
"validators": [validators.optional()],
"description": (
"Defines the size of the rolling window function, "
"relative to the time granularity selected")),
'series': SelectField(
'Series', choices=group_by_choices,
default=default_groupby,
description=(
"relative to the time granularity selected")
}),
'series': (SelectField, {
"label": "Series",
"choices": group_by_choices,
"default": default_groupby,
"description": (
"Defines the grouping of entities. "
"Each serie is shown as a specific color on the chart and "
"has a legend toggle")),
'entity': SelectField(
'Entity', choices=group_by_choices,
default=default_groupby,
description="This define the element to be plotted on the chart"),
'x': SelectField(
'X Axis', choices=datasource.metrics_combo,
default=default_metric,
description="Metric assigned to the [X] axis"),
'y': SelectField(
'Y Axis', choices=datasource.metrics_combo,
default=default_metric,
description="Metric assigned to the [Y] axis"),
'size': SelectField(
'Bubble Size',
default=default_metric,
choices=datasource.metrics_combo),
'url': TextField(
'URL',
description=(
"has a legend toggle")
}),
'entity': (SelectField, {
"label": "Entity",
"choices": group_by_choices,
"default": default_groupby,
"description": "This define the element to be plotted on the chart"
}),
'x': (SelectField, {
"label": "X Axis",
"choices": datasource.metrics_combo,
"default": default_metric,
"description": "Metric assigned to the [X] axis"
}),
'y': (SelectField, {
"label": "Y Axis",
"choices": datasource.metrics_combo,
"default": default_metric,
"description": "Metric assigned to the [Y] axis"
}),
'size': (SelectField, {
"label": 'Bubble Size',
"default": default_metric,
"choices": datasource.metrics_combo
}),
'url': (TextField, {
"label": "URL",
"description": (
"The URL, this field is templated, so you can integrate "
"{{ width }} and/or {{ height }} in your URL string."
),
default='https://www.youtube.com/embed/JkI5rg_VcQ4',),
'where': TextField(
'Custom WHERE clause', default='',
description=(
"default": 'https: //www.youtube.com/embed/JkI5rg_VcQ4',
}),
'where': (TextField, {
"label": "Custom WHERE clause",
"default": '',
"description": (
"The text in this box gets included in your query's WHERE "
"clause, as an AND to other criteria. You can include "
"complex expression, parenthesis and anything else "
"supported by the backend it is directed towards.")),
'having': TextField(
'Custom HAVING clause', default='',
description=(
"supported by the backend it is directed towards.")
}),
'having': (TextField, {
"label": "Custom HAVING clause",
"default": '',
"description": (
"The text in this box gets included in your query's HAVING"
" clause, as an AND to other criteria. You can include "
"complex expression, parenthesis and anything else "
"supported by the backend it is directed towards.")),
'compare_lag': TextField(
'Comparison Period Lag',
description=(
"supported by the backend it is directed towards.")
}),
'compare_lag': (TextField, {
"label": "Comparison Period Lag",
"description": (
"Based on granularity, number of time periods to "
"compare against")),
'compare_suffix': TextField(
'Comparison suffix',
description="Suffix to apply after the percentage display"),
'table_timestamp_format': FreeFormSelectField(
'Table Timestamp Format',
default='smart_date',
choices=TIMESTAMP_CHOICES,
description="Timestamp Format"),
'series_height': FreeFormSelectField(
'Series Height',
default=25,
choices=self.choicify([10, 25, 40, 50, 75, 100, 150, 200]),
description="Pixel height of each series"),
'x_axis_format': FreeFormSelectField(
'X axis format',
default='smart_date',
choices=TIMESTAMP_CHOICES,
description="D3 format syntax for y axis "
"https://github.com/mbostock/\n"
"d3/wiki/Formatting"),
'y_axis_format': FreeFormSelectField(
'Y axis format',
default='.3s',
choices=[
"compare against")
}),
'compare_suffix': (TextField, {
"label": "Comparison suffix",
"description": "Suffix to apply after the percentage display"
}),
'table_timestamp_format': (FreeFormSelectField, {
"label": "Table Timestamp Format",
"default": 'smart_date',
"choices": TIMESTAMP_CHOICES,
"description": "Timestamp Format"
}),
'series_height': (FreeFormSelectField, {
"label": "Series Height",
"default": 25,
"choices": self.choicify([10, 25, 40, 50, 75, 100, 150, 200]),
"description": "Pixel height of each series"
}),
'x_axis_format': (FreeFormSelectField, {
"label": "X axis format",
"default": 'smart_date',
"choices": TIMESTAMP_CHOICES,
"description": "D3 format syntax for y axis "
"https: //github.com/mbostock/\n"
"d3/wiki/Formatting"
}),
'y_axis_format': (FreeFormSelectField, {
"label": "Y axis format",
"default": '.3s',
"choices": [
('.3s', '".3s" | 12.3k'),
('.3%', '".3%" | 1234543.210%'),
('.4r', '".4r" | 12350'),
@ -505,107 +576,155 @@ class FormFactory(object):
('+,', '"+," | +12,345.4321'),
('$,.2f', '"$,.2f" | $12,345.43'),
],
description="D3 format syntax for y axis "
"https://github.com/mbostock/\n"
"d3/wiki/Formatting"),
'markup_type': SelectField(
"Markup Type",
choices=self.choicify(['markdown', 'html']),
default="markdown",
description="Pick your favorite markup language"),
'rotation': SelectField(
"Rotation",
choices=[(s, s) for s in ['random', 'flat', 'square']],
default="random",
description="Rotation to apply to words in the cloud"),
'line_interpolation': SelectField(
"Line Style",
choices=self.choicify([
"description": "D3 format syntax for y axis "
"https: //github.com/mbostock/\n"
"d3/wiki/Formatting"
}),
'markup_type': (SelectField, {
"label": "Markup Type",
"choices": self.choicify(['markdown', 'html']),
"default": "markdown",
"description": "Pick your favorite markup language"
}),
'rotation': (SelectField, {
"label": "Rotation",
"choices": [(s, s) for s in ['random', 'flat', 'square']],
"default": "random",
"description": "Rotation to apply to words in the cloud"
}),
'line_interpolation': (SelectField, {
"label": "Line Style",
"choices": self.choicify([
'linear', 'basis', 'cardinal', 'monotone',
'step-before', 'step-after']),
default='linear',
description="Line interpolation as defined by d3.js"),
'code': TextAreaField(
"Code", description="Put your code here", default=''),
'pandas_aggfunc': SelectField(
"Aggregation function",
choices=self.choicify([
"default": 'linear',
"description": "Line interpolation as defined by d3.js"
}),
'code': (TextAreaField, {
"label": "Code",
"description": "Put your code here",
"default": ''
}),
'pandas_aggfunc': (SelectField, {
"label": "Aggregation function",
"choices": self.choicify([
'sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']),
default='sum',
description=(
"default": 'sum',
"description": (
"Aggregate function to apply when pivoting and "
"computing the total rows and columns")),
'size_from': TextField(
"Font Size From",
default="20",
description="Font size for the smallest value in the list"),
'size_to': TextField(
"Font Size To",
default="150",
description="Font size for the biggest value in the list"),
'show_brush': BetterBooleanField(
"Range Filter", default=False,
description=(
"Whether to display the time range interactive selector")),
'show_datatable': BetterBooleanField(
"Data Table", default=False,
description="Whether to display the interactive data table"),
'include_search': BetterBooleanField(
"Search Box", default=False,
description=(
"Whether to include a client side search box")),
'show_bubbles': BetterBooleanField(
"Show Bubbles", default=False,
description=(
"Whether to display bubbles on top of countries")),
'show_legend': BetterBooleanField(
"Legend", default=True,
description="Whether to display the legend (toggles)"),
'x_axis_showminmax': BetterBooleanField(
"X bounds", default=True,
description=(
"Whether to display the min and max values of the X axis")),
'rich_tooltip': BetterBooleanField(
"Rich Tooltip", default=True,
description=(
"computing the total rows and columns")
}),
'size_from': (TextField, {
"label": "Font Size From",
"default": "20",
"description": "Font size for the smallest value in the list"
}),
'size_to': (TextField, {
"label": "Font Size To",
"default": "150",
"description": "Font size for the biggest value in the list"
}),
'show_brush': (BetterBooleanField, {
"label": "Range Filter",
"default": False,
"description": (
"Whether to display the time range interactive selector")
}),
'show_datatable': (BetterBooleanField, {
"label": "Data Table",
"default": False,
"description": "Whether to display the interactive data table"
}),
'include_search': (BetterBooleanField, {
"label": "Search Box",
"default": False,
"description": (
"Whether to include a client side search box")
}),
'show_bubbles': (BetterBooleanField, {
"label": "Show Bubbles",
"default": False,
"description": (
"Whether to display bubbles on top of countries")
}),
'show_legend': (BetterBooleanField, {
"label": "Legend",
"default": True,
"description": "Whether to display the legend (toggles)"
}),
'x_axis_showminmax': (BetterBooleanField, {
"label": "X bounds",
"default": True,
"description": (
"Whether to display the min and max values of the X axis")
}),
'rich_tooltip': (BetterBooleanField, {
"label": "Rich Tooltip",
"default": True,
"description": (
"The rich tooltip shows a list of all series for that"
" point in time")),
'y_axis_zero': BetterBooleanField(
"Y Axis Zero", default=False,
description=(
" point in time")
}),
'y_axis_zero': (BetterBooleanField, {
"label": "Y Axis Zero",
"default": False,
"description": (
"Force the Y axis to start at 0 instead of the minimum "
"value")),
'y_log_scale': BetterBooleanField(
"Y Log", default=False,
description="Use a log scale for the Y axis"),
'x_log_scale': BetterBooleanField(
"X Log", default=False,
description="Use a log scale for the X axis"),
'donut': BetterBooleanField(
"Donut", default=False,
description="Do you want a donut or a pie?"),
'contribution': BetterBooleanField(
"Contribution", default=False,
description="Compute the contribution to the total"),
'num_period_compare': IntegerField(
"Period Ratio", default=None,
validators=[validators.optional()],
description=(
"value")
}),
'y_log_scale': (BetterBooleanField, {
"label": "Y Log",
"default": False,
"description": "Use a log scale for the Y axis"
}),
'x_log_scale': (BetterBooleanField, {
"label": "X Log",
"default": False,
"description": "Use a log scale for the X axis"
}),
'donut': (BetterBooleanField, {
"label": "Donut",
"default": False,
"description": "Do you want a donut or a pie?"
}),
'contribution': (BetterBooleanField, {
"label": "Contribution",
"default": False,
"description": "Compute the contribution to the total"
}),
'num_period_compare': (IntegerField, {
"label": "Period Ratio",
"default": None,
"validators": [validators.optional()],
"description": (
"[integer] Number of period to compare against, "
"this is relative to the granularity selected")),
'time_compare': TextField(
"Time Shift",
default="",
description=(
"this is relative to the granularity selected")
}),
'time_compare': (TextField, {
"label": "Time Shift",
"default": "",
"description": (
"Overlay a timeseries from a "
"relative time period. Expects relative time delta "
"in natural language (example: 24 hours, 7 days, "
"56 weeks, 365 days")),
'subheader': TextField(
'Subheader',
description=(
"in natural language (example: 24 hours, 7 days, "
"56 weeks, 365 days")
}),
'subheader': (TextField, {
"label": "Subheader",
"description": (
"Description text that shows up below your Big "
"Number")),
"Number")
}),
}
# Override default arguments with form overrides
for field_name, override_map in viz.form_overrides.items():
if field_name in field_data:
field_data[field_name][1].update(override_map)
self.field_dict = {
field_name: v[0](**v[1])
for field_name, v in field_data.items()
}
@staticmethod

View File

@ -16,10 +16,10 @@
<div>
{% set field = form.get_field(fieldname)%}
<div>
{{ viz.get_form_override(fieldname, 'label') or field.label }}
{{ field.label }}
{% if field.description %}
<i class="fa fa-info-circle" data-toggle="tooltip" data-placement="right"
title="{{ viz.get_form_override(fieldname, 'description') or field.description }}"></i>
title="{{ field.description }}"></i>
{% endif %}
{{ field(class_=form.field_css_classes(field.name)) }}
</div>

View File

@ -90,16 +90,6 @@ class BaseViz(object):
self.groupby = self.form_data.get('groupby') or []
self.reassignments()
def get_form_override(self, fieldname, attr):
if (
fieldname in self.form_overrides and
attr in self.form_overrides[fieldname]):
s = self.form_overrides[fieldname][attr]
if attr == 'label':
s = '<label for="{fieldname}">{s}</label>'.format(**locals())
s = Markup(s)
return s
@classmethod
def flat_form_fields(cls):
l = set()
@ -344,6 +334,11 @@ class TableViz(BaseViz):
('include_search', None),
)
})
form_overrides = ({
'metrics': {
'default': [],
},
})
is_timeseries = False
def query_obj(self):