dataface 0.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- d3_format/__init__.py +14 -0
- d3_format/errors.py +19 -0
- d3_format/format.py +551 -0
- d3_format/spec.py +159 -0
- dataface/DATAFACE_SYNTAX.md +1135 -0
- dataface/__init__.py +93 -0
- dataface/_docs_site.py +20 -0
- dataface/_install_hint.py +26 -0
- dataface/agent_api/__init__.py +79 -0
- dataface/agent_api/_init_templates/__init__.py +0 -0
- dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
- dataface/agent_api/_init_templates/dataface.yml +15 -0
- dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
- dataface/agent_api/_init_templates/index.md +24 -0
- dataface/agent_api/_paths.py +118 -0
- dataface/agent_api/_project_agents_md.py +43 -0
- dataface/agent_api/_session_store.py +486 -0
- dataface/agent_api/_state.py +28 -0
- dataface/agent_api/chat.py +221 -0
- dataface/agent_api/dashboards.py +257 -0
- dataface/agent_api/describe.py +366 -0
- dataface/agent_api/describe_query.py +120 -0
- dataface/agent_api/docs/__init__.py +25 -0
- dataface/agent_api/docs/_loader.py +292 -0
- dataface/agent_api/docs/yaml-reference.md +2757 -0
- dataface/agent_api/file_refs.py +118 -0
- dataface/agent_api/init.py +126 -0
- dataface/agent_api/inspect.py +128 -0
- dataface/agent_api/mcp_install.py +170 -0
- dataface/agent_api/query.py +274 -0
- dataface/agent_api/schema.py +658 -0
- dataface/agent_api/schema_search.py +284 -0
- dataface/agent_api/search.py +270 -0
- dataface/agent_api/skill_install.py +141 -0
- dataface/agent_api/skill_render.py +90 -0
- dataface/agent_api/skills.py +293 -0
- dataface/agent_api/surface_aliases.yaml +128 -0
- dataface/agent_api/validate.py +175 -0
- dataface/agent_api/validate_query.py +84 -0
- dataface/ai/__init__.py +39 -0
- dataface/ai/agent.py +139 -0
- dataface/ai/context.py +45 -0
- dataface/ai/events.py +62 -0
- dataface/ai/external_mcp.py +610 -0
- dataface/ai/generate_sql.py +96 -0
- dataface/ai/llm.py +403 -0
- dataface/ai/mcp/__init__.py +51 -0
- dataface/ai/mcp/server.py +289 -0
- dataface/ai/memories.py +85 -0
- dataface/ai/prompts.py +177 -0
- dataface/ai/schema_context.py +138 -0
- dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
- dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
- dataface/ai/skills/dashboard-build/SKILL.md +212 -0
- dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
- dataface/ai/skills/dashboard-design/SKILL.md +182 -0
- dataface/ai/skills/dashboard-review/SKILL.md +113 -0
- dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
- dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
- dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
- dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
- dataface/ai/skills/drill-down-link/SKILL.md +112 -0
- dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
- dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
- dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
- dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
- dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
- dataface/ai/skills/kpi-row/SKILL.md +101 -0
- dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
- dataface/ai/skills/report-design/SKILL.md +184 -0
- dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
- dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
- dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
- dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
- dataface/ai/skills/time-series-trend/SKILL.md +93 -0
- dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
- dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
- dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
- dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
- dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
- dataface/ai/tool_schemas.py +132 -0
- dataface/ai/tools/__init__.py +312 -0
- dataface/ai/yaml_utils.py +57 -0
- dataface/cli/__init__.py +3 -0
- dataface/cli/_console.py +48 -0
- dataface/cli/_error_format.py +83 -0
- dataface/cli/_extras.py +190 -0
- dataface/cli/_json_output.py +8 -0
- dataface/cli/_parsing.py +17 -0
- dataface/cli/_version_info.py +56 -0
- dataface/cli/commands/__init__.py +3 -0
- dataface/cli/commands/_agent_input.py +205 -0
- dataface/cli/commands/_agent_server.py +115 -0
- dataface/cli/commands/chat.py +645 -0
- dataface/cli/commands/describe.py +107 -0
- dataface/cli/commands/docs.py +131 -0
- dataface/cli/commands/extension.py +179 -0
- dataface/cli/commands/init.py +240 -0
- dataface/cli/commands/inspect.py +94 -0
- dataface/cli/commands/mcp_init.py +167 -0
- dataface/cli/commands/query.py +386 -0
- dataface/cli/commands/render.py +291 -0
- dataface/cli/commands/schema.py +411 -0
- dataface/cli/commands/search.py +49 -0
- dataface/cli/commands/serve.py +114 -0
- dataface/cli/commands/skills.py +133 -0
- dataface/cli/commands/skills_init.py +161 -0
- dataface/cli/commands/validate.py +63 -0
- dataface/cli/main.py +1501 -0
- dataface/core/__init__.py +75 -0
- dataface/core/compile/__init__.py +244 -0
- dataface/core/compile/_jinja_helpers.py +78 -0
- dataface/core/compile/channel.py +222 -0
- dataface/core/compile/chart_focus.py +101 -0
- dataface/core/compile/chart_resolved.py +169 -0
- dataface/core/compile/chart_type_detection.py +489 -0
- dataface/core/compile/chart_update.py +261 -0
- dataface/core/compile/colors.py +64 -0
- dataface/core/compile/compiler.py +904 -0
- dataface/core/compile/config.py +823 -0
- dataface/core/compile/custom_chart_types.py +208 -0
- dataface/core/compile/data_table_attachment.py +1287 -0
- dataface/core/compile/detect.py +110 -0
- dataface/core/compile/errors.py +302 -0
- dataface/core/compile/filter_injection.py +319 -0
- dataface/core/compile/introspection.py +527 -0
- dataface/core/compile/jinja.py +511 -0
- dataface/core/compile/labels_env.py +52 -0
- dataface/core/compile/markdown.py +154 -0
- dataface/core/compile/meta.py +388 -0
- dataface/core/compile/models/__init__.py +0 -0
- dataface/core/compile/models/chart/__init__.py +0 -0
- dataface/core/compile/models/chart/authored.py +2137 -0
- dataface/core/compile/models/chart/compiled.py +398 -0
- dataface/core/compile/models/config.py +347 -0
- dataface/core/compile/models/face/__init__.py +0 -0
- dataface/core/compile/models/face/authored.py +659 -0
- dataface/core/compile/models/face/compiled.py +522 -0
- dataface/core/compile/models/factories.py +201 -0
- dataface/core/compile/models/markers.py +40 -0
- dataface/core/compile/models/palette.py +36 -0
- dataface/core/compile/models/primitives.py +415 -0
- dataface/core/compile/models/query/__init__.py +0 -0
- dataface/core/compile/models/query/authored.py +246 -0
- dataface/core/compile/models/query/compiled.py +710 -0
- dataface/core/compile/models/refs.py +137 -0
- dataface/core/compile/models/source.py +611 -0
- dataface/core/compile/models/style/__init__.py +0 -0
- dataface/core/compile/models/style/authored.py +481 -0
- dataface/core/compile/models/style/compiled.py +3399 -0
- dataface/core/compile/models/style/merged.py +1682 -0
- dataface/core/compile/models/theme.py +362 -0
- dataface/core/compile/models/variable/__init__.py +0 -0
- dataface/core/compile/models/variable/authored.py +254 -0
- dataface/core/compile/models/vega_lite/__init__.py +0 -0
- dataface/core/compile/models/vega_lite/config.py +510 -0
- dataface/core/compile/models/vega_lite/contracts.py +171 -0
- dataface/core/compile/normalize_charts.py +494 -0
- dataface/core/compile/normalize_layout.py +1000 -0
- dataface/core/compile/normalize_queries.py +297 -0
- dataface/core/compile/normalize_variables.py +489 -0
- dataface/core/compile/normalizer.py +543 -0
- dataface/core/compile/palette.py +1100 -0
- dataface/core/compile/parameterized.py +658 -0
- dataface/core/compile/parser.py +228 -0
- dataface/core/compile/schema.py +20 -0
- dataface/core/compile/schema_renderers/__init__.py +0 -0
- dataface/core/compile/schema_renderers/json_schema.py +163 -0
- dataface/core/compile/schema_renderers/prompt.py +152 -0
- dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
- dataface/core/compile/sizing.py +2126 -0
- dataface/core/compile/sources.py +518 -0
- dataface/core/compile/sql_authoring_lint.py +56 -0
- dataface/core/compile/style_cascade.py +471 -0
- dataface/core/compile/typography.py +299 -0
- dataface/core/compile/validator.py +301 -0
- dataface/core/compile/variables.py +53 -0
- dataface/core/compile/vega_config.py +98 -0
- dataface/core/compile/vega_lite/__init__.py +6 -0
- dataface/core/compile/vega_lite/validation.py +95 -0
- dataface/core/compile/yaml_error_formatter.py +838 -0
- dataface/core/connections.py +38 -0
- dataface/core/dashboard.py +358 -0
- dataface/core/defaults/default_config.yml +101 -0
- dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
- dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
- dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
- dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
- dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
- dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
- dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
- dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
- dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
- dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
- dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
- dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
- dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
- dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
- dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
- dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
- dataface/core/defaults/palettes/sequential/amber.yml +22 -0
- dataface/core/defaults/palettes/sequential/blue.yml +22 -0
- dataface/core/defaults/palettes/sequential/brown.yml +22 -0
- dataface/core/defaults/palettes/sequential/gray.yml +22 -0
- dataface/core/defaults/palettes/sequential/green.yml +22 -0
- dataface/core/defaults/palettes/sequential/purple.yml +22 -0
- dataface/core/defaults/palettes/sequential/rust.yml +22 -0
- dataface/core/defaults/palettes/sequential/teal.yml +22 -0
- dataface/core/defaults/palettes/tone/negative.yml +32 -0
- dataface/core/defaults/palettes/tone/positive.yml +22 -0
- dataface/core/defaults/palettes/tone/warning.yml +22 -0
- dataface/core/defaults/themes/_base.yaml +786 -0
- dataface/core/defaults/themes/bi.yaml +16 -0
- dataface/core/defaults/themes/carbong100.yaml +41 -0
- dataface/core/defaults/themes/cream.yaml +122 -0
- dataface/core/defaults/themes/dark.yaml +40 -0
- dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
- dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
- dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
- dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
- dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
- dataface/core/defaults/themes/editorial.yaml +147 -0
- dataface/core/defaults/themes/light.yaml +30 -0
- dataface/core/defaults/themes/looker.yaml +17 -0
- dataface/core/defaults/themes/stark.yaml +134 -0
- dataface/core/errors/__init__.py +67 -0
- dataface/core/errors/codes_compile.py +56 -0
- dataface/core/errors/codes_execute.py +177 -0
- dataface/core/errors/codes_render.py +106 -0
- dataface/core/errors/codes_unknown.py +15 -0
- dataface/core/errors/hints.py +74 -0
- dataface/core/errors/registry.py +42 -0
- dataface/core/errors/structured.py +92 -0
- dataface/core/execute/__init__.py +91 -0
- dataface/core/execute/adapters/__init__.py +49 -0
- dataface/core/execute/adapters/adapter_registry.py +400 -0
- dataface/core/execute/adapters/base.py +245 -0
- dataface/core/execute/adapters/csv_adapter.py +239 -0
- dataface/core/execute/adapters/dbt_adapter.py +283 -0
- dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
- dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
- dataface/core/execute/adapters/dbt_utils.py +150 -0
- dataface/core/execute/adapters/http_adapter.py +224 -0
- dataface/core/execute/adapters/metricflow_adapter.py +94 -0
- dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
- dataface/core/execute/adapters/sql_adapter.py +710 -0
- dataface/core/execute/adapters/values_adapter.py +58 -0
- dataface/core/execute/batch.py +744 -0
- dataface/core/execute/cache_backend.py +135 -0
- dataface/core/execute/cache_keys.py +66 -0
- dataface/core/execute/dbt_jinja.py +21 -0
- dataface/core/execute/dialects/__init__.py +121 -0
- dataface/core/execute/dialects/athena.py +75 -0
- dataface/core/execute/dialects/base.py +302 -0
- dataface/core/execute/dialects/bigquery.py +38 -0
- dataface/core/execute/dialects/databricks.py +68 -0
- dataface/core/execute/dialects/duckdb.py +35 -0
- dataface/core/execute/dialects/mysql.py +68 -0
- dataface/core/execute/dialects/postgres.py +39 -0
- dataface/core/execute/dialects/redshift.py +12 -0
- dataface/core/execute/dialects/snowflake.py +51 -0
- dataface/core/execute/dialects/sqlserver.py +92 -0
- dataface/core/execute/duckdb_cache.py +712 -0
- dataface/core/execute/duckdb_config.py +26 -0
- dataface/core/execute/errors.py +213 -0
- dataface/core/execute/executor.py +1249 -0
- dataface/core/execute/parallel.py +162 -0
- dataface/core/execute/setup_sql.py +58 -0
- dataface/core/execute/source_registry.py +72 -0
- dataface/core/execute/source_resolver.py +255 -0
- dataface/core/execute/sql_guard.py +387 -0
- dataface/core/execute/sql_literals.py +199 -0
- dataface/core/fonts.py +52 -0
- dataface/core/inspect/__init__.py +32 -0
- dataface/core/inspect/cache_factory.py +98 -0
- dataface/core/inspect/db_types.py +162 -0
- dataface/core/inspect/dbt_schema.py +96 -0
- dataface/core/inspect/defaults.yml +37 -0
- dataface/core/inspect/fanout_risk.py +109 -0
- dataface/core/inspect/manifest_utils.py +77 -0
- dataface/core/inspect/partials/categorical.yml +40 -0
- dataface/core/inspect/partials/date.yml +40 -0
- dataface/core/inspect/partials/numeric.yml +55 -0
- dataface/core/inspect/partition_types.py +38 -0
- dataface/core/inspect/query_validator.py +975 -0
- dataface/core/inspect/renderer.py +354 -0
- dataface/core/inspect/resolver.py +808 -0
- dataface/core/inspect/search.py +461 -0
- dataface/core/inspect/sources/__init__.py +32 -0
- dataface/core/inspect/sources/dbt.py +738 -0
- dataface/core/inspect/sources/duckdb_utils.py +66 -0
- dataface/core/inspect/templates/__init__.py +1 -0
- dataface/core/inspect/templates/categorical_column.yml +196 -0
- dataface/core/inspect/templates/charts.yml +109 -0
- dataface/core/inspect/templates/date_column.yml +248 -0
- dataface/core/inspect/templates/model.yml +138 -0
- dataface/core/inspect/templates/numeric_column.yml +261 -0
- dataface/core/inspect/templates/quality.yml +80 -0
- dataface/core/inspect/templates/string_column.yml +263 -0
- dataface/core/project_roots.py +165 -0
- dataface/core/render/__init__.py +87 -0
- dataface/core/render/board_links.py +176 -0
- dataface/core/render/chart/__init__.py +27 -0
- dataface/core/render/chart/arc_attached_table.py +251 -0
- dataface/core/render/chart/artifacts.py +16 -0
- dataface/core/render/chart/callout.py +225 -0
- dataface/core/render/chart/decisions.py +358 -0
- dataface/core/render/chart/geo.py +700 -0
- dataface/core/render/chart/kpi.py +916 -0
- dataface/core/render/chart/labels.py +76 -0
- dataface/core/render/chart/pipeline.py +818 -0
- dataface/core/render/chart/presentation.py +36 -0
- dataface/core/render/chart/profile.py +3438 -0
- dataface/core/render/chart/render_single.py +347 -0
- dataface/core/render/chart/renderers.py +193 -0
- dataface/core/render/chart/rendering.py +565 -0
- dataface/core/render/chart/serialization.py +90 -0
- dataface/core/render/chart/spark.py +496 -0
- dataface/core/render/chart/spark_bar.py +370 -0
- dataface/core/render/chart/spec_builders.py +154 -0
- dataface/core/render/chart/standard_renderer.py +2645 -0
- dataface/core/render/chart/table.py +2957 -0
- dataface/core/render/chart/table_support.py +1452 -0
- dataface/core/render/chart/tick_values.py +66 -0
- dataface/core/render/chart/time_unit_detect.py +809 -0
- dataface/core/render/chart/title_overflow.py +157 -0
- dataface/core/render/chart/type_inference.py +122 -0
- dataface/core/render/chart/validation.py +99 -0
- dataface/core/render/chart/vega_lite.py +125 -0
- dataface/core/render/chart/vega_lite_types.py +268 -0
- dataface/core/render/chart/vl_field_maps.py +346 -0
- dataface/core/render/chart_interactivity.py +24 -0
- dataface/core/render/control_registry.py +287 -0
- dataface/core/render/converters/__init__.py +24 -0
- dataface/core/render/converters/chart.py +276 -0
- dataface/core/render/converters/html.py +98 -0
- dataface/core/render/converters/pdf.py +40 -0
- dataface/core/render/converters/png.py +41 -0
- dataface/core/render/errors.py +144 -0
- dataface/core/render/face_api.py +160 -0
- dataface/core/render/faces.py +1194 -0
- dataface/core/render/font_measurement.py +48 -0
- dataface/core/render/font_support.py +197 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
- dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
- dataface/core/render/fonts/InterVariable.ttf +0 -0
- dataface/core/render/fonts/InterVariable.woff2 +0 -0
- dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
- dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
- dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
- dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
- dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
- dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
- dataface/core/render/fonts/_emoji_font_face.css +43 -0
- dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
- dataface/core/render/format_utils.py +329 -0
- dataface/core/render/geo_defaults.yml +28 -0
- dataface/core/render/json_format.py +146 -0
- dataface/core/render/layout_sizing.py +865 -0
- dataface/core/render/layouts.py +541 -0
- dataface/core/render/markdown_defaults.yml +16 -0
- dataface/core/render/missing_vars_prompt.py +79 -0
- dataface/core/render/placeholder.py +389 -0
- dataface/core/render/render_result.py +14 -0
- dataface/core/render/renderer.py +467 -0
- dataface/core/render/script_embedding.py +16 -0
- dataface/core/render/svg_utils.py +212 -0
- dataface/core/render/template_loader.py +69 -0
- dataface/core/render/templates/controls/_styles.css +606 -0
- dataface/core/render/templates/controls/checkbox.html +16 -0
- dataface/core/render/templates/controls/date.html +16 -0
- dataface/core/render/templates/controls/number.html +19 -0
- dataface/core/render/templates/controls/readonly.html +9 -0
- dataface/core/render/templates/controls/select.html +21 -0
- dataface/core/render/templates/controls/slider.html +22 -0
- dataface/core/render/templates/controls/text.html +16 -0
- dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
- dataface/core/render/templates/scripts/variables.js +976 -0
- dataface/core/render/templates/svg/grid_pattern.svg +3 -0
- dataface/core/render/templates/svg/styles.css +51 -0
- dataface/core/render/terminal.py +311 -0
- dataface/core/render/terminal_charts.py +563 -0
- dataface/core/render/terminal_defaults.yml +2 -0
- dataface/core/render/terminal_layouts.py +299 -0
- dataface/core/render/terminal_text.py +31 -0
- dataface/core/render/text/__init__.py +1 -0
- dataface/core/render/text/case.py +113 -0
- dataface/core/render/text_format.py +129 -0
- dataface/core/render/utils.py +106 -0
- dataface/core/render/variable_controls.py +946 -0
- dataface/core/render/variable_input_refinement.py +140 -0
- dataface/core/render/warnings/__init__.py +15 -0
- dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
- dataface/core/render/warnings/base.py +44 -0
- dataface/core/render/warnings/fanout_risk.py +15 -0
- dataface/core/render/warnings/from_query_diagnostic.py +56 -0
- dataface/core/render/warnings/missing_join_predicate.py +13 -0
- dataface/core/render/warnings/query_parse_error.py +14 -0
- dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
- dataface/core/render/warnings/reaggregation.py +14 -0
- dataface/core/render/warnings/registry.py +45 -0
- dataface/core/render/warnings/suppression.py +46 -0
- dataface/core/render/warnings/temporal_single_point.py +63 -0
- dataface/core/render/warnings/unreferenced_chart.py +15 -0
- dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
- dataface/core/render/yaml_format.py +167 -0
- dataface/core/resolve_face.py +195 -0
- dataface/core/schema/__init__.py +0 -0
- dataface/core/schema/guidance.py +151 -0
- dataface/core/scoped_paths.py +59 -0
- dataface/core/serve/__init__.py +14 -0
- dataface/core/serve/bootstrap.py +39 -0
- dataface/core/serve/embedded.py +57 -0
- dataface/core/serve/port.py +129 -0
- dataface/core/serve/server.py +938 -0
- dataface/core/serve/templates/__init__.py +0 -0
- dataface/core/serve/templates/directory.yml +6 -0
- dataface/core/serve/templates/error.html.j2 +217 -0
- dataface/core/utils.py +121 -0
- dataface/core/validate.py +64 -0
- dataface/integrations/__init__.py +0 -0
- dataface/integrations/highlighting.py +351 -0
- dataface/integrations/markdown.py +537 -0
- dataface/py.typed +0 -0
- dataface-0.1.2.dist-info/METADATA +375 -0
- dataface-0.1.2.dist-info/RECORD +455 -0
- dataface-0.1.2.dist-info/WHEEL +4 -0
- dataface-0.1.2.dist-info/entry_points.txt +2 -0
- dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
- mdsvg/__init__.py +168 -0
- mdsvg/fonts.py +656 -0
- mdsvg/images.py +299 -0
- mdsvg/parser.py +629 -0
- mdsvg/playground.py +284 -0
- mdsvg/py.typed +2 -0
- mdsvg/renderer.py +1623 -0
- mdsvg/style.py +355 -0
- mdsvg/types.py +200 -0
- mdsvg/utils.py +86 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dataface-troubleshooting
|
|
3
|
+
kind: workflow
|
|
4
|
+
description: >
|
|
5
|
+
Diagnose and fix Dataface dashboard errors. Use when validation, query
|
|
6
|
+
execution, query inspection, or dashboard rendering returns an error, when a
|
|
7
|
+
dashboard renders but looks wrong, when SQL fails, when YAML won't validate,
|
|
8
|
+
or when the user says 'fix this error', 'debug this dashboard', 'why is this
|
|
9
|
+
broken', 'chart shows no data'. Covers YAML validation failures, SQL
|
|
10
|
+
execution errors, rendering issues, and variable misconfiguration. Do NOT
|
|
11
|
+
use for building new dashboards from scratch (use dashboard-build). Do NOT
|
|
12
|
+
use for design quality review (use dashboard-design).
|
|
13
|
+
metadata:
|
|
14
|
+
author: fivetran
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Troubleshooting Dataface
|
|
18
|
+
|
|
19
|
+
Systematically diagnose and fix errors when building Dataface dashboards. Never guess — use the tools to confirm.
|
|
20
|
+
|
|
21
|
+
## The Iron Rule
|
|
22
|
+
|
|
23
|
+
**Never change working YAML to "fix" a problem you haven't diagnosed.** Read the error message. Reproduce it. Understand the cause. Then fix it.
|
|
24
|
+
|
|
25
|
+
## Diagnostic Workflow
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Error occurs
|
|
29
|
+
→ Read the full error message (not just the first line)
|
|
30
|
+
→ Classify: YAML error, SQL error, or rendering issue?
|
|
31
|
+
→ Apply the relevant fix pattern below
|
|
32
|
+
→ Validate again to confirm the fix
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## YAML Validation Errors
|
|
36
|
+
|
|
37
|
+
These come from `{{ s_validate_dashboard }}`. The error message tells you exactly what's wrong.
|
|
38
|
+
|
|
39
|
+
### "must have at least one layout"
|
|
40
|
+
|
|
41
|
+
Every face needs a layout element. Add `rows: []`, `cols: []`, `grid: {...}`, `tabs: {...}`, or `text: "..."`.
|
|
42
|
+
|
|
43
|
+
### "references unknown chart 'X'"
|
|
44
|
+
|
|
45
|
+
**The most common error.** Layout references *charts*, not queries. The fix:
|
|
46
|
+
|
|
47
|
+
```yaml
|
|
48
|
+
# WRONG — referencing a query name in layout
|
|
49
|
+
queries:
|
|
50
|
+
my_query:
|
|
51
|
+
sql: SELECT ...
|
|
52
|
+
rows:
|
|
53
|
+
- my_query # ❌ This is a query, not a chart
|
|
54
|
+
|
|
55
|
+
# RIGHT — create a chart that references the query
|
|
56
|
+
queries:
|
|
57
|
+
my_query:
|
|
58
|
+
sql: SELECT ...
|
|
59
|
+
charts:
|
|
60
|
+
my_chart:
|
|
61
|
+
query: my_query # Chart references query
|
|
62
|
+
type: table
|
|
63
|
+
rows:
|
|
64
|
+
- my_chart # ✅ Layout references chart
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Structure order: Queries → Charts → Layout.** You cannot skip the Charts layer.
|
|
68
|
+
|
|
69
|
+
### "missing required: query"
|
|
70
|
+
|
|
71
|
+
Charts need a `query:` field. Either reference a named query or define one inline:
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
charts:
|
|
75
|
+
my_chart:
|
|
76
|
+
query: my_query # Reference a named query
|
|
77
|
+
type: bar
|
|
78
|
+
x: category
|
|
79
|
+
y: value
|
|
80
|
+
|
|
81
|
+
# OR inline
|
|
82
|
+
my_chart:
|
|
83
|
+
query:
|
|
84
|
+
sql: SELECT ...
|
|
85
|
+
source: my_profile
|
|
86
|
+
type: bar
|
|
87
|
+
x: category
|
|
88
|
+
y: value
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### "source required" / "missing source"
|
|
92
|
+
|
|
93
|
+
SQL queries must specify which data source to use. Either set a top-level `source:` or specify per-query:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
source: my_profile # Top-level default
|
|
97
|
+
|
|
98
|
+
queries:
|
|
99
|
+
uses_default:
|
|
100
|
+
sql: SELECT ... # Inherits top-level source
|
|
101
|
+
|
|
102
|
+
explicit:
|
|
103
|
+
sql: SELECT ...
|
|
104
|
+
source: other_profile # Overrides for this query
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Variable Options Errors
|
|
108
|
+
|
|
109
|
+
The `default` field goes at the variable level, NOT inside `options`:
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
# WRONG
|
|
113
|
+
variables:
|
|
114
|
+
region:
|
|
115
|
+
input: select
|
|
116
|
+
options:
|
|
117
|
+
static: [North, South]
|
|
118
|
+
default: North # ❌
|
|
119
|
+
|
|
120
|
+
# RIGHT
|
|
121
|
+
variables:
|
|
122
|
+
region:
|
|
123
|
+
input: select
|
|
124
|
+
options:
|
|
125
|
+
static: [North, South]
|
|
126
|
+
default: North # ✅
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Use `options.static` for static values, not `options.values`.
|
|
130
|
+
|
|
131
|
+
## SQL Execution Errors
|
|
132
|
+
|
|
133
|
+
These come from `{{ s_query_face }}`, `{{ s_execute_query }}`, or `{{ s_render_dashboard }}`.
|
|
134
|
+
|
|
135
|
+
### "table does not exist"
|
|
136
|
+
|
|
137
|
+
Discover available tables first via `{{ s_schema }}` (hierarchy drill-down) or `{{ s_schema_search }}` (keyword search). For ad-hoc SQL against the information schema:
|
|
138
|
+
|
|
139
|
+
```sql
|
|
140
|
+
-- PostgreSQL / Redshift
|
|
141
|
+
SELECT table_schema, table_name FROM information_schema.tables;
|
|
142
|
+
|
|
143
|
+
-- BigQuery
|
|
144
|
+
SELECT table_name FROM `project.dataset.INFORMATION_SCHEMA.TABLES`;
|
|
145
|
+
|
|
146
|
+
-- Snowflake
|
|
147
|
+
SHOW TABLES IN SCHEMA my_schema;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### "column does not exist"
|
|
151
|
+
|
|
152
|
+
Check actual column names — don't guess. Use `{{ s_schema }}` at the table/column level for profiling details when available, or:
|
|
153
|
+
|
|
154
|
+
```sql
|
|
155
|
+
SELECT column_name, data_type
|
|
156
|
+
FROM information_schema.columns
|
|
157
|
+
WHERE table_name = 'my_table';
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Type mismatches
|
|
161
|
+
|
|
162
|
+
Common causes:
|
|
163
|
+
|
|
164
|
+
- Comparing a string column to an unquoted value: `WHERE status = active` → `WHERE status = 'active'`
|
|
165
|
+
- Date functions that differ between databases (BigQuery vs Postgres vs Snowflake)
|
|
166
|
+
- Aggregating a non-numeric column
|
|
167
|
+
|
|
168
|
+
## Rendering Issues
|
|
169
|
+
|
|
170
|
+
These show up when `{{ s_render_dashboard }}` produces unexpected visual results.
|
|
171
|
+
|
|
172
|
+
### Chart shows no data
|
|
173
|
+
|
|
174
|
+
- Verify the query returns rows: `{{ s_execute_query }}` with the same SQL
|
|
175
|
+
- Check that `x:` and `y:` column names match the query's SELECT aliases exactly (case-sensitive)
|
|
176
|
+
- Check variable defaults — a restrictive filter might exclude all data
|
|
177
|
+
|
|
178
|
+
### Chart axes are wrong
|
|
179
|
+
|
|
180
|
+
- Ensure `x:` is the categorical/time column and `y:` is the numeric column
|
|
181
|
+
- For time series, ensure the date column is sorted in the SQL: `ORDER BY date`
|
|
182
|
+
|
|
183
|
+
### Layout doesn't look right
|
|
184
|
+
|
|
185
|
+
- Check column spans: `cols: [chart_a, 2]` means chart_a spans 2 columns
|
|
186
|
+
- Charts in a `cols:` array share the row equally unless spans are specified
|
|
187
|
+
- Too many items in one `cols:` array = each gets too narrow
|
|
188
|
+
|
|
189
|
+
## Debugging Checklist
|
|
190
|
+
|
|
191
|
+
When stuck, work through this in order:
|
|
192
|
+
|
|
193
|
+
1. **Read the full error** — not just the first line. The details matter.
|
|
194
|
+
2. **Validate the YAML** — `{{ s_validate_dashboard }}` catches structural issues before SQL runs.
|
|
195
|
+
3. **Test one query at a time** — `{{ s_query_face }}` for saved face queries, `{{ s_execute_query }}` for raw SQL.
|
|
196
|
+
4. **Check column names** — `{{ s_schema }}`, `{{ s_schema_search }}`, or `{{ s_describe_query }}` to verify.
|
|
197
|
+
5. **Simplify** — Remove charts until you find the one that's broken.
|
|
198
|
+
6. **Re-render** — Confirm the fix visually.
|
|
199
|
+
7. **Restore metadata** — Ensure `description` fields remain populated for queries/charts/variables/layout sections.
|
|
200
|
+
|
|
201
|
+
## Common Mistakes
|
|
202
|
+
|
|
203
|
+
| Mistake | Fix |
|
|
204
|
+
|---------|-----|
|
|
205
|
+
| Changing YAML randomly until errors stop | Read the error. Diagnose first, then fix. |
|
|
206
|
+
| Referencing queries in layout | Create a chart that references the query. Layout references charts. |
|
|
207
|
+
| Assuming column names | Use `{{ s_schema }}`, `{{ s_schema_search }}`, or `{{ s_execute_query }}` to verify |
|
|
208
|
+
| Wrong `source` | Call `{{ s_schema }}` (no args) to see available sources |
|
|
209
|
+
| Variable `default` inside `options` | `default` goes at the variable level, not nested inside `options` |
|
|
210
|
+
|
|
211
|
+
## Rationalizations to Resist
|
|
212
|
+
|
|
213
|
+
| Excuse | Reality |
|
|
214
|
+
|--------|---------|
|
|
215
|
+
| "The error message is confusing, I'll try something else" | Read it again carefully — it tells you what's wrong. |
|
|
216
|
+
| "I'll just change the chart type, maybe that'll fix it" | Chart type doesn't fix SQL or YAML structure errors. |
|
|
217
|
+
| "It works for similar dashboards" | This data source may have different column names. Verify. |
|
|
218
|
+
| "I'll skip validation and just render" | Validation is instant and catches errors before the slow SQL runs. |
|
|
219
|
+
|
|
220
|
+
## Red Flags — STOP
|
|
221
|
+
|
|
222
|
+
- About to make a change without understanding the error message
|
|
223
|
+
- Changing multiple things at once (change one thing, validate, repeat)
|
|
224
|
+
- Guessing column names instead of checking the schema
|
|
225
|
+
- The same error keeps coming back (you're not fixing the root cause)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: drill-down-link
|
|
3
|
+
kind: pattern
|
|
4
|
+
description: >
|
|
5
|
+
Pattern for cross-face navigation: a chart or table whose elements link to a
|
|
6
|
+
detail face, passing a row value as a URL path segment or query parameter.
|
|
7
|
+
Use when users need to click from a summary view into a per-item detail face.
|
|
8
|
+
Triggers on: 'drill down', 'click through', 'detail page', 'per-item face',
|
|
9
|
+
'link to detail', 'cross-face navigation'. Do NOT use for filtering within
|
|
10
|
+
the same face (use filter-bar-with-variables). Do NOT use for tabs within a
|
|
11
|
+
single face (use the tabs layout).
|
|
12
|
+
metadata:
|
|
13
|
+
author: fivetran
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Drill-Down Link
|
|
17
|
+
|
|
18
|
+
Two faces wired together: a *source* face whose chart elements are clickable
|
|
19
|
+
links, and a *target* face that receives the clicked value as a URL parameter
|
|
20
|
+
and filters its queries accordingly.
|
|
21
|
+
|
|
22
|
+
The source uses `link:` on a chart (channel placeholder substitution) or
|
|
23
|
+
`link:` on a table column (per-row URL). The target reads the URL parameter
|
|
24
|
+
via a `variables:` entry with `input: text`.
|
|
25
|
+
|
|
26
|
+
## When to reach for this
|
|
27
|
+
|
|
28
|
+
- Users need to click from a ranking or list into a per-item detail view
|
|
29
|
+
- The detail content is rich enough to justify its own face (not just a tooltip)
|
|
30
|
+
- The linking dimension is a natural identifier (region, product, customer ID)
|
|
31
|
+
|
|
32
|
+
## When NOT to use this
|
|
33
|
+
|
|
34
|
+
- Filtering within the same face → `filter-bar-with-variables`
|
|
35
|
+
- Show/hide sections → tabs layout
|
|
36
|
+
- Simple tooltip detail → hover tooltips work automatically, no extra YAML
|
|
37
|
+
|
|
38
|
+
## The pattern — source face
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
charts:
|
|
42
|
+
region_bars:
|
|
43
|
+
type: bar
|
|
44
|
+
query: revenue_by_region
|
|
45
|
+
x: region
|
|
46
|
+
y: revenue
|
|
47
|
+
title: Revenue by Region — click to drill
|
|
48
|
+
link: "/region-detail?region={{ x }}" # {{ x }} = clicked bar's region
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For tables, use `link:` at the chart root (applies to all cells) or per-column
|
|
52
|
+
in `style.columns` (overrides the root for that column):
|
|
53
|
+
|
|
54
|
+
```yaml
|
|
55
|
+
charts:
|
|
56
|
+
customers_table:
|
|
57
|
+
type: table
|
|
58
|
+
query: top_customers
|
|
59
|
+
link: "/customer-detail?id={{ customer_id }}" # default for all cells
|
|
60
|
+
style:
|
|
61
|
+
columns:
|
|
62
|
+
customer_name:
|
|
63
|
+
label: Customer
|
|
64
|
+
# inherits chart-root link
|
|
65
|
+
status:
|
|
66
|
+
label: Status
|
|
67
|
+
link: "/status-detail?status={{ status }}" # overrides root for this column
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## The pattern — target face
|
|
71
|
+
|
|
72
|
+
```yaml
|
|
73
|
+
variables:
|
|
74
|
+
region:
|
|
75
|
+
input: text # populated from ?region= query param
|
|
76
|
+
default: "North" # fallback when opened standalone
|
|
77
|
+
|
|
78
|
+
queries:
|
|
79
|
+
region_detail:
|
|
80
|
+
sql: SELECT * FROM orders WHERE {{ filter('region', region) }}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
See `examples/drill-down-link.yml` for the source face worked example.
|
|
84
|
+
|
|
85
|
+
## Variations
|
|
86
|
+
|
|
87
|
+
| Variation | YAML knob | When |
|
|
88
|
+
|---|---|---|
|
|
89
|
+
| Path segment | `link: "/detail/{{ x }}"` | Clean URLs, server-side routing |
|
|
90
|
+
| Query param | `link: "/detail?id={{ x }}"` | Multiple params, easier debugging |
|
|
91
|
+
| Table cell link | `link:` on column in `style.columns` | Per-row links in a table |
|
|
92
|
+
| In-page filter | `link: "?var={{ x }}"` | Update a variable without navigation |
|
|
93
|
+
| External link | `link: "https://external.com/{{ x }}"` | Link out to another system |
|
|
94
|
+
|
|
95
|
+
## Common pitfalls
|
|
96
|
+
|
|
97
|
+
| Pitfall | Why it breaks | Fix |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| Using `{{ color }}` placeholder on a chart with no color channel | Compile error: `link template references channel 'color' but chart has no 'color' encoding assigned` | Use only the chart's mapped channels: `x`, `y`, `color`, `theta` |
|
|
100
|
+
| Target face has no matching variable | Parameter ignored, shows all data | Add a `variables:` entry on the target with the same name |
|
|
101
|
+
| Using `href:` instead of `link:` | Compile error: `'href:' was renamed to 'link:'` | Use `link:` on all chart types |
|
|
102
|
+
|
|
103
|
+
## Worked example
|
|
104
|
+
|
|
105
|
+
See `examples/drill-down-link.yml` — the source face: a bar chart with
|
|
106
|
+
`link:` that passes the clicked region to a detail face. Inline data, no
|
|
107
|
+
warehouse required. The target face is documented in the body above — author
|
|
108
|
+
it as a separate YAML file in the same `faces/` directory.
|
|
109
|
+
|
|
110
|
+
## YAML Reference
|
|
111
|
+
|
|
112
|
+
For syntax and field details: {{ s_yaml_reference_footer }}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
title: Revenue by Region
|
|
2
|
+
description: >
|
|
3
|
+
Drill-down link pattern — source face. Each bar links to a per-region detail
|
|
4
|
+
face via link. The {{ x }} placeholder is replaced with the clicked region.
|
|
5
|
+
|
|
6
|
+
queries:
|
|
7
|
+
by_region:
|
|
8
|
+
description: Revenue totals by region, pre-ranked
|
|
9
|
+
columns: [region, revenue, orders]
|
|
10
|
+
values:
|
|
11
|
+
- [North, 85000, 320]
|
|
12
|
+
- [East, 71000, 268]
|
|
13
|
+
- [South, 62000, 241]
|
|
14
|
+
- [West, 54000, 198]
|
|
15
|
+
|
|
16
|
+
charts:
|
|
17
|
+
region_bars:
|
|
18
|
+
description: Clickable bar chart — each bar links to the region detail face
|
|
19
|
+
type: bar
|
|
20
|
+
query: by_region
|
|
21
|
+
x: region
|
|
22
|
+
y: revenue
|
|
23
|
+
title: Revenue by Region — click to drill
|
|
24
|
+
link: "/region-detail?region={{ x }}"
|
|
25
|
+
|
|
26
|
+
rows:
|
|
27
|
+
- region_bars
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: faceted-small-multiples
|
|
3
|
+
kind: pattern
|
|
4
|
+
description: >
|
|
5
|
+
Pattern for showing the same metric sliced by a categorical dimension —
|
|
6
|
+
either as one multi-series chart (color encoding) or as N side-by-side
|
|
7
|
+
charts (manual small multiples). Use when comparing a trend or distribution
|
|
8
|
+
across segments. Triggers on: 'by segment', 'by region', 'by category',
|
|
9
|
+
'small multiples', 'faceted', 'breakdown', 'compare across groups',
|
|
10
|
+
'stacked area'. Use color encoding for ≤5 segments in one chart; use manual
|
|
11
|
+
multiples when segments need separate y-scales or spatial separation. Do NOT
|
|
12
|
+
use for aggregate totals (use kpi-row or two-by-two-grid-overview). Do NOT
|
|
13
|
+
use for two-series comparison (use before-after-comparison).
|
|
14
|
+
metadata:
|
|
15
|
+
author: fivetran
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# Faceted Small Multiples
|
|
19
|
+
|
|
20
|
+
Two approaches for showing the same metric broken down by a category:
|
|
21
|
+
|
|
22
|
+
**Option A — Color encoding (one chart):** Add `color: segment_col` to any
|
|
23
|
+
chart. Dataface renders one series per segment value, with a legend. Best for
|
|
24
|
+
≤5 segments, same y-scale.
|
|
25
|
+
|
|
26
|
+
**Option B — Manual multiples (side-by-side charts):** Author N separate
|
|
27
|
+
charts — one per segment — and arrange them in `cols:` or a `grid:`. Best
|
|
28
|
+
when segments need independent y-scales or when you want spatial separation.
|
|
29
|
+
|
|
30
|
+
## When to reach for this
|
|
31
|
+
|
|
32
|
+
- "Show me revenue by region across months" (time × segment)
|
|
33
|
+
- "Compare the distribution of orders across product categories" (category × count)
|
|
34
|
+
- Segments are the primary lens; aggregate total is secondary
|
|
35
|
+
|
|
36
|
+
## When NOT to use this
|
|
37
|
+
|
|
38
|
+
- Two series only → `before-after-comparison`
|
|
39
|
+
- Composition (parts add to 100%) → stacked area (`type: area` + `color:`)
|
|
40
|
+
- More than 8 segments → group the long tail into "Other" in SQL
|
|
41
|
+
|
|
42
|
+
## The pattern — Option A (color encoding)
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
queries:
|
|
46
|
+
revenue_by_segment:
|
|
47
|
+
sql: |
|
|
48
|
+
SELECT month, region, SUM(revenue) AS revenue
|
|
49
|
+
FROM orders
|
|
50
|
+
GROUP BY month, region
|
|
51
|
+
ORDER BY month, region
|
|
52
|
+
|
|
53
|
+
charts:
|
|
54
|
+
region_trend:
|
|
55
|
+
type: line
|
|
56
|
+
query: revenue_by_segment
|
|
57
|
+
x: month
|
|
58
|
+
y: revenue
|
|
59
|
+
color: region # one series per region value
|
|
60
|
+
title: Revenue by Region
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## The pattern — Option B (manual multiples)
|
|
64
|
+
|
|
65
|
+
```yaml
|
|
66
|
+
queries:
|
|
67
|
+
east_data:
|
|
68
|
+
sql: SELECT month, SUM(revenue) AS revenue FROM orders WHERE region='East' GROUP BY 1
|
|
69
|
+
west_data:
|
|
70
|
+
sql: SELECT month, SUM(revenue) AS revenue FROM orders WHERE region='West' GROUP BY 1
|
|
71
|
+
|
|
72
|
+
charts:
|
|
73
|
+
east_chart:
|
|
74
|
+
type: line
|
|
75
|
+
query: east_data
|
|
76
|
+
x: month
|
|
77
|
+
y: revenue
|
|
78
|
+
title: East
|
|
79
|
+
west_chart:
|
|
80
|
+
type: line
|
|
81
|
+
query: west_data
|
|
82
|
+
x: month
|
|
83
|
+
y: revenue
|
|
84
|
+
title: West
|
|
85
|
+
|
|
86
|
+
rows:
|
|
87
|
+
- cols: [east_chart, west_chart] # same visual encoding, side by side
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
See `examples/faceted-small-multiples.yml` for the worked example (Option A).
|
|
91
|
+
|
|
92
|
+
## Variations
|
|
93
|
+
|
|
94
|
+
| Variation | YAML knob | When |
|
|
95
|
+
|---|---|---|
|
|
96
|
+
| Stacked area | `type: area` + `color:` | Show composition — parts of a whole over time |
|
|
97
|
+
| Side-by-side bar | `type: bar` + `color:` | Grouped bars per category |
|
|
98
|
+
| Manual N-up | N charts in a `cols:` row | Independent scales per segment |
|
|
99
|
+
| Grid layout | `grid: columns: 24, col_span: 8` | 3+ multiples in a row |
|
|
100
|
+
|
|
101
|
+
## Common pitfalls
|
|
102
|
+
|
|
103
|
+
| Pitfall | Why it breaks | Fix |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| Too many color segments (>8) | Legend overflows, colors repeat | Limit to top-N in SQL + "Other" bucket |
|
|
106
|
+
| Stacked area with `color:` but no GROUP BY | Wrong aggregation, chart errors | Ensure one row per (x, color) combination |
|
|
107
|
+
| Manual multiples with different y-scales | Misleading comparisons | Use same y-axis domain, or make the difference visible in chart titles |
|
|
108
|
+
|
|
109
|
+
## Worked example
|
|
110
|
+
|
|
111
|
+
See `examples/faceted-small-multiples.yml` — monthly signups by channel using
|
|
112
|
+
color encoding (Option A). Inline data, no warehouse required.
|
|
113
|
+
|
|
114
|
+
## YAML Reference
|
|
115
|
+
|
|
116
|
+
For syntax and field details: {{ s_yaml_reference_footer }}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
title: Signups by Channel
|
|
2
|
+
description: Faceted small multiples pattern — one series per segment via color encoding
|
|
3
|
+
|
|
4
|
+
queries:
|
|
5
|
+
signups_by_channel:
|
|
6
|
+
description: Monthly signups broken down by acquisition channel
|
|
7
|
+
columns: [month, channel, signups]
|
|
8
|
+
values:
|
|
9
|
+
- ["2026-01-01", Organic, 90]
|
|
10
|
+
- ["2026-01-01", Paid, 40]
|
|
11
|
+
- ["2026-01-01", Partner, 18]
|
|
12
|
+
- ["2026-02-01", Organic, 105]
|
|
13
|
+
- ["2026-02-01", Paid, 48]
|
|
14
|
+
- ["2026-02-01", Partner, 22]
|
|
15
|
+
- ["2026-03-01", Organic, 118]
|
|
16
|
+
- ["2026-03-01", Paid, 52]
|
|
17
|
+
- ["2026-03-01", Partner, 29]
|
|
18
|
+
- ["2026-04-01", Organic, 134]
|
|
19
|
+
- ["2026-04-01", Paid, 58]
|
|
20
|
+
- ["2026-04-01", Partner, 34]
|
|
21
|
+
|
|
22
|
+
charts:
|
|
23
|
+
signups_trend:
|
|
24
|
+
description: Signup trend faceted by channel — one colored series per channel
|
|
25
|
+
type: area
|
|
26
|
+
query: signups_by_channel
|
|
27
|
+
x: month
|
|
28
|
+
y: signups
|
|
29
|
+
color: channel
|
|
30
|
+
title: Monthly Signups by Channel
|
|
31
|
+
|
|
32
|
+
rows:
|
|
33
|
+
- signups_trend
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: filter-bar-with-variables
|
|
3
|
+
kind: pattern
|
|
4
|
+
description: >
|
|
5
|
+
Pattern for interactive dashboards with dropdown/date/numeric filter controls
|
|
6
|
+
wired into queries via Jinja variable substitution. Use when users need to
|
|
7
|
+
slice data by dimension, date range, or threshold without editing YAML.
|
|
8
|
+
Triggers on: 'filter', 'dropdown', 'date range', 'interactive', 'variable',
|
|
9
|
+
'select', 'picker', 'parameterized'. Variables render as UI controls above
|
|
10
|
+
the charts. Do NOT use for drill-through navigation between faces (use
|
|
11
|
+
drill-down-link). Do NOT use when all data fits on one chart without
|
|
12
|
+
filtering.
|
|
13
|
+
metadata:
|
|
14
|
+
author: fivetran
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Filter Bar with Variables
|
|
18
|
+
|
|
19
|
+
Variables add interactive controls to a face. Each `variables:` entry renders
|
|
20
|
+
a UI widget (select, date picker, number slider). Queries reference variables
|
|
21
|
+
with `{{ var_name }}` Jinja placeholders — Dataface substitutes the current
|
|
22
|
+
widget value at query time.
|
|
23
|
+
|
|
24
|
+
## When to reach for this
|
|
25
|
+
|
|
26
|
+
- Users need to slice the data by region, category, time window, or threshold
|
|
27
|
+
- The same face serves multiple audiences who want different views
|
|
28
|
+
- Query results would be too large without a default filter
|
|
29
|
+
|
|
30
|
+
## When NOT to use this
|
|
31
|
+
|
|
32
|
+
- Cross-face navigation → `drill-down-link`
|
|
33
|
+
- Static content, no user controls needed
|
|
34
|
+
|
|
35
|
+
## The pattern
|
|
36
|
+
|
|
37
|
+
```yaml
|
|
38
|
+
variables:
|
|
39
|
+
region:
|
|
40
|
+
label: Region
|
|
41
|
+
description: Filter all charts to this region
|
|
42
|
+
options:
|
|
43
|
+
static: [North, South, East, West]
|
|
44
|
+
|
|
45
|
+
date_range:
|
|
46
|
+
label: Date Range
|
|
47
|
+
input: daterange
|
|
48
|
+
column: orders.order_date
|
|
49
|
+
default: ["2025-01-01", "2025-12-31"]
|
|
50
|
+
|
|
51
|
+
queries:
|
|
52
|
+
monthly:
|
|
53
|
+
description: Monthly revenue filtered by region and date window
|
|
54
|
+
sql: |
|
|
55
|
+
SELECT DATE_TRUNC('month', order_date) AS month,
|
|
56
|
+
SUM(revenue) AS revenue
|
|
57
|
+
FROM orders
|
|
58
|
+
WHERE {{ filter('region', region) }}
|
|
59
|
+
AND {{ filter_date_range('order_date', date_range) }}
|
|
60
|
+
GROUP BY 1
|
|
61
|
+
ORDER BY 1
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
See `examples/filter-bar-with-variables.yml` for the worked example.
|
|
65
|
+
|
|
66
|
+
## Variable input types
|
|
67
|
+
|
|
68
|
+
| Input | YAML | Widget |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| Dropdown (static list) | `options: static: [A, B, C]` | Select element |
|
|
71
|
+
| Date range | `input: daterange` | Two date pickers |
|
|
72
|
+
| Single date | `input: date` | One date picker |
|
|
73
|
+
| Numeric input | `input: number` | Free numeric entry |
|
|
74
|
+
| Range slider | `input: slider` (or `range`), `min:`, `max:`, `step:` | Bounded numeric range |
|
|
75
|
+
| Free text | `input: text` | Text input |
|
|
76
|
+
|
|
77
|
+
## Filtering helpers in SQL
|
|
78
|
+
|
|
79
|
+
| Helper | Use for |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `{{ filter('col', var) }}` | Single-value dropdown — emits `col = 'val'` or `1=1` when unset |
|
|
82
|
+
| `{{ filter_date_range('col', date_range) }}` | Date range variable |
|
|
83
|
+
| `{{ filter('col', var, '>=') }}` | Numeric threshold with operator |
|
|
84
|
+
|
|
85
|
+
Always use these helpers — never write `WHERE col = '{{ var }}'` directly. The
|
|
86
|
+
helpers are null-safe (emit `1=1` when the variable is unset) and handle quoting
|
|
87
|
+
correctly.
|
|
88
|
+
|
|
89
|
+
## Common pitfalls
|
|
90
|
+
|
|
91
|
+
| Pitfall | Why it breaks | Fix |
|
|
92
|
+
|---|---|---|
|
|
93
|
+
| Variable name contains a hyphen | Jinja can't parse `{{ my-var }}` | Use underscores: `my_var` |
|
|
94
|
+
| No `default:` on a required variable | Blank widget, query may fail | Add a sensible `default:` value |
|
|
95
|
+
| Scoping variables globally but only one chart needs them | Re-queries all charts | Nest variables + queries + charts in a nested board |
|
|
96
|
+
|
|
97
|
+
## Worked example
|
|
98
|
+
|
|
99
|
+
See `examples/filter-bar-with-variables.yml` — region dropdown and date
|
|
100
|
+
pickers wired to a sales query. Uses inline data to compile without a
|
|
101
|
+
warehouse; swap `columns/values` for `sql:` when connecting to a live source.
|
|
102
|
+
|
|
103
|
+
## YAML Reference
|
|
104
|
+
|
|
105
|
+
For syntax and field details: {{ s_yaml_reference_footer }}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
title: Sales Dashboard with Filters
|
|
2
|
+
description: |
|
|
3
|
+
Filter-bar pattern — region dropdown and date controls wired to queries. Inline data used here; in production, replace with sql: + WHERE {{ filter(...) }}.
|
|
4
|
+
|
|
5
|
+
variables:
|
|
6
|
+
region:
|
|
7
|
+
label: Region
|
|
8
|
+
description: Filter to a single region, or leave blank for all
|
|
9
|
+
options:
|
|
10
|
+
static:
|
|
11
|
+
- North
|
|
12
|
+
- South
|
|
13
|
+
- East
|
|
14
|
+
- West
|
|
15
|
+
start_date:
|
|
16
|
+
label: Start Date
|
|
17
|
+
input: date
|
|
18
|
+
default: "2025-07-01"
|
|
19
|
+
end_date:
|
|
20
|
+
label: End Date
|
|
21
|
+
input: date
|
|
22
|
+
default: "2025-12-31"
|
|
23
|
+
queries:
|
|
24
|
+
monthly_revenue:
|
|
25
|
+
description: Monthly revenue — replace with sql and {{ filter }} for a live source
|
|
26
|
+
columns:
|
|
27
|
+
- month
|
|
28
|
+
- region
|
|
29
|
+
- revenue
|
|
30
|
+
values:
|
|
31
|
+
- ['2025-07-01', 'North', 32000]
|
|
32
|
+
- ['2025-08-01', 'North', 35000]
|
|
33
|
+
- ['2025-09-01', 'North', 38000]
|
|
34
|
+
- ['2025-07-01', 'South', 21000]
|
|
35
|
+
- ['2025-08-01', 'South', 23000]
|
|
36
|
+
- ['2025-09-01', 'South', 26000]
|
|
37
|
+
charts:
|
|
38
|
+
revenue_by_month:
|
|
39
|
+
description: Monthly revenue trend by region
|
|
40
|
+
type: bar
|
|
41
|
+
query: monthly_revenue
|
|
42
|
+
x: month
|
|
43
|
+
y: revenue
|
|
44
|
+
color: region
|
|
45
|
+
title: Monthly Revenue by Region
|
|
46
|
+
style:
|
|
47
|
+
stack: zero
|
|
48
|
+
rows:
|
|
49
|
+
- revenue_by_month
|