@graphenedata/cli 0.0.10 → 0.0.12
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/bin.js +15 -0
- package/cli.ts +6 -1
- package/dist/cli/cli.js +126 -113
- package/dist/docs/agent-instructions.md +18 -0
- package/dist/docs/graphene.md +308 -182
- package/dist/ui/app.css +8 -10
- package/dist/ui/components/_Table.svelte +16 -13
- package/dist/ui/internal/NavSidebar.svelte +24 -8
- package/dist/ui/internal/NavSidebarHMR.svelte +8 -0
- package/dist/ui/internal/queryEngine.ts +1 -1
- package/dist/ui/web.js +1 -1
- package/package.json +3 -2
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,19 @@ 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
|
+
- [Available functions](#available-functions)
|
|
26
|
+
- [Aggregate functions](#aggregate-functions)
|
|
27
|
+
- [Date and time functions](#date-and-time-functions)
|
|
28
|
+
- [Conditional Functions](#conditional-functions)
|
|
29
|
+
- [Math Functions](#math-functions)
|
|
30
|
+
- [Type Conversion](#type-conversion)
|
|
31
|
+
- [Subqueries, CTEs, and chaining queries](#subqueries-ctes-and-chaining-queries)
|
|
32
|
+
- [Other miscellaneous details](#other-miscellaneous-details)
|
|
23
33
|
- [`table as` statements](#table-as-statements)
|
|
24
34
|
- [`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
35
|
- [Graphene data apps (dashboards)](#graphene-data-apps-dashboards)
|
|
30
36
|
- [Visualization components](#visualization-components)
|
|
31
37
|
- [Bar chart](#bar-chart)
|
|
@@ -68,8 +74,6 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
68
74
|
- [Input components](#input-components)
|
|
69
75
|
- [Text input](#text-input)
|
|
70
76
|
- [All text input attributes](#all-text-input-attributes)
|
|
71
|
-
- [Date range](#date-range)
|
|
72
|
-
- [All date range attributes](#all-date-range-attributes)
|
|
73
77
|
- [Dropdown](#dropdown)
|
|
74
78
|
- [All dropdown attributes](#all-dropdown-attributes)
|
|
75
79
|
- [DropdownOption](#dropdownoption)
|
|
@@ -81,16 +85,27 @@ Graphene also has a CLI that lets you check syntax, run queries, serve data apps
|
|
|
81
85
|
- [Currencies](#currencies)
|
|
82
86
|
- [Numbers](#numbers)
|
|
83
87
|
- [Percentages](#percentages)
|
|
84
|
-
- [Graphene CLI](#graphene-cli)
|
|
85
|
-
- [AGENT INSTRUCTIONS](#agent-instructions)
|
|
86
88
|
|
|
87
|
-
|
|
89
|
+
# Graphene CLI
|
|
90
|
+
|
|
91
|
+
These are the available commands:
|
|
92
|
+
- `npm run graphene check` - Checks the syntax (GSQL and Markdown) for the entire Graphene project.
|
|
93
|
+
- `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.
|
|
94
|
+
- `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.
|
|
95
|
+
- `npm run graphene compile [GSQL | gsqlPath]` - Shows how GSQL is translated into the underlying database SQL.
|
|
96
|
+
- `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.
|
|
97
|
+
|
|
98
|
+
# Graphene SQL (GSQL)
|
|
88
99
|
|
|
89
|
-
GSQL is comprised of
|
|
100
|
+
GSQL is comprised of four primary statements:
|
|
101
|
+
1. `table` statements that declare existing tables and semantic metadata
|
|
102
|
+
2. `select` statements that query tables
|
|
103
|
+
3. `table as` statements that create new tables using `select`
|
|
104
|
+
4. `extend` statements that attach semantic metadata to tables
|
|
90
105
|
|
|
91
|
-
|
|
106
|
+
## `table` statements
|
|
92
107
|
|
|
93
|
-
`table` statements
|
|
108
|
+
`table` statements declare tables that already exist in your database. Here's an example of two tables, `orders` and `users`, in GSQL.
|
|
94
109
|
|
|
95
110
|
```sql
|
|
96
111
|
table orders (
|
|
@@ -123,25 +138,25 @@ table users (
|
|
|
123
138
|
|
|
124
139
|
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
140
|
|
|
126
|
-
|
|
141
|
+
### Base columns (required)
|
|
127
142
|
|
|
128
143
|
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
144
|
|
|
130
|
-
|
|
145
|
+
### Join relationships
|
|
131
146
|
|
|
132
147
|
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
148
|
|
|
134
149
|
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
150
|
|
|
136
|
-
This information is provided with the two supported join types, `
|
|
137
|
-
- `
|
|
138
|
-
- `
|
|
151
|
+
This information is provided with the two supported join types, `join one` and `join many`:
|
|
152
|
+
- `join one` is used if there are many rows in the **left** table for each row in the **right** table.
|
|
153
|
+
- `join many` is used if there are many rows in the **right** table for each row in the **left** table.
|
|
139
154
|
|
|
140
155
|
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
156
|
|
|
142
157
|
Note that all joins in GSQL are left outer joins. There is no inner, right, or cross join.
|
|
143
158
|
|
|
144
|
-
|
|
159
|
+
#### Multiple join relationships between the same two tables
|
|
145
160
|
|
|
146
161
|
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
162
|
|
|
@@ -164,12 +179,12 @@ table users (
|
|
|
164
179
|
)
|
|
165
180
|
```
|
|
166
181
|
|
|
167
|
-
|
|
182
|
+
#### Best practices for modeling join relationships
|
|
168
183
|
|
|
169
184
|
- 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
185
|
- 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
186
|
|
|
172
|
-
|
|
187
|
+
### Stored expressions
|
|
173
188
|
|
|
174
189
|
**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
190
|
|
|
@@ -194,8 +209,7 @@ table orders (
|
|
|
194
209
|
)
|
|
195
210
|
```
|
|
196
211
|
|
|
197
|
-
|
|
198
|
-
### `select` statements
|
|
212
|
+
## `select` statements
|
|
199
213
|
|
|
200
214
|
`select` is how you write queries in Graphene SQL. It behaves similarly to regular SQL except in the following ways:
|
|
201
215
|
- It can invoke join relationships and stored expressions from `table` statements.
|
|
@@ -203,7 +217,7 @@ table orders (
|
|
|
203
217
|
|
|
204
218
|
These differences are described in the sections below.
|
|
205
219
|
|
|
206
|
-
|
|
220
|
+
### Using join relationships in queries
|
|
207
221
|
|
|
208
222
|
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
223
|
|
|
@@ -237,7 +251,7 @@ order by 2 desc
|
|
|
237
251
|
limit 10
|
|
238
252
|
```
|
|
239
253
|
|
|
240
|
-
|
|
254
|
+
#### Multi-hop joins
|
|
241
255
|
|
|
242
256
|
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
257
|
|
|
@@ -278,7 +292,7 @@ order by 2 desc
|
|
|
278
292
|
limit 10
|
|
279
293
|
```
|
|
280
294
|
|
|
281
|
-
|
|
295
|
+
### Using scalar stored expressions (dimensions) in queries
|
|
282
296
|
|
|
283
297
|
A stored expression can be invoked in a query by simply referencing it by name.
|
|
284
298
|
|
|
@@ -326,7 +340,9 @@ group by 1
|
|
|
326
340
|
|
|
327
341
|
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
342
|
|
|
329
|
-
|
|
343
|
+
### Using aggregative stored expressions (measures) in queries
|
|
344
|
+
|
|
345
|
+
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
346
|
|
|
331
347
|
```sql
|
|
332
348
|
-- Profit by month
|
|
@@ -349,41 +365,219 @@ group by 1
|
|
|
349
365
|
order by 1 asc
|
|
350
366
|
```
|
|
351
367
|
|
|
352
|
-
|
|
368
|
+
[CRITICAL!] This means:
|
|
369
|
+
- 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.
|
|
370
|
+
- 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.
|
|
371
|
+
- 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.
|
|
372
|
+
- 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.
|
|
373
|
+
|
|
374
|
+
Another way of thinking about this is that measures are "self-aggregating."
|
|
375
|
+
|
|
376
|
+
### Safe aggregation in fan-outs
|
|
377
|
+
|
|
378
|
+
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.
|
|
379
|
+
|
|
380
|
+
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.
|
|
381
|
+
|
|
382
|
+
>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.
|
|
383
|
+
|
|
384
|
+
Here's an example of a fan-out:
|
|
385
|
+
|
|
386
|
+
```sql
|
|
387
|
+
table orders (
|
|
388
|
+
id BIGINT primary_key
|
|
389
|
+
customer_name VARCHAR
|
|
390
|
+
amt_with_shipping FLOAT
|
|
391
|
+
|
|
392
|
+
join many order_items on id = order_items.order_id
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
table order_items (
|
|
396
|
+
id BIGINT primary_key
|
|
397
|
+
order_id BIGINT
|
|
398
|
+
product VARCHAR
|
|
399
|
+
price FLOAT
|
|
400
|
+
|
|
401
|
+
join one orders on order_id = orders.id
|
|
402
|
+
)
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
With the following data:
|
|
406
|
+
|
|
407
|
+
**orders**
|
|
408
|
+
|
|
409
|
+
| id | customer_name | amt_with_shipping |
|
|
410
|
+
|----|---------------|-------------------|
|
|
411
|
+
| 1 | Alice | 110.00 |
|
|
412
|
+
| 2 | Bob | 85.00 |
|
|
413
|
+
|
|
414
|
+
**order_items**
|
|
415
|
+
|
|
416
|
+
| id | order_id | product | price |
|
|
417
|
+
|----|----------|---------|-------|
|
|
418
|
+
| 1 | 1 | Widget | 60.00 |
|
|
419
|
+
| 2 | 1 | Gadget | 40.00 |
|
|
420
|
+
| 3 | 2 | Widget | 60.00 |
|
|
421
|
+
| 4 | 2 | Thingamajig | 15.00 |
|
|
353
422
|
|
|
354
|
-
|
|
423
|
+
When joining orders to order_items, the result looks like:
|
|
355
424
|
|
|
356
|
-
|
|
425
|
+
**orders joined to order_items**
|
|
426
|
+
|
|
427
|
+
| orders.id | customer_name | amt_with_shipping | order_items.id | product | price |
|
|
428
|
+
|-----------|---------------|-------------------|----------------|---------|-------|
|
|
429
|
+
| 1 | Alice | 110.00 | 1 | Widget | 60.00 |
|
|
430
|
+
| 1 | Alice | 110.00 | 2 | Gadget | 40.00 |
|
|
431
|
+
| 2 | Bob | 85.00 | 3 | Widget | 60.00 |
|
|
432
|
+
| 2 | Bob | 85.00 | 4 | Thingamajig | 15.00 |
|
|
433
|
+
|
|
434
|
+
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.
|
|
435
|
+
|
|
436
|
+
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:
|
|
437
|
+
|
|
438
|
+
```sql
|
|
439
|
+
select
|
|
440
|
+
customer_name,
|
|
441
|
+
sum(orders.amt_with_shipping) as total_spent,
|
|
442
|
+
count(order_items.id) as items_purchased
|
|
443
|
+
from orders
|
|
444
|
+
group by customer_name
|
|
445
|
+
```
|
|
357
446
|
|
|
358
|
-
|
|
447
|
+
This returns:
|
|
359
448
|
|
|
360
|
-
|
|
449
|
+
| customer_name | total_spent | items_purchased |
|
|
450
|
+
|---------------|-------------|-----------------|
|
|
451
|
+
| Alice | 110.00 | 2 |
|
|
452
|
+
| Bob | 85.00 | 2 |
|
|
361
453
|
|
|
362
|
-
|
|
454
|
+
In regular SQL, you'd need a subquery or CTE to avoid the fan-out problem:
|
|
363
455
|
|
|
364
456
|
```sql
|
|
457
|
+
WITH order_totals AS (
|
|
458
|
+
SELECT customer_name, SUM(amt_with_shipping) as total_spent
|
|
459
|
+
FROM orders
|
|
460
|
+
GROUP BY customer_name
|
|
461
|
+
),
|
|
462
|
+
item_counts AS (
|
|
463
|
+
SELECT o.customer_name, COUNT(oi.id) as items_purchased
|
|
464
|
+
FROM orders o
|
|
465
|
+
JOIN order_items oi ON o.id = oi.order_id
|
|
466
|
+
GROUP BY o.customer_name
|
|
467
|
+
)
|
|
365
468
|
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`
|
|
469
|
+
ot.customer_name,
|
|
470
|
+
ot.total_spent,
|
|
471
|
+
ic.items_purchased
|
|
472
|
+
FROM order_totals ot
|
|
473
|
+
JOIN item_counts ic ON ot.customer_name = ic.customer_name
|
|
378
474
|
```
|
|
379
475
|
|
|
380
|
-
|
|
476
|
+
### Available functions
|
|
477
|
+
|
|
478
|
+
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.
|
|
479
|
+
|
|
480
|
+
#### Aggregate functions
|
|
481
|
+
|
|
482
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
483
|
+
| - | - | - | - | - | - | - |
|
|
484
|
+
| count(), count(*) | Counts the number of rows. | - | Number | x | x | x |
|
|
485
|
+
| count(column) | Counts the number of non-null values in a column. | `column` - Any column/expression | Number | x | x | x |
|
|
486
|
+
| count(distinct column) | Counts the number of distinct non-null values in a column. | `column` - Any column/expression | Number | x | x | x |
|
|
487
|
+
| sum(column) | Calculates the sum of numeric values. | `column` - Numeric column/expression | Number | x | x | x |
|
|
488
|
+
| avg(column) | Calculates the average (mean) of numeric values. | `column` - Numeric column/expression | Number | x | x | x |
|
|
489
|
+
| min(column) | Returns the minimum value. | `column` - Any comparable column/expression | Same as input | x | x | x |
|
|
490
|
+
| max(column) | Returns the maximum value. | `column` - Any comparable column/expression | Same as input | x | x | x |
|
|
491
|
+
| string_agg(column) | Concatenates string values. | `column` - String column/expression | String | x | x | x |
|
|
492
|
+
| stddev(column) | Calculates the standard deviation. | `column` - Numeric column/expression | Number | x | x | x |
|
|
493
|
+
| pXX(column) | Returns the XXth percentile (e.g., p50, p975, p9999). | `column` - Numeric column/expression | Number | x | x (≤p99) | x |
|
|
494
|
+
|
|
495
|
+
#### Date and time functions
|
|
496
|
+
|
|
497
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
498
|
+
| - | - | - | - | - | - | - |
|
|
499
|
+
| current_date() | Returns the current date. | - | Date | x | x | x |
|
|
500
|
+
| current_time() | Returns the current time. | - | Timestamp | x | x | x |
|
|
501
|
+
| current_timestamp() | Returns the current timestamp. | - | Timestamp | x | x | x |
|
|
502
|
+
| local_timestamp() | Returns the local timestamp. | - | Timestamp | x | x | x |
|
|
503
|
+
| current_datetime() | Returns the current datetime (BigQuery only). | - | Timestamp | | x | |
|
|
504
|
+
| 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 | | |
|
|
505
|
+
| 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 | |
|
|
506
|
+
| 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 |
|
|
507
|
+
| 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 | |
|
|
508
|
+
|
|
509
|
+
#### Conditional Functions
|
|
510
|
+
|
|
511
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
512
|
+
| - | - | - | - | - | - | - |
|
|
513
|
+
| 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 | |
|
|
514
|
+
| case when ... then ... else ... end | Evaluates conditions and returns values. | Multiple when/then clauses | Varies | x | x | x |
|
|
515
|
+
| coalesce(value1, value2, ...) | Returns first non-null value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
516
|
+
|
|
517
|
+
#### Math Functions
|
|
518
|
+
|
|
519
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
520
|
+
| - | - | - | - | - | - | - |
|
|
521
|
+
| floor(number) | Rounds down to nearest integer. | `number` - Numeric value | Number | x | x | x |
|
|
522
|
+
| ceil(number) | Rounds up to nearest integer. | `number` - Numeric value | Number | x | x | x |
|
|
523
|
+
| greatest(value1, value2, ...) | Returns the greatest value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
524
|
+
| least(value1, value2, ...) | Returns the smallest value. | `value1, value2, ...` - Same type | Same as input | x | x | x |
|
|
525
|
+
| safe_divide(numerator, denominator) | Divides, returning null on division by zero (BigQuery). | `numerator` - Number ; `denominator` - Number | Number | | x | |
|
|
381
526
|
|
|
382
|
-
####
|
|
527
|
+
#### Type Conversion
|
|
383
528
|
|
|
384
|
-
|
|
529
|
+
| Function | Description | Parameters | Return Type | DuckDB | BigQuery | Snowflake |
|
|
530
|
+
| - | - | - | - | - | - | - |
|
|
531
|
+
| 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 |
|
|
532
|
+
| value::type | Alternative cast syntax. | `value` - Any value ; `type` - Target type | Specified type | x | x | x |
|
|
385
533
|
|
|
386
|
-
###
|
|
534
|
+
### Subqueries, CTEs, and chaining queries
|
|
535
|
+
|
|
536
|
+
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.
|
|
537
|
+
|
|
538
|
+
Using `table as`:
|
|
539
|
+
|
|
540
|
+
```sql
|
|
541
|
+
table sales_per_store as (
|
|
542
|
+
select
|
|
543
|
+
store_id,
|
|
544
|
+
sum(amount) as total_sales
|
|
545
|
+
from orders
|
|
546
|
+
group by store_id
|
|
547
|
+
)
|
|
548
|
+
|
|
549
|
+
-- average store sales
|
|
550
|
+
select avg(total_sales)
|
|
551
|
+
from sales_per_store
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
In a Markdown file:
|
|
555
|
+
|
|
556
|
+
````md
|
|
557
|
+
```sql sales_per_store
|
|
558
|
+
select
|
|
559
|
+
store_id,
|
|
560
|
+
sum(amount) as total_sales
|
|
561
|
+
from orders
|
|
562
|
+
group by store_id
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
```sql average_store_sales
|
|
566
|
+
select avg(total_sales)
|
|
567
|
+
from sales_per_store
|
|
568
|
+
```
|
|
569
|
+
````
|
|
570
|
+
|
|
571
|
+
### Other miscellaneous details
|
|
572
|
+
|
|
573
|
+
- The clauses in a `select` statement (`select`, `from`, `join`, `group by`, etc.) can be written in any order. They cannot be repeated, however.
|
|
574
|
+
- `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`.
|
|
575
|
+
- Expressions in `group by` are implicitly selected, so `from orders select avg(amount) group by user_id` will return two columns.
|
|
576
|
+
- `count` is a reserved word. Do not alias your columns as `count`.
|
|
577
|
+
- Window functions and set operations (`union [all]`, `intersect`, `except`) are not supported.
|
|
578
|
+
- Date and timestamp literals can be written with explicit keywords (`date '2024-01-01'` or `timestamp '2024-01-01 12:00:00'`), but these keywords are optional when the expected type is known from context (e.g., when comparing against a date or timestamp column). Interval literals always require the `interval` keyword.
|
|
579
|
+
|
|
580
|
+
## `table as` statements
|
|
387
581
|
|
|
388
582
|
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
583
|
|
|
@@ -424,11 +618,11 @@ table user_facts as (
|
|
|
424
618
|
)
|
|
425
619
|
```
|
|
426
620
|
|
|
427
|
-
`table as` statements are conceptually the same as view tables in regular SQL. A few things to note:
|
|
428
|
-
- You cannot
|
|
621
|
+
`table as` statements are conceptually the same as view tables and CTEs in regular SQL. A few things to note:
|
|
622
|
+
- You cannot declare join relationships or stored expressions directly in a `table as` statement. Use an `extend` statement.
|
|
429
623
|
- 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
624
|
|
|
431
|
-
|
|
625
|
+
## `extend` statements
|
|
432
626
|
|
|
433
627
|
`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
628
|
|
|
@@ -457,53 +651,7 @@ extend daily_orders (
|
|
|
457
651
|
|
|
458
652
|
Note that you cannot add new base columns with `extend`; you can only add joins and stored expressions.
|
|
459
653
|
|
|
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)
|
|
654
|
+
# Graphene data apps (dashboards)
|
|
507
655
|
|
|
508
656
|
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
657
|
|
|
@@ -537,9 +685,9 @@ Best practices
|
|
|
537
685
|
- If you have multiple time series charts, align their x-axes to have the same range and granularity.
|
|
538
686
|
- Use the same color for a given metric if it is used in multiple charts.
|
|
539
687
|
|
|
540
|
-
|
|
688
|
+
## Visualization components
|
|
541
689
|
|
|
542
|
-
|
|
690
|
+
### Bar chart
|
|
543
691
|
|
|
544
692
|
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
693
|
|
|
@@ -555,9 +703,9 @@ Here's an example:
|
|
|
555
703
|
/>
|
|
556
704
|
```
|
|
557
705
|
|
|
558
|
-
|
|
706
|
+
#### All bar chart attributes
|
|
559
707
|
|
|
560
|
-
|
|
708
|
+
##### General
|
|
561
709
|
|
|
562
710
|
| Attribute | Description | Options | Default |
|
|
563
711
|
|----------|-------------|---------|---------|
|
|
@@ -569,11 +717,11 @@ Here's an example:
|
|
|
569
717
|
| downloadableData | Whether to show the download button to allow users to download the data | `true`, `false` | `true` |
|
|
570
718
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | `true`, `false` | `true` |
|
|
571
719
|
|
|
572
|
-
|
|
720
|
+
##### Data
|
|
573
721
|
|
|
574
722
|
| Attribute | Description | Required | Options | Default |
|
|
575
723
|
|----------|-------------|----------|---------|---------|
|
|
576
|
-
| data |
|
|
724
|
+
| data | GSQL query or table name | true | query name | - |
|
|
577
725
|
| x | Column or expression to use for the x-axis of the chart | false | column name, stored expression name, GSQL expression | First column |
|
|
578
726
|
| 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
727
|
| 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 +733,7 @@ Here's an example:
|
|
|
585
733
|
| 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
734
|
| 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
735
|
|
|
588
|
-
|
|
736
|
+
##### Formatting & Styling
|
|
589
737
|
|
|
590
738
|
| Attribute | Description | Options | Default |
|
|
591
739
|
|----------|-------------|---------|---------|
|
|
@@ -603,7 +751,7 @@ Here's an example:
|
|
|
603
751
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | number | - |
|
|
604
752
|
| xLabelWrap | Whether to wrap x-axis labels when there is not enough space. Default behaviour is to truncate the labels. | `true`, `false` | `false` |
|
|
605
753
|
|
|
606
|
-
|
|
754
|
+
##### Value Labels
|
|
607
755
|
|
|
608
756
|
| Attribute | Description | Options | Default |
|
|
609
757
|
|----------|-------------|---------|---------|
|
|
@@ -618,7 +766,7 @@ Here's an example:
|
|
|
618
766
|
| 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
767
|
| showAllLabels | Allow all labels to appear on chart, including overlapping labels | `true`, `false` | `false` |
|
|
620
768
|
|
|
621
|
-
|
|
769
|
+
##### Axes
|
|
622
770
|
|
|
623
771
|
| Attribute | Description | Options | Default |
|
|
624
772
|
|----------|-------------|---------|---------|
|
|
@@ -648,13 +796,13 @@ Here's an example:
|
|
|
648
796
|
| y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | `true`, `false` | `false` |
|
|
649
797
|
| 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
798
|
|
|
651
|
-
|
|
799
|
+
##### Interactivity
|
|
652
800
|
|
|
653
801
|
| Attribute | Description | Options |
|
|
654
802
|
|----------|-------------|---------|
|
|
655
803
|
| 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
804
|
|
|
657
|
-
|
|
805
|
+
### Pie chart
|
|
658
806
|
|
|
659
807
|
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
808
|
|
|
@@ -669,24 +817,24 @@ Here's an example:
|
|
|
669
817
|
/>
|
|
670
818
|
```
|
|
671
819
|
|
|
672
|
-
|
|
820
|
+
#### All pie chart attributes
|
|
673
821
|
|
|
674
|
-
|
|
822
|
+
##### General
|
|
675
823
|
|
|
676
824
|
| Attribute | Description | Options | Default |
|
|
677
825
|
|----------|-------------|---------|---------|
|
|
678
826
|
| title | Chart title. Appears at top left of chart. | string | - |
|
|
679
827
|
| subtitle | Chart subtitle. Appears just under title. | string | - |
|
|
680
828
|
|
|
681
|
-
|
|
829
|
+
##### Data
|
|
682
830
|
|
|
683
831
|
| Attribute | Description | Required | Options | Default |
|
|
684
832
|
|------|-------------|----------|---------|---------|
|
|
685
|
-
| data |
|
|
833
|
+
| data | GSQL query or table name | true | query name | - |
|
|
686
834
|
| category | Column or expression to use for slice names | true | column name, stored expression name, GSQL expression | - |
|
|
687
835
|
| value | Column or expression to use for slice values | true | column name, stored expression name, GSQL expression | - |
|
|
688
836
|
|
|
689
|
-
|
|
837
|
+
### Line chart
|
|
690
838
|
|
|
691
839
|
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
840
|
|
|
@@ -703,9 +851,9 @@ Here's an example:
|
|
|
703
851
|
/>
|
|
704
852
|
```
|
|
705
853
|
|
|
706
|
-
|
|
854
|
+
#### All line chart attributes
|
|
707
855
|
|
|
708
|
-
|
|
856
|
+
##### General
|
|
709
857
|
|
|
710
858
|
| Attribute | Description | Required | Options | Default |
|
|
711
859
|
|------|-------------|----------|---------|---------|
|
|
@@ -717,11 +865,11 @@ Here's an example:
|
|
|
717
865
|
| downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
|
|
718
866
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
|
|
719
867
|
|
|
720
|
-
|
|
868
|
+
##### Data
|
|
721
869
|
|
|
722
870
|
| Attribute | Description | Required | Options | Default |
|
|
723
871
|
|------|-------------|----------|---------|---------|
|
|
724
|
-
| data |
|
|
872
|
+
| data | GSQL query or table name | true | query name | - |
|
|
725
873
|
| x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | - |
|
|
726
874
|
| 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
875
|
| 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 +880,7 @@ Here's an example:
|
|
|
732
880
|
| 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
881
|
| 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
882
|
|
|
735
|
-
|
|
883
|
+
##### Formatting & Styling
|
|
736
884
|
|
|
737
885
|
| Attribute | Description | Required | Options | Default |
|
|
738
886
|
|------|-------------|----------|---------|---------|
|
|
@@ -763,7 +911,7 @@ Here's an example:
|
|
|
763
911
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
|
|
764
912
|
| 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
913
|
|
|
766
|
-
|
|
914
|
+
##### Axes
|
|
767
915
|
|
|
768
916
|
| Attribute | Description | Required | Options | Default |
|
|
769
917
|
|------|-------------|----------|---------|---------|
|
|
@@ -791,14 +939,14 @@ Here's an example:
|
|
|
791
939
|
| y2Max | Maximum value for the y2-axis | false | number | - |
|
|
792
940
|
| y2Scale | Whether to scale the y-axis to fit your data. `y2Min` and `y2Max` take precedence over `y2Scale` | false | `true`, `false` | `false` |
|
|
793
941
|
|
|
794
|
-
|
|
942
|
+
##### Interactivity
|
|
795
943
|
|
|
796
944
|
| Attribute | Description | Required | Options | Default |
|
|
797
945
|
|------|-------------|----------|---------|---------|
|
|
798
946
|
| 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
947
|
|
|
800
948
|
|
|
801
|
-
|
|
949
|
+
### Area chart
|
|
802
950
|
|
|
803
951
|
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
952
|
|
|
@@ -812,9 +960,9 @@ Here's an example:
|
|
|
812
960
|
/>
|
|
813
961
|
```
|
|
814
962
|
|
|
815
|
-
|
|
963
|
+
#### All area chart attributes
|
|
816
964
|
|
|
817
|
-
|
|
965
|
+
##### General
|
|
818
966
|
|
|
819
967
|
| Attribute | Description | Required | Options | Default |
|
|
820
968
|
|------|-------------|----------|---------|---------|
|
|
@@ -826,11 +974,11 @@ Here's an example:
|
|
|
826
974
|
| downloadableData | Whether to show the download button to allow users to download the data | false | `true`, `false` | `true` |
|
|
827
975
|
| downloadableImage | Whether to show the button to allow users to save the chart as an image | false | `true`, `false` | `true` |
|
|
828
976
|
|
|
829
|
-
|
|
977
|
+
##### Data
|
|
830
978
|
|
|
831
979
|
| Attribute | Description | Required | Options | Default |
|
|
832
980
|
|------|-------------|----------|---------|---------|
|
|
833
|
-
| data |
|
|
981
|
+
| data | GSQL query or table name | true | query name | - |
|
|
834
982
|
| x | Column or expression to use for the x-axis of the chart | true | column name, stored expression name, GSQL expression | First column |
|
|
835
983
|
| 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
984
|
| 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 +988,7 @@ Here's an example:
|
|
|
840
988
|
| 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
989
|
| 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
990
|
|
|
843
|
-
|
|
991
|
+
##### Formatting & Styling
|
|
844
992
|
|
|
845
993
|
| Attribute | Description | Required | Options | Default |
|
|
846
994
|
|------|-------------|----------|---------|---------|
|
|
@@ -859,7 +1007,7 @@ Here's an example:
|
|
|
859
1007
|
| rightPadding | Number representing the padding (whitespace) on the left side of the chart. Useful to avoid labels getting cut off | false | number | - |
|
|
860
1008
|
| 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
1009
|
|
|
862
|
-
|
|
1010
|
+
##### Value Labels
|
|
863
1011
|
|
|
864
1012
|
| Attribute | Description | Required | Options | Default |
|
|
865
1013
|
|------|-------------|----------|---------|---------|
|
|
@@ -870,7 +1018,7 @@ Here's an example:
|
|
|
870
1018
|
| 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
1019
|
| showAllLabels | Allow all labels to appear on chart, including overlapping labels | false | `true`, `false` | `false` |
|
|
872
1020
|
|
|
873
|
-
|
|
1021
|
+
##### Axes
|
|
874
1022
|
|
|
875
1023
|
| Attribute | Description | Required | Options | Default |
|
|
876
1024
|
|------|-------------|----------|---------|---------|
|
|
@@ -890,14 +1038,14 @@ Here's an example:
|
|
|
890
1038
|
| yMax | Maximum value for the y-axis | false | number | - |
|
|
891
1039
|
| yScale | Whether to scale the y-axis to fit your data. `yMin` and `yMax` take precedence over `yScale` | false | `true`, `false` | `false` |
|
|
892
1040
|
|
|
893
|
-
|
|
1041
|
+
##### Interactivity
|
|
894
1042
|
|
|
895
1043
|
| Attribute | Description | Required | Options | Default |
|
|
896
1044
|
|------|-------------|----------|---------|---------|
|
|
897
1045
|
| 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
1046
|
|
|
899
1047
|
|
|
900
|
-
|
|
1048
|
+
### Big value
|
|
901
1049
|
|
|
902
1050
|
Use big values to display a large value standalone, and optionally include a comparison and a sparkline.
|
|
903
1051
|
|
|
@@ -914,13 +1062,13 @@ Here's an example:
|
|
|
914
1062
|
/>
|
|
915
1063
|
```
|
|
916
1064
|
|
|
917
|
-
|
|
1065
|
+
#### All big value attributes
|
|
918
1066
|
|
|
919
|
-
|
|
1067
|
+
##### Data
|
|
920
1068
|
|
|
921
1069
|
| Attribute | Description | Required | Options | Default |
|
|
922
1070
|
|------|-------------|----------|---------|---------|
|
|
923
|
-
| data |
|
|
1071
|
+
| data | GSQL query or table name | true | query name | - |
|
|
924
1072
|
| value | Column or expression to pull the main value from. | true | column name, stored expression name, GSQL expression | - |
|
|
925
1073
|
| title | Title of the card. | false | string | Title of the value column. |
|
|
926
1074
|
| minWidth | Overrides min-width of component | false | % or px value | `"18%"` |
|
|
@@ -930,7 +1078,7 @@ Here's an example:
|
|
|
930
1078
|
| 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
1079
|
| 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
1080
|
|
|
933
|
-
|
|
1081
|
+
##### Comparison
|
|
934
1082
|
|
|
935
1083
|
| Attribute | Description | Required | Options | Default |
|
|
936
1084
|
|------|-------------|----------|---------|---------|
|
|
@@ -942,7 +1090,7 @@ Here's an example:
|
|
|
942
1090
|
| neutralMax | Sets the top of the range for 'neutral' values - neutral values appear in grey rather than red or green | false | number | `0` |
|
|
943
1091
|
| comparisonFmt | Sets format for the comparison ([see available formats](#value-formatting)) | false | Excel-style format, built-in format | - |
|
|
944
1092
|
|
|
945
|
-
|
|
1093
|
+
##### Sparkline
|
|
946
1094
|
|
|
947
1095
|
| Attribute | Description | Required | Options | Default |
|
|
948
1096
|
|------|-------------|----------|---------|---------|
|
|
@@ -955,7 +1103,7 @@ Here's an example:
|
|
|
955
1103
|
| 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
1104
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
957
1105
|
|
|
958
|
-
|
|
1106
|
+
### Table
|
|
959
1107
|
|
|
960
1108
|
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
1109
|
|
|
@@ -965,13 +1113,13 @@ Here's an example:
|
|
|
965
1113
|
<Table data=orders_summary />
|
|
966
1114
|
```
|
|
967
1115
|
|
|
968
|
-
|
|
1116
|
+
#### All table attributes
|
|
969
1117
|
|
|
970
|
-
|
|
1118
|
+
##### Table
|
|
971
1119
|
|
|
972
1120
|
| Attribute | Description | Required | Options | Default |
|
|
973
1121
|
|------|-------------|----------|---------|---------|
|
|
974
|
-
| data |
|
|
1122
|
+
| data | GSQL query or table name | true | query name | - |
|
|
975
1123
|
| 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
1124
|
| title | Title for the table | false | string | - |
|
|
977
1125
|
| subtitle | Subtitle - appears under the title | false | string | - |
|
|
@@ -997,7 +1145,7 @@ Here's an example:
|
|
|
997
1145
|
| 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
1146
|
| 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
1147
|
|
|
1000
|
-
|
|
1148
|
+
##### Groups
|
|
1001
1149
|
|
|
1002
1150
|
| Attribute | Description | Required | Options | Default |
|
|
1003
1151
|
|------|-------------|----------|---------|---------|
|
|
@@ -1011,7 +1159,7 @@ Here's an example:
|
|
|
1011
1159
|
| subtotalFontColor | [groupType=section] Font color for the subtotal row | false | Hex color code, css color name | - |
|
|
1012
1160
|
| groupNamePosition | [groupType=section] Where the group label will appear in its cell | false | `top`, `middle`, `bottom` | `middle` |
|
|
1013
1161
|
|
|
1014
|
-
|
|
1162
|
+
##### Column
|
|
1015
1163
|
|
|
1016
1164
|
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
1165
|
|
|
@@ -1102,11 +1250,11 @@ Conditional formatting (`contentType=colorscale`)
|
|
|
1102
1250
|
| 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
1251
|
| 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
1252
|
|
|
1105
|
-
|
|
1253
|
+
## Input components
|
|
1106
1254
|
|
|
1107
|
-
|
|
1255
|
+
### Text input
|
|
1108
1256
|
|
|
1109
|
-
Creates a text input that can be used to filter or search.
|
|
1257
|
+
Creates a text input that can be used to filter or search.
|
|
1110
1258
|
|
|
1111
1259
|
Here's an example:
|
|
1112
1260
|
|
|
@@ -1125,7 +1273,7 @@ from users
|
|
|
1125
1273
|
where email ilike concat('%', $name_of_input, '%')
|
|
1126
1274
|
```
|
|
1127
1275
|
|
|
1128
|
-
|
|
1276
|
+
#### All text input attributes
|
|
1129
1277
|
|
|
1130
1278
|
| Attribute | Description | Required | Options | Default |
|
|
1131
1279
|
|------|-------------|----------|---------|---------|
|
|
@@ -1136,9 +1284,9 @@ where email ilike concat('%', $name_of_input, '%')
|
|
|
1136
1284
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
1137
1285
|
|
|
1138
1286
|
|
|
1139
|
-
|
|
1287
|
+
### Dropdown
|
|
1140
1288
|
|
|
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.
|
|
1289
|
+
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
1290
|
|
|
1143
1291
|
Here's an example:
|
|
1144
1292
|
|
|
@@ -1164,12 +1312,12 @@ from orders
|
|
|
1164
1312
|
where status = $status_dropdown
|
|
1165
1313
|
```
|
|
1166
1314
|
|
|
1167
|
-
|
|
1315
|
+
#### All dropdown attributes
|
|
1168
1316
|
|
|
1169
1317
|
| Attribute | Description | Required | Options | Default |
|
|
1170
1318
|
|------|-------------|----------|---------|---------|
|
|
1171
1319
|
| name | Name of the dropdown, used to reference the selected value elsewhere as `"$name"` | true | - | - |
|
|
1172
|
-
| data |
|
|
1320
|
+
| data | GSQL query or table name | false | query name | - |
|
|
1173
1321
|
| value | Column name from the query containing values to pick from | false | column name | - |
|
|
1174
1322
|
| multiple | Enables multi-select which returns a list | false | `true`, `false` | `false` |
|
|
1175
1323
|
| 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 +1331,7 @@ where status = $status_dropdown
|
|
|
1183
1331
|
| hideDuringPrint | Hide the component when the report is printed | false | `true`, `false` | `true` |
|
|
1184
1332
|
| description | Adds an info icon with description tooltip on hover | false | string | - |
|
|
1185
1333
|
|
|
1186
|
-
|
|
1334
|
+
##### DropdownOption
|
|
1187
1335
|
|
|
1188
1336
|
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
1337
|
|
|
@@ -1202,11 +1350,11 @@ Here's an example:
|
|
|
1202
1350
|
| value | Value to use when the option is selected | true | - | - |
|
|
1203
1351
|
| valueLabel | Label to display for the option in the dropdown | false | - | Uses the value |
|
|
1204
1352
|
|
|
1205
|
-
|
|
1353
|
+
## Other components
|
|
1206
1354
|
|
|
1207
1355
|
`<Row></Row>` - Evenly distributes components inside along the same row.
|
|
1208
1356
|
|
|
1209
|
-
|
|
1357
|
+
## Value formatting
|
|
1210
1358
|
|
|
1211
1359
|
The easiest way to format numbers and dates in Graphene is through component attributes. You can pass in either of the following:
|
|
1212
1360
|
|
|
@@ -1241,11 +1389,11 @@ In the example above, `xFmt` is passing in an Excel-style code to format the dat
|
|
|
1241
1389
|
|
|
1242
1390
|
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
1391
|
|
|
1244
|
-
|
|
1392
|
+
### Built-in Formats
|
|
1245
1393
|
|
|
1246
1394
|
Graphene supports a variety of date/time, number, percentage, and currency formats.
|
|
1247
1395
|
|
|
1248
|
-
|
|
1396
|
+
#### Auto-Formatting
|
|
1249
1397
|
|
|
1250
1398
|
Wherever you see `auto` listed beside a format, that means Graphene will automatically format your value based on the context it is in.
|
|
1251
1399
|
|
|
@@ -1253,7 +1401,7 @@ For example, Graphene automatically formats large numbers into shortened version
|
|
|
1253
1401
|
|
|
1254
1402
|
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
1403
|
|
|
1256
|
-
|
|
1404
|
+
#### Dates
|
|
1257
1405
|
|
|
1258
1406
|
Graphene supports the following date formats:
|
|
1259
1407
|
|
|
@@ -1269,7 +1417,7 @@ Graphene supports the following date formats:
|
|
|
1269
1417
|
* `dmy` - Day/month/year (e.g., 9/1/22)
|
|
1270
1418
|
* `hms` - Time format (e.g., 11:45:03 AM)
|
|
1271
1419
|
|
|
1272
|
-
|
|
1420
|
+
#### Currencies
|
|
1273
1421
|
|
|
1274
1422
|
Supported currencies include USD, AUD, BRL, CAD, CNY, EUR, GBP, JPY, INR, KRW, NGN, RUB, and SEK.
|
|
1275
1423
|
|
|
@@ -1288,7 +1436,7 @@ For example, the available tags for USD are:
|
|
|
1288
1436
|
|
|
1289
1437
|
Similar patterns apply to other supported currencies.
|
|
1290
1438
|
|
|
1291
|
-
|
|
1439
|
+
#### Numbers
|
|
1292
1440
|
|
|
1293
1441
|
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
1442
|
|
|
@@ -1303,7 +1451,7 @@ Available number formats:
|
|
|
1303
1451
|
* `mult`, `mult0`, `mult1`, `mult2` - Multiplier format (e.g., 5.32x)
|
|
1304
1452
|
* `sci` - Scientific notation
|
|
1305
1453
|
|
|
1306
|
-
|
|
1454
|
+
#### Percentages
|
|
1307
1455
|
|
|
1308
1456
|
Available percentage formats:
|
|
1309
1457
|
|
|
@@ -1312,25 +1460,3 @@ Available percentage formats:
|
|
|
1312
1460
|
* `pct1` - Percentage with 1 decimal place (e.g., 73.1%)
|
|
1313
1461
|
* `pct2` - Percentage with 2 decimal places (e.g., 73.10%)
|
|
1314
1462
|
* `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.
|