@graphenedata/cli 0.0.9 → 0.0.11
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.
- package/cli.ts +6 -1
- package/dist/cli/cli.js +155 -143
- package/dist/docs/agent-instructions.md +18 -0
- package/dist/docs/graphene.md +310 -182
- package/dist/ui/app.css +8 -10
- package/dist/ui/internal/NavSidebar.svelte +24 -8
- package/dist/ui/internal/NavSidebarHMR.svelte +8 -0
- package/dist/ui/internal/queryEngine.ts +4 -2
- package/dist/ui/web.js +1 -1
- package/package.json +1 -1
package/dist/docs/graphene.md
CHANGED
|
@@ -8,6 +8,7 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
8
8
|
|
|
9
9
|
**Table of Contents**
|
|
10
10
|
|
|
11
|
+
- [Graphene CLI](#graphene-cli)
|
|
11
12
|
- [Graphene SQL (GSQL)](#graphene-sql-gsql)
|
|
12
13
|
- [`table` statements](#table-statements)
|
|
13
14
|
- [Base columns (required)](#base-columns-required)
|
|
@@ -18,14 +19,22 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
18
19
|
- [`select` statements](#select-statements)
|
|
19
20
|
- [Using join relationships in queries](#using-join-relationships-in-queries)
|
|
20
21
|
- [Multi-hop joins](#multi-hop-joins)
|
|
21
|
-
- [Using stored expressions in queries](#using-stored-expressions-in-queries)
|
|
22
|
+
- [Using scalar stored expressions (dimensions) in queries](#using-scalar-stored-expressions-dimensions-in-queries)
|
|
23
|
+
- [Using aggregative stored expressions (measures) in queries](#using-aggregative-stored-expressions-measures-in-queries)
|
|
22
24
|
- [Safe aggregation in fan-outs](#safe-aggregation-in-fan-outs)
|
|
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
|
+
- [Available functions](#available-functions)
|
|
29
|
+
- [Aggregate functions](#aggregate-functions)
|
|
30
|
+
- [Date and time functions](#date-and-time-functions)
|
|
31
|
+
- [Conditional Functions](#conditional-functions)
|
|
32
|
+
- [Math Functions](#math-functions)
|
|
33
|
+
- [Type Conversion](#type-conversion)
|
|
34
|
+
- [Subqueries, CTEs, and chaining queries](#subqueries-ctes-and-chaining-queries)
|
|
35
|
+
- [Other miscellaneous details](#other-miscellaneous-details)
|
|
23
36
|
- [`table as` statements](#table-as-statements)
|
|
24
37
|
- [`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
38
|
- [Graphene data apps (dashboards)](#graphene-data-apps-dashboards)
|
|
30
39
|
- [Visualization components](#visualization-components)
|
|
31
40
|
- [Bar chart](#bar-chart)
|
|
@@ -68,8 +77,6 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
68
77
|
- [Input components](#input-components)
|
|
69
78
|
- [Text input](#text-input)
|
|
70
79
|
- [All text input attributes](#all-text-input-attributes)
|
|
71
|
-
- [Date range](#date-range)
|
|
72
|
-
- [All date range attributes](#all-date-range-attributes)
|
|
73
80
|
- [Dropdown](#dropdown)
|
|
74
81
|
- [All dropdown attributes](#all-dropdown-attributes)
|
|
75
82
|
- [DropdownOption](#dropdownoption)
|
|
@@ -81,16 +88,27 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
81
88
|
- [Currencies](#currencies)
|
|
82
89
|
- [Numbers](#numbers)
|
|
83
90
|
- [Percentages](#percentages)
|
|
84
|
-
- [Graphene CLI](#graphene-cli)
|
|
85
|
-
- [AGENT INSTRUCTIONS](#agent-instructions)
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
# Graphene CLI
|
|
93
|
+
|
|
94
|
+
These are the available commands:
|
|
95
|
+
- `npm run graphene check` - Checks the syntax (GSQL and Markdown) for the entire Graphene project.
|
|
96
|
+
- `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.
|
|
97
|
+
- `npm run graphene check [mdPath] -c [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.
|
|
98
|
+
- `npm run graphene compile [GSQL | gsqlPath]` - Shows how GSQL is translated into the underlying database SQL.
|
|
99
|
+
- `npm run graphene run [GSQL | gsqlPath]` - Runs a GSQL query. The tables and semantics defined in all .gsql files in the project are available for the query to use.
|
|
100
|
+
|
|
101
|
+
# Graphene SQL (GSQL)
|
|
88
102
|
|
|
89
|
-
GSQL is comprised of
|
|
103
|
+
GSQL is comprised of four primary statements:
|
|
104
|
+
1. `table` statements that declare existing tables and semantic metadata
|
|
105
|
+
2. `select` statements that query tables
|
|
106
|
+
3. `table as` statements that create new tables using `select`
|
|
107
|
+
4. `extend` statements that attach semantic metadata to tables
|
|
90
108
|
|
|
91
|
-
|
|
109
|
+
## `table` statements
|
|
92
110
|
|
|
93
|
-
`table` statements
|
|
111
|
+
`table` statements declare tables that already exist in your database. Here's an example of two tables, `orders` and `users`, in GSQL.
|
|
94
112
|
|
|
95
113
|
```sql
|
|
96
114
|
table orders (
|
|
@@ -123,25 +141,25 @@ table users (
|
|
|
123
141
|
|
|
124
142
|
We can break down a table statement into three parts: [base columns](#base-columns-required), [join relationships](#join-relationships), and [stored expressions](#stored-expressions) (aka dimensions and measures).
|
|
125
143
|
|
|
126
|
-
|
|
144
|
+
### Base columns (required)
|
|
127
145
|
|
|
128
146
|
The base column set is simply a reflection of the underlying database table's schema. Similar to `create table` statements in regular SQL DDL, you list each column's name and data type. One column must be designated as the primary key.
|
|
129
147
|
|
|
130
|
-
|
|
148
|
+
### Join relationships
|
|
131
149
|
|
|
132
150
|
Join relationships in a `table` statement declare joins that can be used when querying them. This makes query writing easier and more foolproof. See [Using join relationships in queries](#using-join-relationships-in-queries) below for how to use modeled joins in queries.
|
|
133
151
|
|
|
134
152
|
The other main difference about joins in GSQL vs. regular SQL is that you have to explain if there are many rows in the left table for each row in the right table, or vice versa. This additional bit of information allows Graphene to prevent incorrect aggregation as a result of row duplication (aka fan-out) through joins. See [Safe aggregation in fan-outs](#safe-aggregation-in-fan-outs) for more details.
|
|
135
153
|
|
|
136
|
-
This information is provided with the two supported join types, `
|
|
137
|
-
- `
|
|
138
|
-
- `
|
|
154
|
+
This information is provided with the two supported join types, `join one` and `join many`:
|
|
155
|
+
- `join one` is used if there are many rows in the **left** table for each row in the **right** table.
|
|
156
|
+
- `join many` is used if there are many rows in the **right** table for each row in the **left** table.
|
|
139
157
|
|
|
140
158
|
In the example above with `orders` and `users`, the joins confirm that there are many orders per user, and only one user per order.
|
|
141
159
|
|
|
142
160
|
Note that all joins in GSQL are left outer joins. There is no inner, right, or cross join.
|
|
143
161
|
|
|
144
|
-
|
|
162
|
+
#### Multiple join relationships between the same two tables
|
|
145
163
|
|
|
146
164
|
Sometimes there are multiple valid ways to join two tables together. You can model this in Graphene by aliasing the various joins with `as`, just as you would in normal SQL. For example:
|
|
147
165
|
|
|
@@ -164,12 +182,12 @@ table users (
|
|
|
164
182
|
)
|
|
165
183
|
```
|
|
166
184
|
|
|
167
|
-
|
|
185
|
+
#### Best practices for modeling join relationships
|
|
168
186
|
|
|
169
187
|
- For a given `table` statement, only model joins that are directly on that table. Multi-hop join paths do not need to be written explicitly in order for queries to traverse them.
|
|
170
188
|
- A join between two tables should be modeled in both the respective `table` statements. This may seem redundant but it offers more flexibility for queries to choose which table to set in the `from` (remember that direction matters in queries since all joins are left joins).
|
|
171
189
|
|
|
172
|
-
|
|
190
|
+
### Stored expressions
|
|
173
191
|
|
|
174
192
|
**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.
|
|
175
193
|
|
|
@@ -194,8 +212,7 @@ table orders (
|
|
|
194
212
|
)
|
|
195
213
|
```
|
|
196
214
|
|
|
197
|
-
|
|
198
|
-
### `select` statements
|
|
215
|
+
## `select` statements
|
|
199
216
|
|
|
200
217
|
`select` is how you write queries in Graphene SQL. It behaves similarly to regular SQL except in the following ways:
|
|
201
218
|
- It can invoke join relationships and stored expressions from `table` statements.
|
|
@@ -203,7 +220,7 @@ table orders (
|
|
|
203
220
|
|
|
204
221
|
These differences are described in the sections below.
|
|
205
222
|
|
|
206
|
-
|
|
223
|
+
### Using join relationships in queries
|
|
207
224
|
|
|
208
225
|
If a `table` has join relationships declared in it, a `select` query on that table can leverage that join without needing to write its own join statement. This is helpful for query writers who have not memorized all the correct join keys.
|
|
209
226
|
|
|
@@ -237,7 +254,7 @@ order by 2 desc
|
|
|
237
254
|
limit 10
|
|
238
255
|
```
|
|
239
256
|
|
|
240
|
-
|
|
257
|
+
#### Multi-hop joins
|
|
241
258
|
|
|
242
259
|
Sometimes you need to access columns or stored expressions in a table that is two or more joins away from the `from` table. To do this, simply use more dot operators to trace the desired join path. For example, say there is another table added to our project, `countries`:
|
|
243
260
|
|
|
@@ -278,7 +295,7 @@ order by 2 desc
|
|
|
278
295
|
limit 10
|
|
279
296
|
```
|
|
280
297
|
|
|
281
|
-
|
|
298
|
+
### Using scalar stored expressions (dimensions) in queries
|
|
282
299
|
|
|
283
300
|
A stored expression can be invoked in a query by simply referencing it by name.
|
|
284
301
|
|
|
@@ -326,7 +343,9 @@ group by 1
|
|
|
326
343
|
|
|
327
344
|
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.
|
|
328
345
|
|
|
329
|
-
|
|
346
|
+
### Using aggregative stored expressions (measures) in queries
|
|
347
|
+
|
|
348
|
+
The macro concept is important to understand when invoking stored expressions that are **aggregative** (ie. contain agg functions), which can also be called "measures." Here's an example.
|
|
330
349
|
|
|
331
350
|
```sql
|
|
332
351
|
-- Profit by month
|
|
@@ -349,41 +368,218 @@ group by 1
|
|
|
349
368
|
order by 1 asc
|
|
350
369
|
```
|
|
351
370
|
|
|
352
|
-
|
|
371
|
+
[CRITICAL!] This means:
|
|
372
|
+
- You would NEVER wrap a measure in an agg function like `sum(my_measure)`, for the same reason that you cannot do `SUM(SUM(foo))` in regular SQL.
|
|
373
|
+
- You would NEVER group by a measure like `group by my_measure`, for the same reason that you cannot do `GROUP BY SUM(foo)` in regular SQL.
|
|
374
|
+
- You CAN wrap a measure in a scalar function like `floor(my_measure)`, for the same reason that can do `FLOOR(SUM(foo))` in regular SQL.
|
|
375
|
+
- You CAN compose measures together in expressions like `my_measure + my_other_measure`, for the same reason that you can do `SUM(foo) + SUM(bar)` in regular SQL.
|
|
376
|
+
|
|
377
|
+
Another way of thinking about this is that measures are "self-aggregating."
|
|
378
|
+
|
|
379
|
+
### Safe aggregation in fan-outs
|
|
380
|
+
|
|
381
|
+
Aggregations in GSQL are fan-out safe. In the event of a join, Graphene knows which values are duplicated ("fanned out") and will discard the duplicates when calculating aggregates.
|
|
382
|
+
|
|
383
|
+
To do this, Graphene assumes that the column or expression you're aggregating is only dependent on one table. The grain of this table establishes the "correct" grain to compute the aggregate over.
|
|
384
|
+
|
|
385
|
+
>NOTE: Graphene does not support aggregating over expressions that depend on multiple tables (e.g. `sum(table1.col - table2.col)`). To work around this, you can consolidate the expression into a dimension e.g. `my_dim: col - table2.col` and then aggregate over that dimension.
|
|
386
|
+
|
|
387
|
+
Here's an example of a fan-out:
|
|
388
|
+
|
|
389
|
+
```sql
|
|
390
|
+
table orders (
|
|
391
|
+
id BIGINT primary_key
|
|
392
|
+
customer_name VARCHAR
|
|
393
|
+
amt_with_shipping FLOAT
|
|
394
|
+
|
|
395
|
+
join many order_items on id = order_items.order_id
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
table order_items (
|
|
399
|
+
id BIGINT primary_key
|
|
400
|
+
order_id BIGINT
|
|
401
|
+
product VARCHAR
|
|
402
|
+
price FLOAT
|
|
403
|
+
|
|
404
|
+
join one orders on order_id = orders.id
|
|
405
|
+
)
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
With the following data:
|
|
409
|
+
|
|
410
|
+
**orders**
|
|
411
|
+
|
|
412
|
+
| id | customer_name | amt_with_shipping |
|
|
413
|
+
|----|---------------|-------------------|
|
|
414
|
+
| 1 | Alice | 110.00 |
|
|
415
|
+
| 2 | Bob | 85.00 |
|
|
416
|
+
|
|
417
|
+
**order_items**
|
|
418
|
+
|
|
419
|
+
| id | order_id | product | price |
|
|
420
|
+
|----|----------|---------|-------|
|
|
421
|
+
| 1 | 1 | Widget | 60.00 |
|
|
422
|
+
| 2 | 1 | Gadget | 40.00 |
|
|
423
|
+
| 3 | 2 | Widget | 60.00 |
|
|
424
|
+
| 4 | 2 | Thingamajig | 15.00 |
|
|
353
425
|
|
|
354
|
-
|
|
426
|
+
When joining orders to order_items, the result looks like:
|
|
355
427
|
|
|
356
|
-
|
|
428
|
+
**orders joined to order_items**
|
|
429
|
+
|
|
430
|
+
| orders.id | customer_name | amt_with_shipping | order_items.id | product | price |
|
|
431
|
+
|-----------|---------------|-------------------|----------------|---------|-------|
|
|
432
|
+
| 1 | Alice | 110.00 | 1 | Widget | 60.00 |
|
|
433
|
+
| 1 | Alice | 110.00 | 2 | Gadget | 40.00 |
|
|
434
|
+
| 2 | Bob | 85.00 | 3 | Widget | 60.00 |
|
|
435
|
+
| 2 | Bob | 85.00 | 4 | Thingamajig | 15.00 |
|
|
436
|
+
|
|
437
|
+
Notice that both orders appear twice because they each contain two items. In regular SQL, if you naively computed `sum(amt_with_shipping)` over this joined result, you'd get 390.00 instead of the correct 195.00. In GSQL, because `amt_with_shipping` belongs to the `orders` table, Graphene knows to compute the sum at the `orders` grain, yielding 195.00.
|
|
438
|
+
|
|
439
|
+
Here's how you can use this to simplify your queries. Say you want to see total order value and total item count by customer. In GSQL, you can write this directly:
|
|
440
|
+
|
|
441
|
+
```sql
|
|
442
|
+
select
|
|
443
|
+
customer_name,
|
|
444
|
+
sum(orders.amt_with_shipping) as total_spent,
|
|
445
|
+
count(order_items.id) as items_purchased
|
|
446
|
+
from orders
|
|
447
|
+
group by customer_name
|
|
448
|
+
```
|
|
357
449
|
|
|
358
|
-
|
|
450
|
+
This returns:
|
|
359
451
|
|
|
360
|
-
|
|
452
|
+
| customer_name | total_spent | items_purchased |
|
|
453
|
+
|---------------|-------------|-----------------|
|
|
454
|
+
| Alice | 110.00 | 2 |
|
|
455
|
+
| Bob | 85.00 | 2 |
|
|
361
456
|
|
|
362
|
-
|
|
457
|
+
In regular SQL, you'd need a subquery or CTE to avoid the fan-out problem:
|
|
363
458
|
|
|
364
459
|
```sql
|
|
460
|
+
WITH order_totals AS (
|
|
461
|
+
SELECT customer_name, SUM(amt_with_shipping) as total_spent
|
|
462
|
+
FROM orders
|
|
463
|
+
GROUP BY customer_name
|
|
464
|
+
),
|
|
465
|
+
item_counts AS (
|
|
466
|
+
SELECT o.customer_name, COUNT(oi.id) as items_purchased
|
|
467
|
+
FROM orders o
|
|
468
|
+
JOIN order_items oi ON o.id = oi.order_id
|
|
469
|
+
GROUP BY o.customer_name
|
|
470
|
+
)
|
|
365
471
|
SELECT
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
))
|
|
372
|
-
-
|
|
373
|
-
SUM(DISTINCT (cast(cast(concat('0x', substr(to_hex(md5(CAST(users_0.`id` AS STRING))), 1, 15)) as int64) as numeric) * 4294967296 + cast(cast(concat('0x', substr(to_hex(md5(CAST(users_0.`id` AS STRING))), 16, 8)) as int64) as numeric)) * 0.000000001)
|
|
374
|
-
)/(1*1.0)) AS FLOAT64))/NULLIF(COUNT(DISTINCT CASE WHEN users_0.`age` IS NOT NULL THEN users_0.`id` END),0) as `col_0`
|
|
375
|
-
FROM `bigquery-public-data.thelook_ecommerce.orders` as base
|
|
376
|
-
LEFT JOIN `bigquery-public-data.thelook_ecommerce.users` AS users_0
|
|
377
|
-
ON users_0.`id`=base.`user_id`
|
|
472
|
+
ot.customer_name,
|
|
473
|
+
ot.total_spent,
|
|
474
|
+
ic.items_purchased
|
|
475
|
+
FROM order_totals ot
|
|
476
|
+
JOIN item_counts ic ON ot.customer_name = ic.customer_name
|
|
378
477
|
```
|
|
379
478
|
|
|
380
|
-
|
|
479
|
+
### Available functions
|
|
480
|
+
|
|
481
|
+
Function availability varies depending on the connected database, noted in the tables below. Check your package.json to see what database you are connected to.
|
|
482
|
+
|
|
483
|
+
#### Aggregate functions
|
|
484
|
+
|
|
485
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
486
|
+
| - | - | - | - | - | - | - |
|
|
487
|
+
| count(), count(*) | Counts the number of rows. | - | Number | x | x | x |
|
|
488
|
+
| count(column) | Counts the number of non-null values in a column. | `column` - Any column/expression | Number | x | x | x |
|
|
489
|
+
| count(distinct column) | Counts the number of distinct non-null values in a column. | `column` - Any column/expression | Number | x | x | x |
|
|
490
|
+
| sum(column) | Calculates the sum of numeric values. | `column` - Numeric column/expression | Number | x | x | x |
|
|
491
|
+
| avg(column) | Calculates the average (mean) of numeric values. | `column` - Numeric column/expression | Number | x | x | x |
|
|
492
|
+
| min(column) | Returns the minimum value. | `column` - Any comparable column/expression | Same as input | x | x | x |
|
|
493
|
+
| max(column) | Returns the maximum value. | `column` - Any comparable column/expression | Same as input | x | x | x |
|
|
494
|
+
| string_agg(column) | Concatenates string values. | `column` - String column/expression | String | x | x | x |
|
|
495
|
+
| stddev(column) | Calculates the standard deviation. | `column` - Numeric column/expression | Number | x | x | x |
|
|
496
|
+
| pXX(column) | Returns the XXth percentile (e.g., p50, p975, p9999). | `column` - Numeric column/expression | Number | x | x (≤p99) | x |
|
|
497
|
+
|
|
498
|
+
#### Date and time functions
|
|
499
|
+
|
|
500
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
501
|
+
| - | - | - | - | - | - | - |
|
|
502
|
+
| current_date() | Returns the current date. | - | Date | x | x | x |
|
|
503
|
+
| current_time() | Returns the current time. | - | Timestamp | x | x | x |
|
|
504
|
+
| current_timestamp() | Returns the current timestamp. | - | Timestamp | x | x | x |
|
|
505
|
+
| local_timestamp() | Returns the local timestamp. | - | Timestamp | x | x | x |
|
|
506
|
+
| current_datetime() | Returns the current datetime (BigQuery only). | - | Timestamp | | x | |
|
|
507
|
+
| date_trunc(unit, date) | Truncates date/timestamp to unit (DuckDB). | `unit` - Quoted date part ('year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second') ; `date` - Timestamp | Date or timestamp | x | | |
|
|
508
|
+
| date_trunc(date, unit) | Truncates date/timestamp to unit (BigQuery). | `date` - Date or timestamp ; `unit` - Unquoted date part (year, quarter, month, week, day, hour, minute, second) | Date or timestamp | | x | |
|
|
509
|
+
| extract(unit from timestamp) | Extracts a date part from timestamp. | `unit` - Date part (year, quarter, month, week, day, hour, minute, second, day_of_week, day_of_year) ; `timestamp` - Timestamp/date | Number | x | x | x |
|
|
510
|
+
| timestamp_diff(start, end, unit) | Calculates difference between timestamps (BigQuery). | `start` - Timestamp ; `end` - Timestamp ; `unit` - Keyword (year, quarter, month, week, day, hour, minute, second) | Number | | x | |
|
|
511
|
+
|
|
512
|
+
#### Conditional Functions
|
|
513
|
+
|
|
514
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
515
|
+
| - | - | - | - | - | - | - |
|
|
516
|
+
| if(condition, trueValue, falseValue) | Returns one of two values based on condition. | `condition` - Boolean ; `trueValue` - Any type ; `falseValue` - Same type as trueValue | Same as value args | x | x | |
|
|
517
|
+
| case when ... then ... else ... end | Evaluates conditions and returns values. | Multiple when/then clauses | Varies | x | x | x |
|
|
518
|
+
| coalesce(value1, value2, ...) | Returns first non-null value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
519
|
+
|
|
520
|
+
#### Math Functions
|
|
521
|
+
|
|
522
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
523
|
+
| - | - | - | - | - | - | - |
|
|
524
|
+
| floor(number) | Rounds down to nearest integer. | `number` - Numeric value | Number | x | x | x |
|
|
525
|
+
| ceil(number) | Rounds up to nearest integer. | `number` - Numeric value | Number | x | x | x |
|
|
526
|
+
| greatest(value1, value2, ...) | Returns the greatest value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
527
|
+
| least(value1, value2, ...) | Returns the smallest value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
528
|
+
| safe_divide(numerator, denominator) | Divides, returning null on division by zero (BigQuery). | `numerator` - Number ; `denominator` - Number | Number | | x | |
|
|
381
529
|
|
|
382
|
-
####
|
|
530
|
+
#### Type Conversion
|
|
383
531
|
|
|
384
|
-
|
|
532
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
533
|
+
| - | - | - | - | - | - | - |
|
|
534
|
+
| cast(value as type) | Converts value to specified type. | `value` - Any value ; `type` - Target type (int, int64, integer, bigint, smallint, tinyint, byteint, float, float64, double, decimal, numeric, bigdecimal, number, text, string, varchar, variant, bool, boolean, date, datetime, time, timestamp, timestamp_ntz, geography) | Specified type | x | x | x |
|
|
535
|
+
| value::type | Alternative cast syntax. | `value` - Any value ; `type` - Target type | Specified type | x | x | x |
|
|
385
536
|
|
|
386
|
-
###
|
|
537
|
+
### Subqueries, CTEs, and chaining queries
|
|
538
|
+
|
|
539
|
+
Queries can be chained together for more complex, multi-stage query logic. Instead of using subqueries or CTEs (`WITH`), in GSQL this is done by using the `table as` statement, or in Markdown, by simply chaining queries.
|
|
540
|
+
|
|
541
|
+
Using `table as`:
|
|
542
|
+
|
|
543
|
+
```sql
|
|
544
|
+
table sales_per_store as (
|
|
545
|
+
select
|
|
546
|
+
store_id,
|
|
547
|
+
sum(amount) as total_sales
|
|
548
|
+
from orders
|
|
549
|
+
group by store_id
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
-- average store sales
|
|
553
|
+
select avg(total_sales)
|
|
554
|
+
from sales_per_store
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
In a Markdown file:
|
|
558
|
+
|
|
559
|
+
````md
|
|
560
|
+
```sql sales_per_store
|
|
561
|
+
select
|
|
562
|
+
store_id,
|
|
563
|
+
sum(amount) as total_sales
|
|
564
|
+
from orders
|
|
565
|
+
group by store_id
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
```sql average_store_sales
|
|
569
|
+
select avg(total_sales)
|
|
570
|
+
from sales_per_store
|
|
571
|
+
```
|
|
572
|
+
````
|
|
573
|
+
|
|
574
|
+
### Other miscellaneous details
|
|
575
|
+
|
|
576
|
+
- The clauses in a `select` statement (`select`, `from`, `join`, `group by`, etc.) can be written in any order. They cannot be repeated, however.
|
|
577
|
+
- `group by all` is implied if aggregative and scalar expressions are both present in the `select` clause. This means that `group by` can be omitted and the query will still effectively execute the `group by all`.
|
|
578
|
+
- Expressions in `group by` are implicitly selected, so `from orders select avg(amount) group by user_id` will return two columns.
|
|
579
|
+
- `count` is a reserved word. Do not alias your columns as `count`.
|
|
580
|
+
- Window functions and set operations (`union [all]`, `intersect`, `except`) are not supported.
|
|
581
|
+
|
|
582
|
+
## `table as` statements
|
|
387
583
|
|
|
388
584
|
You can turn the output of any `select` statement into a table with `table foo as (select ...)`. Here's an example of an additional table `user_facts` added to the two tables from earlier:
|
|
389
585
|
|
|
@@ -424,11 +620,11 @@ table user_facts as (
|
|
|
424
620
|
)
|
|
425
621
|
```
|
|
426
622
|
|
|
427
|
-
`table as` statements are conceptually the same as view tables in regular SQL. A few things to note:
|
|
428
|
-
- You cannot
|
|
623
|
+
`table as` statements are conceptually the same as view tables and CTEs in regular SQL. A few things to note:
|
|
624
|
+
- You cannot declare join relationships or stored expressions directly in a `table as` statement. Use an `extend` statement.
|
|
429
625
|
- 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`.
|
|
430
626
|
|
|
431
|
-
|
|
627
|
+
## `extend` statements
|
|
432
628
|
|
|
433
629
|
`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.
|
|
434
630
|
|
|
@@ -457,53 +653,7 @@ extend daily_orders (
|
|
|
457
653
|
|
|
458
654
|
Note that you cannot add new base columns with `extend`; you can only add joins and stored expressions.
|
|
459
655
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
Graphene understands a handful of common literal formats so you rarely need explicit casts when filtering or doing time math.
|
|
463
|
-
|
|
464
|
-
**Date and timestamp literals**
|
|
465
|
-
|
|
466
|
-
- `YYYY`, `YYYY-MM`, and `YYYY-MM-DD` strings are treated as dates. Leading/trailing spaces are ignored.
|
|
467
|
-
- `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`.
|
|
468
|
-
|
|
469
|
-
```sql
|
|
470
|
-
from users select id
|
|
471
|
-
where created_at >= '2024-01-01' and created_at <= '2024-02-01'
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
**Interval literals**
|
|
475
|
-
|
|
476
|
-
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).
|
|
477
|
-
|
|
478
|
-
```sql
|
|
479
|
-
from users select
|
|
480
|
-
created_at + '5 minutes' as first_seen_plus_5,
|
|
481
|
-
created_at - '2 days' as first_seen_minus_2
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
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"”.
|
|
485
|
-
|
|
486
|
-
### Other miscellaneous details about GSQL
|
|
487
|
-
|
|
488
|
-
- Trailing commas in `table` statements are optional.
|
|
489
|
-
- Trailing semicolons after `table` and `table as` statements are optional.
|
|
490
|
-
- The clauses in a `select` statement (`select`, `from`, `join`, `group by`, etc.) can be written in any order. They cannot be repeated, however.
|
|
491
|
-
- `group by all` is implied if aggregative and scalar expressions are both present in the `select` clause. This means that `group by` can be omitted and the query will still effectively execute the `group by all`.
|
|
492
|
-
- Expressions in `group by` are implicitly selected, so `from orders select avg(amount) group by user_id` will return two columns.
|
|
493
|
-
- `count` is a reserved word. Do not alias your columns as `count`.
|
|
494
|
-
- Window functions and set operations are not supported.
|
|
495
|
-
- Subqueries are not supported. However, you can accomplish the same functionality by chaining queries:
|
|
496
|
-
````md
|
|
497
|
-
```sql my_subquery
|
|
498
|
-
select ...
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
```sql my_query
|
|
502
|
-
select ... from my_subquery
|
|
503
|
-
```
|
|
504
|
-
````
|
|
505
|
-
|
|
506
|
-
## Graphene data apps (dashboards)
|
|
656
|
+
# Graphene data apps (dashboards)
|
|
507
657
|
|
|
508
658
|
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.
|
|
509
659
|
|
|
@@ -537,9 +687,9 @@ Best practices
|
|
|
537
687
|
- If you have multiple time series charts, align their x-axes to have the same range and granularity.
|
|
538
688
|
- Use the same color for a given metric if it is used in multiple charts.
|
|
539
689
|
|
|
540
|
-
|
|
690
|
+
## Visualization components
|
|
541
691
|
|
|
542
|
-
|
|
692
|
+
### Bar chart
|
|
543
693
|
|
|
544
694
|
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.
|
|
545
695
|
|
|
@@ -555,9 +705,9 @@ Here's an example:
|
|
|
555
705
|
/>
|
|
556
706
|
```
|
|
557
707
|
|
|
558
|
-
|
|
708
|
+
#### All bar chart attributes
|
|
559
709
|
|
|
560
|
-
|
|
710
|
+
##### General
|
|
561
711
|
|
|
562
712
|
| Attribute | Description | Options | Default |
|
|
563
713
|
|----------|-------------|---------|---------|
|
|
@@ -569,11 +719,11 @@ Here's an example:
|
|
|
569
719
|
| downloadableData | Whether to show the download button to allow users to download the data | `true`, `false` | `true` |
|
|
570
720
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | `true`, `false` | `true` |
|
|
571
721
|
|
|
572
|
-
|
|
722
|
+
##### Data
|
|
573
723
|
|
|
574
724
|
| Attribute | Description | Required | Options | Default |
|
|
575
725
|
|----------|-------------|----------|---------|---------|
|
|
576
|
-
| data |
|
|
726
|
+
| data | GSQL query or table name | true | query name | - |
|
|
577
727
|
| x | Column or expression to use for the x-axis of the chart | false | column name, stored expression name, GSQL expression | First column |
|
|
578
728
|
| 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 e.g. `"col1, my_expr"` | Any non-assigned numeric columns |
|
|
579
729
|
| 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 e.g. `"col1, my_expr"` | - |
|
|
@@ -585,7 +735,7 @@ Here's an example:
|
|
|
585
735
|
| 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` |
|
|
586
736
|
| 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 |
|
|
587
737
|
|
|
588
|
-
|
|
738
|
+
##### Formatting & Styling
|
|
589
739
|
|
|
590
740
|
| Attribute | Description | Options | Default |
|
|
591
741
|
|----------|-------------|---------|---------|
|
|
@@ -603,7 +753,7 @@ Here's an example:
|
|
|
603
753
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | number | - |
|
|
604
754
|
| xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | `true`, `false` | `false` |
|
|
605
755
|
|
|
606
|
-
|
|
756
|
+
##### Value Labels
|
|
607
757
|
|
|
608
758
|
| Attribute | Description | Options | Default |
|
|
609
759
|
|----------|-------------|---------|---------|
|
|
@@ -618,7 +768,7 @@ Here's an example:
|
|
|
618
768
|
| 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 | - |
|
|
619
769
|
| showAllLabels | Allow all labels to appear on chart, including overlapping labels | `true`, `false` | `false` |
|
|
620
770
|
|
|
621
|
-
|
|
771
|
+
##### Axes
|
|
622
772
|
|
|
623
773
|
| Attribute | Description | Options | Default |
|
|
624
774
|
|----------|-------------|---------|---------|
|
|
@@ -648,13 +798,13 @@ Here's an example:
|
|
|
648
798
|
| y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | `true`, `false` | `false` |
|
|
649
799
|
| 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 |
|
|
650
800
|
|
|
651
|
-
|
|
801
|
+
##### Interactivity
|
|
652
802
|
|
|
653
803
|
| Attribute | Description | Options |
|
|
654
804
|
|----------|-------------|---------|
|
|
655
805
|
| connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | string |
|
|
656
806
|
|
|
657
|
-
|
|
807
|
+
### Pie chart
|
|
658
808
|
|
|
659
809
|
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.
|
|
660
810
|
|
|
@@ -669,24 +819,24 @@ Here's an example:
|
|
|
669
819
|
/>
|
|
670
820
|
```
|
|
671
821
|
|
|
672
|
-
|
|
822
|
+
#### All pie chart attributes
|
|
673
823
|
|
|
674
|
-
|
|
824
|
+
##### General
|
|
675
825
|
|
|
676
826
|
| Attribute | Description | Options | Default |
|
|
677
827
|
|----------|-------------|---------|---------|
|
|
678
828
|
| title | Chart title. Appears at top left of chart. | string | - |
|
|
679
829
|
| subtitle | Chart subtitle. Appears just under title. | string | - |
|
|
680
830
|
|
|
681
|
-
|
|
831
|
+
##### Data
|
|
682
832
|
|
|
683
833
|
| Attribute | Description | Required | Options | Default |
|
|
684
834
|
|------|-------------|----------|---------|---------|
|
|
685
|
-
| data |
|
|
835
|
+
| data | GSQL query or table name | true | query name | - |
|
|
686
836
|
| category | Column or expression to use for slice names | true | column name, stored expression name, GSQL expression | - |
|
|
687
837
|
| value | Column or expression to use for slice values | true | column name, stored expression name, GSQL expression | - |
|
|
688
838
|
|
|
689
|
-
|
|
839
|
+
### Line chart
|
|
690
840
|
|
|
691
841
|
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.
|
|
692
842
|
|
|
@@ -703,9 +853,9 @@ Here's an example:
|
|
|
703
853
|
/>
|
|
704
854
|
```
|
|
705
855
|
|
|
706
|
-
|
|
856
|
+
#### All line chart attributes
|
|
707
857
|
|
|
708
|
-
|
|
858
|
+
##### General
|
|
709
859
|
|
|
710
860
|
| Attribute | Description | Required | Options | Default |
|
|
711
861
|
|------|-------------|----------|---------|---------|
|
|
@@ -717,11 +867,11 @@ Here's an example:
|
|
|
717
867
|
| downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
|
|
718
868
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
|
|
719
869
|
|
|
720
|
-
|
|
870
|
+
##### Data
|
|
721
871
|
|
|
722
872
|
| Attribute | Description | Required | Options | Default |
|
|
723
873
|
|------|-------------|----------|---------|---------|
|
|
724
|
-
| data |
|
|
874
|
+
| data | GSQL query or table name | true | query name | - |
|
|
725
875
|
| x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | - |
|
|
726
876
|
| 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 e.g. `"col1, my_expr"` | - |
|
|
727
877
|
| 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 e.g. `"col1, my_expr"` | - |
|
|
@@ -732,7 +882,7 @@ Here's an example:
|
|
|
732
882
|
| 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` |
|
|
733
883
|
| 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 | - |
|
|
734
884
|
|
|
735
|
-
|
|
885
|
+
##### Formatting & Styling
|
|
736
886
|
|
|
737
887
|
| Attribute | Description | Required | Options | Default |
|
|
738
888
|
|------|-------------|----------|---------|---------|
|
|
@@ -763,7 +913,7 @@ Here's an example:
|
|
|
763
913
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
|
|
764
914
|
| xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | false | `true`, `false` | `false` |
|
|
765
915
|
|
|
766
|
-
|
|
916
|
+
##### Axes
|
|
767
917
|
|
|
768
918
|
| Attribute | Description | Required | Options | Default |
|
|
769
919
|
|------|-------------|----------|---------|---------|
|
|
@@ -791,14 +941,14 @@ Here's an example:
|
|
|
791
941
|
| y2Max | Maximum value for the y2-axis | false | number | - |
|
|
792
942
|
| y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | false | `true`, `false` | `false` |
|
|
793
943
|
|
|
794
|
-
|
|
944
|
+
##### Interactivity
|
|
795
945
|
|
|
796
946
|
| Attribute | Description | Required | Options | Default |
|
|
797
947
|
|------|-------------|----------|---------|---------|
|
|
798
948
|
| connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | false | - | - |
|
|
799
949
|
|
|
800
950
|
|
|
801
|
-
|
|
951
|
+
### Area chart
|
|
802
952
|
|
|
803
953
|
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.
|
|
804
954
|
|
|
@@ -812,9 +962,9 @@ Here's an example:
|
|
|
812
962
|
/>
|
|
813
963
|
```
|
|
814
964
|
|
|
815
|
-
|
|
965
|
+
#### All area chart attributes
|
|
816
966
|
|
|
817
|
-
|
|
967
|
+
##### General
|
|
818
968
|
|
|
819
969
|
| Attribute | Description | Required | Options | Default |
|
|
820
970
|
|------|-------------|----------|---------|---------|
|
|
@@ -826,11 +976,11 @@ Here's an example:
|
|
|
826
976
|
| downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
|
|
827
977
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
|
|
828
978
|
|
|
829
|
-
|
|
979
|
+
##### Data
|
|
830
980
|
|
|
831
981
|
| Attribute | Description | Required | Options | Default |
|
|
832
982
|
|------|-------------|----------|---------|---------|
|
|
833
|
-
| data |
|
|
983
|
+
| data | GSQL query or table name | true | query name | - |
|
|
834
984
|
| x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | First column |
|
|
835
985
|
| 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 e.g. `"col1, my_expr"` | Any non-assigned numeric columns |
|
|
836
986
|
| 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 | - |
|
|
@@ -840,7 +990,7 @@ Here's an example:
|
|
|
840
990
|
| 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` |
|
|
841
991
|
| 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" |
|
|
842
992
|
|
|
843
|
-
|
|
993
|
+
##### Formatting & Styling
|
|
844
994
|
|
|
845
995
|
| Attribute | Description | Required | Options | Default |
|
|
846
996
|
|------|-------------|----------|---------|---------|
|
|
@@ -859,7 +1009,7 @@ Here's an example:
|
|
|
859
1009
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
|
|
860
1010
|
| xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | false | `true`, `false` | `false` |
|
|
861
1011
|
|
|
862
|
-
|
|
1012
|
+
##### Value Labels
|
|
863
1013
|
|
|
864
1014
|
| Attribute | Description | Required | Options | Default |
|
|
865
1015
|
|------|-------------|----------|---------|---------|
|
|
@@ -870,7 +1020,7 @@ Here's an example:
|
|
|
870
1020
|
| labelFmt | Format to use for value labels ([see available formats](#value-formatting)) | false | Excel-style format, built-in format name | same as y column |
|
|
871
1021
|
| showAllLabels | Allow all labels to appear on chart, including overlapping labels | false | `true`, `false` | `false` |
|
|
872
1022
|
|
|
873
|
-
|
|
1023
|
+
##### Axes
|
|
874
1024
|
|
|
875
1025
|
| Attribute | Description | Required | Options | Default |
|
|
876
1026
|
|------|-------------|----------|---------|---------|
|
|
@@ -890,14 +1040,14 @@ Here's an example:
|
|
|
890
1040
|
| yMax | Maximum value for the y-axis | false | number | - |
|
|
891
1041
|
| yScale | Whether to scale the y-axis to fit your data. `yMin` and `yMax` take precedence over `yScale` | false | `true`, `false` | `false` |
|
|
892
1042
|
|
|
893
|
-
|
|
1043
|
+
##### Interactivity
|
|
894
1044
|
|
|
895
1045
|
| Attribute | Description | Required | Options | Default |
|
|
896
1046
|
|------|-------------|----------|---------|---------|
|
|
897
1047
|
| connectGroup | Group name to connect this chart to other charts for synchronized tooltip hovering. Charts with the same `connectGroup` name will become connected | false | - | - |
|
|
898
1048
|
|
|
899
1049
|
|
|
900
|
-
|
|
1050
|
+
### Big value
|
|
901
1051
|
|
|
902
1052
|
Use big values to display a large value standalone, and optionally include a comparison and a sparkline.
|
|
903
1053
|
|
|
@@ -914,13 +1064,13 @@ Here's an example:
|
|
|
914
1064
|
/>
|
|
915
1065
|
```
|
|
916
1066
|
|
|
917
|
-
|
|
1067
|
+
#### All big value attributes
|
|
918
1068
|
|
|
919
|
-
|
|
1069
|
+
##### Data
|
|
920
1070
|
|
|
921
1071
|
| Attribute | Description | Required | Options | Default |
|
|
922
1072
|
|------|-------------|----------|---------|---------|
|
|
923
|
-
| data |
|
|
1073
|
+
| data | GSQL query or table name | true | query name | - |
|
|
924
1074
|
| value | Column or expression to pull the main value from. | true | column name, stored expression name, GSQL expression | - |
|
|
925
1075
|
| title | Title of the card. | false | string | Title of the value column. |
|
|
926
1076
|
| minWidth | Overrides min-width of component | false | % or px value | `"18%"` |
|
|
@@ -930,7 +1080,7 @@ Here's an example:
|
|
|
930
1080
|
| 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"` |
|
|
931
1081
|
| 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 | - | - |
|
|
932
1082
|
|
|
933
|
-
|
|
1083
|
+
##### Comparison
|
|
934
1084
|
|
|
935
1085
|
| Attribute | Description | Required | Options | Default |
|
|
936
1086
|
|------|-------------|----------|---------|---------|
|
|
@@ -942,7 +1092,7 @@ Here's an example:
|
|
|
942
1092
|
| neutralMax | Sets the top of the range for 'neutral' values - neutral values appear in grey rather than red or green | false | number | `0` |
|
|
943
1093
|
| comparisonFmt | Sets format for the comparison ([see available formats](#value-formatting)) | false | Excel-style format, built-in format | - |
|
|
944
1094
|
|
|
945
|
-
|
|
1095
|
+
##### Sparkline
|
|
946
1096
|
|
|
947
1097
|
| Attribute | Description | Required | Options | Default |
|
|
948
1098
|
|------|-------------|----------|---------|---------|
|
|
@@ -955,7 +1105,7 @@ Here's an example:
|
|
|
955
1105
|
| 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 | - |
|
|
956
1106
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
957
1107
|
|
|
958
|
-
|
|
1108
|
+
### Table
|
|
959
1109
|
|
|
960
1110
|
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.
|
|
961
1111
|
|
|
@@ -965,13 +1115,13 @@ Here's an example:
|
|
|
965
1115
|
<Table data=orders_summary />
|
|
966
1116
|
```
|
|
967
1117
|
|
|
968
|
-
|
|
1118
|
+
#### All table attributes
|
|
969
1119
|
|
|
970
|
-
|
|
1120
|
+
##### Table
|
|
971
1121
|
|
|
972
1122
|
| Attribute | Description | Required | Options | Default |
|
|
973
1123
|
|------|-------------|----------|---------|---------|
|
|
974
|
-
| data |
|
|
1124
|
+
| data | GSQL query or table name | true | query name | - |
|
|
975
1125
|
| 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` |
|
|
976
1126
|
| title | Title for the table | false | string | - |
|
|
977
1127
|
| subtitle | Subtitle - appears under the title | false | string | - |
|
|
@@ -997,7 +1147,7 @@ Here's an example:
|
|
|
997
1147
|
| 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` |
|
|
998
1148
|
| 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" |
|
|
999
1149
|
|
|
1000
|
-
|
|
1150
|
+
##### Groups
|
|
1001
1151
|
|
|
1002
1152
|
| Attribute | Description | Required | Options | Default |
|
|
1003
1153
|
|------|-------------|----------|---------|---------|
|
|
@@ -1011,7 +1161,7 @@ Here's an example:
|
|
|
1011
1161
|
| subtotalFontColor | [groupType=section] Font color for the subtotal row | false | Hex color code, css color name | - |
|
|
1012
1162
|
| groupNamePosition | [groupType=section] Where the group label will appear in its cell | false | `top`, `middle`, `bottom` | `middle` |
|
|
1013
1163
|
|
|
1014
|
-
|
|
1164
|
+
##### Column
|
|
1015
1165
|
|
|
1016
1166
|
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.
|
|
1017
1167
|
|
|
@@ -1102,11 +1252,11 @@ Conditional formatting (`contentType=colorscale`)
|
|
|
1102
1252
|
| 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 | - |
|
|
1103
1253
|
| 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 | - |
|
|
1104
1254
|
|
|
1105
|
-
|
|
1255
|
+
## Input components
|
|
1106
1256
|
|
|
1107
|
-
|
|
1257
|
+
### Text input
|
|
1108
1258
|
|
|
1109
|
-
Creates a text input that can be used to filter or search.
|
|
1259
|
+
Creates a text input that can be used to filter or search.
|
|
1110
1260
|
|
|
1111
1261
|
Here's an example:
|
|
1112
1262
|
|
|
@@ -1125,7 +1275,7 @@ from users
|
|
|
1125
1275
|
where email ilike concat('%', $name_of_input, '%')
|
|
1126
1276
|
```
|
|
1127
1277
|
|
|
1128
|
-
|
|
1278
|
+
#### All text input attributes
|
|
1129
1279
|
|
|
1130
1280
|
| Attribute | Description | Required | Options | Default |
|
|
1131
1281
|
|------|-------------|----------|---------|---------|
|
|
@@ -1136,9 +1286,9 @@ where email ilike concat('%', $name_of_input, '%')
|
|
|
1136
1286
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
1137
1287
|
|
|
1138
1288
|
|
|
1139
|
-
|
|
1289
|
+
### Dropdown
|
|
1140
1290
|
|
|
1141
|
-
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.
|
|
1291
|
+
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.
|
|
1142
1292
|
|
|
1143
1293
|
Here's an example:
|
|
1144
1294
|
|
|
@@ -1164,12 +1314,12 @@ from orders
|
|
|
1164
1314
|
where status = $status_dropdown
|
|
1165
1315
|
```
|
|
1166
1316
|
|
|
1167
|
-
|
|
1317
|
+
#### All dropdown attributes
|
|
1168
1318
|
|
|
1169
1319
|
| Attribute | Description | Required | Options | Default |
|
|
1170
1320
|
|------|-------------|----------|---------|---------|
|
|
1171
1321
|
| name | Name of the dropdown, used to reference the selected value elsewhere as `"$name"` | true | - | - |
|
|
1172
|
-
| data |
|
|
1322
|
+
| data | GSQL query or table name | false | query name | - |
|
|
1173
1323
|
| value | Column name from the query containing values to pick from | false | column name | - |
|
|
1174
1324
|
| multiple | Enables multi-select which returns a list | false | `true`, `false` | `false` |
|
|
1175
1325
|
| 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"` | - |
|
|
@@ -1183,7 +1333,7 @@ where status = $status_dropdown
|
|
|
1183
1333
|
| hideDuringPrint | Hide the component when the report is printed | false | `true`, `false` | `true` |
|
|
1184
1334
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
1185
1335
|
|
|
1186
|
-
|
|
1336
|
+
##### DropdownOption
|
|
1187
1337
|
|
|
1188
1338
|
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.
|
|
1189
1339
|
|
|
@@ -1202,11 +1352,11 @@ Here's an example:
|
|
|
1202
1352
|
| value | Value to use when the option is selected | true | - | - |
|
|
1203
1353
|
| valueLabel | Label to display for the option in the dropdown | false | - | Uses the value |
|
|
1204
1354
|
|
|
1205
|
-
|
|
1355
|
+
## Other components
|
|
1206
1356
|
|
|
1207
1357
|
`<Row></Row>` - Evenly distributes components inside along the same row.
|
|
1208
1358
|
|
|
1209
|
-
|
|
1359
|
+
## Value formatting
|
|
1210
1360
|
|
|
1211
1361
|
The easiest way to format numbers and dates in Graphene is through component attributes. You can pass in either of the following:
|
|
1212
1362
|
|
|
@@ -1241,11 +1391,11 @@ In the example above, `xFmt` is passing in an Excel-style code to format the dat
|
|
|
1241
1391
|
|
|
1242
1392
|
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.
|
|
1243
1393
|
|
|
1244
|
-
|
|
1394
|
+
### Built-in Formats
|
|
1245
1395
|
|
|
1246
1396
|
Graphene supports a variety of date/time, number, percentage, and currency formats.
|
|
1247
1397
|
|
|
1248
|
-
|
|
1398
|
+
#### Auto-Formatting
|
|
1249
1399
|
|
|
1250
1400
|
Wherever you see `auto` listed beside a format, that means Graphene will automatically format your value based on the context it is in.
|
|
1251
1401
|
|
|
@@ -1253,7 +1403,7 @@ For example, Graphene automatically formats large numbers into shortened version
|
|
|
1253
1403
|
|
|
1254
1404
|
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.
|
|
1255
1405
|
|
|
1256
|
-
|
|
1406
|
+
#### Dates
|
|
1257
1407
|
|
|
1258
1408
|
Graphene supports the following date formats:
|
|
1259
1409
|
|
|
@@ -1269,7 +1419,7 @@ Graphene supports the following date formats:
|
|
|
1269
1419
|
* `dmy` - Day/month/year (e.g., 9/1/22)
|
|
1270
1420
|
* `hms` - Time format (e.g., 11:45:03 AM)
|
|
1271
1421
|
|
|
1272
|
-
|
|
1422
|
+
#### Currencies
|
|
1273
1423
|
|
|
1274
1424
|
Supported currencies include USD, AUD, BRL, CAD, CNY, EUR, GBP, JPY, INR, KRW, NGN, RUB, and SEK.
|
|
1275
1425
|
|
|
@@ -1288,7 +1438,7 @@ For example, the available tags for USD are:
|
|
|
1288
1438
|
|
|
1289
1439
|
Similar patterns apply to other supported currencies.
|
|
1290
1440
|
|
|
1291
|
-
|
|
1441
|
+
#### Numbers
|
|
1292
1442
|
|
|
1293
1443
|
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).
|
|
1294
1444
|
|
|
@@ -1303,7 +1453,7 @@ Available number formats:
|
|
|
1303
1453
|
* `mult`, `mult0`, `mult1`, `mult2` - Multiplier format (e.g., 5.32x)
|
|
1304
1454
|
* `sci` - Scientific notation
|
|
1305
1455
|
|
|
1306
|
-
|
|
1456
|
+
#### Percentages
|
|
1307
1457
|
|
|
1308
1458
|
Available percentage formats:
|
|
1309
1459
|
|
|
@@ -1312,25 +1462,3 @@ Available percentage formats:
|
|
|
1312
1462
|
* `pct1` - Percentage with 1 decimal place (e.g., 73.1%)
|
|
1313
1463
|
* `pct2` - Percentage with 2 decimal places (e.g., 73.10%)
|
|
1314
1464
|
* `pct3` - Percentage with 3 decimal places (e.g., 73.100%)
|
|
1315
|
-
|
|
1316
|
-
## Graphene CLI
|
|
1317
|
-
|
|
1318
|
-
These are the available commands:
|
|
1319
|
-
- `npm run graphene check` - Checks the syntax (GSQL and Markdown) for the entire Graphene project.
|
|
1320
|
-
- `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.
|
|
1321
|
-
- `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`.
|
|
1322
|
-
- `npm run graphene compile "<GSQL>"` - Shows how GSQL is translated into the underlying database SQL.
|
|
1323
|
-
- `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.
|
|
1324
|
-
|
|
1325
|
-
# AGENT INSTRUCTIONS
|
|
1326
|
-
|
|
1327
|
-
Follow these guidelines when working in a Graphene project.
|
|
1328
|
-
- When formulating GSQL queries:
|
|
1329
|
-
- 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!
|
|
1330
|
-
- 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.
|
|
1331
|
-
- Do not try to search the web for Graphene-specific info; you will not find anything. All the documentation is here in graphene.md.
|
|
1332
|
-
- When writing to a .gsql file, check your code with `npm run graphene check`.
|
|
1333
|
-
- When writing to a Graphene .md file:
|
|
1334
|
-
- 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.
|
|
1335
|
-
- 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).
|
|
1336
|
-
- 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.
|