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.
Files changed (455) hide show
  1. d3_format/__init__.py +14 -0
  2. d3_format/errors.py +19 -0
  3. d3_format/format.py +551 -0
  4. d3_format/spec.py +159 -0
  5. dataface/DATAFACE_SYNTAX.md +1135 -0
  6. dataface/__init__.py +93 -0
  7. dataface/_docs_site.py +20 -0
  8. dataface/_install_hint.py +26 -0
  9. dataface/agent_api/__init__.py +79 -0
  10. dataface/agent_api/_init_templates/__init__.py +0 -0
  11. dataface/agent_api/_init_templates/agents_dft_snippet.md +26 -0
  12. dataface/agent_api/_init_templates/dataface.yml +15 -0
  13. dataface/agent_api/_init_templates/faces-dataface.yml +144 -0
  14. dataface/agent_api/_init_templates/index.md +24 -0
  15. dataface/agent_api/_paths.py +118 -0
  16. dataface/agent_api/_project_agents_md.py +43 -0
  17. dataface/agent_api/_session_store.py +486 -0
  18. dataface/agent_api/_state.py +28 -0
  19. dataface/agent_api/chat.py +221 -0
  20. dataface/agent_api/dashboards.py +257 -0
  21. dataface/agent_api/describe.py +366 -0
  22. dataface/agent_api/describe_query.py +120 -0
  23. dataface/agent_api/docs/__init__.py +25 -0
  24. dataface/agent_api/docs/_loader.py +292 -0
  25. dataface/agent_api/docs/yaml-reference.md +2757 -0
  26. dataface/agent_api/file_refs.py +118 -0
  27. dataface/agent_api/init.py +126 -0
  28. dataface/agent_api/inspect.py +128 -0
  29. dataface/agent_api/mcp_install.py +170 -0
  30. dataface/agent_api/query.py +274 -0
  31. dataface/agent_api/schema.py +658 -0
  32. dataface/agent_api/schema_search.py +284 -0
  33. dataface/agent_api/search.py +270 -0
  34. dataface/agent_api/skill_install.py +141 -0
  35. dataface/agent_api/skill_render.py +90 -0
  36. dataface/agent_api/skills.py +293 -0
  37. dataface/agent_api/surface_aliases.yaml +128 -0
  38. dataface/agent_api/validate.py +175 -0
  39. dataface/agent_api/validate_query.py +84 -0
  40. dataface/ai/__init__.py +39 -0
  41. dataface/ai/agent.py +139 -0
  42. dataface/ai/context.py +45 -0
  43. dataface/ai/events.py +62 -0
  44. dataface/ai/external_mcp.py +610 -0
  45. dataface/ai/generate_sql.py +96 -0
  46. dataface/ai/llm.py +403 -0
  47. dataface/ai/mcp/__init__.py +51 -0
  48. dataface/ai/mcp/server.py +289 -0
  49. dataface/ai/memories.py +85 -0
  50. dataface/ai/prompts.py +177 -0
  51. dataface/ai/schema_context.py +138 -0
  52. dataface/ai/skills/before-after-comparison/SKILL.md +102 -0
  53. dataface/ai/skills/before-after-comparison/examples/before-after-comparison.yml +24 -0
  54. dataface/ai/skills/dashboard-build/SKILL.md +212 -0
  55. dataface/ai/skills/dashboard-build/examples/_smoke.yml +15 -0
  56. dataface/ai/skills/dashboard-design/SKILL.md +182 -0
  57. dataface/ai/skills/dashboard-review/SKILL.md +113 -0
  58. dataface/ai/skills/dashboard-structural-review/SKILL.md +173 -0
  59. dataface/ai/skills/dashboard-visual-review/SKILL.md +139 -0
  60. dataface/ai/skills/dataface-mcp-setup/SKILL.md +177 -0
  61. dataface/ai/skills/dataface-troubleshooting/SKILL.md +225 -0
  62. dataface/ai/skills/drill-down-link/SKILL.md +112 -0
  63. dataface/ai/skills/drill-down-link/examples/drill-down-link.yml +27 -0
  64. dataface/ai/skills/faceted-small-multiples/SKILL.md +116 -0
  65. dataface/ai/skills/faceted-small-multiples/examples/faceted-small-multiples.yml +33 -0
  66. dataface/ai/skills/filter-bar-with-variables/SKILL.md +105 -0
  67. dataface/ai/skills/filter-bar-with-variables/examples/filter-bar-with-variables.yml +49 -0
  68. dataface/ai/skills/kpi-row/SKILL.md +101 -0
  69. dataface/ai/skills/kpi-row/examples/kpi-row.yml +55 -0
  70. dataface/ai/skills/report-design/SKILL.md +184 -0
  71. dataface/ai/skills/single-metric-bignum/SKILL.md +90 -0
  72. dataface/ai/skills/single-metric-bignum/examples/single-metric-bignum.yml +27 -0
  73. dataface/ai/skills/table-heavy-ops-dashboard/SKILL.md +114 -0
  74. dataface/ai/skills/table-heavy-ops-dashboard/examples/table-heavy-ops-dashboard.yml +48 -0
  75. dataface/ai/skills/time-series-trend/SKILL.md +93 -0
  76. dataface/ai/skills/time-series-trend/examples/time-series-trend.yml +26 -0
  77. dataface/ai/skills/top-n-with-detail/SKILL.md +98 -0
  78. dataface/ai/skills/top-n-with-detail/examples/top-n-with-detail.yml +45 -0
  79. dataface/ai/skills/two-by-two-grid-overview/SKILL.md +78 -0
  80. dataface/ai/skills/two-by-two-grid-overview/examples/two-by-two-grid-overview.yml +64 -0
  81. dataface/ai/tool_schemas.py +132 -0
  82. dataface/ai/tools/__init__.py +312 -0
  83. dataface/ai/yaml_utils.py +57 -0
  84. dataface/cli/__init__.py +3 -0
  85. dataface/cli/_console.py +48 -0
  86. dataface/cli/_error_format.py +83 -0
  87. dataface/cli/_extras.py +190 -0
  88. dataface/cli/_json_output.py +8 -0
  89. dataface/cli/_parsing.py +17 -0
  90. dataface/cli/_version_info.py +56 -0
  91. dataface/cli/commands/__init__.py +3 -0
  92. dataface/cli/commands/_agent_input.py +205 -0
  93. dataface/cli/commands/_agent_server.py +115 -0
  94. dataface/cli/commands/chat.py +645 -0
  95. dataface/cli/commands/describe.py +107 -0
  96. dataface/cli/commands/docs.py +131 -0
  97. dataface/cli/commands/extension.py +179 -0
  98. dataface/cli/commands/init.py +240 -0
  99. dataface/cli/commands/inspect.py +94 -0
  100. dataface/cli/commands/mcp_init.py +167 -0
  101. dataface/cli/commands/query.py +386 -0
  102. dataface/cli/commands/render.py +291 -0
  103. dataface/cli/commands/schema.py +411 -0
  104. dataface/cli/commands/search.py +49 -0
  105. dataface/cli/commands/serve.py +114 -0
  106. dataface/cli/commands/skills.py +133 -0
  107. dataface/cli/commands/skills_init.py +161 -0
  108. dataface/cli/commands/validate.py +63 -0
  109. dataface/cli/main.py +1501 -0
  110. dataface/core/__init__.py +75 -0
  111. dataface/core/compile/__init__.py +244 -0
  112. dataface/core/compile/_jinja_helpers.py +78 -0
  113. dataface/core/compile/channel.py +222 -0
  114. dataface/core/compile/chart_focus.py +101 -0
  115. dataface/core/compile/chart_resolved.py +169 -0
  116. dataface/core/compile/chart_type_detection.py +489 -0
  117. dataface/core/compile/chart_update.py +261 -0
  118. dataface/core/compile/colors.py +64 -0
  119. dataface/core/compile/compiler.py +904 -0
  120. dataface/core/compile/config.py +823 -0
  121. dataface/core/compile/custom_chart_types.py +208 -0
  122. dataface/core/compile/data_table_attachment.py +1287 -0
  123. dataface/core/compile/detect.py +110 -0
  124. dataface/core/compile/errors.py +302 -0
  125. dataface/core/compile/filter_injection.py +319 -0
  126. dataface/core/compile/introspection.py +527 -0
  127. dataface/core/compile/jinja.py +511 -0
  128. dataface/core/compile/labels_env.py +52 -0
  129. dataface/core/compile/markdown.py +154 -0
  130. dataface/core/compile/meta.py +388 -0
  131. dataface/core/compile/models/__init__.py +0 -0
  132. dataface/core/compile/models/chart/__init__.py +0 -0
  133. dataface/core/compile/models/chart/authored.py +2137 -0
  134. dataface/core/compile/models/chart/compiled.py +398 -0
  135. dataface/core/compile/models/config.py +347 -0
  136. dataface/core/compile/models/face/__init__.py +0 -0
  137. dataface/core/compile/models/face/authored.py +659 -0
  138. dataface/core/compile/models/face/compiled.py +522 -0
  139. dataface/core/compile/models/factories.py +201 -0
  140. dataface/core/compile/models/markers.py +40 -0
  141. dataface/core/compile/models/palette.py +36 -0
  142. dataface/core/compile/models/primitives.py +415 -0
  143. dataface/core/compile/models/query/__init__.py +0 -0
  144. dataface/core/compile/models/query/authored.py +246 -0
  145. dataface/core/compile/models/query/compiled.py +710 -0
  146. dataface/core/compile/models/refs.py +137 -0
  147. dataface/core/compile/models/source.py +611 -0
  148. dataface/core/compile/models/style/__init__.py +0 -0
  149. dataface/core/compile/models/style/authored.py +481 -0
  150. dataface/core/compile/models/style/compiled.py +3399 -0
  151. dataface/core/compile/models/style/merged.py +1682 -0
  152. dataface/core/compile/models/theme.py +362 -0
  153. dataface/core/compile/models/variable/__init__.py +0 -0
  154. dataface/core/compile/models/variable/authored.py +254 -0
  155. dataface/core/compile/models/vega_lite/__init__.py +0 -0
  156. dataface/core/compile/models/vega_lite/config.py +510 -0
  157. dataface/core/compile/models/vega_lite/contracts.py +171 -0
  158. dataface/core/compile/normalize_charts.py +494 -0
  159. dataface/core/compile/normalize_layout.py +1000 -0
  160. dataface/core/compile/normalize_queries.py +297 -0
  161. dataface/core/compile/normalize_variables.py +489 -0
  162. dataface/core/compile/normalizer.py +543 -0
  163. dataface/core/compile/palette.py +1100 -0
  164. dataface/core/compile/parameterized.py +658 -0
  165. dataface/core/compile/parser.py +228 -0
  166. dataface/core/compile/schema.py +20 -0
  167. dataface/core/compile/schema_renderers/__init__.py +0 -0
  168. dataface/core/compile/schema_renderers/json_schema.py +163 -0
  169. dataface/core/compile/schema_renderers/prompt.py +152 -0
  170. dataface/core/compile/schema_renderers/vscode_schema.py +301 -0
  171. dataface/core/compile/sizing.py +2126 -0
  172. dataface/core/compile/sources.py +518 -0
  173. dataface/core/compile/sql_authoring_lint.py +56 -0
  174. dataface/core/compile/style_cascade.py +471 -0
  175. dataface/core/compile/typography.py +299 -0
  176. dataface/core/compile/validator.py +301 -0
  177. dataface/core/compile/variables.py +53 -0
  178. dataface/core/compile/vega_config.py +98 -0
  179. dataface/core/compile/vega_lite/__init__.py +6 -0
  180. dataface/core/compile/vega_lite/validation.py +95 -0
  181. dataface/core/compile/yaml_error_formatter.py +838 -0
  182. dataface/core/connections.py +38 -0
  183. dataface/core/dashboard.py +358 -0
  184. dataface/core/defaults/default_config.yml +101 -0
  185. dataface/core/defaults/palettes/categorical/category-10-dark.yml +32 -0
  186. dataface/core/defaults/palettes/categorical/category-10-light.yml +43 -0
  187. dataface/core/defaults/palettes/categorical/category-10.yml +31 -0
  188. dataface/core/defaults/palettes/categorical/category-6-tonal-blue.yml +22 -0
  189. dataface/core/defaults/palettes/categorical/category-6-tonal-brown.yml +29 -0
  190. dataface/core/defaults/palettes/categorical/category-6-tonal-green.yml +20 -0
  191. dataface/core/defaults/palettes/categorical/category-6-tonal-orange.yml +21 -0
  192. dataface/core/defaults/palettes/categorical/category-6-tonal-purple.yml +20 -0
  193. dataface/core/defaults/palettes/categorical/editorial-10-dark.yml +32 -0
  194. dataface/core/defaults/palettes/categorical/editorial-10.yml +40 -0
  195. dataface/core/defaults/palettes/categorical/hero-6.yml +17 -0
  196. dataface/core/defaults/palettes/categorical/single-blue.yml +11 -0
  197. dataface/core/defaults/palettes/categorical/tableau.yml +20 -0
  198. dataface/core/defaults/palettes/data/xkcd_colors.json +3803 -0
  199. dataface/core/defaults/palettes/diverging/blue-red.yml +25 -0
  200. dataface/core/defaults/palettes/diverging/coolwarm.yml +24 -0
  201. dataface/core/defaults/palettes/diverging/crimson-green.yml +23 -0
  202. dataface/core/defaults/palettes/diverging/orange-teal.yml +23 -0
  203. dataface/core/defaults/palettes/diverging/sunset.yml +24 -0
  204. dataface/core/defaults/palettes/scaffold/dft-creams.yml +38 -0
  205. dataface/core/defaults/palettes/scaffold/dft-grays.yml +53 -0
  206. dataface/core/defaults/palettes/sequential/amber.yml +22 -0
  207. dataface/core/defaults/palettes/sequential/blue.yml +22 -0
  208. dataface/core/defaults/palettes/sequential/brown.yml +22 -0
  209. dataface/core/defaults/palettes/sequential/gray.yml +22 -0
  210. dataface/core/defaults/palettes/sequential/green.yml +22 -0
  211. dataface/core/defaults/palettes/sequential/purple.yml +22 -0
  212. dataface/core/defaults/palettes/sequential/rust.yml +22 -0
  213. dataface/core/defaults/palettes/sequential/teal.yml +22 -0
  214. dataface/core/defaults/palettes/tone/negative.yml +32 -0
  215. dataface/core/defaults/palettes/tone/positive.yml +22 -0
  216. dataface/core/defaults/palettes/tone/warning.yml +22 -0
  217. dataface/core/defaults/themes/_base.yaml +786 -0
  218. dataface/core/defaults/themes/bi.yaml +16 -0
  219. dataface/core/defaults/themes/carbong100.yaml +41 -0
  220. dataface/core/defaults/themes/cream.yaml +122 -0
  221. dataface/core/defaults/themes/dark.yaml +40 -0
  222. dataface/core/defaults/themes/diagnostics-title-angle-extreme.yaml +9 -0
  223. dataface/core/defaults/themes/diagnostics-title-baseline-extreme.yaml +9 -0
  224. dataface/core/defaults/themes/diagnostics-title-baseline.yaml +24 -0
  225. dataface/core/defaults/themes/diagnostics-title-center.yaml +8 -0
  226. dataface/core/defaults/themes/diagnostics-title-color-extreme.yaml +24 -0
  227. dataface/core/defaults/themes/diagnostics-title-font-extreme.yaml +25 -0
  228. dataface/core/defaults/themes/diagnostics-title-left.yaml +8 -0
  229. dataface/core/defaults/themes/diagnostics-title-offset-extreme.yaml +9 -0
  230. dataface/core/defaults/themes/diagnostics-title-size-extreme.yaml +24 -0
  231. dataface/core/defaults/themes/diagnostics-title-weight-extreme.yaml +24 -0
  232. dataface/core/defaults/themes/editorial.yaml +147 -0
  233. dataface/core/defaults/themes/light.yaml +30 -0
  234. dataface/core/defaults/themes/looker.yaml +17 -0
  235. dataface/core/defaults/themes/stark.yaml +134 -0
  236. dataface/core/errors/__init__.py +67 -0
  237. dataface/core/errors/codes_compile.py +56 -0
  238. dataface/core/errors/codes_execute.py +177 -0
  239. dataface/core/errors/codes_render.py +106 -0
  240. dataface/core/errors/codes_unknown.py +15 -0
  241. dataface/core/errors/hints.py +74 -0
  242. dataface/core/errors/registry.py +42 -0
  243. dataface/core/errors/structured.py +92 -0
  244. dataface/core/execute/__init__.py +91 -0
  245. dataface/core/execute/adapters/__init__.py +49 -0
  246. dataface/core/execute/adapters/adapter_registry.py +400 -0
  247. dataface/core/execute/adapters/base.py +245 -0
  248. dataface/core/execute/adapters/csv_adapter.py +239 -0
  249. dataface/core/execute/adapters/dbt_adapter.py +283 -0
  250. dataface/core/execute/adapters/dbt_adapter_factory.py +212 -0
  251. dataface/core/execute/adapters/dbt_macro_loader.py +95 -0
  252. dataface/core/execute/adapters/dbt_utils.py +150 -0
  253. dataface/core/execute/adapters/http_adapter.py +224 -0
  254. dataface/core/execute/adapters/metricflow_adapter.py +94 -0
  255. dataface/core/execute/adapters/schema_resolver_adapter.py +144 -0
  256. dataface/core/execute/adapters/sql_adapter.py +710 -0
  257. dataface/core/execute/adapters/values_adapter.py +58 -0
  258. dataface/core/execute/batch.py +744 -0
  259. dataface/core/execute/cache_backend.py +135 -0
  260. dataface/core/execute/cache_keys.py +66 -0
  261. dataface/core/execute/dbt_jinja.py +21 -0
  262. dataface/core/execute/dialects/__init__.py +121 -0
  263. dataface/core/execute/dialects/athena.py +75 -0
  264. dataface/core/execute/dialects/base.py +302 -0
  265. dataface/core/execute/dialects/bigquery.py +38 -0
  266. dataface/core/execute/dialects/databricks.py +68 -0
  267. dataface/core/execute/dialects/duckdb.py +35 -0
  268. dataface/core/execute/dialects/mysql.py +68 -0
  269. dataface/core/execute/dialects/postgres.py +39 -0
  270. dataface/core/execute/dialects/redshift.py +12 -0
  271. dataface/core/execute/dialects/snowflake.py +51 -0
  272. dataface/core/execute/dialects/sqlserver.py +92 -0
  273. dataface/core/execute/duckdb_cache.py +712 -0
  274. dataface/core/execute/duckdb_config.py +26 -0
  275. dataface/core/execute/errors.py +213 -0
  276. dataface/core/execute/executor.py +1249 -0
  277. dataface/core/execute/parallel.py +162 -0
  278. dataface/core/execute/setup_sql.py +58 -0
  279. dataface/core/execute/source_registry.py +72 -0
  280. dataface/core/execute/source_resolver.py +255 -0
  281. dataface/core/execute/sql_guard.py +387 -0
  282. dataface/core/execute/sql_literals.py +199 -0
  283. dataface/core/fonts.py +52 -0
  284. dataface/core/inspect/__init__.py +32 -0
  285. dataface/core/inspect/cache_factory.py +98 -0
  286. dataface/core/inspect/db_types.py +162 -0
  287. dataface/core/inspect/dbt_schema.py +96 -0
  288. dataface/core/inspect/defaults.yml +37 -0
  289. dataface/core/inspect/fanout_risk.py +109 -0
  290. dataface/core/inspect/manifest_utils.py +77 -0
  291. dataface/core/inspect/partials/categorical.yml +40 -0
  292. dataface/core/inspect/partials/date.yml +40 -0
  293. dataface/core/inspect/partials/numeric.yml +55 -0
  294. dataface/core/inspect/partition_types.py +38 -0
  295. dataface/core/inspect/query_validator.py +975 -0
  296. dataface/core/inspect/renderer.py +354 -0
  297. dataface/core/inspect/resolver.py +808 -0
  298. dataface/core/inspect/search.py +461 -0
  299. dataface/core/inspect/sources/__init__.py +32 -0
  300. dataface/core/inspect/sources/dbt.py +738 -0
  301. dataface/core/inspect/sources/duckdb_utils.py +66 -0
  302. dataface/core/inspect/templates/__init__.py +1 -0
  303. dataface/core/inspect/templates/categorical_column.yml +196 -0
  304. dataface/core/inspect/templates/charts.yml +109 -0
  305. dataface/core/inspect/templates/date_column.yml +248 -0
  306. dataface/core/inspect/templates/model.yml +138 -0
  307. dataface/core/inspect/templates/numeric_column.yml +261 -0
  308. dataface/core/inspect/templates/quality.yml +80 -0
  309. dataface/core/inspect/templates/string_column.yml +263 -0
  310. dataface/core/project_roots.py +165 -0
  311. dataface/core/render/__init__.py +87 -0
  312. dataface/core/render/board_links.py +176 -0
  313. dataface/core/render/chart/__init__.py +27 -0
  314. dataface/core/render/chart/arc_attached_table.py +251 -0
  315. dataface/core/render/chart/artifacts.py +16 -0
  316. dataface/core/render/chart/callout.py +225 -0
  317. dataface/core/render/chart/decisions.py +358 -0
  318. dataface/core/render/chart/geo.py +700 -0
  319. dataface/core/render/chart/kpi.py +916 -0
  320. dataface/core/render/chart/labels.py +76 -0
  321. dataface/core/render/chart/pipeline.py +818 -0
  322. dataface/core/render/chart/presentation.py +36 -0
  323. dataface/core/render/chart/profile.py +3438 -0
  324. dataface/core/render/chart/render_single.py +347 -0
  325. dataface/core/render/chart/renderers.py +193 -0
  326. dataface/core/render/chart/rendering.py +565 -0
  327. dataface/core/render/chart/serialization.py +90 -0
  328. dataface/core/render/chart/spark.py +496 -0
  329. dataface/core/render/chart/spark_bar.py +370 -0
  330. dataface/core/render/chart/spec_builders.py +154 -0
  331. dataface/core/render/chart/standard_renderer.py +2645 -0
  332. dataface/core/render/chart/table.py +2957 -0
  333. dataface/core/render/chart/table_support.py +1452 -0
  334. dataface/core/render/chart/tick_values.py +66 -0
  335. dataface/core/render/chart/time_unit_detect.py +809 -0
  336. dataface/core/render/chart/title_overflow.py +157 -0
  337. dataface/core/render/chart/type_inference.py +122 -0
  338. dataface/core/render/chart/validation.py +99 -0
  339. dataface/core/render/chart/vega_lite.py +125 -0
  340. dataface/core/render/chart/vega_lite_types.py +268 -0
  341. dataface/core/render/chart/vl_field_maps.py +346 -0
  342. dataface/core/render/chart_interactivity.py +24 -0
  343. dataface/core/render/control_registry.py +287 -0
  344. dataface/core/render/converters/__init__.py +24 -0
  345. dataface/core/render/converters/chart.py +276 -0
  346. dataface/core/render/converters/html.py +98 -0
  347. dataface/core/render/converters/pdf.py +40 -0
  348. dataface/core/render/converters/png.py +41 -0
  349. dataface/core/render/errors.py +144 -0
  350. dataface/core/render/face_api.py +160 -0
  351. dataface/core/render/faces.py +1194 -0
  352. dataface/core/render/font_measurement.py +48 -0
  353. dataface/core/render/font_support.py +197 -0
  354. dataface/core/render/fonts/DFTSansTabular-Regular.ttf +0 -0
  355. dataface/core/render/fonts/DFTSansTabular-Regular.woff2 +0 -0
  356. dataface/core/render/fonts/DFTSerifOldstyleProportional-Regular.ttf +0 -0
  357. dataface/core/render/fonts/DFTSerifOldstyleTabular-Regular.ttf +0 -0
  358. dataface/core/render/fonts/InterVariable.ttf +0 -0
  359. dataface/core/render/fonts/InterVariable.woff2 +0 -0
  360. dataface/core/render/fonts/NOTO_COLOR_EMOJI_LICENSE.txt +93 -0
  361. dataface/core/render/fonts/NOTO_EMOJI_LICENSE.txt +93 -0
  362. dataface/core/render/fonts/NotoColorEmoji-Regular.ttf +0 -0
  363. dataface/core/render/fonts/NotoColorEmoji-Regular.woff2 +0 -0
  364. dataface/core/render/fonts/NotoEmoji-Regular.ttf +0 -0
  365. dataface/core/render/fonts/NotoEmoji-Regular.woff2 +0 -0
  366. dataface/core/render/fonts/SOURCE_CODE_PRO_LICENSE.txt +93 -0
  367. dataface/core/render/fonts/SOURCE_SERIF_4_LICENSE.txt +98 -0
  368. dataface/core/render/fonts/SourceCodePro-Regular.ttf +0 -0
  369. dataface/core/render/fonts/SourceSerif4-Regular.ttf +0 -0
  370. dataface/core/render/fonts/_emoji_font_face.css +43 -0
  371. dataface/core/render/fonts/source-serif-4-variable-latin.woff2 +0 -0
  372. dataface/core/render/format_utils.py +329 -0
  373. dataface/core/render/geo_defaults.yml +28 -0
  374. dataface/core/render/json_format.py +146 -0
  375. dataface/core/render/layout_sizing.py +865 -0
  376. dataface/core/render/layouts.py +541 -0
  377. dataface/core/render/markdown_defaults.yml +16 -0
  378. dataface/core/render/missing_vars_prompt.py +79 -0
  379. dataface/core/render/placeholder.py +389 -0
  380. dataface/core/render/render_result.py +14 -0
  381. dataface/core/render/renderer.py +467 -0
  382. dataface/core/render/script_embedding.py +16 -0
  383. dataface/core/render/svg_utils.py +212 -0
  384. dataface/core/render/template_loader.py +69 -0
  385. dataface/core/render/templates/controls/_styles.css +606 -0
  386. dataface/core/render/templates/controls/checkbox.html +16 -0
  387. dataface/core/render/templates/controls/date.html +16 -0
  388. dataface/core/render/templates/controls/number.html +19 -0
  389. dataface/core/render/templates/controls/readonly.html +9 -0
  390. dataface/core/render/templates/controls/select.html +21 -0
  391. dataface/core/render/templates/controls/slider.html +22 -0
  392. dataface/core/render/templates/controls/text.html +16 -0
  393. dataface/core/render/templates/scripts/chart_interactivity.js +191 -0
  394. dataface/core/render/templates/scripts/variables.js +976 -0
  395. dataface/core/render/templates/svg/grid_pattern.svg +3 -0
  396. dataface/core/render/templates/svg/styles.css +51 -0
  397. dataface/core/render/terminal.py +311 -0
  398. dataface/core/render/terminal_charts.py +563 -0
  399. dataface/core/render/terminal_defaults.yml +2 -0
  400. dataface/core/render/terminal_layouts.py +299 -0
  401. dataface/core/render/terminal_text.py +31 -0
  402. dataface/core/render/text/__init__.py +1 -0
  403. dataface/core/render/text/case.py +113 -0
  404. dataface/core/render/text_format.py +129 -0
  405. dataface/core/render/utils.py +106 -0
  406. dataface/core/render/variable_controls.py +946 -0
  407. dataface/core/render/variable_input_refinement.py +140 -0
  408. dataface/core/render/warnings/__init__.py +15 -0
  409. dataface/core/render/warnings/bar_color_1_to_1_with_x.py +80 -0
  410. dataface/core/render/warnings/base.py +44 -0
  411. dataface/core/render/warnings/fanout_risk.py +15 -0
  412. dataface/core/render/warnings/from_query_diagnostic.py +56 -0
  413. dataface/core/render/warnings/missing_join_predicate.py +13 -0
  414. dataface/core/render/warnings/query_parse_error.py +14 -0
  415. dataface/core/render/warnings/query_returned_zero_rows.py +42 -0
  416. dataface/core/render/warnings/reaggregation.py +14 -0
  417. dataface/core/render/warnings/registry.py +45 -0
  418. dataface/core/render/warnings/suppression.py +46 -0
  419. dataface/core/render/warnings/temporal_single_point.py +63 -0
  420. dataface/core/render/warnings/unreferenced_chart.py +15 -0
  421. dataface/core/render/warnings/y_encoding_mostly_null.py +76 -0
  422. dataface/core/render/yaml_format.py +167 -0
  423. dataface/core/resolve_face.py +195 -0
  424. dataface/core/schema/__init__.py +0 -0
  425. dataface/core/schema/guidance.py +151 -0
  426. dataface/core/scoped_paths.py +59 -0
  427. dataface/core/serve/__init__.py +14 -0
  428. dataface/core/serve/bootstrap.py +39 -0
  429. dataface/core/serve/embedded.py +57 -0
  430. dataface/core/serve/port.py +129 -0
  431. dataface/core/serve/server.py +938 -0
  432. dataface/core/serve/templates/__init__.py +0 -0
  433. dataface/core/serve/templates/directory.yml +6 -0
  434. dataface/core/serve/templates/error.html.j2 +217 -0
  435. dataface/core/utils.py +121 -0
  436. dataface/core/validate.py +64 -0
  437. dataface/integrations/__init__.py +0 -0
  438. dataface/integrations/highlighting.py +351 -0
  439. dataface/integrations/markdown.py +537 -0
  440. dataface/py.typed +0 -0
  441. dataface-0.1.2.dist-info/METADATA +375 -0
  442. dataface-0.1.2.dist-info/RECORD +455 -0
  443. dataface-0.1.2.dist-info/WHEEL +4 -0
  444. dataface-0.1.2.dist-info/entry_points.txt +2 -0
  445. dataface-0.1.2.dist-info/licenses/LICENSE +202 -0
  446. mdsvg/__init__.py +168 -0
  447. mdsvg/fonts.py +656 -0
  448. mdsvg/images.py +299 -0
  449. mdsvg/parser.py +629 -0
  450. mdsvg/playground.py +284 -0
  451. mdsvg/py.typed +2 -0
  452. mdsvg/renderer.py +1623 -0
  453. mdsvg/style.py +355 -0
  454. mdsvg/types.py +200 -0
  455. mdsvg/utils.py +86 -0
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: kpi-row
3
+ kind: pattern
4
+ description: >
5
+ Pattern for a row of 3–5 KPI cards at the top of a face. Use when showing
6
+ summary metrics (revenue, orders, conversion rate, avg order value) from a
7
+ single aggregated query. Triggers on: 'KPI row', 'summary metrics', 'top
8
+ metrics', 'hero numbers', 'scorecard'. Each KPI needs a separate single-row
9
+ query OR one query with multiple columns. Do NOT use for time-series trends
10
+ (use time-series-trend). Do NOT use for a single hero metric (use
11
+ single-metric-bignum). Do NOT use if the data has more than 1 row per KPI.
12
+ metadata:
13
+ author: fivetran
14
+ ---
15
+
16
+ # KPI Row
17
+
18
+ A horizontal row of 3–5 KPI cards placed at the top of a face. Each KPI
19
+ displays one aggregate value (a number, currency, or percent) with a label and
20
+ an optional prior-period delta in the support row.
21
+
22
+ ## When to reach for this
23
+
24
+ - The face opens with a "how are we doing overall?" summary before detail charts
25
+ - You have 3–5 numeric aggregates drawn from the same time window
26
+ - Some metrics have a prior-period comparison to show trend direction
27
+
28
+ ## When NOT to use this
29
+
30
+ - Single hero metric with a sparkline → use `single-metric-bignum`
31
+ - Data has multiple rows per KPI → aggregate to one row first
32
+ - More than 6 KPIs → split into two rows or a `two-by-two-grid-overview`
33
+
34
+ ## The pattern
35
+
36
+ ```yaml
37
+ queries:
38
+ kpis:
39
+ columns: [revenue, orders, avg_order, rev_delta, ord_delta]
40
+ values: [[248500, 1420, 175, 0.12, 0.08]]
41
+
42
+ charts:
43
+ revenue_kpi:
44
+ type: kpi
45
+ query: kpis
46
+ label: Revenue
47
+ value: revenue
48
+ format: currency_whole
49
+ support:
50
+ value: rev_delta
51
+ label: vs last period
52
+ format: percent_delta
53
+ glyph: "▲"
54
+ tone: positive
55
+
56
+ orders_kpi:
57
+ type: kpi
58
+ query: kpis
59
+ label: Orders
60
+ value: orders
61
+ support:
62
+ value: ord_delta
63
+ label: vs last period
64
+ format: percent_delta
65
+ glyph: "▲"
66
+ tone: positive
67
+
68
+ rows:
69
+ - height: 120
70
+ cols: [revenue_kpi, orders_kpi]
71
+ ```
72
+
73
+ See `examples/kpi-row.yml` for the full 3-KPI worked example.
74
+
75
+ ## Variations
76
+
77
+ | Variation | YAML knob | When |
78
+ |---|---|---|
79
+ | No delta | omit `support:` | Prior period not available |
80
+ | Currency | `format: currency_whole` | Revenue, spend, cost |
81
+ | Percent | `format: percent` | Rate, conversion, margin |
82
+ | Negative delta | `tone: negative`, `glyph: "▼"` | Unfavorable direction |
83
+ | Fixed row height | `height: 120` on the row | Prevent KPIs growing taller than charts below |
84
+
85
+ ## Common pitfalls
86
+
87
+ | Pitfall | Why it breaks | Fix |
88
+ |---|---|---|
89
+ | Query returns multiple rows | `ChartDataError` — KPI expects exactly 1 row | Add `SUM()`/`COUNT()` to aggregate to one row |
90
+ | Delta column missing from query | Render error — column not found | Include delta columns in the same query |
91
+ | `glyph: "▲"` without `tone:` | Arrow renders but no semantic color | Add `tone: positive` or `tone: negative` |
92
+ | Overloaded label | Hard to scan at a glance | ≤ 3 words per label |
93
+
94
+ ## Worked example
95
+
96
+ See `examples/kpi-row.yml` — three KPIs (Revenue, Orders, Avg Order Value)
97
+ from one inline-data query. Compiles and renders without a warehouse.
98
+
99
+ ## YAML Reference
100
+
101
+ For syntax and field details: {{ s_yaml_reference_footer }}
@@ -0,0 +1,55 @@
1
+ title: Q1 Sales Summary
2
+ description: KPI row pattern — three summary metrics from one aggregated query
3
+
4
+ queries:
5
+ kpis:
6
+ description: Single-row aggregate with current values and prior-period deltas
7
+ columns: [revenue, orders, avg_order, rev_delta, ord_delta, aov_delta]
8
+ values:
9
+ - [248500, 1420, 175, 0.12, 0.08, 0.04]
10
+
11
+ charts:
12
+ revenue_kpi:
13
+ type: kpi
14
+ query: kpis
15
+ label: Revenue
16
+ value: revenue
17
+ format: currency_whole
18
+ support:
19
+ value: rev_delta
20
+ label: vs last quarter
21
+ format: percent_delta
22
+ glyph: "▲"
23
+ tone: positive
24
+
25
+ orders_kpi:
26
+ type: kpi
27
+ query: kpis
28
+ label: Orders
29
+ value: orders
30
+ support:
31
+ value: ord_delta
32
+ label: vs last quarter
33
+ format: percent_delta
34
+ glyph: "▲"
35
+ tone: positive
36
+
37
+ aov_kpi:
38
+ type: kpi
39
+ query: kpis
40
+ label: Avg Order Value
41
+ value: avg_order
42
+ format: currency
43
+ support:
44
+ value: aov_delta
45
+ label: vs last quarter
46
+ format: percent_delta
47
+ glyph: "▲"
48
+ tone: positive
49
+
50
+ rows:
51
+ - height: 120
52
+ cols:
53
+ - revenue_kpi
54
+ - orders_kpi
55
+ - aov_kpi
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: report-design
3
+ kind: workflow
4
+ description: >
5
+ Design principles for Dataface narrative reports — data-driven documents
6
+ that answer specific questions. Use when creating analyses, investigations,
7
+ periodic reports, or when the user says 'write a report', 'analyze this
8
+ data', 'create an analysis', 'narrative report'. Covers narrative
9
+ structure, chart selection for reports, content writing, and the
10
+ executive-summary-first pattern. Do NOT use for at-a-glance monitoring
11
+ dashboards (use dashboard-design). Do NOT use for the
12
+ build-test-iterate workflow (use dashboard-build).
13
+ metadata:
14
+ author: fivetran
15
+ ---
16
+
17
+ # Report Design
18
+
19
+ Reports are narrative-driven documents that tell a story with data and answer specific questions. They are NOT dashboards.
20
+
21
+ > Implementing in YAML? Switch to `{{ s_skill_build }}` for the build-test-iterate workflow.
22
+
23
+ ## Report vs. Dashboard
24
+
25
+ | | Report | Dashboard |
26
+ |--|--------|-----------|
27
+ | **Purpose** | Answer a question, tell a story | Monitor status at a glance |
28
+ | **Text** | Extensive — narrative + recommendations | Minimal — titles and labels |
29
+ | **Charts** | Support the narrative (3-6 typically) | ARE the content |
30
+ | **Structure** | Executive summary → analysis → conclusions | KPIs → trends → breakdowns |
31
+ | **Interaction** | Read in minutes | Scan in seconds |
32
+
33
+ If the user needs at-a-glance monitoring, use the `dashboard-design` skill instead.
34
+
35
+ ## Core Principles
36
+
37
+ 1. **Answer the question first** — lead with the conclusion, not the methodology
38
+ 2. **Every chart serves the narrative** — no chart without explanatory text above it
39
+ 3. **Tell a story** — setting (context) → conflict (problem/question) → resolution (findings + recommendations)
40
+ 4. **Be specific** — "Revenue dropped 12% because Region X lost 3 key accounts" not "Revenue decreased"
41
+ 5. **Professional tone** — direct, concise, active voice
42
+
43
+ ## Metadata Requirement
44
+
45
+ When producing Dataface YAML, include `description` metadata for AI context/search:
46
+
47
+ - `queries.*.description`: query purpose
48
+ - `charts.*.description`: what evidence the chart provides
49
+ - `variables.*.description`: filter meaning (if variables are present)
50
+ - Layout object `description` fields (`rows`/`cols`/`grid.items`/`tabs.items`) where section context helps
51
+
52
+ ## Narrative Structure
53
+
54
+ Every report follows this arc:
55
+
56
+ ```
57
+ 1. EXECUTIVE SUMMARY
58
+ - 2-3 sentences with key findings
59
+ - Recommendation in bold
60
+ - The answer, upfront
61
+
62
+ 2. CONTEXT
63
+ - Time period, scope, data sources
64
+ - Why this analysis was needed
65
+
66
+ 3. ANALYSIS SECTIONS (2-4)
67
+ - Each section: one finding
68
+ - Pattern: State finding → explain significance → show chart evidence
69
+ - Transition between sections
70
+
71
+ 4. CONCLUSIONS & RECOMMENDATIONS
72
+ - Numbered, specific, actionable (who/what/when)
73
+ - Quantify expected impact when possible
74
+ ```
75
+
76
+ ## Chart Selection for Reports
77
+
78
+ Reports use fewer charts than dashboards. Each must be referenced in the narrative:
79
+
80
+ | Report Need | Chart Type | Example Narrative |
81
+ |-------------|-----------|-------------------|
82
+ | The trend that tells the story | `line` | "Revenue has been declining since March" |
83
+ | Segments that matter | `bar` | "Region X underperformed by 23%" |
84
+ | A key metric | `kpi` | "Total impact: $2.3M" |
85
+ | Detailed breakdown | `table` | "Here are the top 10 affected accounts" |
86
+ | Composition change | `area` (stacked) | "The product mix shifted toward lower-margin items" |
87
+
88
+ **Prefer:** Fewer charts with more text. Tables for evidence. KPIs for anchoring key numbers.
89
+
90
+ **Avoid:** Many KPIs in a row (dashboard pattern). Charts without narrative context. Interactive filters (reports present a specific analysis).
91
+
92
+ ## Writing Content
93
+
94
+ Use `text:` blocks in YAML for narrative text (Markdown).
95
+
96
+ **Opening each section:**
97
+ - State the finding first
98
+ - Explain why it matters
99
+ - Introduce the chart
100
+
101
+ **Closing each section:**
102
+ - Summarize the implication
103
+ - Transition to the next section
104
+
105
+ **Tone guidelines:**
106
+ - Active voice: "Revenue declined" not "A decline was observed"
107
+ - Specific numbers: "12% decline" not "significant decrease"
108
+ - No filler: Cut "It's worth noting that..." — just note it
109
+ - Honest about uncertainty where data doesn't fully support a claim
110
+
111
+ ## YAML Structure for Reports
112
+
113
+ Reports use heavier `text:` usage than dashboards:
114
+
115
+ ```yaml
116
+ title: "Q3 Revenue Analysis"
117
+ source: warehouse
118
+
119
+ queries:
120
+ revenue_trend:
121
+ sql: SELECT month, revenue FROM monthly_revenue ORDER BY month
122
+
123
+ charts:
124
+ trend:
125
+ query: revenue_trend
126
+ type: line
127
+ x: month
128
+ y: revenue
129
+
130
+ rows:
131
+ - text: |
132
+ ## Executive Summary
133
+ Q3 revenue declined 12% quarter-over-quarter, driven primarily
134
+ by the loss of three enterprise accounts in the West region.
135
+ **Recommendation: Prioritize retention program for accounts >$100K ARR.**
136
+
137
+ - text: |
138
+ ## Revenue Trend
139
+ Monthly revenue peaked in June and has declined each month since.
140
+ - trend
141
+
142
+ - text: |
143
+ ## Conclusions
144
+ 1. Launch retention program for enterprise accounts by end of month
145
+ 2. Investigate West region account manager capacity
146
+ ```
147
+
148
+ Key differences from dashboard YAML:
149
+ - Heavy `text:` blocks with narrative
150
+ - Fewer charts (3-6), more text
151
+ - No `variables:` — reports present a specific analysis
152
+ - Top-level flow follows the narrative arc
153
+
154
+ ## Quality Checklist
155
+
156
+ - [ ] Answers the question in the executive summary
157
+ - [ ] Executive summary comes first (conclusion before methodology)
158
+ - [ ] Every chart has narrative context above it
159
+ - [ ] Findings are specific (numbers, percentages, comparisons)
160
+ - [ ] Recommendations are actionable (who/what/when)
161
+ - [ ] Story flows logically section to section
162
+ - [ ] Appropriate length (3-6 analysis sections)
163
+ - [ ] Professional tone (direct, specific, active voice)
164
+ - [ ] Query/chart/variable/layout `description` metadata is filled for AI context
165
+
166
+ ## Common Mistakes
167
+
168
+ | Mistake | Fix |
169
+ |---------|-----|
170
+ | Methodology before conclusions | Lead with the answer — executives read top-down |
171
+ | Chart without narrative context | Every chart needs explanatory text above it |
172
+ | Vague findings ("revenue decreased") | Be specific: "revenue declined 12% QoQ" |
173
+ | Dashboard patterns in a report (KPI row) | Reports use narrative flow, not monitoring layout |
174
+ | Too many charts | 3-6 max — each must serve the story |
175
+ | Hedging without reason | Be confident where data supports it |
176
+
177
+ ## Rationalizations to Resist
178
+
179
+ | Excuse | Reality |
180
+ |--------|---------|
181
+ | "User wants the methodology first" | They don't. They want the answer. Methodology can follow. |
182
+ | "Adding more charts shows thoroughness" | It shows clutter. Every chart must serve the narrative. |
183
+ | "I'll add filters so they can explore" | That's a dashboard. Reports present a specific analysis. |
184
+ | "The data speaks for itself" | It never does. Interpret it — that's the report's job. |
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: single-metric-bignum
3
+ kind: pattern
4
+ description: >
5
+ Pattern for a single hero KPI displayed at large scale with a prior-period
6
+ delta in the support row. Use when one metric is the primary signal of the
7
+ face and should visually dominate. Triggers on: 'hero metric', 'big number',
8
+ 'single KPI', 'headline metric', 'north star', 'key metric', 'monthly
9
+ recurring revenue', 'MRR'. Optionally add a sparkline for trend context.
10
+ Do NOT use for three or more metrics (use kpi-row). Do NOT use when the
11
+ chart type is more important than the number (use time-series-trend).
12
+ metadata:
13
+ author: fivetran
14
+ ---
15
+
16
+ # Single-Metric Bignum
17
+
18
+ One KPI rendered at the largest readable size, backed by a one-row query,
19
+ with a support row showing the prior-period delta. The visual emphasis signals
20
+ "this is what matters most on this face."
21
+
22
+ ## When to reach for this
23
+
24
+ - A face exists to answer one question: "what is our MRR today?"
25
+ - The metric is a North Star that stakeholders check every day
26
+ - You want delta context (up X% vs last period) without a full chart
27
+
28
+ ## When NOT to use this
29
+
30
+ - Three or more equally-important metrics → `kpi-row`
31
+ - Trend history is the point, not the current value → `time-series-trend`
32
+ - Sparkline is critical (needs array data) → note this in the face description
33
+
34
+ ## The pattern
35
+
36
+ ```yaml
37
+ queries:
38
+ hero:
39
+ # Compute current and prior totals upstream (e.g. in your dbt model) and
40
+ # select two columns. Inline window math against an aggregate row tends
41
+ # to break across warehouses — keep this query trivial.
42
+ sql: |
43
+ SELECT mrr, prior_mrr, (mrr - prior_mrr) / prior_mrr AS delta
44
+ FROM mrr_summary
45
+
46
+ charts:
47
+ mrr_kpi:
48
+ type: kpi
49
+ query: hero
50
+ label: Monthly Recurring Revenue
51
+ value: mrr
52
+ format: "$,.2s" # e.g. $1.84M
53
+ support:
54
+ value: delta
55
+ label: vs last month
56
+ format: "+.1%"
57
+ glyph: "▲"
58
+ tone: positive # positive / negative / warning
59
+ ```
60
+
61
+ See `examples/single-metric-bignum.yml` for the worked example.
62
+
63
+ ## Variations
64
+
65
+ | Variation | YAML knob | When |
66
+ |---|---|---|
67
+ | Large currency | `format: "$,.2s"` | Millions/billions (e.g., `$1.84M`) |
68
+ | Plain count | `format: ",.0f"` | Raw integer |
69
+ | Percent | `format: ".1%"` | Conversion rate, margin |
70
+ | Negative delta | `tone: negative`, `glyph: "▼"` | Unfavorable direction |
71
+ | Status string | `query: { rows: [{ status: "On track" }] }` + `value: status` | Qualitative health status |
72
+ | Sparkline | add a `spark` column in the query (array type) | Requires a warehouse that supports arrays |
73
+
74
+ ## Common pitfalls
75
+
76
+ | Pitfall | Why it breaks | Fix |
77
+ |---|---|---|
78
+ | Query returns multiple rows | ChartDataError | Use `SUM()`/`MAX()` to collapse to exactly 1 row |
79
+ | `format: "$,.2s"` on a small number | Rounds aggressively (e.g. `$175` → `$0.00k`) | Use `"$,.0f"` for values under $10k |
80
+ | `tone:` without `glyph:` | Delta has semantic color but no directional icon | Add `glyph: "▲"` or `"▼"` |
81
+ | Overlong label | Label wraps awkwardly at large sizes | ≤ 4 words |
82
+
83
+ ## Worked example
84
+
85
+ See `examples/single-metric-bignum.yml` — a hero MRR KPI with a +14.2%
86
+ support row. Inline data, no warehouse required.
87
+
88
+ ## YAML Reference
89
+
90
+ For syntax and field details: {{ s_yaml_reference_footer }}
@@ -0,0 +1,27 @@
1
+ title: Monthly Recurring Revenue
2
+ description: Single-metric bignum pattern — hero KPI with prior-period delta support row
3
+
4
+ queries:
5
+ hero:
6
+ description: Current MRR and month-over-month growth rate
7
+ columns: [mrr, delta_pct]
8
+ values:
9
+ - [1840000, 0.142]
10
+
11
+ charts:
12
+ mrr_kpi:
13
+ description: Hero MRR metric with month-over-month delta
14
+ type: kpi
15
+ query: hero
16
+ label: Monthly Recurring Revenue
17
+ value: mrr
18
+ format: currency_compact
19
+ support:
20
+ value: delta_pct
21
+ label: vs last month
22
+ format: percent_delta
23
+ glyph: "▲"
24
+ tone: positive
25
+
26
+ rows:
27
+ - mrr_kpi
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: table-heavy-ops-dashboard
3
+ kind: pattern
4
+ description: >
5
+ Pattern for operational dashboards dominated by sortable tables with
6
+ per-column formatting, labels, and conditional formatting. Use when users
7
+ need to monitor status, triage incidents, or review row-level data with
8
+ currency/percent/date formatting and visual severity cues. Triggers on:
9
+ 'ops dashboard', 'incident table', 'ticket queue', 'status monitor',
10
+ 'formatted table', 'sortable list', 'operational view'. Do NOT use when a
11
+ chart communicates the pattern better (use top-n-with-detail for rankings).
12
+ Do NOT use for purely aggregated summaries (use kpi-row or
13
+ two-by-two-grid-overview).
14
+ metadata:
15
+ author: fivetran
16
+ ---
17
+
18
+ # Table-Heavy Ops Dashboard
19
+
20
+ An operational view where one or more tables dominate. Each table uses
21
+ `style.columns` to configure labels, number formats, and per-column widths.
22
+ Conditional formatting adds severity colors without changing the data.
23
+
24
+ ## When to reach for this
25
+
26
+ - Users need to scan, sort, and triage rows (incidents, tickets, pipelines)
27
+ - Columns have mixed types: currency, percent, status strings, dates
28
+ - Severity or thresholds matter (P1 red, P2 yellow, resolved grey)
29
+
30
+ ## When NOT to use this
31
+
32
+ - Data is better shown as a chart → pair with `top-n-with-detail`
33
+ - Data has only 1–5 aggregated rows → use `kpi-row` instead
34
+ - Table has hundreds of columns → subset in SQL first
35
+
36
+ ## The pattern
37
+
38
+ ```yaml
39
+ charts:
40
+ incidents:
41
+ type: table
42
+ query: open_incidents
43
+ title: Open Incidents
44
+ style:
45
+ columns:
46
+ - column: ticket_id
47
+ label: Ticket
48
+ - column: priority
49
+ label: Priority
50
+ - column: status
51
+ label: Status
52
+ - column: revenue_impact
53
+ label: Revenue Impact
54
+ format: "$,.0f"
55
+ align: right
56
+ width: 140
57
+ - column: created_at
58
+ label: Opened
59
+ format: "%Y-%m-%d"
60
+ header_overflow: wrap-two
61
+ conditional_formatting:
62
+ priority:
63
+ when:
64
+ - eq: P1
65
+ background: "#fee2e2"
66
+ font:
67
+ color: "#991b1b"
68
+ weight: "600"
69
+ - eq: P2
70
+ background: "#fef3c7"
71
+ font:
72
+ color: "#92400e"
73
+ - default: true
74
+ font:
75
+ color: "#334155"
76
+ ```
77
+
78
+ See `examples/table-heavy-ops-dashboard.yml` for the inline-data worked example.
79
+
80
+ ## Variations
81
+
82
+ | Variation | YAML knob | When |
83
+ |---|---|---|
84
+ | Currency column | `format: "$,.0f"` | Revenue, cost, spend |
85
+ | Percent column | `format: ".1%"` | Rate, margin, conversion |
86
+ | Date column | `format: "%Y-%m-%d"` | ISO dates |
87
+ | Link cell | `link: "/detail?id={{ ticket_id }}"` | Click-through to detail |
88
+ | Header wrapping | `header_overflow: wrap-two` | Long column labels |
89
+ | Spark cell | `spark: line` or `spark.type: bar-normalize` | Trend arrays or % values |
90
+ | Continuous color | `scale.background.palette` | Numeric intensity |
91
+ | Header style | `style.table.header.*` | BI or minimal header tone |
92
+
93
+ ## Common pitfalls
94
+
95
+ | Pitfall | Why it breaks | Fix |
96
+ |---|---|---|
97
+ | Too many columns | Hard to scan, horizontal scroll | Limit to 6–8 most important columns |
98
+ | Formatting strings not D3/Excel format | Wrong output | Use D3 format specs: `"$,.0f"`, `".1%"` |
99
+ | Conditional rule with no style override | `ConditionalRule` validation error | Set `background:`, `font.color`, `font.weight`, or `glyph:` on each rule |
100
+ | Sorting expectation mismatch | Default sort is query order | Add `ORDER BY priority` in SQL for triage queues |
101
+
102
+ Conditional predicates are `eq`, `ne`, `lt`, `lte`, `gt`, `gte`, `between`,
103
+ `in`, `is_null`, and `default`. Use `in:` in YAML, not `in_:`. `default: true`
104
+ must be the last rule.
105
+
106
+ ## Worked example
107
+
108
+ See `examples/table-heavy-ops-dashboard.yml` — five incident rows with
109
+ priority, status, revenue impact, and owner columns. Inline data, no warehouse
110
+ needed.
111
+
112
+ ## YAML Reference
113
+
114
+ For syntax and field details: {{ s_yaml_reference_footer }}
@@ -0,0 +1,48 @@
1
+ title: Incident Queue
2
+ description: Table-heavy ops dashboard pattern — formatted table with per-column labels and types
3
+
4
+ queries:
5
+ open_incidents:
6
+ description: Open and in-progress incidents with severity and impact
7
+ columns: [ticket_id, priority, status, assignee, revenue_impact]
8
+ values:
9
+ - ["T-001", "P1", "Open", "Alice", 15000]
10
+ - ["T-002", "P2", "In Progress", "Bob", 4500]
11
+ - ["T-003", "P1", "Open", "Carol", 22000]
12
+ - ["T-004", "P3", "Resolved", "Dave", 800]
13
+ - ["T-005", "P2", "In Progress", "Alice", 7200]
14
+
15
+ charts:
16
+ incidents_table:
17
+ description: Triageable incident list with priority, owner, and revenue impact
18
+ type: table
19
+ query: open_incidents
20
+ title: Open Incidents
21
+ style:
22
+ columns:
23
+ ticket_id:
24
+ label: Ticket
25
+ priority:
26
+ label: Priority
27
+ status:
28
+ label: Status
29
+ assignee:
30
+ label: Owner
31
+ revenue_impact:
32
+ label: Revenue Impact
33
+ format: currency_whole
34
+ conditional_formatting:
35
+ priority:
36
+ when:
37
+ - eq: P1
38
+ background: "#fee2e2"
39
+ font:
40
+ color: "#991b1b"
41
+ weight: "600"
42
+ - eq: P2
43
+ background: "#fef3c7"
44
+ font:
45
+ color: "#92400e"
46
+
47
+ rows:
48
+ - incidents_table