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:
parent
849063c797
commit
cb384d051b
799
caravel/forms.py
799
caravel/forms.py
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Reference in New Issue