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,101 @@
|
|
|
1
|
+
"""Chart focus utilities.
|
|
2
|
+
|
|
3
|
+
This module provides the `focus_on_chart()` function for rendering a single
|
|
4
|
+
chart from a dataface. It transforms a compiled face to show only one chart
|
|
5
|
+
with its dependent variables.
|
|
6
|
+
|
|
7
|
+
There are two ways to focus on a chart:
|
|
8
|
+
|
|
9
|
+
1. **YAML field** (recommended for users):
|
|
10
|
+
Add `chart_focus: chart_id` to your dataface YAML.
|
|
11
|
+
The compiler will automatically apply the focus during normalization.
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
title: Sales Dataface
|
|
15
|
+
chart_focus: revenue_chart # Render only this chart
|
|
16
|
+
charts:
|
|
17
|
+
revenue_chart:
|
|
18
|
+
query: sales
|
|
19
|
+
type: bar
|
|
20
|
+
rows:
|
|
21
|
+
- revenue_chart
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Python API** (for programmatic use):
|
|
25
|
+
```python
|
|
26
|
+
from dataface.core.compile import compile, focus_on_chart
|
|
27
|
+
|
|
28
|
+
result = compile(yaml_content)
|
|
29
|
+
focused = focus_on_chart(result.face, "revenue_chart")
|
|
30
|
+
render(focused, executor, format="svg")
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Use cases:
|
|
34
|
+
- Chart editing (focus on one chart while editing)
|
|
35
|
+
- Export single chart (SVG/PNG/PDF)
|
|
36
|
+
- Embed a single chart in another page
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
from dataface.core.compile.models.face.authored import LayoutType
|
|
40
|
+
from dataface.core.compile.models.face.compiled import Face, Layout, LayoutItem
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def focus_on_chart(face: Face, chart_id: str) -> Face:
|
|
44
|
+
"""Transform a compiled face to focus on a single chart.
|
|
45
|
+
|
|
46
|
+
Creates a new face with:
|
|
47
|
+
- Only the specified chart in the layout
|
|
48
|
+
- Only the variables that chart depends on
|
|
49
|
+
- All sources and queries unchanged (they're lazy-loaded anyway)
|
|
50
|
+
|
|
51
|
+
This is called automatically when `chart_focus` is set in the YAML.
|
|
52
|
+
It can also be called directly for programmatic chart focusing.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
face: The compiled face containing the chart
|
|
56
|
+
chart_id: The ID of the chart to focus on
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
A new Face with simplified layout and filtered variables
|
|
60
|
+
|
|
61
|
+
Raises:
|
|
62
|
+
ValueError: If the chart is not found
|
|
63
|
+
|
|
64
|
+
Example:
|
|
65
|
+
>>> result = compile(yaml_content)
|
|
66
|
+
>>> focused = focus_on_chart(result.face, "revenue_chart")
|
|
67
|
+
>>> render(focused, executor, format="svg")
|
|
68
|
+
"""
|
|
69
|
+
# Find the chart - all charts (including inline) are now in face.charts
|
|
70
|
+
chart = face.charts.get(chart_id)
|
|
71
|
+
if chart is None:
|
|
72
|
+
available_charts = (
|
|
73
|
+
", ".join(sorted(face.charts.keys())) if face.charts else "none"
|
|
74
|
+
)
|
|
75
|
+
raise ValueError(
|
|
76
|
+
f"Chart '{chart_id}' not found in face. Available charts: {available_charts}"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
# Get the chart's variable dependencies
|
|
80
|
+
deps = chart.get_dependencies()
|
|
81
|
+
|
|
82
|
+
# Filter variables to only those the chart needs
|
|
83
|
+
focused_variables = {
|
|
84
|
+
name: var for name, var in face.variables.items() if name in deps.variables
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Create a simple layout with just this chart
|
|
88
|
+
chart_item = LayoutItem(type="chart", chart=chart)
|
|
89
|
+
simple_layout = Layout(type=LayoutType.ROWS, items=[chart_item])
|
|
90
|
+
|
|
91
|
+
# Create new face with focused content
|
|
92
|
+
# No title - this is a focused view, not a dataface
|
|
93
|
+
focused_face = face.model_copy(
|
|
94
|
+
update={
|
|
95
|
+
"variables": focused_variables,
|
|
96
|
+
"layout": simple_layout,
|
|
97
|
+
"title": "",
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
return focused_face
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"""Compile-time domain models for resolved chart semantics.
|
|
2
|
+
|
|
3
|
+
Stage: COMPILE
|
|
4
|
+
Purpose: Define resolved chart contracts that cross the compile→render boundary.
|
|
5
|
+
|
|
6
|
+
ResolvedChart is the canonical representation of a chart after compile-time
|
|
7
|
+
resolution — it is what render functions consume.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass, field
|
|
13
|
+
from typing import Any, Literal
|
|
14
|
+
|
|
15
|
+
from dataface.core.compile.channel import ResolvedStyleChannel
|
|
16
|
+
from dataface.core.compile.config import get_config
|
|
17
|
+
from dataface.core.compile.models.chart.authored import (
|
|
18
|
+
GEO_CHART_TYPES,
|
|
19
|
+
ChartLabels,
|
|
20
|
+
ChartTotal,
|
|
21
|
+
KpiSupportConfig,
|
|
22
|
+
)
|
|
23
|
+
from dataface.core.compile.models.chart.compiled import (
|
|
24
|
+
NON_ASPECT_RATIO_TYPES,
|
|
25
|
+
Chart,
|
|
26
|
+
)
|
|
27
|
+
from dataface.core.compile.models.primitives import FormatConfig
|
|
28
|
+
from dataface.core.compile.models.style.compiled import TableColumnDefaultsConfig
|
|
29
|
+
from dataface.core.compile.models.style.merged import (
|
|
30
|
+
MergedChartsStyle,
|
|
31
|
+
resolve_style,
|
|
32
|
+
)
|
|
33
|
+
from dataface.core.compile.models.vega_lite.contracts import Projection
|
|
34
|
+
|
|
35
|
+
FormatState = str | FormatConfig | None
|
|
36
|
+
ZeroState = bool | None
|
|
37
|
+
|
|
38
|
+
GEO_RENDERER_TYPES = GEO_CHART_TYPES
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def _renderer_family_for(chart_type: str) -> str:
|
|
42
|
+
"""Classify a resolved chart type into the renderer family that owns it."""
|
|
43
|
+
if chart_type in NON_ASPECT_RATIO_TYPES:
|
|
44
|
+
return "svg"
|
|
45
|
+
if chart_type in GEO_RENDERER_TYPES:
|
|
46
|
+
return "geo"
|
|
47
|
+
return "vega"
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def effective_color_field(chart: ResolvedChart) -> str | None:
|
|
51
|
+
"""Return the color data field from resolved_channels, or None."""
|
|
52
|
+
color_ch = chart.resolved_channels.get("color")
|
|
53
|
+
if color_ch is None or color_ch.mode == "literal":
|
|
54
|
+
return None
|
|
55
|
+
return color_ch.data_field or None
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def is_grouped_bar(chart: ResolvedChart) -> bool:
|
|
59
|
+
"""True when a bar chart defaults to grouped (side-by-side) columns.
|
|
60
|
+
|
|
61
|
+
A bar with stack=None and a color data field renders as grouped columns
|
|
62
|
+
(xOffset/yOffset) rather than VL's stacked default.
|
|
63
|
+
"""
|
|
64
|
+
return (
|
|
65
|
+
chart.chart_type == "bar"
|
|
66
|
+
and chart.stack is None
|
|
67
|
+
and effective_color_field(chart) is not None
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@dataclass(frozen=True)
|
|
72
|
+
class ChartLayer:
|
|
73
|
+
"""A single resolved layer in a layered chart.
|
|
74
|
+
|
|
75
|
+
``axis_y`` carries the typed per-layer dual-axis settings (``orient``,
|
|
76
|
+
``title``) parsed from authored YAML, normalized to a plain dict.
|
|
77
|
+
None means "no per-layer override."
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
chart_type: str
|
|
81
|
+
query_name: str | None = None
|
|
82
|
+
x: str | None = None
|
|
83
|
+
y: str | None = None
|
|
84
|
+
label: str | None = None
|
|
85
|
+
color: str | None = None
|
|
86
|
+
fill: str | None = None
|
|
87
|
+
size: str | None = None
|
|
88
|
+
shape: str | None = None
|
|
89
|
+
axis_y: dict[str, Any] | None = None
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@dataclass(frozen=True, kw_only=True)
|
|
93
|
+
class ResolvedChart:
|
|
94
|
+
"""Render-ready chart semantics with the chart-local style cascade pre-applied.
|
|
95
|
+
|
|
96
|
+
The renderer reads ``resolved_style`` for ALL style state — chart-local
|
|
97
|
+
overrides (axis, legend, scale, mark, palette, …) are baked in by
|
|
98
|
+
``build_resolved_style`` during compile. The renderer never sees the
|
|
99
|
+
original ChartStylePatch, so it cannot discriminate authored vs cascaded
|
|
100
|
+
values — and does not need to.
|
|
101
|
+
|
|
102
|
+
``orientation`` is promoted to a first-class field (was on ChartStylePatch).
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
source_chart: Chart | Any
|
|
106
|
+
id: str
|
|
107
|
+
chart_type: str
|
|
108
|
+
title: str = ""
|
|
109
|
+
subtitle: str = ""
|
|
110
|
+
description: str = ""
|
|
111
|
+
# KPI-only — text rendered above the headline value. Empty for non-KPI.
|
|
112
|
+
label: str = ""
|
|
113
|
+
x: str | None = None
|
|
114
|
+
y: str | list[str] | None = None
|
|
115
|
+
size: str | None = None
|
|
116
|
+
shape: str | None = None
|
|
117
|
+
theta: str | None = None
|
|
118
|
+
total: ChartTotal | None = None
|
|
119
|
+
labels: ChartLabels | None = None
|
|
120
|
+
format: FormatState = None
|
|
121
|
+
message: str | None = None
|
|
122
|
+
zero: ZeroState = None
|
|
123
|
+
x_label: str | None = None
|
|
124
|
+
y_label: str | None = None
|
|
125
|
+
geo: str | dict[str, Any] | None = None
|
|
126
|
+
geo_source: str | None = None
|
|
127
|
+
lookup: str | None = None
|
|
128
|
+
value: str | None = None
|
|
129
|
+
support: KpiSupportConfig | None = None
|
|
130
|
+
projection: str | Projection | None = None
|
|
131
|
+
latitude: str | None = None
|
|
132
|
+
longitude: str | None = None
|
|
133
|
+
# For point_map / bubble_map: tile-layer config dict.
|
|
134
|
+
basemap: dict[str, Any] | None = None
|
|
135
|
+
sort: Any = None
|
|
136
|
+
# stack accepts bool | Literal["zero","normalize","center"] | None
|
|
137
|
+
stack: Any = None
|
|
138
|
+
orientation: Literal["vertical", "horizontal"] = "vertical"
|
|
139
|
+
link: str | None = None
|
|
140
|
+
query_name: str | None = None
|
|
141
|
+
variable_dependencies: set[str] = field(default_factory=set)
|
|
142
|
+
resolved_style: MergedChartsStyle = field(
|
|
143
|
+
default_factory=lambda: resolve_style(get_config().style).charts
|
|
144
|
+
)
|
|
145
|
+
# Chart-local table-column configs — preserved for table rendering and
|
|
146
|
+
# gradient lowering. ChartStylePatch.columns is the authored shape; the
|
|
147
|
+
# renderer reads from here, not from source_chart.style.
|
|
148
|
+
columns: dict[str, Any] | None = None
|
|
149
|
+
# Promoted from ChartStylePatch.header_overflow so the table renderer
|
|
150
|
+
# reads it from a typed first-class field instead of reaching back into
|
|
151
|
+
# source_chart.style at emit time.
|
|
152
|
+
header_overflow: Literal["clip", "truncate", "wrap-two", "wrap"] | None = None
|
|
153
|
+
# Promoted from ChartStylePatch.column_defaults so the table renderer
|
|
154
|
+
# applies inherited defaults to query-inferred columns without reaching
|
|
155
|
+
# back into source_chart.style.
|
|
156
|
+
column_defaults: TableColumnDefaultsConfig | None = None
|
|
157
|
+
layers: tuple[ChartLayer, ...] = ()
|
|
158
|
+
resolved_channels: dict[str, ResolvedStyleChannel] = field(default_factory=dict)
|
|
159
|
+
# Only meaningful on layered charts with per-layer datasets.
|
|
160
|
+
x_domain: Literal["union", "primary"] | None = None
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def renderer_family(self) -> str:
|
|
164
|
+
return _renderer_family_for(self.chart_type)
|
|
165
|
+
|
|
166
|
+
@property
|
|
167
|
+
def query(self) -> Any:
|
|
168
|
+
"""Delegate to source_chart.query so callers need not unwrap source_chart."""
|
|
169
|
+
return getattr(self.source_chart, "query", None)
|