@graphenedata/cli 0.0.4 → 0.0.6

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 (74) hide show
  1. package/cli.ts +25 -55
  2. package/dist/cli/cli.js +1194 -435
  3. package/dist/docs/graphene.md +1074 -166
  4. package/dist/ui/component-utilities/echarts.js +3 -1
  5. package/dist/ui/component-utilities/inputUtils.ts +11 -0
  6. package/dist/ui/component-utilities/themeStores.ts +35 -7
  7. package/dist/ui/components/Area.svelte +6 -3
  8. package/dist/ui/components/AreaChart.svelte +3 -1
  9. package/dist/ui/components/Bar.svelte +14 -8
  10. package/dist/ui/components/BarChart.svelte +3 -1
  11. package/dist/ui/components/BigValue.svelte +1 -1
  12. package/dist/ui/components/Chart.svelte +57 -101
  13. package/dist/ui/components/Column.svelte +2 -0
  14. package/dist/ui/components/ECharts.svelte +2 -0
  15. package/dist/ui/components/Line.svelte +8 -5
  16. package/dist/ui/components/LineChart.svelte +3 -2
  17. package/dist/ui/components/PieChart.svelte +1 -1
  18. package/dist/ui/components/QueryLoad.svelte +5 -6
  19. package/dist/ui/components/TableRow.svelte +1 -1
  20. package/dist/ui/components/_Table.svelte +2 -0
  21. package/dist/ui/internal/queryEngine.ts +39 -15
  22. package/dist/ui/internal/telemetry.ts +5 -3
  23. package/dist/ui/web.js +28 -12
  24. package/package.json +3 -2
  25. package/dist/docs/data_apps/components/charts/annotations.md +0 -673
  26. package/dist/docs/data_apps/components/charts/area-chart.md +0 -202
  27. package/dist/docs/data_apps/components/charts/bar-chart.md +0 -317
  28. package/dist/docs/data_apps/components/charts/box-plot.md +0 -190
  29. package/dist/docs/data_apps/components/charts/bubble-chart.md +0 -151
  30. package/dist/docs/data_apps/components/charts/calendar-heatmap.md +0 -112
  31. package/dist/docs/data_apps/components/charts/custom-echarts.md +0 -308
  32. package/dist/docs/data_apps/components/charts/echarts-options.md +0 -217
  33. package/dist/docs/data_apps/components/charts/funnel-chart.md +0 -106
  34. package/dist/docs/data_apps/components/charts/heatmap.md +0 -180
  35. package/dist/docs/data_apps/components/charts/histogram.md +0 -107
  36. package/dist/docs/data_apps/components/charts/line-chart.md +0 -265
  37. package/dist/docs/data_apps/components/charts/mixed-type-charts.md +0 -240
  38. package/dist/docs/data_apps/components/charts/sankey-diagram.md +0 -301
  39. package/dist/docs/data_apps/components/charts/scatter-plot.md +0 -134
  40. package/dist/docs/data_apps/components/charts/sparkline.md +0 -68
  41. package/dist/docs/data_apps/components/data/big-value.md +0 -153
  42. package/dist/docs/data_apps/components/data/delta.md +0 -89
  43. package/dist/docs/data_apps/components/data/table.md +0 -470
  44. package/dist/docs/data_apps/components/data/value.md +0 -97
  45. package/dist/docs/data_apps/components/inputs/button-group.md +0 -154
  46. package/dist/docs/data_apps/components/inputs/checkbox.md +0 -52
  47. package/dist/docs/data_apps/components/inputs/date-input.md +0 -131
  48. package/dist/docs/data_apps/components/inputs/date-range.md +0 -124
  49. package/dist/docs/data_apps/components/inputs/dimension-grid.md +0 -67
  50. package/dist/docs/data_apps/components/inputs/dropdown.md +0 -199
  51. package/dist/docs/data_apps/components/inputs/index.md +0 -3
  52. package/dist/docs/data_apps/components/inputs/slider.md +0 -126
  53. package/dist/docs/data_apps/components/inputs/text-input.md +0 -86
  54. package/dist/docs/data_apps/components/maps/area-map.md +0 -397
  55. package/dist/docs/data_apps/components/maps/base-map.md +0 -269
  56. package/dist/docs/data_apps/components/maps/bubble-map.md +0 -361
  57. package/dist/docs/data_apps/components/maps/point-map.md +0 -326
  58. package/dist/docs/data_apps/components/maps/us-map.md +0 -167
  59. package/dist/docs/data_apps/components/ui/accordion.md +0 -116
  60. package/dist/docs/data_apps/components/ui/alert.md +0 -37
  61. package/dist/docs/data_apps/components/ui/big-link.md +0 -19
  62. package/dist/docs/data_apps/components/ui/details.md +0 -58
  63. package/dist/docs/data_apps/components/ui/download-data.md +0 -41
  64. package/dist/docs/data_apps/components/ui/embed.md +0 -47
  65. package/dist/docs/data_apps/components/ui/grid.md +0 -45
  66. package/dist/docs/data_apps/components/ui/image.md +0 -61
  67. package/dist/docs/data_apps/components/ui/info.md +0 -47
  68. package/dist/docs/data_apps/components/ui/last-refreshed.md +0 -28
  69. package/dist/docs/data_apps/components/ui/link-button.md +0 -20
  70. package/dist/docs/data_apps/components/ui/link.md +0 -40
  71. package/dist/docs/data_apps/components/ui/modal.md +0 -57
  72. package/dist/docs/data_apps/components/ui/note.md +0 -32
  73. package/dist/docs/data_apps/components/ui/print-format-components.md +0 -85
  74. package/dist/docs/data_apps/components/ui/tabs.md +0 -122
@@ -1,4 +1,4 @@
1
- # How to develop in Graphene
1
+ # Graphene documentation
2
2
 
3
3
  Graphene is a framework for data analysis, semantic modeling, and data visualization in code. Graphene projects are comprised of:
4
4
  - .gsql files that define semantics-enriched tables (aka semantic models)
@@ -6,6 +6,84 @@ Graphene is a framework for data analysis, semantic modeling, and data visualiza
6
6
 
7
7
  Graphene also has a CLI that lets you check syntax, run queries, serve data apps, and more.
8
8
 
