def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names default_groupby = gb_cols[0] if gb_cols else None group_by_choices = [(s, s) for s in datasource.groupby_column_names] # 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([ 'fire', 'blue_white_yellow', 'white_black', 'black_white' ]), default='blue_white_yellow', description=""), 'normalize_across': SelectField( 'Normalize Across', choices=self.choicify(['heatmap', 'x', 'y']), default='heatmap', description=("Color will be rendered based on a ratio " "of the cell against the sum of across this " "criteria")), 'canvas_image_rendering': SelectField( 'Rendering', choices=( ('pixelated', 'pixelated (Sharp)'), ('auto', 'auto (Smooth)'), ), 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=("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=("Number of step to take between ticks when " "printing the y scale")), 'bar_stacked': BetterBooleanField('Stacked Bars', default=False, description=""), '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=( ('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=( "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"), 'granularity': FreeFormSelectField( 'Time Granularity', default="one day", choices=self.choicify([ 'all', '5 seconds', '30 seconds', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), 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'")), 'link_length': FreeFormSelectField('Link Length', default="200", choices=self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), description="Link length in the force layout"), 'charge': FreeFormSelectField('Charge', default="-500", choices=self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-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=( "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([ '1 hour ago', '12 hours ago', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), 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([ '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([ '5', '10', '15', '25', '50', '75', '100', ])), 'whisker_options': FreeFormSelectField( 'Whisker/outlier options', default="Tukey", description=( "Determines how whiskers and outliers are calculated."), choices=self.choicify([ 'Tukey', 'Min/max (no outliers)', '2/98 percentiles', '9/91 percentiles', ])), '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=( "Defines a rolling window function to apply, works along " "with the [Periods] text box")), 'rolling_periods': IntegerField( '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=( "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', default='www.airbnb.com', ), 'where': TextField( '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=( "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=("Based on granularity, number of time periods to " "compare against")), 'compare_suffix': TextField( 'Comparison suffix', description="Suffix to apply after the percentage display"), 'x_axis_format': FreeFormSelectField( 'X axis format', default='smart_date', choices=[ ('smart_date', 'Adaptative formating'), ("%m/%d/%Y", '"%m/%d/%Y" | 01/14/2019'), ("%Y-%m-%d", '"%Y-%m-%d" | 2019-01-14'), ("%Y-%m-%d %H:%M:%S", '"%Y-%m-%d %H:%M:%S" | 2019-01-14 01:32:10'), ("%H:%M:%S", '"%H:%M:%S" | 01:32:10'), ], 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=[ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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([ '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( ['sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']), 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=( "The rich tooltip shows a list of all series for that" " point in time")), 'y_axis_zero': BetterBooleanField( "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=("[integer] Number of period to compare against, " "this is relative to the granularity selected")), 'time_compare': TextField("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=("Description text that shows up below your Big " "Number")), }
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource if not datasource.metrics_combo: raise Exception("Please define at least one metric for your table") default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names 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 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, { "label": "Normalize Across", "choices": self.choicify([ 'heatmap', 'x', 'y']), "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, { "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": ( "image-rendering CSS attribute of the canvas object that " "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, { "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, { "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": ( "The country code standard that Caravel should expect " "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": ( "Defines the origin where time buckets start, " "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', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), "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, { "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, { "label": "Subdomain", "default": "day", "choices": self.choicify([ 'min', 'hour', 'day', 'week', 'month', ]), "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, { "label": "Link Length", "default": "200", "choices": self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), "description": "Link length in the force layout" }), 'charge': (FreeFormSelectField, { "label": "Charge", "default": "-500", "choices": self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), "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, { "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', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), "description": ( "Timestamp from filter. This supports free form typing and " "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, { "label": "Max Bubble Size", "default": "25", "choices": self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) }), 'whisker_options': (FreeFormSelectField, { "label": "Whisker/outlier options", "default": "Tukey", "description": ( "Determines how whiskers and outliers are calculated."), "choices": self.choicify([ 'Tukey', 'Min/max (no outliers)', '2/98 percentiles', '9/91 percentiles', ]) }), '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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "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, { "label": "Periods", "validators": [validators.optional()], "description": ( "Defines the size of the rolling window function, " "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, { "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, { "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, { "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, { "label": "Comparison Period Lag", "description": ( "Based on granularity, number of time periods to " "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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "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, { "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": ( "Aggregate function to apply when pivoting and " "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, { "label": "Y Axis Zero", "default": False, "description": ( "Force the Y axis to start at 0 instead of the minimum " "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, { "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, { "label": "Subheader", "description": ( "Description text that shows up below your Big " "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() }
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource if not datasource.metrics_combo: raise Exception("Please define at least one metric for your table") default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names default_groupby = gb_cols[0] if gb_cols else None group_by_choices = self.choicify(gb_cols) order_by_choices = [] for s in sorted(datasource.num_cols): order_by_choices.append((json.dumps([s, True]), s + ' [asc]')) order_by_choices.append((json.dumps([s, False]), s + ' [desc]')) # Pool of all the fields that can be used in Caravel 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") }), 'order_by_cols': (SelectMultipleSortableField, { "label": _("Ordering"), "choices": order_by_choices, "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": ( ('stack', _('stack')), ('stream', _('stream')), ('expand', _('expand')), ), "default": 'stack', "description": "" }), 'linear_color_scheme': (SelectField, { "label": _("Color Scheme"), "choices": ( ('fire', _('fire')), ('blue_white_yellow', _('blue_white_yellow')), ('white_black', _('white_black')), ('black_white', _('black_white')), ), "default": 'blue_white_yellow', "description": "" }), 'normalize_across': (SelectField, { "label": _("Normalize Across"), "choices": ( ('heatmap', _('heatmap')), ('x', _('x')), ('y', _('y')), ), "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, { "label": _("Color Scale"), "choices": ( ('series', _('series')), ('overall', _('overall')), ('change', _('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": _( "image-rendering CSS attribute of the canvas object that " "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, { "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, { "label": _("Stacked Bars"), "default": False, "description": "" }), 'show_markers': (BetterBooleanField, { "label": _("Show Markers"), "default": False, "description": ( "Show data points as circle markers on top of the lines " "in the chart") }), 'show_bar_value': (BetterBooleanField, { "label": _("Bar Values"), "default": False, "description": "Show the value on top of the bars or not" }), 'show_controls': (BetterBooleanField, { "label": _("Extra Controls"), "default": False, "description": _( "Whether to show extra controls or not. Extra controls " "include things like making mulitBar charts stacked " "or side by side.") }), 'reduce_x_ticks': (BetterBooleanField, { "label": _("Reduce X ticks"), "default": False, "description": _( "Reduces the number of X axis ticks to be rendered. " "If true, the x axis wont overflow and labels may be " "missing. If false, a minimum width will be applied " "to columns and the width may overflow into an " "horizontal scroll."), }), '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": _( "The country code standard that Caravel should expect " "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), "default": datasource.column_names[0], "description": _("Columns to display") }), 'all_columns_y': (SelectField, { "label": _("Y"), "choices": self.choicify(datasource.column_names), "default": datasource.column_names[0], "description": _("Columns to display") }), 'druid_time_origin': (FreeFormSelectField, { "label": _("Origin"), "choices": ( ('', _('default')), ('now', _('now')), ), "default": '', "description": _( "Defines the origin where time buckets start, " "accepts natural dates as in 'now', 'sunday' or '1970-01-01'") }), 'bottom_margin': (FreeFormSelectField, { "label": _("Bottom Margin"), "choices": self.choicify(['auto', 50, 75, 100, 125, 150, 200]), "default": 'auto', "description": _( "Bottom marging, in pixels, allowing for more room for " "axis labels"), }), 'granularity': (FreeFormSelectField, { "label": _("Time Granularity"), "default": "one day", "choices": ( ('all', _('all')), ('5 seconds', _('5 seconds')), ('30 seconds', _('30 seconds')), ('1 minute', _('1 minute')), ('5 minutes', _('5 minutes')), ('1 hour', _('1 hour')), ('6 hour', _('6 hour')), ('1 day', _('1 day')), ('7 days', _('7 days')), ), "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, { "label": _("Domain"), "default": "month", "choices": ( ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ('year', _('year')), ), "description": _( "The time unit used for the grouping of blocks") }), 'subdomain_granularity': (SelectField, { "label": _("Subdomain"), "default": "day", "choices": ( ('min', _('min')), ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ), "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, { "label": _("Link Length"), "default": "200", "choices": self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), "description": _("Link length in the force layout") }), 'charge': (FreeFormSelectField, { "label": _("Charge"), "default": "-500", "choices": self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), "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 below is applied against this column or " "expression") }), 'resample_rule': (FreeFormSelectField, { "label": _("Resample Rule"), "default": '', "choices": ( ('1T', _('1T')), ('1H', _('1H')), ('1D', _('1D')), ('7D', _('7D')), ('1M', _('1M')), ('1AS', _('1AS')), ), "description": _("Pandas resample rule") }), 'resample_how': (FreeFormSelectField, { "label": _("Resample How"), "default": '', "choices": ( ('', ''), ('mean', _('mean')), ('sum', _('sum')), ('median', _('median')), ), "description": _("Pandas resample how") }), 'resample_fillmethod': (FreeFormSelectField, { "label": _("Resample Fill Method"), "default": '', "choices": ( ('', ''), ('ffill', _('ffill')), ('bfill', _('bfill')), ), "description": _("Pandas resample fill method") }), 'since': (FreeFormSelectField, { "label": _("Since"), "default": "7 days ago", "choices": ( ('1 hour ago', _('1 hour ago')), ('12 hours ago', _('12 hours ago')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ), "description": _( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'") }), 'until': (FreeFormSelectField, { "label": _("Until"), "default": "now", "choices": ( ('now', _('now')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ) }), 'max_bubble_size': (FreeFormSelectField, { "label": _("Max Bubble Size"), "default": "25", "choices": self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) }), 'whisker_options': (FreeFormSelectField, { "label": _("Whisker/outlier options"), "default": "Tukey", "description": _( "Determines how whiskers and outliers are calculated."), "choices": ( ('Tukey', _('Tukey')), ('Min/max (no outliers)', _('Min/max (no outliers)')), ('2/98 percentiles', _('2/98 percentiles')), ('9/91 percentiles', _('9/91 percentiles')), ) }), '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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "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, { "label": _("Periods"), "validators": [validators.optional()], "description": _( "Defines the size of the rolling window function, " "relative to the time granularity selected") }), 'series': (SelectField, { "label": _("Series"), "choices": group_by_choices, "default": default_groupby, "description": _( "Defines the grouping of entities. " "Each series is shown as a specific color on the chart and " "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', }), 'x_axis_label': (TextField, { "label": _("X Axis Label"), "default": '', }), 'y_axis_label': (TextField, { "label": _("Y Axis Label"), "default": '', }), '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, { "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, { "label": _("Comparison Period Lag"), "description": _( "Based on granularity, number of time periods to " "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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "label": _("Markup Type"), "choices": ( ('markdown', _('markdown')), ('html', _('html')) ), "default": "markdown", "description": _("Pick your favorite markup language") }), 'rotation': (SelectField, { "label": _("Rotation"), "choices": ( ('random', _('random')), ('flat', _('flat')), ('square', _('square')), ), "default": "random", "description": _("Rotation to apply to words in the cloud") }), 'line_interpolation': (SelectField, { "label": _("Line Style"), "choices": ( ('linear', _('linear')), ('basis', _('basis')), ('cardinal', _('cardinal')), ('monotone', _('monotone')), ('step-before', _('step-before')), ('step-after', _('step-after')), ), "default": 'linear', "description": _("Line interpolation as defined by d3.js") }), 'pie_label_type': (SelectField, { "label": _("Label Type"), "default": 'key', "choices": ( ('key', _("Category Name")), ('value', _("Value")), ('percent', _("Percentage")), ), "description": _("What should be shown on the label?") }), 'code': (TextAreaField, { "label": _("Code"), "description": _("Put your code here"), "default": '' }), 'pandas_aggfunc': (SelectField, { "label": _("Aggregation function"), "choices": ( ('sum', _('sum')), ('mean', _('mean')), ('min', _('min')), ('max', _('max')), ('median', _('median')), ('stdev', _('stdev')), ('var', _('var')), ), "default": 'sum', "description": _( "Aggregate function to apply when pivoting and " "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") }), 'date_filter': (BetterBooleanField, { "label": _("Date Filter"), "default": False, "description": _("Whether to include a time filter") }), '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, { "label": _("Y Axis Zero"), "default": False, "description": _( "Force the Y axis to start at 0 instead of the minimum " "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?") }), 'labels_outside': (BetterBooleanField, { "label": _("Put labels outside"), "default": True, "description": _("Put the labels outside the 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") }), 'period_ratio_type': (SelectField, { "label": _("Period Ratio Type"), "default": 'growth', "choices": ( ('factor', _('factor')), ('growth', _('growth')), ('value', _('value')), ), "description": _( "`factor` means (new/previous), `growth` is " "((new/previous) - 1), `value` is (new-previous)") }), '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, { "label": _("Subheader"), "description": _( "Description text that shows up below your Big " "Number") }), 'mapbox_label': (SelectMultipleSortableField, { "label": "Label", "choices": self.choicify(["count"] + datasource.column_names), "description": _( "'count' is COUNT(*) if a group by is used. " "Numerical columns will be aggregated with the aggregator. " "Non-numerical columns will be used to label points. " "Leave empty to get a count of points in each cluster."), }), 'mapbox_style': (SelectField, { "label": "Map Style", "choices": [ ("mapbox://styles/mapbox/streets-v9", "Streets"), ("mapbox://styles/mapbox/dark-v9", "Dark"), ("mapbox://styles/mapbox/light-v9", "Light"), ("mapbox://styles/mapbox/satellite-streets-v9", "Satellite Streets"), ("mapbox://styles/mapbox/satellite-v9", "Satellite"), ("mapbox://styles/mapbox/outdoors-v9", "Outdoors"), ], "default": "mapbox://styles/mapbox/streets-v9", "description": _("Base layer map style") }), 'clustering_radius': (FreeFormSelectField, { "label": _("Clustering Radius"), "default": "60", "choices": self.choicify([ '0', '20', '40', '60', '80', '100', '200', '500', '1000', ]), "description": _( "The radius (in pixels) the algorithm uses to define a cluster. " "Choose 0 to turn off clustering, but beware that a large " "number of points (>1000) will cause lag.") }), 'point_radius': (SelectField, { "label": _("Point Radius"), "default": "Auto", "choices": self.choicify(["Auto"] + datasource.column_names), "description": _( "The radius of individual points (ones that are not in a cluster). " "Either a numerical column or 'Auto', which scales the point based " "on the largest cluster") }), 'point_radius_unit': (SelectField, { "label": _("Point Radius Unit"), "default": "Pixels", "choices": self.choicify([ "Pixels", "Miles", "Kilometers", ]), "description": _("The unit of measure for the specified point radius") }), 'global_opacity': (DecimalField, { "label": _("Opacity"), "default": 1, "description": _( "Opacity of all clusters, points, and labels. " "Between 0 and 1."), }), 'viewport_zoom': (DecimalField, { "label": _("Zoom"), "default": 11, "validators": [validators.optional()], "description": _("Zoom level of the map"), "places": 8, }), 'viewport_latitude': (DecimalField, { "label": _("Default latitude"), "default": 37.772123, "description": _("Latitude of default viewport"), "places": 8, }), 'viewport_longitude': (DecimalField, { "label": _("Default longitude"), "default": -122.405293, "description": _("Longitude of default viewport"), "places": 8, }), 'render_while_dragging': (BetterBooleanField, { "label": _("Live render"), "default": True, "description": _("Points and clusters will update as viewport " "is being changed") }), 'mapbox_color': (FreeFormSelectField, { "label": _("RGB Color"), "default": "rgb(0, 122, 135)", "choices": [ ("rgb(0, 139, 139)", "Dark Cyan"), ("rgb(128, 0, 128)", "Purple"), ("rgb(255, 215, 0)", "Gold"), ("rgb(69, 69, 69)", "Dim Gray"), ("rgb(220, 20, 60)", "Crimson"), ("rgb(34, 139, 34)", "Forest Green"), ], "description": _("The color for points and clusters in RGB") }), } # 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() }
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource if not datasource.metrics_combo: raise Exception("Please define at least one metric for your table") default_metric = datasource.metrics_combo[0][0] gb_cols = datasource.groupby_column_names default_groupby = gb_cols[0] if gb_cols else None group_by_choices = self.choicify(gb_cols) order_by_choices = [] for s in sorted(datasource.num_cols): order_by_choices.append((json.dumps([s, True]), s + ' [asc]')) order_by_choices.append((json.dumps([s, False]), s + ' [desc]')) # Pool of all the fields that can be used in Caravel 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") }), 'order_by_cols': (SelectMultipleSortableField, { "label": _("Ordering"), "choices": order_by_choices, "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": ( ('stack', _('stack')), ('stream', _('stream')), ('expand', _('expand')), ), "default": 'stack', "description": "" }), 'linear_color_scheme': (SelectField, { "label": _("Color Scheme"), "choices": ( ('fire', _('fire')), ('blue_white_yellow', _('blue_white_yellow')), ('white_black', _('white_black')), ('black_white', _('black_white')), ), "default": 'blue_white_yellow', "description": "" }), 'normalize_across': (SelectField, { "label": _("Normalize Across"), "choices": ( ('heatmap', _('heatmap')), ('x', _('x')), ('y', _('y')), ), "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, { "label": _("Color Scale"), "choices": ( ('series', _('series')), ('overall', _('overall')), ('change', _('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": _( "image-rendering CSS attribute of the canvas object that " "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, { "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, { "label": _("Stacked Bars"), "default": False, "description": "" }), 'show_controls': (BetterBooleanField, { "label": _("Extra Controls"), "default": False, "description": ( "Whether to show extra controls or not. Extra controls " "include things like making mulitBar charts stacked " "or side by side.") }), 'reduce_x_ticks': (BetterBooleanField, { "label": _("Reduce X ticks"), "default": False, "description": _( "Reduces the number of X axis ticks to be rendered. " "If true, the x axis wont overflow and labels may be " "missing. If false, a minimum width will be applied " "to columns and the width may overflow into an " "horizontal scroll."), }), '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": _( "The country code standard that Caravel should expect " "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": _( "Defines the origin where time buckets start, " "accepts natural dates as in 'now', 'sunday' or '1970-01-01'") }), 'bottom_margin': (FreeFormSelectField, { "label": _("Bottom Margin"), "choices": self.choicify([50, 75, 100, 125, 150, 200]), "default": 50, "description": _( "Bottom marging, in pixels, allowing for more room for " "axis labels"), }), 'granularity': (FreeFormSelectField, { "label": _("Time Granularity"), "default": "one day", "choices": ( ('all', _('all')), ('5 seconds', _('5 seconds')), ('30 seconds', _('30 seconds')), ('1 minute', _('1 minute')), ('5 minutes', _('5 minutes')), ('1 hour', _('1 hour')), ('6 hour', _('6 hour')), ('1 day', _('1 day')), ('7 days', _('7 days')), ), "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, { "label": _("Domain"), "default": "month", "choices": ( ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ('year', _('year')), ), "description": _( "The time unit used for the grouping of blocks") }), 'subdomain_granularity': (SelectField, { "label": _("Subdomain"), "default": "day", "choices": ( ('min', _('min')), ('hour', _('hour')), ('day', _('day')), ('week', _('week')), ('month', _('month')), ), "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, { "label": _("Link Length"), "default": "200", "choices": self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), "description": _("Link length in the force layout") }), 'charge': (FreeFormSelectField, { "label": _("Charge"), "default": "-500", "choices": self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-2500', '-5000', ]), "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, { "label": _("Resample Rule"), "default": '', "choices": ( ('1T', _('1T')), ('1H', _('1H')), ('1D', _('1D')), ('7D', _('7D')), ('1M', _('1M')), ('1AS', _('1AS')), ), "description": _("Pandas resample rule") }), 'resample_how': (FreeFormSelectField, { "label": _("Resample How"), "default": '', "choices": ( ('', ''), ('mean', _('mean')), ('sum', _('sum')), ('median', _('median')), ), "description": _("Pandas resample how") }), 'resample_fillmethod': (FreeFormSelectField, { "label": _("Resample Fill Method"), "default": '', "choices": ( ('', ''), ('ffill', _('ffill')), ('bfill', _('bfill')), ), "description": _("Pandas resample fill method") }), 'since': (FreeFormSelectField, { "label": _("Since"), "default": "7 days ago", "choices": ( ('1 hour ago', _('1 hour ago')), ('12 hours ago', _('12 hours ago')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ), "description": _( "Timestamp from filter. This supports free form typing and " "natural language as in '1 day ago', '28 days' or '3 years'") }), 'until': (FreeFormSelectField, { "label": _("Until"), "default": "now", "choices": ( ('now', _('now')), ('1 day ago', _('1 day ago')), ('7 days ago', _('7 days ago')), ('28 days ago', _('28 days ago')), ('90 days ago', _('90 days ago')), ('1 year ago', _('1 year ago')), ) }), 'max_bubble_size': (FreeFormSelectField, { "label": _("Max Bubble Size"), "default": "25", "choices": self.choicify([ '5', '10', '15', '25', '50', '75', '100', ]) }), 'whisker_options': (FreeFormSelectField, { "label": _("Whisker/outlier options"), "default": "Tukey", "description": _( "Determines how whiskers and outliers are calculated."), "choices": ( ('Tukey', _('Tukey')), ('Min/max (no outliers)', _('Min/max (no outliers)')), ('2/98 percentiles', _('2/98 percentiles')), ('9/91 percentiles', _('9/91 percentiles')), ) }), '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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "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, { "label": _("Periods"), "validators": [validators.optional()], "description": _( "Defines the size of the rolling window function, " "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, { "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', }), 'x_axis_label': (TextField, { "label": _("X Axis Label"), "default": '', }), 'y_axis_label': (TextField, { "label": _("Y Axis Label"), "default": '', }), '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, { "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, { "label": _("Comparison Period Lag"), "description": _( "Based on granularity, number of time periods to " "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'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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, { "label": _("Markup Type"), "choices": ( ('markdown', _('markdown')), ('html', _('html')) ), "default": "markdown", "description": _("Pick your favorite markup language") }), 'rotation': (SelectField, { "label": _("Rotation"), "choices": ( ('random', _('random')), ('flat', _('flat')), ('square', _('square')), ), "default": "random", "description": _("Rotation to apply to words in the cloud") }), 'line_interpolation': (SelectField, { "label": _("Line Style"), "choices": ( ('linear', _('linear')), ('basis', _('basis')), ('cardinal', _('cardinal')), ('monotone', _('monotone')), ('step-before', _('step-before')), ('step-after', _('step-after')), ), "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": ( ('sum', _('sum')), ('mean', _('mean')), ('min', _('min')), ('max', _('max')), ('median', _('median')), ('stdev', _('stdev')), ('var', _('var')), ), "default": 'sum', "description": _( "Aggregate function to apply when pivoting and " "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, { "label": _("Y Axis Zero"), "default": False, "description": _( "Force the Y axis to start at 0 instead of the minimum " "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, { "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, { "label": _("Subheader"), "description": _( "Description text that shows up below your Big " "Number") }), 'mapbox_label': (SelectMultipleSortableField, { "label": "Label", "choices": self.choicify(["count"] + datasource.column_names), "description": _( "'count' is COUNT(*) if a group by is used. " "Numerical columns will be aggregated with the aggregator. " "Non-numerical columns will be used to label points. " "Leave empty to get a count of points in each cluster."), }), 'mapbox_style': (SelectField, { "label": "Map Style", "choices": [ ("mapbox://styles/mapbox/streets-v9", "Streets"), ("mapbox://styles/mapbox/dark-v9", "Dark"), ("mapbox://styles/mapbox/light-v9", "Light"), ("mapbox://styles/mapbox/satellite-streets-v9", "Satellite Streets"), ("mapbox://styles/mapbox/satellite-v9", "Satellite"), ("mapbox://styles/mapbox/outdoors-v9", "Outdoors"), ], "description": _("Base layer map style") }), 'clustering_radius': (FreeFormSelectField, { "label": _("Clustering Radius"), "default": "60", "choices": self.choicify([ '0', '20', '40', '60', '80', '100', '200', '500', '1000', ]), "description": _( "The radius (in pixels) the algorithm uses to define a cluster. " "Choose 0 to turn off clustering, but beware that a large " "number of points (>1000) will cause lag.") }), 'point_radius': (SelectField, { "label": _("Point Radius"), "default": "Auto", "choices": self.choicify(["Auto"] + datasource.column_names), "description": _( "The radius of individual points (ones that are not in a cluster). " "Either a numerical column or 'Auto', which scales the point based " "on the largest cluster") }), 'point_radius_unit': (SelectField, { "label": _("Point Radius Unit"), "default": "Pixels", "choices": self.choicify([ "Pixels", "Miles", "Kilometers", ]), "description": _("The unit of measure for the specified point radius") }), 'global_opacity': (DecimalField, { "label": _("Opacity"), "default": 1, "description": _( "Opacity of all clusters, points, and labels. " "Between 0 and 1."), }), 'viewport_zoom': (DecimalField, { "label": _("Zoom"), "default": 11, "validators": [validators.optional()], "description": _("Zoom level of the map"), "places": 8, }), 'viewport_latitude': (DecimalField, { "label": _("Default latitude"), "default": 37.772123, "description": _("Latitude of default viewport"), "places": 8, }), 'viewport_longitude': (DecimalField, { "label": _("Default longitude"), "default": -122.405293, "description": _("Longitude of default viewport"), "places": 8, }), 'render_while_dragging': (BetterBooleanField, { "label": _("Live render"), "default": True, "description": _("Points and clusters will update as viewport " "is being changed") }), 'mapbox_color': (FreeFormSelectField, { "label": _("RGB Color"), "default": "rgb(0, 122, 135)", "choices": [ ("rgb(0, 139, 139)", "Dark Cyan"), ("rgb(128, 0, 128)", "Purple"), ("rgb(255, 215, 0)", "Gold"), ("rgb(69, 69, 69)", "Dim Gray"), ("rgb(220, 20, 60)", "Crimson"), ("rgb(34, 139, 34)", "Forest Green"), ], "description": _("The color for points and clusters in RGB") }), } # 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() }
def __init__(self, viz): self.viz = viz from caravel.viz import viz_types viz = self.viz datasource = viz.datasource default_metric = datasource.metrics_combo[0][0] default_groupby = datasource.groupby_column_names[0] group_by_choices = [(s, s) for s in datasource.groupby_column_names] # 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([ 'fire', 'blue_white_yellow', 'white_black', 'black_white']), default='blue_white_yellow', description=""), 'normalize_across': SelectField( 'Normalize Across', choices=self.choicify([ 'heatmap', 'x', 'y']), default='heatmap', description=( "Color will be rendered based on a ratio " "of the cell against the sum of across this " "criteria")), 'canvas_image_rendering': SelectField( 'Rendering', choices=( ('pixelated', 'pixelated (Sharp)'), ('auto', 'auto (Smooth)'), ), 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=( "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=( "Number of step to take between ticks when " "printing the y scale")), 'bar_stacked': BetterBooleanField( 'Stacked Bars', default=False, description=""), '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=( ('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=( "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"), 'granularity': FreeFormSelectField( 'Time Granularity', default="one day", choices=self.choicify([ 'all', '5 seconds', '30 seconds', '1 minute', '5 minutes', '1 hour', '6 hour', '1 day', '7 days', ]), 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'")), 'link_length': FreeFormSelectField( 'Link Length', default="200", choices=self.choicify([ '10', '25', '50', '75', '100', '150', '200', '250', ]), description="Link length in the force layout"), 'charge': FreeFormSelectField( 'Charge', default="-500", choices=self.choicify([ '-50', '-75', '-100', '-150', '-200', '-250', '-500', '-1000', '-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=( "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([ '1 hour ago', '12 hours ago', '1 day ago', '7 days ago', '28 days ago', '90 days ago', '1 year ago' ]), 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([ '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([ '5', '10', '15', '25', '50', '75', '100', ]) ), '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=( "Defines a rolling window function to apply, works along " "with the [Periods] text box")), 'rolling_periods': IntegerField( '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=( "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', default='www.airbnb.com',), 'where': TextField( '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=( "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=( "Based on granularity, number of time periods to " "compare against")), 'compare_suffix': TextField( 'Comparison suffix', description="Suffix to apply after the percentage display"), 'x_axis_format': FreeFormSelectField( 'X axis format', default='smart_date', choices=[ ('smart_date', 'Adaptative formating'), ("%m/%d/%Y", '"%m/%d/%Y" | 01/14/2019'), ("%Y-%m-%d", '"%Y-%m-%d" | 2019-01-14'), ("%Y-%m-%d %H:%M:%S", '"%Y-%m-%d %H:%M:%S" | 2019-01-14 01:32:10'), ("%H:%M:%S", '"%H:%M:%S" | 01:32:10'), ], 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=[ ('.3s', '".3s" | 12.3k'), ('.3%', '".3%" | 1234543.210%'), ('.4r', '".4r" | 12350'), ('.3f', '".3f" | 12345.432'), ('+,', '"+," | +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([ '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([ 'sum', 'mean', 'min', 'max', 'median', 'stdev', 'var']), 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=( "The rich tooltip shows a list of all series for that" " point in time")), 'y_axis_zero': BetterBooleanField( "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=( "[integer] Number of period to compare against, " "this is relative to the granularity selected")), 'time_compare': TextField( "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=( "Description text that shows up below your Big " "Number")), }