9
+ **Table of Contents**
10
+
11
+ - [Graphene SQL (GSQL)](#graphene-sql-gsql)
12
+ - [`table` statements](#table-statements)
13
+ - [Base columns (required)](#base-columns-required)
14
+ - [Join relationships](#join-relationships)
15
+ - [Multiple join relationships between the same two tables](#multiple-join-relationships-between-the-same-two-tables)
16
+ - [Best practices for modeling join relationships](#best-practices-for-modeling-join-relationships)
17
+ - [Stored expressions](#stored-expressions)
18
+ - [`select` statements](#select-statements)
19
+ - [Using join relationships in queries](#using-join-relationships-in-queries)
20
+ - [Multi-hop joins](#multi-hop-joins)
21
+ - [Using stored expressions in queries](#using-stored-expressions-in-queries)
22
+ - [Safe aggregation in fan-outs](#safe-aggregation-in-fan-outs)
23
+ - [`table as` statements](#table-as-statements)
24
+ - [`extend` statements](#extend-statements)
25
+ - [Working with dates, timestamps, and intervals](#working-with-dates-timestamps-and-intervals)
26
+ - [Date and timestamp literals](#date-and-timestamp-literals)
27
+ - [Interval literals](#interval-literals)
28
+ - [Other miscellaneous details about GSQL](#other-miscellaneous-details-about-gsql)
29
+ - [Graphene data apps (dashboards)](#graphene-data-apps-dashboards)
30
+ - [Visualization components](#visualization-components)
31
+ - [Bar chart](#bar-chart)
32
+ - [All bar chart attributes](#all-bar-chart-attributes)
33
+ - [General](#general)
34
+ - [Data](#data)
35
+ - [Formatting & Styling](#formatting--styling)
36
+ - [Value Labels](#value-labels)
37
+ - [Axes](#axes)
38
+ - [Interactivity](#interactivity)
39
+ - [Pie chart](#pie-chart)
40
+ - [All pie chart attributes](#all-pie-chart-attributes)
41
+ - [General](#general-1)
42
+ - [Data](#data-1)
43
+ - [Line chart](#line-chart)
44
+ - [All line chart attributes](#all-line-chart-attributes)
45
+ - [General](#general-2)
46
+ - [Data](#data-2)
47
+ - [Formatting & Styling](#formatting--styling-1)
48
+ - [Axes](#axes-1)
49
+ - [Interactivity](#interactivity-1)
50
+ - [Area chart](#area-chart)
51
+ - [All area chart attributes](#all-area-chart-attributes)
52
+ - [General](#general-3)
53
+ - [Data](#data-3)
54
+ - [Formatting & Styling](#formatting--styling-2)
55
+ - [Value Labels](#value-labels-1)
56
+ - [Axes](#axes-2)
57
+ - [Interactivity](#interactivity-2)
58
+ - [Big value](#big-value)
59
+ - [All big value attributes](#all-big-value-attributes)
60
+ - [Data](#data-4)
61
+ - [Comparison](#comparison)
62
+ - [Sparkline](#sparkline)
63
+ - [Table](#table)
64
+ - [All table attributes](#all-table-attributes)
65
+ - [Table](#table-1)
66
+ - [Groups](#groups)
67
+ - [Column](#column)
68
+ - [Input components](#input-components)
69
+ - [Text input](#text-input)
70
+ - [All text input attributes](#all-text-input-attributes)
71
+ - [Date range](#date-range)
72
+ - [All date range attributes](#all-date-range-attributes)
73
+ - [Dropdown](#dropdown)
74
+ - [All dropdown attributes](#all-dropdown-attributes)
75
+ - [DropdownOption](#dropdownoption)
76
+ - [Other components](#other-components)
77
+ - [Value formatting](#value-formatting)
78
+ - [Built-in Formats](#built-in-formats)
79
+ - [Auto-Formatting](#auto-formatting)
80
+ - [Dates](#dates)
81
+ - [Currencies](#currencies)
82
+ - [Numbers](#numbers)
83
+ - [Percentages](#percentages)
84
+ - [Graphene CLI](#graphene-cli)
85
+ - [AGENT INSTRUCTIONS](#agent-instructions)
86
+
9
87
  ## Graphene SQL (GSQL)
10
88
 
11
89
  GSQL is comprised of `table` statements that declare tables and `select` statements that query them.
@@ -16,40 +94,30 @@ GSQL is comprised of `table` statements that declare tables and `select` stateme
16
94
 
17
95
  ```sql
18
96
  table orders (
19
-
20
- /* Base columns */
21
-
22
- id BIGINT primary_key,
23
- user_id BIGINT,
24
- created_at DATETIME,
25
- status STRING, -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
26
- amount FLOAT, -- Amount paid by customer
27
- cost FLOAT, -- Cost of materials
28
-
29
- /* Join relationships */
30
-
31
- join_one users on user_id = users.id,
32
-
33
- /* Scalar expressions */
34
-
35
- status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
36
-
37
- /* Agg expressions */
38
-
39
- sum(case when revenue_recognized then amount else 0 end) as revenue,
40
- sum(case when revenue_recognized then cost else 0 end) as cogs,
41
- revenue - cogs as profit,
42
- profit / revenue as profit_margin
97
+ id BIGINT primary_key
98
+ user_id BIGINT
99
+ created_at DATETIME
100
+ status STRING -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
101
+ amount FLOAT -- Amount paid by customer
102
+ cost FLOAT -- Cost of materials
103
+
104
+ join one users on user_id = users.id
105
+
106
+ revenue_recognized: status in ('Processing', 'Shipped', 'Complete')
107
+ revenue: sum(case when revenue_recognized then amount else 0 end)
108
+ cogs: sum(case when revenue_recognized then cost else 0 end)
109
+ profit: revenue - cogs
110
+ profit_margin: profit / revenue
43
111
  )
44
112
 
45
113
  table users (
46
- id BIGINT primary_key,
47
- name VARCHAR,
48
- email VARCHAR,
49
- age INTEGER,
50
- country_code VARCHAR,
114
+ id BIGINT primary_key
115
+ name VARCHAR
116
+ email VARCHAR
117
+ age INTEGER
118
+ country_code VARCHAR
51
119
 
52
- join_many orders on id = orders.user_id
120
+ join many orders on id = orders.user_id
53
121
  )
54
122
  ```
55
123
 
@@ -80,19 +148,19 @@ Sometimes there are multiple valid ways to join two tables together. You can mod
80
148
  ```sql
81
149
  table projects (
82
150
  ...
83
- owner_id BIGINT,
84
- viewer_id BIGINT,
151
+ owner_id BIGINT
152
+ viewer_id BIGINT
85
153
 
86
- join_one users as project_owner on owner_id = project_owner.id,
87
- join_one users as project_viewer on viewer_id = project_viewer.id
154
+ join one users as project_owner on owner_id = project_owner.id
155
+ join one users as project_viewer on viewer_id = project_viewer.id
88
156
  )
89
157
 
90
158
  table users (
91
159
  ...
92
- id BIGINT,
160
+ id BIGINT
93
161
 
94
- join_many projects as projects_as_owner on id = projects_as_owner.owner_id,
95
- join_many projects as projects_as_viewer on id = projects_as_viewer.viewer_id
162
+ join many projects as projects_as_owner on id = projects_as_owner.owner_id
163
+ join many projects as projects_as_viewer on id = projects_as_viewer.viewer_id
96
164
  )
97
165
  ```
98
166
 
@@ -105,26 +173,24 @@ table users (
105
173
 
106
174
  **Stored expressions** are GSQL expressions (ie. any arbitrary combination of functions, operators, and column references) that you want to make reusable to queries. Stored expressions are great for canonizing metrics, segments, and other important business definitions.
107
175
 
108
- A stored expression must be given a name via `as`. It can then be referenced by name in queries that use the parent table. See [Using stored expressions in queries](#using-stored-expressions-in-queries) below for how to use stored expressions in queries.
176
+ A stored expression must be given a name via `name: expression`. It can then be referenced by name in queries that use the parent table. See [Using stored expressions in queries](#using-stored-expressions-in-queries) below for how to use stored expressions in queries.
109
177
 
110
178
  Like expressions in regular SQL, expressions in GSQL are either scalar or aggregative. In BI parlance, these would be called dimensions and measures, respectively.
111
179
 
112
- Expressions can refer to other expressions, as shown below.
180
+ Expressions can refer to other expressions, as from the example before:
113
181
 
114
182
  ```sql
115
183
  table orders (
116
184
  ...
117
185
 
118
186
  /* Scalar expressions */
119
-
120
- status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
187
+ revenue_recognized: status in ('Processing', 'Shipped', 'Complete')
121
188
 
122
189
  /* Agg expressions */
123
-
124
- sum(case when revenue_recognized then amount else 0 end) as revenue,
125
- sum(case when revenue_recognized then cost else 0 end) as cogs,
126
- revenue - cogs as profit, -- even though there are no agg functions here, this is still aggregative as it references other aggregative expressions
127
- profit / revenue as profit_margin
190
+ revenue: sum(case when revenue_recognized then amount else 0 end)
191
+ cogs: sum(case when revenue_recognized then cost else 0 end)
192
+ profit: revenue - cogs -- even though there are no agg functions here, this is still aggregative as it references other aggregative expressions
193
+ profit_margin: profit / revenue
128
194
  )
129
195
  ```
130
196
 
@@ -145,31 +211,15 @@ If you recall the model from before:
145
211
 
146
212
  ```sql
147
213
  table orders (
148
- id BIGINT primary_key,
214
+ ...
149
215
  user_id BIGINT,
150
- created_at DATETIME,
151
- status STRING, -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
152
- amount FLOAT, -- Amount paid by customer
153
- cost FLOAT, -- Cost of materials
154
-
155
- join_one users on user_id = users.id,
156
-
157
- status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
158
-
159
- sum(case when revenue_recognized then amount else 0 end) as revenue,
160
- sum(case when revenue_recognized then cost else 0 end) as cogs,
161
- revenue - cogs as profit,
162
- profit / revenue as profit_margin
216
+ join one users on user_id = users.id
163
217
  )
164
218
 
165
219
  table users (
166
220
  id BIGINT primary_key,
167
221
  name VARCHAR,
168
- email VARCHAR,
169
- age INTEGER,
170
- country_code VARCHAR,
171
-
172
- join_many orders on id = orders.user_id
222
+ ...
173
223
  )
174
224
  ```
175
225
 
@@ -195,23 +245,23 @@ Sometimes you need to access columns or stored expressions in a table that is tw
195
245
  table orders (
196
246
  ...
197
247
 
198
- join_one users on user_id = users.id
248
+ join one users on user_id = users.id
199
249
  )
200
250
 
201
251
  table users (
202
252
  ...
203
253
 
204
- join_many orders on id = orders.user_id,
205
- join_one country on country_code = countries.code
254
+ join many orders on id = orders.user_id
255
+ join one country on country_code = countries.code
206
256
  )
207
257
 
208
258
  table countries (
209
- code VARCHAR primary_key,
210
- name VARCHAR,
211
- currency VARCHAR,
212
- free_shipping BOOLEAN,
259
+ code VARCHAR primary_key
260
+ name VARCHAR
261
+ currency VARCHAR
262
+ free_shipping BOOLEAN
213
263
 
214
- join_many users on code = users.country_code
264
+ join many users on code = users.country_code
215
265
  )
216
266
  ```
217
267
 
@@ -232,35 +282,24 @@ limit 10
232
282
 
233
283
  A stored expression can be invoked in a query by simply referencing it by name.
234
284
 
235
- Again, using the model from before:
285
+ Again, using the orders table from before:
236
286
 
237
287
  ```sql
238
288
  table orders (
239
- id BIGINT primary_key,
240
- user_id BIGINT,
241
- created_at DATETIME,
242
- status STRING, -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
243
- amount FLOAT, -- Amount paid by customer
244
- cost FLOAT, -- Cost of materials
245
-
246
- join_one users on user_id = users.id,
247
-
248
- status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
249
-
250
- sum(case when revenue_recognized then amount else 0 end) as revenue,
251
- sum(case when revenue_recognized then cost else 0 end) as cogs,
252
- revenue - cogs as profit,
253
- profit / revenue as profit_margin
254
- )
255
-
256
- table users (
257
- id BIGINT primary_key,
258
- name VARCHAR,
259
- email VARCHAR,
260
- age INTEGER,
261
- country_code VARCHAR,
262
-
263
- join_many orders on id = orders.user_id
289
+ id BIGINT primary_key
290
+ user_id BIGINT
291
+ created_at DATETIME
292
+ status STRING -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
293
+ amount FLOAT -- Amount paid by customer
294
+ cost FLOAT -- Cost of materials
295
+
296
+ join one users on user_id = users.id
297
+
298
+ revenue_recognized: status in ('Processing', 'Shipped', 'Complete')
299
+ revenue: sum(case when revenue_recognized then amount else 0 end)
300
+ cogs: sum(case when revenue_recognized then cost else 0 end)
301
+ profit: revenue - cogs
302
+ profit_margin: profit / revenue
264
303
  )
265
304
  ```
266
305
 
@@ -282,7 +321,7 @@ select
282
321
  status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
283
322
  count(*)
284
323
  from orders
285
- group by 1
324
+ group by 1
286
325
  ```
287
326
 
288
327
  You can see that invoking a stored expression is like using a macro: the definition for the stored expression is effectively expanded in-line by Graphene when it runs the query.
@@ -323,7 +362,7 @@ GSQL aims to solve this problem. With the additional information provided via `j
323
362
  The query `select avg(users.age) from orders` will be rewritten to the following SQL when Graphene queries the underlying database (this is for BigQuery, specifically):
324
363
 
325
364
  ```sql
326
- SELECT
365
+ SELECT
327
366
  (CAST((
328
367
  (
329
368
  SUM(DISTINCT
@@ -346,45 +385,38 @@ You can turn the output of any `select` statement into a table with `table foo a
346
385
 
347
386
  ```sql
348
387
  table orders (
349
- id BIGINT primary_key,
350
- user_id BIGINT,
351
- created_at DATETIME,
352
- status STRING, -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
353
- amount FLOAT, -- Amount paid by customer
354
- cost FLOAT, -- Cost of materials
355
-
356
- join_one users on user_id = users.id,
357
-
358
- status in ('Processing', 'Shipped', 'Complete') as revenue_recognized,
359
-
360
- sum(case when revenue_recognized then amount else 0 end) as revenue,
361
- sum(case when revenue_recognized then cost else 0 end) as cogs,
362
- revenue - cogs as profit,
363
- profit / revenue as profit_margin
388
+ id BIGINT primary_key
389
+ user_id BIGINT
390
+ created_at DATETIME
391
+ status STRING -- One of 'Processing', 'Shipped', 'Complete', 'Cancelled', 'Returned'
392
+ amount FLOAT -- Amount paid by customer
393
+ cost FLOAT -- Cost of materials
394
+
395
+ join one users on user_id = users.id
396
+
397
+ revenue_recognized: status in ('Processing', 'Shipped', 'Complete')
398
+ revenue: sum(case when revenue_recognized then amount else 0 end)
399
+ cogs: sum(case when revenue_recognized then cost else 0 end)
400
+ profit: revenue - cogs
401
+ profit_margin: profit / revenue
364
402
  )
365
403
 
366
404
  table users (
367
- id BIGINT primary_key,
368
- name VARCHAR,
369
- email VARCHAR,
370
- age INTEGER,
371
-
372
- join_many orders on id = orders.user_id,
373
- join_one user_facts on id = user_facts.id,
405
+ id BIGINT primary_key
406
+ name VARCHAR
407
+ email VARCHAR
408
+ age INTEGER
374
409
 
375
- /* Scalar expressions */
410
+ join many orders on id = orders.user_id
411
+ join one user_facts on id = user_facts.id
376
412
 
377
- user_facts.ltv as ltv,
378
- user_facts.lifetime_orders as lifetime_orders
413
+ ltv: user_facts.ltv
414
+ lifetime_orders: user_facts.lifetime_orders
379
415
  )
380
416
 
381
417
  table user_facts as (
382
- select
383
- id,
384
- orders.revenue as ltv,
385
- count(orders.id) as lifetime_orders,
386
- from users
387
- group by id
418
+ select id, orders.revenue as ltv, count(orders.id) as lifetime_orders,
419
+ from users group by id
388
420
  )
389
421
  ```
390
422
 
@@ -392,6 +424,61 @@ table user_facts as (
392
424
  - You cannot yet declare join relationships or stored expressions directly in a `table as` statement. Other tables can declare join relationships to it, though, as shown above.
393
425
  - In the example above, the `ltv` and `lifetime_orders` columns from `user_facts` are "hoisted" back into `users` so that they appear as if they are columns from `users`. This is simply a design choice which allows query writers to never need to know about `user_facts`.
394
426
 
427
+ ### `extend` statements
428
+
429
+ `extend` statements allow you to add join relationships or stored expressions to an existing table. This is especially useful for tables created via `table as` statements, which do not support defining these properties directly.
430
+
431
+ For example, if we have a `table as` statement that creates a daily summary of orders:
432
+
433
+ ```sql
434
+ table daily_orders as (
435
+ select
436
+ date_trunc(created_at, day) as day,
437
+ count(*) as num_orders,
438
+ sum(amount) as total_revenue
439
+ from orders
440
+ group by 1
441
+ )
442
+ ```
443
+
444
+ We can extend this table to add measures or joins:
445
+
446
+ ```sql
447
+ extend daily_orders (
448
+ join one calendar on day = calendar.date
449
+
450
+ avg_order_value: total_revenue / num_orders
451
+ )
452
+ ```
453
+
454
+ Note that you cannot add new base columns with `extend`; you can only add joins and stored expressions.
455
+
456
+ ### Working with dates, timestamps, and intervals
457
+
458
+ Graphene understands a handful of common literal formats so you rarely need explicit casts when filtering or doing time math.
459
+
460
+ **Date and timestamp literals**
461
+
462
+ - `YYYY`, `YYYY-MM`, and `YYYY-MM-DD` strings are treated as dates. Leading/trailing spaces are ignored.
463
+ - `YYYY-MM-DD HH[:MM[:SS]]` (with either a space or `T` between the date and time) is treated as a timestamp. Missing minutes or seconds default to `00`.
464
+
465
+ ```sql
466
+ from users select id
467
+ where created_at >= '2024-01-01' and created_at <= '2024-02-01'
468
+ ```
469
+
470
+ **Interval literals**
471
+
472
+ To add or subtract time, provide a quantity followed by a unit inside a string literal. Supported units include `second`, `minute`, `hour`, `day`, `week`, `month`, `quarter`, and `year` (plural forms or shorthands like `secs`, `mins`, `hrs` also work).
473
+
474
+ ```sql
475
+ from users select
476
+ created_at + '5 minutes' as first_seen_plus_5,
477
+ created_at - '2 days' as first_seen_minus_2
478
+ ```
479
+
480
+ Interval literals accept decimals (`'1.5 hours'`) and negative values (`'-7 days'`). Invalid strings produce a diagnostic such as “Could not parse interval literal: "many moons"”.
481
+
395
482
  ### Other miscellaneous details about GSQL
396
483
 
397
484
  - Trailing commas in `table` statements are optional.
@@ -401,62 +488,883 @@ table user_facts as (
401
488
  - Expressions in `group by` are implicitly selected, so `from orders select avg(amount) group by user_id` will return two columns.
402
489
  - `count` is a reserved word. Do not alias your columns as `count`.
403
490
  - Window functions and set operations are not supported.
404
-
405
- ## Graphene visualizations
491
+ - Subqueries are not supported. However, you can accomplish the same functionality by chaining queries:
492
+ ````md
493
+ ```sql my_subquery
494
+ select ...
495
+ ```
496
+
497
+ ```sql my_query
498
+ select ... from my_subquery
499
+ ```
500
+ ````
501
+
502
+ ## Graphene data apps (dashboards)
406
503
 
407
504
  Graphene data apps are written in Markdown with the addition of special Graphene HTML components. Markdown files can contain named GSQL queries in code fences that components can then refer to. Those queries can use any tables defined in .gsql files.
408
505
 
409
- ````markdown
410
- # Order analysis
411
- Looking at our order breakdowns.
506
+ _my_first_dashboard.md_
507
+ ````md
508
+ # Order analysis
412
509
 
413
- ```sql orders_by_month
414
- from orders select date_trunc(created_at, month) as month, count(*) as num_orders, profit
415
- ```
510
+ Looking at our order breakdowns.
416
511
 
417
- <Row>
418
- <LineChart data="orders_by_month" x="month" y="num_orders" title="Orders by Month" />
419
- <LineChart data="orders" x="date_trunc(created_at, month)" y="profit" title="Profit by Month, USD" />
420
- </Row>
512
+ ```sql orders_by_month
513
+ select
514
+ date_trunc(created_at, month) as month,
515
+ count(*) as num_orders,
516
+ profit
517
+ from orders
518
+ group by month
519
+ ```
520
+
521
+ <Row>
522
+ <LineChart title="Orders by Month" data=orders_by_month x=month y=num_orders />
523
+ <LineChart title="Profit by Month, USD" data=orders x="date_trunc(created_at, month)" y=profit />
524
+ </Row>
421
525
  ````
422
526
 
423
- Note that components can also directly refer to Graphene tables in their `data` property; it is not always necessary to prepare data in a code-fenced query. Properties that take column references can also take whole GSQL expressions, as shown in the second line chart from the example above.
527
+ Syntax notes
528
+ - The `data` attribute can also refer directly to modeled GSQL tables instead of code-fenced queries.
529
+ - Attributes that take column references can also take whole GSQL expressions, as shown in the second line chart from the example above.
530
+ - Like in HTML, the string value assigned to an attribute does not need to be wrapped in double quotes if it only contains alphanumeric characters, `-`, `_`, `:`, or `.`.
424
531
 
425
532
  Best practices
426
533
  - If you have multiple time series charts, align their x-axes to have the same range and granularity.
427
534
  - Use the same color for a given metric if it is used in multiple charts.
428
535
 
429
- ### Components
536
+ ### Visualization components
537
+
538
+ #### Bar chart
539
+
540
+ Use bar or column charts to compare a metric across categories. Bar charts are best with a small number of categories and series, and should generally start at 0.
541
+
542
+ Here's an example:
543
+
544
+ ```markdown
545
+ <BarChart
546
+ title="Sales by Category"
547
+ data=orders_by_category_2021
548
+ x=month
549
+ y=sales
550
+ series=category
551
+ />
552
+ ```
553
+
554
+ ##### All bar chart attributes
555
+
556
+ ###### General
557
+
558
+ | Attribute | Description | Options | Default |
559
+ |----------|-------------|---------|---------|
560
+ | title | Chart title. Appears at top left of chart. | string | - |
561
+ | subtitle | Chart subtitle. Appears just under title. | string | - |
562
+ | legend | Turns legend on or off. Legend appears at top center of chart. | `true`, `false` | `true` for multiple series |
563
+ | chartAreaHeight | Minimum height of the chart area (excl. header and footer) in pixels. Adjusting the height affects all viewport sizes and may impact the mobile UX. | number | `180` |
564
+ | renderer | Which chart renderer type (canvas or SVG) to use. See ECharts' documentation on renderers. | `canvas`, `svg` | `canvas` |
565
+ | downloadableData | Whether to show the download button to allow users to download the data | `true`, `false` | `true` |
566
+ | downloadableImage | Whether to show the button to allow users to save the chart as an image | `true`, `false` | `true` |
567
+
568
+ ###### Data
569
+
570
+ | Attribute | Description | Required | Options | Default |
571
+ |----------|-------------|----------|---------|---------|
572
+ | data | Query name, wrapped in curly braces | true | query name | - |
573
+ | x | Column or expression to use for the x-axis of the chart | false | column name, stored expression name, GSQL expression | First column |
574
+ | y | Column(s) or expression(s) to use for the y-axis of the chart. Each will create its own series. Consider a split axis with `y2` if there is a difference of scale or unit of measure between the series. | false | column name, stored expression name, GSQL expression, list of any combination of these | Any non-assigned numeric columns |
575
+ | y2 | Column(s) or expression(s) to include on a secondary y-axis. | false | column name, stored expression name, GSQL expression, list of any combination of these | - |
576
+ | y2SeriesType | Chart type to apply to the series on the y2 axis | false | `bar`, `line`, `scatter` | `bar` |
577
+ | series | Column or expression to use to define the series (groups) in a multi-series chart. Use when values of a particular column dictate the multiple series to plot, eg. `country` would create a series for every distinct country in the column. | false | column name, stored expression name, GSQL expression | - |
578
+ | sort | Whether to apply default sort to your data. Default sort is x ascending for number and date x-axes, and y descending for category x-axes | false | `true`, `false` | `true` |
579
+ | type | Grouping method to use for multi-series charts | false | `stacked`, `grouped`, `stacked100` | `stacked` |
580
+ | stackName | Name for an individual stack. If separate Bar components are used with different stackNames, the chart will show multiple stacks | false | string | - |
581
+ | emptySet | Sets behaviour for empty datasets. Can throw an error, a warning, or allow empty. When set to 'error', empty datasets will block builds in `build:strict`. Note this only applies to initial page load - empty datasets caused by input component changes (dropdowns, etc.) are allowed. | false | `error`, `warn`, `pass` | `error` |
582
+ | emptyMessage | Text to display when an empty dataset is received - only applies when `emptySet` is 'warn' or 'pass', or when the empty dataset is a result of an input component change (dropdowns, etc.). | false | string | No records |
583
+
584
+ ###### Formatting & Styling
585
+
586
+ | Attribute | Description | Options | Default |
587
+ |----------|-------------|---------|---------|
588
+ | xFmt | Format to use for x column ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
589
+ | yFmt | Format to use for y column ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
590
+ | y2Fmt | Format to use for y2 column(s) ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
591
+ | seriesLabelFmt | Format to use for series label ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
592
+ | fillColor | Color to override default series color. Only accepts a single color. | CSS name, hexademical, RGB, HSL | - |
593
+ | fillOpacity | % of the full color that should be rendered, with remainder being transparent | number (0 to 1) | `1` |
594
+ | outlineWidth | Width of line surrounding each bar | number | `0` |
595
+ | outlineColor | Color to use for outline if outlineWidth > 0 | CSS name, hexademical, RGB, HSL | - |
596
+ | colorPalette | List of custom colors to use for the chart | list of color strings (CSS name, hexademical, RGB, HSL) e.g. `"#cf0d06, #eb5752, #e88a87"` | built-in color palette |
597
+ | seriesOrder | Apply a specific order to the series in a multi-series chart. | list of series names in the order they should be used in the chart `"Canada, US"` | default order implied by the data |
598
+ | leftPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | number | - |
599
+ | rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | number | - |
600
+ | xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | `true`, `false` | `false` |
601
+
602
+ ###### Value Labels
603
+
604
+ | Attribute | Description | Options | Default |
605
+ |----------|-------------|---------|---------|
606
+ | labels | Show value labels | `true`, `false` | `false` |
607
+ | stackTotalLabel | If using labels, whether to show a total at the top of stacked bar chart | `true`, `false` | `true` |
608
+ | seriesLabels | If using labels, whether to show series labels | `true`, `false` | `true` |
609
+ | labelSize | Font size of value labels | number | `11` |
610
+ | labelPosition | Where label will appear on your series | `outside`, `inside` | Single Series: `outside`, Stacked: `inside`, Grouped: `outside` |
611
+ | labelColor | Font color of value labels | CSS name, hexademical, RGB, HSL | Automatic based on color contrast of background |
612
+ | labelFmt | Format to use for value labels ([see available formats](#value-formatting)) | Excel-style format, built-in format name | same as y column |
613
+ | yLabelFmt | Format to use for value labels for series on the y axis. Overrides any other formats ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
614
+ | y2LabelFmt | Format to use for value labels for series on the y2 axis. Overrides any other formats ([see available formats](#value-formatting)) | Excel-style format, built-in format name | - |
615
+ | showAllLabels | Allow all labels to appear on chart, including overlapping labels | `true`, `false` | `false` |
616
+
617
+ ###### Axes
618
+
619
+ | Attribute | Description | Options | Default |
620
+ |----------|-------------|---------|---------|
621
+ | swapXY | Swap the x and y axes to create a horizontal chart | `true`, `false` | `false` |
622
+ | yLog | Whether to use a log scale for the y-axis | `true`, `false` | `false` |
623
+ | yLogBase | Base to use when log scale is enabled | number | `10` |
624
+ | xAxisTitle | Name to show under x-axis. If 'true', formatted column name is used. Only works with swapXY=false | string, `true`, `false` | `false` |
625
+ | yAxisTitle | Name to show beside y-axis. If 'true', formatted column name is used. | string, `true`, `false` | `false` |
626
+ | y2AxisTitle | Name to show beside y2 axis. If 'true', formatted column name is used. | string, `true`, `false` | `false` |
627
+ | xGridlines | Turns on/off gridlines extending from x-axis tick marks (vertical lines when swapXY=false) | `true`, `false` | `false` |
628
+ | yGridlines | Turns on/off gridlines extending from y-axis tick marks (horizontal lines when swapXY=false) | `true`, `false` | `true` |
629
+ | y2Gridlines | Turns on/off gridlines extending from y2-axis tick marks (horizontal lines when swapXY=false) | `true`, `false` | `true` |
630
+ | xAxisLabels | Turns on/off value labels on the x-axis | `true`, `false` | `true` |
631
+ | yAxisLabels | Turns on/off value labels on the y-axis | `true`, `false` | `true` |
632
+ | y2AxisLabels | Turns on/off value labels on the y2-axis | `true`, `false` | `true` |
633
+ | xBaseline | Turns on/off thick axis line (line appears at y=0) | `true`, `false` | `true` |
634
+ | yBaseline | Turns on/off thick axis line (line appears directly alongside the y-axis labels) | `true`, `false` | `false` |
635
+ | y2Baseline | Turns on/off thick axis line (line appears directly alongside the y2-axis labels) | `true`, `false` | `false` |
636
+ | xTickMarks | Turns on/off tick marks for each of the x-axis labels | `true`, `false` | `false` |
637
+ | yTickMarks | Turns on/off tick marks for each of the y-axis labels | `true`, `false` | `false` |
638
+ | y2TickMarks | Turns on/off tick marks for each of the y2-axis labels | `true`, `false` | `false` |
639
+ | yMin | Starting value for the y-axis | number | - |
640
+ | yMax | Maximum value for the y-axis | number | - |
641
+ | yScale | Whether to scale the y-axis to fit your data. `yMin` and `yMax` take precedence over `yScale` | `true`, `false` | `false` |
642
+ | y2Min | Starting value for the y2-axis | number | - |
643
+ | y2Max | Maximum value for the y2-axis | number | - |
644
+ | y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | `true`, `false` | `false` |
645
+ | yAxisColor | Turns on/off color on the y-axis (turned on by default when secondary y-axis is used). Can also be used to set a specific color | `true`, `false`, color string (CSS name, hexademical, RGB, HSL) | `true` when y2 used; `false` otherwise |
646
+
647
+ ###### Interactivity
648
+
649
+ | Attribute | Description | Options |
650
+ |----------|-------------|---------|
651
+ | connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | string |
652
+
653
+ #### Pie chart
654
+
655
+ Use a pie chart to show part-to-whole relationships across categories. Best for a small number of categories where proportions are easy to compare.
656
+
657
+ Here's an example:
658
+
659
+ ```markdown
660
+ <PieChart
661
+ title="Sales share by category"
662
+ data=orders_by_category_2021
663
+ category=category
664
+ value=sales
665
+ />
666
+ ```
667
+
668
+ ##### All pie chart attributes
669
+
670
+ ###### General
671
+
672
+ | Attribute | Description | Options | Default |
673
+ |----------|-------------|---------|---------|
674
+ | title | Chart title. Appears at top left of chart. | string | - |
675
+ | subtitle | Chart subtitle. Appears just under title. | string | - |
676
+
677
+ ###### Data
678
+
679
+ | Attribute | Description | Required | Options | Default |
680
+ |------|-------------|----------|---------|---------|
681
+ | data | Query name, wrapped in curly braces | true | query name | - |
682
+ | category | Column or expression to use for slice names | true | column name, stored expression name, GSQL expression | - |
683
+ | value | Column or expression to use for slice values | true | column name, stored expression name, GSQL expression | - |
684
+
685
+ #### Line chart
686
+
687
+ Use line charts to display how one or more metrics vary over time. Line charts are suitable for plotting a large number of data points on the same chart.
688
+
689
+ Here's an example:
690
+
691
+ ```markdown
692
+ <LineChart
693
+ title="Monthly Sales"
694
+ subtitle="Includes all categories"
695
+ data=orders_by_month
696
+ x=month
697
+ y=sales_usd0k
698
+ yAxisTitle="Sales per Month"
699
+ />
700
+ ```
701
+
702
+ ##### All line chart attributes
703
+
704
+ ###### General
705
+
706
+ | Attribute | Description | Required | Options | Default |
707
+ |------|-------------|----------|---------|---------|
708
+ | title | Chart title. Appears at top left of chart. | false | string | - |
709
+ | subtitle | Chart subtitle. Appears just under title. | false | string | - |
710
+ | legend | Turn legend on or off. Legend appears at top center of chart. | false | `true`, `false` | `true` for multiple series |
711
+ | chartAreaHeight | Minimum height of the chart area (excl. header and footer) in pixels. Adjusting the height affects all viewport sizes and may impact the mobile UX. | false | number | `180` |
712
+ | renderer | Which chart renderer type (canvas or SVG) to use. See ECharts' [documentation on renderers](https://echarts.apache.org/handbook/en/best-practices/canvas-vs-svg/). | false | `canvas`, `svg` | `canvas` |
713
+ | downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
714
+ | downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
715
+
716
+ ###### Data
717
+
718
+ | Attribute | Description | Required | Options | Default |
719
+ |------|-------------|----------|---------|---------|
720
+ | data | Query name, wrapped in curly braces | true | query name | - |
721
+ | x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | - |
722
+ | y | Column(s) or expression(s) to use for the y-axis of the chart. Each will create its own series. Consider a split axis with `y2` if there is a difference of scale or unit of measure between the series. | true | column name, stored expression name, GSQL expression, list of any combination of these | - |
723
+ | y2 | Column(s) or expression(s) to include on a secondary y-axis. | false | column name, stored expression name, GSQL expression, list of any combination of these | - |
724
+ | y2SeriesType | Chart type to apply to the series on the y2 axis | false | `line`, `bar`, `scatter` | `line` |
725
+ | series | Column or expression to use to define the series (groups) in a multi-series chart. Use when values of a particular column dictate the multiple series to plot, eg. `country` would create a series for every distinct country in the column. | false | column name, stored expression name, GSQL expression | - |
726
+ | sort | Whether to apply default sort to your data. Default is x ascending for number and date x-axes, and y descending for category x-axes | false | `true`, `false` | `true` |
727
+ | handleMissing | Treatment of missing values in the dataset | false | `gap`, `connect`, `zero` | `gap` |
728
+ | emptySet | Sets behaviour for empty datasets. Can throw an error, a warning, or allow empty. When set to 'error', empty datasets will block builds in `build:strict`. Note this only applies to initial page load - empty datasets caused by input component changes (dropdowns, etc.) are allowed. | false | `error`, `warn`, `pass` | `error` |
729
+ | emptyMessage | Text to display when an empty dataset is received - only applies when `emptySet` is 'warn' or 'pass', or when the empty dataset is a result of an input component change (dropdowns, etc.). | false | string | - |
730
+
731
+ ###### Formatting & Styling
732
+
733
+ | Attribute | Description | Required | Options | Default |
734
+ |------|-------------|----------|---------|---------|
735
+ | xFmt | Format to use for x column ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
736
+ | yFmt | Format to use for y column(s) ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
737
+ | y2Fmt | Format to use for y2 column(s) ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
738
+ | seriesLabelFmt | Format to use for series label ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
739
+ | step | Specifies whether the chart is displayed as a step line | false | `true`, `false` | `false` |
740
+ | stepPosition | Configures the position of turn points for a step line chart | false | `start`, `middle`, `end` | `end` |
741
+ | lineColor | Color to override default series color. Only accepts a single color | false | CSS name, hexademical, RGB, HSL | - |
742
+ | lineOpacity | % of the full color that should be rendered, with remainder being transparent | false | number (0 to 1) | `1` |
743
+ | lineType | Options to show breaks in a line (dashed or dotted) | false | `solid`, `dashed`, `dotted` | `solid` |
744
+ | lineWidth | Thickness of line (in pixels) | false | number | `2` |
745
+ | markers | Turn on/off markers (shapes rendered onto the points of a line) | false | `true`, `false` | `false` |
746
+ | markerShape | Shape to use if markers=true | false | `circle`, `emptyCircle`, `rect`, `triangle`, `diamond` | `circle` |
747
+ | markerSize | Size of each shape (in pixels) | false | number | `8` |
748
+ | colorPalette | List of custom colors to use for the chart | false | list of color strings (CSS name, hexademical, RGB, HSL) e.g. `"#cf0d06, #eb5752, #e88a87"` | - |
749
+ | seriesOrder | Apply a specific order to the series in a multi-series chart. | false | list of series names in the order they should be used in the chart `"Canada, US"` | default order implied by the data |
750
+ | labels | Show value labels | false | `true`, `false` | `false` |
751
+ | labelSize | Font size of value labels | false | number | `11` |
752
+ | labelPosition | Where label will appear on your series | false | `above`, `middle`, `below` | `above` |
753
+ | labelColor | Font color of value labels | false | CSS name, hexademical, RGB, HSL | - |
754
+ | labelFmt | Format to use for value labels ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
755
+ | yLabelFmt | Format to use for value labels for series on the y axis. Overrides any other formats ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
756
+ | y2LabelFmt | Format to use for value labels for series on the y2 axis. Overrides any other formats ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
757
+ | showAllLabels | Allow all labels to appear on chart, including overlapping labels | false | `true`, `false` | `false` |
758
+ | leftPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
759
+ | rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
760
+ | xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | false | `true`, `false` | `false` |
761
+
762
+ ###### Axes
763
+
764
+ | Attribute | Description | Required | Options | Default |
765
+ |------|-------------|----------|---------|---------|
766
+ | yLog | Whether to use a log scale for the y-axis | false | `true`, `false` | `false` |
767
+ | yLogBase | Base to use when log scale is enabled | false | number | `10` |
768
+ | xAxisTitle | Name to show under x-axis. If 'true', formatted column name is used. Only works with swapXY=false | false | `true`, `string`, `false` | `false` |
769
+ | yAxisTitle | Name to show beside y-axis. If 'true', formatted column name is used. | false | `true`, `string`, `false` | `false` |
770
+ | y2AxisTitle | Name to show beside y2 axis. If 'true', formatted column name is used. | false | `true`, `string`, `false` | `false` |
771
+ | xGridlines | Turns on/off gridlines extending from x-axis tick marks (vertical lines when swapXY=false) | false | `true`, `false` | `false` |
772
+ | yGridlines | Turns on/off gridlines extending from y-axis tick marks (horizontal lines when swapXY=false) | false | `true`, `false` | `true` |
773
+ | y2Gridlines | Turns on/off gridlines extending from y2-axis tick marks (horizontal lines when swapXY=false) | false | `true`, `false` | `true` |
774
+ | xAxisLabels | Turns on/off value labels on the x-axis | false | `true`, `false` | `true` |
775
+ | yAxisLabels | Turns on/off value labels on the y-axis | false | `true`, `false` | `true` |
776
+ | y2AxisLabels | Turns on/off value labels on the y2-axis | false | `true`, `false` | `true` |
777
+ | xBaseline | Turns on/off thick axis line (line appears at y=0) | false | `true`, `false` | `true` |
778
+ | yBaseline | Turns on/off thick axis line (line appears directly alongside the y-axis labels) | false | `true`, `false` | `false` |
779
+ | y2Baseline | Turns on/off thick axis line (line appears directly alongside the y2-axis labels) | false | `true`, `false` | `false` |
780
+ | xTickMarks | Turns on/off tick marks for each of the x-axis labels | false | `true`, `false` | `false` |
781
+ | yTickMarks | Turns on/off tick marks for each of the y-axis labels | false | `true`, `false` | `false` |
782
+ | y2TickMarks | Turns on/off tick marks for each of the y2-axis labels | false | `true`, `false` | `false` |
783
+ | yMin | Starting value for the y-axis | false | number | - |
784
+ | yMax | Maximum value for the y-axis | false | number | - |
785
+ | yScale | Whether to scale the y-axis to fit your data. `yMin` and `yMax` take precedence over `yScale` | false | `true`, `false` | `false` |
786
+ | y2Min | Starting value for the y2-axis | false | number | - |
787
+ | y2Max | Maximum value for the y2-axis | false | number | - |
788
+ | y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | false | `true`, `false` | `false` |
789
+
790
+ ###### Interactivity
791
+
792
+ | Attribute | Description | Required | Options | Default |
793
+ |------|-------------|----------|---------|---------|
794
+ | connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | false | - | - |
795
+
796
+
797
+ #### Area chart
798
+
799
+ Use area charts to track how a metric with multiple series changes over time, or a continuous range. Area charts emphasize changes in the sum of series over the individual series.
800
+
801
+ Here's an example:
802
+
803
+ ```markdown
804
+ <AreaChart
805
+ data=orders_by_month
806
+ x=month
807
+ y=sales
808
+ />
809
+ ```
810
+
811
+ ##### All area chart attributes
812
+
813
+ ###### General
814
+
815
+ | Attribute | Description | Required | Options | Default |
816
+ |------|-------------|----------|---------|---------|
817
+ | title | Chart title. Appears at top left of chart. | false | string | - |
818
+ | subtitle | Chart subtitle. Appears just under title. | false | string | - |
819
+ | legend | Turn legend on or off. Legend appears at top center of chart. | false | `true`, `false` | `true` for multiple series |
820
+ | chartAreaHeight | Minimum height of the chart area (excl. header and footer) in pixels. Adjusting the height affects all viewport sizes and may impact the mobile UX. | false | number | `180` |
821
+ | renderer | Which chart renderer type (canvas or SVG) to use. See ECharts' [documentation on renderers](https://echarts.apache.org/handbook/en/best-practices/canvas-vs-svg/). | false | `canvas`, `svg` | `canvas` |
822
+ | downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
823
+ | downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
824
+
825
+ ###### Data
826
+
827
+ | Attribute | Description | Required | Options | Default |
828
+ |------|-------------|----------|---------|---------|
829
+ | data | Query name, wrapped in curly braces | true | query name | - |
830
+ | x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | First column |
831
+ | y | Column(s) or expression(s) to use for the y-axis of the chart. Each will create its own series. Consider a split axis with `y2` if there is a difference of scale or unit of measure between the series. | true | column name, stored expression name, GSQL expression, list of any combination of these | Any non-assigned numeric columns |
832
+ | series | Column or expression to use to define the series (groups) in a multi-series chart. Use when values of a particular column dictate the multiple series to plot, eg. `country` would create a series for every distinct country in the column. | false | column name, stored expression name, GSQL expression | - |
833
+ | sort | Whether to apply default sort to your data. Default sort is x ascending for number and date x-axes, and y descending for category x-axes | false | `true`, `false` | `true` |
834
+ | type | Grouping method to use for multi-series charts | false | `stacked`, `stacked100` | `stacked` |
835
+ | handleMissing | Treatment of missing values in the dataset | false | `gap`, `connect`, `zero` | `gap` for single series, `zero` for multi-series |
836
+ | emptySet | Sets behaviour for empty datasets. Can throw an error, a warning, or allow empty. When set to 'error', empty datasets will block builds in `build:strict`. Note this only applies to initial page load - empty datasets caused by input component changes (dropdowns, etc.) are allowed. | false | `error`, `warn`, `pass` | `error` |
837
+ | emptyMessage | Text to display when an empty dataset is received - only applies when `emptySet` is 'warn' or 'pass', or when the empty dataset is a result of an input component change (dropdowns, etc.). | false | string | "No records" |
838
+
839
+ ###### Formatting & Styling
840
+
841
+ | Attribute | Description | Required | Options | Default |
842
+ |------|-------------|----------|---------|---------|
843
+ | xFmt | Format to use for x column ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
844
+ | yFmt | Format to use for y column ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
845
+ | seriesLabelFmt | Format to use for series label ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | - |
846
+ | step | Specifies whether the chart is displayed as a step line | false | `true`, `false` | `false` |
847
+ | stepPosition | Configures the position of turn points for a step line chart | false | `start`, `middle`, `end` | `end` |
848
+ | fillColor | Color to override default series color. Only accepts a single color. | false | CSS name, hexademical, RGB, HSL | - |
849
+ | lineColor | Color to override default line color. Only accepts a single color. | false | CSS name, hexademical, RGB, HSL | - |
850
+ | fillOpacity | % of the full color that should be rendered, with remainder being transparent | false | number (0 to 1) | `0.7` |
851
+ | line | Show line on top of the area | false | `true`, `false` | `true` |
852
+ | colorPalette | List of custom colors to use for the chart | false | list of color strings (CSS name, hexademical, RGB, HSL) e.g. `"#cf0d06, #eb5752, #e88a87"` | built-in color palette |
853
+ | seriesOrder | Apply a specific order to the series in a multi-series chart. | false | list of series names in the order they should be used in the chart `"Canada, US"` | default order implied by the data |
854
+ | leftPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
855
+ | rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
856
+ | xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | false | `true`, `false` | `false` |
857
+
858
+ ###### Value Labels
859
+
860
+ | Attribute | Description | Required | Options | Default |
861
+ |------|-------------|----------|---------|---------|
862
+ | labels | Show value labels | false | `true`, `false` | `false` |
863
+ | labelSize | Font size of value labels | false | number | `11` |
864
+ | labelPosition | Where label will appear on your series | false | `above`, `middle`, `below` | `above` |
865
+ | labelColor | Font color of value labels | false | CSS name, hexademical, RGB, HSL | Automatic based on color contrast of background |
866
+ | labelFmt | Format to use for value labels ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | same as y column |
867
+ | showAllLabels | Allow all labels to appear on chart, including overlapping labels | false | `true`, `false` | `false` |
868
+
869
+ ###### Axes
870
+
871
+ | Attribute | Description | Required | Options | Default |
872
+ |------|-------------|----------|---------|---------|
873
+ | yLog | Whether to use a log scale for the y-axis | false | `true`, `false` | `false` |
874
+ | yLogBase | Base to use when log scale is enabled | false | number | `10` |
875
+ | xAxisTitle | Name to show under x-axis. If 'true', formatted column name is used. Only works with swapXY=false | false | `true`, `string`, `false` | `false` |
876
+ | yAxisTitle | Name to show beside y-axis. If 'true', formatted column name is used. | false | `true`, `string`, `false` | `false` |
877
+ | xGridlines | Turns on/off gridlines extending from x-axis tick marks (vertical lines when swapXY=false) | false | `true`, `false` | `false` |
878
+ | yGridlines | Turns on/off gridlines extending from y-axis tick marks (horizontal lines when swapXY=false) | false | `true`, `false` | `true` |
879
+ | xAxisLabels | Turns on/off value labels on the x-axis | false | `true`, `false` | `true` |
880
+ | yAxisLabels | Turns on/off value labels on the y-axis | false | `true`, `false` | `true` |
881
+ | xBaseline | Turns on/off thick axis line (line appears at y=0) | false | `true`, `false` | `true` |
882
+ | yBaseline | Turns on/off thick axis line (line appears directly alongside the y-axis labels) | false | `true`, `false` | `false` |
883
+ | xTickMarks | Turns on/off tick marks for each of the x-axis labels | false | `true`, `false` | `false` |
884
+ | yTickMarks | Turns on/off tick marks for each of the y-axis labels | false | `true`, `false` | `false` |
885
+ | yMin | Starting value for the y-axis | false | number | - |
886
+ | yMax | Maximum value for the y-axis | false | number | - |
887
+ | yScale | Whether to scale the y-axis to fit your data. `yMin` and `yMax` take precedence over `yScale` | false | `true`, `false` | `false` |
888
+
889
+ ###### Interactivity
890
+
891
+ | Attribute | Description | Required | Options | Default |
892
+ |------|-------------|----------|---------|---------|
893
+ | connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | false | - | - |
894
+
895
+
896
+ #### Big value
897
+
898
+ Use big values to display a large value standalone, and optionally include a comparison and a sparkline.
899
+
900
+ Here's an example:
901
+
902
+ ```markdown
903
+ <BigValue
904
+ data=orders_with_comparisons
905
+ value=num_orders
906
+ sparkline=month
907
+ comparison=order_growth
908
+ comparisonFmt=pct1
909
+ comparisonTitle="vs. Last Month"
910
+ />
911
+ ```
912
+
913
+ ##### All big value attributes
914
+
915
+ ###### Data
916
+
917
+ | Attribute | Description | Required | Options | Default |
918
+ |------|-------------|----------|---------|---------|
919
+ | data | Query name, wrapped in curly braces | true | query name | - |
920
+ | value | Column or expression to pull the main value from. | true | column name, stored expression name, GSQL expression | - |
921
+ | title | Title of the card. | false | string | Title of the value column. |
922
+ | minWidth | Overrides min-width of component | false | % or px value | `"18%"` |
923
+ | maxWidth | Adds a max-width to the component | false | % or px value | - |
924
+ | fmt | Sets format for the value ([see available formats](#value-formatting)) | false | Excel-style format, built-in format | - |
925
+ | emptySet | Sets behaviour for empty datasets. Can throw an error, a warning, or allow empty. When set to 'error', empty datasets will block builds in `build:strict`. Note this only applies to initial page load - empty datasets caused by input component changes (dropdowns, etc.) are allowed. | false | `error`, `warn`, `pass` | `error` |
926
+ | emptyMessage | Text to display when an empty dataset is received - only applies when `emptySet` is 'warn' or 'pass', or when the empty dataset is a result of an input component change (dropdowns, etc.). | false | string | `"No records"` |
927
+ | link | Used to navigate to other pages. Can be a full external link like `"https://google.com"` or an internal link like `"/sales/performance"` | false | - | - |
928
+
929
+ ###### Comparison
930
+
931
+ | Attribute | Description | Required | Options | Default |
932
+ |------|-------------|----------|---------|---------|
933
+ | comparison | Column or expression to pull the comparison value from. | false | column name, stored expression name, GSQL expression | - |
934
+ | comparisonTitle | Text to the right of the comparison. | false | string | Title of the comparison column. |
935
+ | comparisonDelta | Whether to display delta symbol and color | false | `true`, `false` | `true` |
936
+ | downIsGood | If present, negative comparison values appear in green, and positive values appear in red. | false | `true`, `false` | `false` |
937
+ | neutralMin | Sets the bottom of the range for 'neutral' values - neutral values appear in grey rather than red or green | false | number | `0` |
938
+ | neutralMax | Sets the top of the range for 'neutral' values - neutral values appear in grey rather than red or green | false | number | `0` |
939
+ | comparisonFmt | Sets format for the comparison ([see available formats](#value-formatting)) | false | Excel-style format, built-in format | - |
940
+
941
+ ###### Sparkline
942
+
943
+ | Attribute | Description | Required | Options | Default |
944
+ |------|-------------|----------|---------|---------|
945
+ | sparkline | Column or expression to pull the date from to create the sparkline. | false | column name, stored expression name, GSQL expression | - |
946
+ | sparklineType | Chart type for sparkline | false | `line`, `area`, `bar` | `line` |
947
+ | sparklineValueFmt | Formatting for tooltip values | false | format code | same as fmt if supplied |
948
+ | sparklineDateFmt | Formatting for tooltip dates | false | format code | `YYYY-MM-DD` |
949
+ | sparklineColor | Color of visualization | false | CSS name, hexademical, RGB, HSL | - |
950
+ | sparklineYScale | Whether to truncate the y-axis of the chart to enhance visibility | false | `true`, `false` | `false` |
951
+ | connectGroup | Group name to connect this sparkline to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | false | string | - |
952
+ | description | Adds an info icon with description tooltip on hover | false | string | - |
953
+
954
+ #### Table
955
+
956
+ Use a Table component to display a richly formatted table of data from a query. Tables are powerful default choice for data display that allow high information density, and are easy to read.
957
+
958
+ Here's an example:
959
+
960
+ ```markdown
961
+ <Table data=orders_summary />
962
+ ```
963
+
964
+ ##### All table attributes
965
+
966
+ ###### Table
967
+
968
+ | Attribute | Description | Required | Options | Default |
969
+ |------|-------------|----------|---------|---------|
970
+ | data | Query name, wrapped in curly braces | true | query name | - |
971
+ | rows | Number of rows to show in the table before paginating results. Use `"rows=all"` to show all rows in the table. | false | number, `all` | `10` |
972
+ | title | Title for the table | false | string | - |
973
+ | subtitle | Subtitle - appears under the title | false | string | - |
974
+ | headerColor | Background color of the header row | false | Hex color code, css color name | - |
975
+ | headerFontColor | Font color of the header row | false | Hex color code, css color name | - |
976
+ | totalRow | Show a total row at the bottom of the table, defaults to sum of all numeric columns | false | `true`, `false` | `false` |
977
+ | totalRowColor | Background color of the total row | false | Hex color code, css color name | - |
978
+ | totalFontColor | Font color of the total row | false | Hex color code, css color name | - |
979
+ | rowNumbers | Turns on or off row index numbers | false | `true`, `false` | `false` |
980
+ | rowLines | Turns on or off borders at the bottom of each row | false | `true`, `false` | `true` |
981
+ | rowShading | Shades every second row in light grey | false | `true`, `false` | `false` |
982
+ | backgroundColor | Background color of the table | false | Hex color code, css color name | - |
983
+ | sortable | Enable sort for each column - click the column title to sort | false | `true`, `false` | `true` |
984
+ | sort | Column to sort by on initial page load. Sort direction is asc if unspecified. Can only sort by one column using this prop. If you need multi-column sort, use the order by clause in your sql in combination with this prop. | false | 'column name + asc/desc' | - |
985
+ | search | Add a search bar to the top of your table | false | `true`, `false` | `false` |
986
+ | downloadable | Enable download data button below the table on hover | false | `true`, `false` | `true` |
987
+ | formatColumnTitles | Enable auto-formatting of column titles. Turn off to show raw SQL column names | false | `true`, `false` | `true` |
988
+ | wrapTitles | Wrap column titles | false | `true`, `false` | `false` |
989
+ | compact | Enable a more compact table view that allows more content vertically and horizontally | false | `true`, `false` | `false` |
990
+ | link | Makes each row of your table a clickable link. Accepts a column or expression containing the link to use for each row in your table | false | column name, stored expression name, GSQL expression | - |
991
+ | showLinkCol | Whether to show the column supplied to the `link` attribute | false | `true`, `false` | `false` |
992
+ | generateMarkdown | Helper for writing Table syntax with many columns. When set to true, markdown for the Table including each `Column` contained within the query will be generated and displayed below the table. | false | `true`, `false` | `false` |
993
+ | emptySet | Sets behaviour for empty datasets. Can throw an error, a warning, or allow empty. When set to 'error', empty datasets will block builds in `build:strict`. Note this only applies to initial page load - empty datasets caused by input component changes (dropdowns, etc.) are allowed. | false | `error`, `warn`, `pass` | `error` |
994
+ | emptyMessage | Text to display when an empty dataset is received - only applies when `emptySet` is 'warn' or 'pass', or when the empty dataset is a result of an input component change (dropdowns, etc.). | false | string | "No records" |
995
+
996
+ ###### Groups
997
+
998
+ | Attribute | Description | Required | Options | Default |
999
+ |------|-------------|----------|---------|---------|
1000
+ | groupBy | Column or expression to use to create groups. Note that groups are currently limited to a single group column. | false | column name, stored expression name, GSQL expression | - |
1001
+ | groupType | How the groups are shown in the table. Can be accordion (expand/collapse) or section (group column values are merged across rows) | false | `accordion`, `section` | `accordion` |
1002
+ | subtotals | Whether to show aggregated totals for the groups | false | `true`, `false` | `false` |
1003
+ | subtotalFmt | Specify an override format to use in the subtotal row ([see available formats](#value-formatting)). Custom strings or values are unformatted by default. | false | Excel-style format, built-in format | - |
1004
+ | groupsOpen | [groupType=accordion] Whether to show the accordions as open on page load | false | `true`, `false` | `true` |
1005
+ | accordionRowColor | [groupType=accordion] Background color for the accordion row | false | Hex color code, css color name | - |
1006
+ | subtotalRowColor | [groupType=section] Background color for the subtotal row | false | Hex color code, css color name | - |
1007
+ | subtotalFontColor | [groupType=section] Font color for the subtotal row | false | Hex color code, css color name | - |
1008
+ | groupNamePosition | [groupType=section] Where the group label will appear in its cell | false | `top`, `middle`, `bottom` | `middle` |
1009
+
1010
+ ###### Column
1011
+
1012
+ Use the Column sub-component to choose specific columns to display in your table, and to apply options to specific columns. If you don't supply any columns to the table, it will display all columns from your query result.
1013
+
1014
+ Here's an example:
1015
+
1016
+ ```markdown
1017
+ <Table data=country_summary>
1018
+ <Column id=country />
1019
+ <Column id=category />
1020
+ <Column id=value_usd fmt=eur />
1021
+ <Column id=yoy title="Y/Y Growth" fmt=pct3 />
1022
+ </Table>
1023
+ ```
1024
+
1025
+ | Attribute | Description | Required | Options | Default |
1026
+ |------|-------------|----------|---------|---------|
1027
+ | id | Column id (from SQL query) | true | column name | - |
1028
+ | title | Override title of column | false | string | column name (formatted) |
1029
+ | description | Adds an info icon with description tooltip on hover | false | string | - |
1030
+ | align | Align column text | false | `left`, `center`, `right` | `left` |
1031
+ | fmt | Format the values in the column ([see available formats](#value-formatting)) | false | Excel-style format, built-in format | - |
1032
+ | fmtColumn | Column to use to format values in this column. This is used to achieve different value formats by row. The fmtColumn should contain strings of format codes - either Graphene built-in formats or Excel codes. | false | column name | - |
1033
+ | totalAgg | Specify an aggregation function to use for the total row. Accepts predefined functions, custom strings or values | false | `sum`, `mean`, `weightedMean`, `median`, `min`, `max`, `count`, `countDistinct`, custom string or value | `sum` |
1034
+ | totalFmt | Specify an override format to use in the total row ([see available formats](#value-formatting)). Custom strings or values are unformatted by default. | false | Excel-style format, built-in format | - |
1035
+ | weightCol | Column or expression to use as the weight values for weighted mean aggregation. If not specified, a weight of 1 for each value will be used and the result will be the same as the `mean` aggregation. | false | column name, stored expression name, GSQL expression | - |
1036
+ | wrap | Wrap column text | false | `true`, `false` | `false` |
1037
+ | wrapTitle | Wrap column title | false | `true`, `false` | `false` |
1038
+ | contentType | Lets you specify how to treat the content within a column. See below for contentType-specific options. | false | `link`, `image`, `delta`, `colorscale`, `html` | - |
1039
+ | colGroup | Group name to display above a group of columns. Columns with the same group name will get a shared header above them | false | string | - |
1040
+ | redNegatives | Conditionally sets the font color to red based on whether the selected value is less than 0 | false | `true`, `false` | `false` |
1041
+
1042
+ Column attributes for specific contentTypes:
1043
+
1044
+ Images (`contentType=image`)
1045
+
1046
+ | Attribute | Description | Required | Options | Default |
1047
+ |------|-------------|----------|---------|---------|
1048
+ | height | Height of image in pixels | false | number | original height of image |
1049
+ | width | Width of image in pixels | false | number | original width of image |
1050
+ | alt | Alt text for image | false | column name | Name of the image file (excluding the file extension) |
1051
+
1052
+ Links (`contentType=link`)
1053
+
1054
+ | Attribute | Description | Required | Options | Default |
1055
+ |------|-------------|----------|---------|---------|
1056
+ | linkLabel | Text to display for link | false | column name, string | raw url |
1057
+ | openInNewTab | Whether to open link in new tab | false | `true`, `false` | `false` |
1058
+
1059
+ Deltas (`contentType=delta`)
1060
+
1061
+ | Attribute | Description | Required | Options | Default |
1062
+ |------|-------------|----------|---------|---------|
1063
+ | deltaSymbol | Whether to show the up/down delta arrow symbol | false | `true`, `false` | `true` |
1064
+ | downIsGood | If present, negative comparison values appear in green, and positive values appear in red. | false | `true`, `false` | `false` |
1065
+ | showValue | Whether to show the delta value. Set this to false to show only the delta arrow indicator. | false | `true`, `false` | `true` |
1066
+ | neutralMin | Start of the range for 'neutral' values, which appear in grey font with a dash instead of an up/down arrow. By default, neutral is not applied to any values. | false | number | `0` |
1067
+ | neutralMax | End of the range for 'neutral' values, which appear in grey font with a dash instead of an up/down arrow. By default, neutral is not applied to any values. | false | number | `0` |
1068
+ | chip | Whether to display the delta as a 'chip', with a background color and border. | false | `true`, `false` | `false` |
1069
+
1070
+ Sparklines (`contentType=sparkline` | `contentType=sparkarea` | `contentType=sparkbar`)
1071
+
1072
+ | Attribute | Description | Required | Options | Default |
1073
+ |------|-------------|----------|---------|---------|
1074
+ | sparkX | Column within an array cell to use as the x-axis for the spark viz. Arrays can be created inside a query using the `"array_agg()"` function from DuckDB | false | column from array cell | - |
1075
+ | sparkY | Column within an array cell to use as the y-axis for the spark viz. Arrays can be created inside a query using the `"array_agg()"` function from DuckDB | false | column from array cell | - |
1076
+ | sparkYScale | Whether to truncate the y-axis | false | `true`, `false` | `false` |
1077
+ | sparkHeight | Height of the spark viz. Making the viz taller will increase the height of the full table row | false | number | `18` |
1078
+ | sparkWidth | Width of the spark viz | false | number | `90` |
1079
+ | sparkColor | Color of the spark viz | false | Hex color code, css color name | - |
1080
+
1081
+ Bar chart column (`contentType=bar`)
1082
+
1083
+ | Attribute | Description | Required | Options | Default |
1084
+ |------|-------------|----------|---------|---------|
1085
+ | barColor | Color of the bars. Affects positive bars only. See `negativeBarColor` to change color of negative bars | false | Hex color code, css color name | - |
1086
+ | negativeBarColor | Color of negative bars | false | Hex color code, css color name | - |
1087
+ | hideLabels | Whether to hide the data labels on the bars | false | `true`, `false` | `false` |
1088
+ | backgroundColor | Background color for bar chart | false | Hex color code, css color name | `transparent` |
1089
+
1090
+ Conditional formatting (`contentType=colorscale`)
1091
+
1092
+ | Attribute | Description | Required | Options | Default |
1093
+ |------|-------------|----------|---------|---------|
1094
+ | colorScale | Color to use for the scale | false | - | `green` |
1095
+ | colorMin | Set a minimum for the scale. Any values below that minimum will appear in the lowest color on the scale | false | number | min of column |
1096
+ | colorMid | Set a midpoint for the scale | false | number | mid of column |
1097
+ | colorMax | Set a maximum for the scale. Any values above that maximum will appear in the highest color on the scale | false | number | max of column |
1098
+ | colorBreakpoints | List of numbers to use as breakpoints for each color in your color scale. Should line up with the colors you provide in `colorScale` | false | list of numbers | - |
1099
+ | scaleColumn | Column or expression to use to define the color scale range. Values in this column will have their cell color determined by the value in the scaleColumn | false | column name, stored expression name, GSQL expression | - |
1100
+
1101
+ ### Input components
1102
+
1103
+ #### Text input
1104
+
1105
+ Creates a text input that can be used to filter or search. To see how to filter a query using a text input, see Filters.
1106
+
1107
+ Here's an example:
1108
+
1109
+ ```markdown
1110
+ <TextInput
1111
+ name=name_of_input
1112
+ title=Search
1113
+ />
1114
+ ```
1115
+
1116
+ The user-inputted text would then be referenced in GSQL via `$name_of_input`. For example:
1117
+
1118
+ ```sql
1119
+ select *
1120
+ from users
1121
+ where email ilike concat('%', $name_of_input, '%')
1122
+ ```
1123
+
1124
+ ##### All text input attributes
1125
+
1126
+ | Attribute | Description | Required | Options | Default |
1127
+ |------|-------------|----------|---------|---------|
1128
+ | name | Name of the text input, used to reference the selected value elsewhere as `"$name"` | true | string | - |
1129
+ | title | Title displayed above the text input | false | string | - |
1130
+ | placeholder | Alternative placeholder text displayed in the text input | false | string | `"Type to search"` |
1131
+ | hideDuringPrint | Hide the component when the report is printed | false | `true`, `false` | `true` |
1132
+ | description | Adds an info icon with description tooltip on hover | false | string | - |
1133
+
1134
+
1135
+ #### Date range
1136
+
1137
+ Creates a date picker that can be used to filter a query. Includes a set of preset ranges for quick selection of common date ranges (relative to the supplied end date). To see how to filter a query using an input component, see Filters.
1138
+
1139
+ Here's an example:
1140
+
1141
+ ```markdown
1142
+ <DateRange
1143
+ name=date_range_name
1144
+ data=orders_by_day
1145
+ dates=day
1146
+ />
1147
+ ```
1148
+
1149
+ The start and end dates for the user-selected range would then be referenced in GSQL as `$date_range_name_start` and `$date_range_name_end` at the end. For example:
1150
+
1151
+ ```sql
1152
+ select *
1153
+ from orders
1154
+ where created_at > $date_range_name_start and < $date_range_name_end
1155
+ ```
1156
+
1157
+ ##### All date range attributes
1158
+
1159
+ | Attribute | Description | Required | Options | Default |
1160
+ |------|-------------|----------|---------|---------|
1161
+ | name | Name of the DateRange, used to reference the selected values elsewhere as `"$name_start"` or `"$name_end"` | true | string | - |
1162
+ | data | Query name, wrapped in curly braces | false | query name | - |
1163
+ | dates | Column or expression from the query containing date range to span | false | column name, stored expression name, GSQL expression | - |
1164
+ | start | A manually specified start date to use for the range | false | string formatted YYYY-MM-DD | - |
1165
+ | end | A manually specified end date to use for the range | false | string formatted YYYY-MM-DD | - |
1166
+ | title | Title to display in the Date Range component | false | string | - |
1167
+ | presetRanges | Customize "Select a Range" drop down, by including preset range options | false | list of values e.g. `"Last 7 Days, Last 30 Days"`. Allowed values: `Last 7 Days`, `Last 30 Days`, `Last 90 Days`, `Last 365 Days`, `Last 3 Months`, `Last 6 Months`, `Last 12 Months`, `Last Month`, `Last Year`, `Month to Date`, `Month to Today`, `Year to Date`, `Year to Today`, `All Time` | - |
1168
+ | defaultValue | Accepts preset in string format to apply default value in Date Range picker | false | `"Last 7 Days"`, `"Last 30 Days"`, `"Last 90 Days"`, `"Last 365 Days"`, `"Last 3 Months"`, `"Last 6 Months"`, `"Last 12 Months"`, `"Last Month"`, `"Last Year"`, `"Month to Date"`, `"Month to Today"`, `"Year to Date"`, `"Year to Today"`, `"All Time"` | - |
1169
+ | hideDuringPrint | Hide the component when the report is printed | false | `true`, `false` | `true` |
1170
+ | description | Adds an info icon with description tooltip on hover | false | string | - |
1171
+
1172
+
1173
+ #### Dropdown
1174
+
1175
+ Creates a dropdown menu with a list of options that can be selected. The selected option can be used to filter queries or in markdown. To see how to filter a query using a dropdown, see Filters.
1176
+
1177
+ Here's an example:
1178
+
1179
+ ````markdown
1180
+ ```sql statuses
1181
+ select distinct status from orders
1182
+ ```
1183
+
1184
+ <Dropdown
1185
+ title="Select Order Status"
1186
+ name="status_dropdown"
1187
+ data="statuses"
1188
+ value="status"
1189
+ defaultValue="Complete"
1190
+ />
1191
+ ````
1192
+
1193
+ The user-selected value would then be referenced in GSQL as `$status_dropdown`. For example:
1194
+
1195
+ ```sql
1196
+ select *
1197
+ from orders
1198
+ where status = $status_dropdown
1199
+ ```
1200
+
1201
+ ##### All dropdown attributes
1202
+
1203
+ | Attribute | Description | Required | Options | Default |
1204
+ |------|-------------|----------|---------|---------|
1205
+ | name | Name of the dropdown, used to reference the selected value elsewhere as `"$name"` | true | - | - |
1206
+ | data | Query name, wrapped in curly braces | false | query name | - |
1207
+ | value | Column name from the query containing values to pick from | false | column name | - |
1208
+ | multiple | Enables multi-select which returns a list | false | `true`, `false` | `false` |
1209
+ | defaultValue | Value to use when the dropdown is first loaded. Must be one of the options in the dropdown. Lists supported for multi-select. | false | value from dropdown, list of values e.g. `"Value 1, Value 2"` | - |
1210
+ | selectAllByDefault | Selects and returns all values, multiple attribute required | false | `true`, `false` | `false` |
1211
+ | noDefault | Stops any default from being selected. Overrides any set `defaultValue`. | false | boolean | `false` |
1212
+ | disableSelectAll | Removes the `"Select all"` button. Recommended for large datasets. | false | boolean | `false` |
1213
+ | label | Column name from the query containing labels to display instead of the values (e.g., you may want to have the drop-down use `customer_id` as the value, but show `customer_name` to your users) | false | column name | Uses the column in value |
1214
+ | title | Title to display above the dropdown | false | string | - |
1215
+ | order | Column to sort options by, with optional ordering keyword | false | column name [ `asc`, `desc` ] | Ascending based on dropdown value (or label, if specified) |
1216
+ | where | SQL where fragment to filter options by (e.g., where sales > 40000) | false | SQL where clause | - |
1217
+ | hideDuringPrint | Hide the component when the report is printed | false | `true`, `false` | `true` |
1218
+ | description | Adds an info icon with description tooltip on hover | false | string | - |
1219
+
1220
+ ###### DropdownOption
1221
+
1222
+ The `DropdownOption` sub-component can be used to manually add options to a dropdown. This is useful to add a default option, or to add options that are not in a query.
1223
+
1224
+ Here's an example:
1225
+
1226
+ ```markdown
1227
+ <Dropdown name=hardcoded>
1228
+ <DropdownOption valueLabel="Option One" value=1 />
1229
+ <DropdownOption valueLabel="Option Two" value=2 />
1230
+ <DropdownOption valueLabel="Option Three" value=3 />
1231
+ </Dropdown>
1232
+ ```
1233
+
1234
+ | Attribute | Description | Required | Options | Default |
1235
+ |------|-------------|----------|---------|---------|
1236
+ | value | Value to use when the option is selected | true | - | - |
1237
+ | valueLabel | Label to display for the option in the dropdown | false | - | Uses the value |
1238
+
1239
+ ### Other components
1240
+
1241
+ `<Row></Row>` - Evenly distributes components inside along the same row.
1242
+
1243
+ ### Value formatting
1244
+
1245
+ The easiest way to format numbers and dates in Graphene is through component attributes. You can pass in either of the following:
1246
+
1247
+ * [Excel-style format codes](https://support.microsoft.com/en-us/office/number-format-codes-in-excel-for-mac-5026bbd6-04bc-48cd-bf33-80f18b4eae68) (e.g., `fmt="$#,##0.0"`)
1248
+ * [Graphene's built-in formats](#built-in-formats) (e.g., `fmt=usd2k`)
1249
+
1250
+ For example, you can use the `fmt` attribute to format values inside a BigValue component:
1251
+
1252
+ ```markdown
1253
+ <BigValue
1254
+ data=sales_data
1255
+ value=sales
1256
+ fmt="$#,##0"
1257
+ />
1258
+ ```
1259
+
1260
+ Within charts, you can format individual columns using `xFmt` and `yFmt`:
1261
+
1262
+ ```markdown
1263
+ <LineChart
1264
+ data=sales_data
1265
+ x=date
1266
+ y=sales
1267
+ xFmt="m/d"
1268
+ yFmt=eur
1269
+ />
1270
+ ```
1271
+
1272
+ In the example above, `xFmt` is passing in an Excel-style code to format the dates and `yFmt` is referencing a built-in format (see the full list of supported formats below).
1273
+
1274
+ **Date formatting**
1275
+
1276
+ Formatting does not apply to the date axis of a chart. For example, if you set `xFmt` to `"m/d/yy"`, you will only see that formatting reflected in your chart tooltips and annotations. This is to ensure that the chart axis labels have the correct spacing.
1277
+
1278
+ #### Built-in Formats
1279
+
1280
+ Graphene supports a variety of date/time, number, percentage, and currency formats.
1281
+
1282
+ ##### Auto-Formatting
1283
+
1284
+ Wherever you see `auto` listed beside a format, that means Graphene will automatically format your value based on the context it is in.
1285
+
1286
+ For example, Graphene automatically formats large numbers into shortened versions based on the size of the median number in a column (e.g., 4,000,000 → 4M).
1287
+
1288
+ You can choose to handle these numbers differently by choosing a specific format code. For example, if Graphene is formatting a column as millions, but you want to see all numbers in thousands, you could use the `num0k` format, which will show all numbers in the column in thousands with 0 decimal places.
1289
+
1290
+ ##### Dates
1291
+
1292
+ Graphene supports the following date formats:
1293
+
1294
+ * `ddd` - Short day name (e.g., Mon, Tue)
1295
+ * `dddd` - Full day name (e.g., Monday, Tuesday)
1296
+ * `mmm` - Short month name (e.g., Jan, Feb)
1297
+ * `mmmm` - Full month name (e.g., January, February)
1298
+ * `yyyy` - Four-digit year
1299
+ * `shortdate` - Short date format (e.g., Jan 9/22)
1300
+ * `longdate` - Long date format (e.g., January 9, 2022)
1301
+ * `fulldate` - Full date format (e.g., Monday January 9, 2022)
1302
+ * `mdy` - Month/day/year (e.g., 1/9/22)
1303
+ * `dmy` - Day/month/year (e.g., 9/1/22)
1304
+ * `hms` - Time format (e.g., 11:45:03 AM)
1305
+
1306
+ ##### Currencies
1307
+
1308
+ Supported currencies include USD, AUD, BRL, CAD, CNY, EUR, GBP, JPY, INR, KRW, NGN, RUB, and SEK.
1309
+
1310
+ In order to use currency tags, use the currency code, optionally appended with:
1311
+
1312
+ * a number indicating the number of decimal places to show (0-2)
1313
+ * a letter indicating the order of magnitude to show ("","k", "m", "b")
1314
+
1315
+ For example, the available tags for USD are:
1316
+
1317
+ * `usd` (auto) - Automatically formats based on value size
1318
+ * `usd0`, `usd1`, `usd2` - USD with 0, 1, or 2 decimal places
1319
+ * `usd0k`, `usd1k`, `usd2k` - USD in thousands (e.g., $64k)
1320
+ * `usd0m`, `usd1m`, `usd2m` - USD in millions (e.g., $42M)
1321
+ * `usd0b`, `usd1b`, `usd2b` - USD in billions (e.g., $1B)
1322
+
1323
+ Similar patterns apply to other supported currencies.
1324
+
1325
+ ##### Numbers
1326
+
1327
+ The default number format (when no `fmt` is specified) automatically handles decimal places and summary units (in the same way that `usd` does for currency).
1328
+
1329
+ Available number formats:
1330
+
1331
+ * `num0`, `num1`, `num2`, `num3`, `num4` - Numbers with 0-4 decimal places
1332
+ * `num0k`, `num1k`, `num2k` - Numbers in thousands (e.g., 64k)
1333
+ * `num0m`, `num1m`, `num2m` - Numbers in millions (e.g., 42M)
1334
+ * `num0b`, `num1b`, `num2b` - Numbers in billions (e.g., 1B)
1335
+ * `id` - Integer format for IDs
1336
+ * `fract` - Fraction format
1337
+ * `mult`, `mult0`, `mult1`, `mult2` - Multiplier format (e.g., 5.32x)
1338
+ * `sci` - Scientific notation
1339
+
1340
+ ##### Percentages
1341
+
1342
+ Available percentage formats:
430
1343
 
431
- The following components are available:
432
- - [BarChart](./data_apps/components/charts/bar-chart.md)
433
- - [LineChart](./data_apps/components/charts/line-chart.md)
434
- - [AreaChart](./data_apps/components/charts/area-chart.md)
435
- - PieChart - takes a `category` and `value` attribute
436
- - Row - evenly distributes its children in a row
437
- - [DateRange](./data_apps/components/inputs/date-range.md)
438
- - [BigValue](./data_apps/components/data/big-value.md)
439
- - [Table](./data_apps/components/data/table.md)
440
- - [TextInput](./data_apps/components/inputs/text-input.md)
1344
+ * `pct` (auto) - Automatically formats percentages based on value
1345
+ * `pct0` - Percentage with 0 decimal places (e.g., 73%)
1346
+ * `pct1` - Percentage with 1 decimal place (e.g., 73.1%)
1347
+ * `pct2` - Percentage with 2 decimal places (e.g., 73.10%)
1348
+ * `pct3` - Percentage with 3 decimal places (e.g., 73.100%)
441
1349
 
442
- ## Using the Graphene CLI
1350
+ ## Graphene CLI
443
1351
 
444
1352
  These are the available commands:
445
- - `npm run graphene check` - Checks the syntax for the entire Graphene project.
1353
+ - `npm run graphene check` - Checks the syntax (GSQL and Markdown) for the entire Graphene project.
1354
+ - `npm run graphene check <mdPath>` - Checks the syntax for a specified Graphene markdown file. Will also do a runtime check if the dev server is running, and if successful, take a full page screenshot to a temp directory for the agent to view.
1355
+ - `npm run graphene check <mdPath> --chart "<chartTitle>"` - Same as above, except if the runtime check is successful, only takes a screenshot of the specified chart. `<chartTitle>` must match (case sensitive) the `title` attribute on the chart component. `-c` can be used as shorthand for `--chart`.
446
1356
  - `npm run graphene compile "<GSQL>"` - Shows how GSQL is translated into the underlying database SQL.
447
1357
  - `npm run graphene run "<GSQL>"` - Runs a GSQL query. The tables and semantics defined in all .gsql files in the project are available for the query to use.
448
- - `npm run graphene serve` - Starts (or restarts) the dev server, which allows the user to view their Graphene app on localhost.
449
- - `npm run graphene view <mdPath>` - Captures a screenshot of a given .md file, along with any errors encountered.
450
1358
 
451
- ## AGENT INSTRUCTIONS
1359
+ # AGENT INSTRUCTIONS
452
1360
 
453
1361
  Follow these guidelines when working in a Graphene project.
454
1362
  - When formulating GSQL queries:
455
1363
  - First check all available stored expressions to see if there are any you can use. DO NOT redefine important business definitions like `profit` if they've already been modeled!
456
1364
  - Run your GSQL queries in the CLI first, _before_ you write them to a file. This way you can reason about the results to make sure they make sense.
457
- - Do not try to search the web for Graphene-specific info; you will not find anything. All the documentation is in /docs.
1365
+ - Do not try to search the web for Graphene-specific info; you will not find anything. All the documentation is here in graphene.md.
458
1366
  - When writing to a .gsql file, check your code with `npm run graphene check`.
459
1367
  - When writing to a Graphene .md file:
460
- - First read ALL the linked component docs listed in [Components](#components) above.
461
- - Check your code with `npm run graphene check`.
462
- - Once there are no syntax errors, do a visual check by running `npm run graphene view <mdPath>` and looking at the .png it generates.
1368
+ - Always check your code with `npm run graphene check <mdPath>`. Run the command with full permissions because the screenshot may not work in a sandbox.
1369
+ - Then do a visual check by either a) looking at the screenshot that `npm run graphene check <mdPath>` creates, or b) using your browser tool to open the .md file at `localhost:<port>/mdPath` (without the .md extension; default port 4000).
1370
+ - Critique what you see: Are all the data values formatted in a way that is easy to read? Does the shape of the visualized data require an adjustment to scale, axis min/max, etc.? Are any visualizations missing data altogether? Is that visualization type really the best way to paint the picture? Etc.