trevl 0.1.0
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/NOTICE +9 -0
- data/README.md +431 -0
- data/Rakefile +10 -0
- data/assets/trendence-logo.svg +17 -0
- data/assets/trevl-logo.svg +20 -0
- data/docs/screenshots/01_bar_chart.png +0 -0
- data/docs/screenshots/02_column_chart.png +0 -0
- data/docs/screenshots/03_line_chart.png +0 -0
- data/docs/screenshots/04_pie_chart.png +0 -0
- data/docs/screenshots/05_computed_fields.png +0 -0
- data/docs/screenshots/06_postprocess_top_n.png +0 -0
- data/docs/screenshots/10_multi_series.png +0 -0
- data/examples/01_bar_chart.yml +16 -0
- data/examples/02_column_chart.yml +19 -0
- data/examples/03_line_chart.yml +21 -0
- data/examples/04_pie_chart.yml +15 -0
- data/examples/05_computed_fields.yml +26 -0
- data/examples/06_postprocess_top_n.yml +21 -0
- data/examples/07_score_kpi.yml +13 -0
- data/examples/08_table.yml +14 -0
- data/examples/09_template_inheritance.yml +25 -0
- data/examples/10_multi_series.yml +23 -0
- data/lib/trevl/auth/bearer_token.rb +23 -0
- data/lib/trevl/configuration.rb +24 -0
- data/lib/trevl/core_ext/hash.rb +37 -0
- data/lib/trevl/data_source/api.rb +86 -0
- data/lib/trevl/data_source/base.rb +19 -0
- data/lib/trevl/data_source/cube.rb +70 -0
- data/lib/trevl/data_source/static.rb +30 -0
- data/lib/trevl/data_source.rb +38 -0
- data/lib/trevl/errors.rb +9 -0
- data/lib/trevl/highcharts_asset.rb +45 -0
- data/lib/trevl/html_renderer.rb +91 -0
- data/lib/trevl/notebook/display.rb +53 -0
- data/lib/trevl/notebook.rb +41 -0
- data/lib/trevl/processor.rb +106 -0
- data/lib/trevl/renderer/data_fetcher.rb +63 -0
- data/lib/trevl/renderer/ref_parser.rb +61 -0
- data/lib/trevl/renderer/transform.rb +104 -0
- data/lib/trevl/renderer.rb +345 -0
- data/lib/trevl/schema/component.json +337 -0
- data/lib/trevl/schema/document.json +41 -0
- data/lib/trevl/template_store.rb +38 -0
- data/lib/trevl/validator.rb +96 -0
- data/lib/trevl/version.rb +5 -0
- data/lib/trevl.rb +99 -0
- data/llms.txt +171 -0
- data/notebooks/demo.ipynb +312 -0
- data/notebooks/exploration.ipynb +164 -0
- data/scripts/generate_screenshots.rb +107 -0
- metadata +137 -0
data/llms.txt
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# TREVL — TREndence Visualization Language
|
|
2
|
+
|
|
3
|
+
> Write YAML, get Highcharts. AI-first Ruby gem for declarative data visualization.
|
|
4
|
+
|
|
5
|
+
## What is TREVL?
|
|
6
|
+
|
|
7
|
+
TREVL is a YAML-based DSL that turns declarative component definitions into Highcharts JSON.
|
|
8
|
+
You describe what data to fetch, how to transform it, and how to display it.
|
|
9
|
+
The engine does the rest.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
gem "trevl", github: "trendence/trevl"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Component Types
|
|
18
|
+
|
|
19
|
+
| Type | Required fields |
|
|
20
|
+
|--------|------------------------------------|
|
|
21
|
+
| chart | id, type, api, highchartsData |
|
|
22
|
+
| score | id, type, api, display |
|
|
23
|
+
| table | id, type, api, tableData |
|
|
24
|
+
| text | id, type |
|
|
25
|
+
| filter | id, type, api, filters |
|
|
26
|
+
|
|
27
|
+
## Variable Reference Syntax
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
$endpoint.data.fieldName → row field value
|
|
31
|
+
$endpoint.meta.fieldName → metadata value
|
|
32
|
+
$resource.endpoint.data.fieldName → with resource qualifier
|
|
33
|
+
$computedFieldName → computed field shorthand
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Minimal Chart Example
|
|
37
|
+
|
|
38
|
+
```yaml
|
|
39
|
+
components:
|
|
40
|
+
- id: my_chart
|
|
41
|
+
type: chart
|
|
42
|
+
api: my_data_source
|
|
43
|
+
highchartsData:
|
|
44
|
+
chart:
|
|
45
|
+
type: bar
|
|
46
|
+
title:
|
|
47
|
+
text: My Chart
|
|
48
|
+
series:
|
|
49
|
+
- name: Values
|
|
50
|
+
data:
|
|
51
|
+
x: "$endpoint.data.label"
|
|
52
|
+
y: "$endpoint.data.value"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Computed Fields (per-row JavaScript)
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
computed:
|
|
59
|
+
- name: color
|
|
60
|
+
arguments:
|
|
61
|
+
val: "$endpoint.data.value"
|
|
62
|
+
code: 'val > 50 ? "#003F85" : "#ccc"'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Postprocess (full-dataset JavaScript)
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
postprocess: |
|
|
69
|
+
$result = $result
|
|
70
|
+
.sort(function(a, b) { return b.value - a.value; })
|
|
71
|
+
.slice(0, 10);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Templates (inherit + override)
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
- id: my_chart
|
|
78
|
+
type: chart
|
|
79
|
+
api: myapi
|
|
80
|
+
template: blue_bar
|
|
81
|
+
highchartsData:
|
|
82
|
+
title:
|
|
83
|
+
text: Override Title Only
|
|
84
|
+
series:
|
|
85
|
+
- data:
|
|
86
|
+
y: "$endpoint.data.value"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Score Example
|
|
90
|
+
|
|
91
|
+
```yaml
|
|
92
|
+
- id: kpi
|
|
93
|
+
type: score
|
|
94
|
+
api: myapi
|
|
95
|
+
display:
|
|
96
|
+
value: "$endpoint.data.avg_salary"
|
|
97
|
+
unit: " EUR"
|
|
98
|
+
header:
|
|
99
|
+
title: Average Salary
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Table Example
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
- id: data_table
|
|
106
|
+
type: table
|
|
107
|
+
api: myapi
|
|
108
|
+
tableData:
|
|
109
|
+
headers: ["Name", "Value"]
|
|
110
|
+
columns:
|
|
111
|
+
- identifier: name
|
|
112
|
+
value: "$endpoint.data.name"
|
|
113
|
+
- identifier: val
|
|
114
|
+
value: "$endpoint.data.value"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Ruby API
|
|
118
|
+
|
|
119
|
+
```ruby
|
|
120
|
+
require "trevl"
|
|
121
|
+
|
|
122
|
+
# Register data source
|
|
123
|
+
Trevl::DataSource.register("demo", Trevl::DataSource::Static.new(
|
|
124
|
+
data: {"salary" => {"data" => [...], "meta" => {}}}
|
|
125
|
+
))
|
|
126
|
+
|
|
127
|
+
# Validate
|
|
128
|
+
result = Trevl.validate(yaml)
|
|
129
|
+
result.valid? # => true/false
|
|
130
|
+
result.errors # => ["[component_id] Missing required field: api"]
|
|
131
|
+
|
|
132
|
+
# Render to Highcharts JSON
|
|
133
|
+
results = Trevl.render(yaml)
|
|
134
|
+
results.first["highchartsData"] # => Highcharts JSON
|
|
135
|
+
|
|
136
|
+
# Render with inline data (no global registration; answers any api name,
|
|
137
|
+
# components may omit api: — use for request-specific data)
|
|
138
|
+
results = Trevl.render(yaml, data: {"salary" => [{"level" => "q50", "value" => 45000}]})
|
|
139
|
+
|
|
140
|
+
# Render with per-call data source instances (win over data: and registry)
|
|
141
|
+
results = Trevl.render(yaml, data_sources: {"demo" => Trevl::DataSource::Static.new(
|
|
142
|
+
data: {"salary" => {"data" => [...], "meta" => {}}}
|
|
143
|
+
)})
|
|
144
|
+
|
|
145
|
+
# Render to standalone HTML (self-contained, offline)
|
|
146
|
+
html = Trevl.render_to_html(yaml, width: 800, height: 400)
|
|
147
|
+
File.write("chart.html", html)
|
|
148
|
+
|
|
149
|
+
# Discover data source fields
|
|
150
|
+
Trevl::DataSource.for("demo").field_names("salary")
|
|
151
|
+
# => ["label", "value"]
|
|
152
|
+
|
|
153
|
+
# Get this reference
|
|
154
|
+
Trevl.schema_reference # => this text
|
|
155
|
+
|
|
156
|
+
# List examples
|
|
157
|
+
Trevl.examples # => [{name: "bar_chart", yaml: "...", description: "..."}, ...]
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Highcharts Chart Types
|
|
161
|
+
|
|
162
|
+
bar, column, line, area, pie, scatter, spline, areaspline, heatmap, bubble, waterfall, funnel, gauge, solidgauge, bullet
|
|
163
|
+
|
|
164
|
+
## Filter Operators
|
|
165
|
+
|
|
166
|
+
equals, notEquals, gt, gte, lt, lte, afterDate, beforeDate, set, notSet, contains, notContains
|
|
167
|
+
|
|
168
|
+
## Docs
|
|
169
|
+
|
|
170
|
+
https://trevl.trendence.com
|
|
171
|
+
https://github.com/trendence/trevl
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "34e8ac3b",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"# TREVL Demo Notebook\n",
|
|
9
|
+
"\n",
|
|
10
|
+
"Interactive data visualization with TREVL YAML and Highcharts."
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"cell_type": "code",
|
|
15
|
+
"execution_count": null,
|
|
16
|
+
"id": "fd72b046",
|
|
17
|
+
"metadata": {},
|
|
18
|
+
"outputs": [],
|
|
19
|
+
"source": [
|
|
20
|
+
"$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))\n",
|
|
21
|
+
"require 'trevl'\n",
|
|
22
|
+
"require 'trevl/notebook'\n",
|
|
23
|
+
"\n",
|
|
24
|
+
"puts \"TREVL v#{Trevl::VERSION} loaded\""
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"cell_type": "markdown",
|
|
29
|
+
"id": "2c27ff7f",
|
|
30
|
+
"metadata": {},
|
|
31
|
+
"source": [
|
|
32
|
+
"## 1. Simple Bar Chart"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"cell_type": "code",
|
|
37
|
+
"execution_count": null,
|
|
38
|
+
"id": "5971e608",
|
|
39
|
+
"metadata": {},
|
|
40
|
+
"outputs": [],
|
|
41
|
+
"source": [
|
|
42
|
+
"nb = Trevl::Notebook.new\n",
|
|
43
|
+
"\n",
|
|
44
|
+
"salary_data = {\n",
|
|
45
|
+
" \"salary\" => {\n",
|
|
46
|
+
" \"data\" => [\n",
|
|
47
|
+
" {\"label\" => \"Junior\", \"value\" => 42000},\n",
|
|
48
|
+
" {\"label\" => \"Mid-Level\", \"value\" => 58000},\n",
|
|
49
|
+
" {\"label\" => \"Senior\", \"value\" => 78000},\n",
|
|
50
|
+
" {\"label\" => \"Lead\", \"value\" => 92000},\n",
|
|
51
|
+
" {\"label\" => \"Principal\", \"value\" => 110000}\n",
|
|
52
|
+
" ]\n",
|
|
53
|
+
" }\n",
|
|
54
|
+
"}\n",
|
|
55
|
+
"\n",
|
|
56
|
+
"nb.chart(<<~YAML, data: salary_data)\n",
|
|
57
|
+
" components:\n",
|
|
58
|
+
" - id: salary_bar\n",
|
|
59
|
+
" type: chart\n",
|
|
60
|
+
" api: static\n",
|
|
61
|
+
" highchartsData:\n",
|
|
62
|
+
" chart:\n",
|
|
63
|
+
" type: bar\n",
|
|
64
|
+
" title:\n",
|
|
65
|
+
" text: Salary by Seniority (EUR)\n",
|
|
66
|
+
" colors: [\"#003F85\"]\n",
|
|
67
|
+
" yAxis:\n",
|
|
68
|
+
" title:\n",
|
|
69
|
+
" text: Annual Salary (EUR)\n",
|
|
70
|
+
" series:\n",
|
|
71
|
+
" - name: Salary\n",
|
|
72
|
+
" data:\n",
|
|
73
|
+
" x: \"$salary.data.label\"\n",
|
|
74
|
+
" y: \"$salary.data.value\"\n",
|
|
75
|
+
"YAML"
|
|
76
|
+
]
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"cell_type": "markdown",
|
|
80
|
+
"id": "21bf9b3f",
|
|
81
|
+
"metadata": {},
|
|
82
|
+
"source": [
|
|
83
|
+
"## 2. Column Chart with Computed Fields"
|
|
84
|
+
]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"cell_type": "code",
|
|
88
|
+
"execution_count": null,
|
|
89
|
+
"id": "7ccb1bb6",
|
|
90
|
+
"metadata": {},
|
|
91
|
+
"outputs": [],
|
|
92
|
+
"source": [
|
|
93
|
+
"skills_data = {\n",
|
|
94
|
+
" \"skills\" => {\n",
|
|
95
|
+
" \"data\" => [\n",
|
|
96
|
+
" {\"name\" => \"Python\", \"demand\" => 85},\n",
|
|
97
|
+
" {\"name\" => \"JavaScript\", \"demand\" => 78},\n",
|
|
98
|
+
" {\"name\" => \"SQL\", \"demand\" => 72},\n",
|
|
99
|
+
" {\"name\" => \"Java\", \"demand\" => 65},\n",
|
|
100
|
+
" {\"name\" => \"Ruby\", \"demand\" => 45},\n",
|
|
101
|
+
" {\"name\" => \"Go\", \"demand\" => 38},\n",
|
|
102
|
+
" {\"name\" => \"Rust\", \"demand\" => 22}\n",
|
|
103
|
+
" ]\n",
|
|
104
|
+
" }\n",
|
|
105
|
+
"}\n",
|
|
106
|
+
"\n",
|
|
107
|
+
"yaml = <<~YAML\n",
|
|
108
|
+
" components:\n",
|
|
109
|
+
" - id: skills_chart\n",
|
|
110
|
+
" type: chart\n",
|
|
111
|
+
" api: static\n",
|
|
112
|
+
" computed:\n",
|
|
113
|
+
" - name: color\n",
|
|
114
|
+
" arguments:\n",
|
|
115
|
+
" d: \"$skills.data.demand\"\n",
|
|
116
|
+
" code: 'd > 70 ? \"#003F85\" : d > 50 ? \"#4A90D9\" : \"#B0C4DE\"'\n",
|
|
117
|
+
" highchartsData:\n",
|
|
118
|
+
" chart:\n",
|
|
119
|
+
" type: column\n",
|
|
120
|
+
" title:\n",
|
|
121
|
+
" text: Programming Language Demand\n",
|
|
122
|
+
" yAxis:\n",
|
|
123
|
+
" title:\n",
|
|
124
|
+
" text: Demand Score\n",
|
|
125
|
+
" max: 100\n",
|
|
126
|
+
" plotOptions:\n",
|
|
127
|
+
" column:\n",
|
|
128
|
+
" borderRadius: 4\n",
|
|
129
|
+
" colorByPoint: true\n",
|
|
130
|
+
" series:\n",
|
|
131
|
+
" - name: Demand\n",
|
|
132
|
+
" data:\n",
|
|
133
|
+
" x: \"$skills.data.name\"\n",
|
|
134
|
+
" y: \"$skills.data.demand\"\n",
|
|
135
|
+
" color: \"$color\"\n",
|
|
136
|
+
"YAML\n",
|
|
137
|
+
"\n",
|
|
138
|
+
"nb.chart(yaml, data: skills_data)"
|
|
139
|
+
]
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"cell_type": "markdown",
|
|
143
|
+
"id": "62267b86",
|
|
144
|
+
"metadata": {},
|
|
145
|
+
"source": [
|
|
146
|
+
"## 3. Postprocess: Top-N with Sorting"
|
|
147
|
+
]
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
"cell_type": "code",
|
|
151
|
+
"execution_count": null,
|
|
152
|
+
"id": "59018534",
|
|
153
|
+
"metadata": {},
|
|
154
|
+
"outputs": [],
|
|
155
|
+
"source": [
|
|
156
|
+
"cities_data = {\n",
|
|
157
|
+
" \"cities\" => {\n",
|
|
158
|
+
" \"data\" => [\n",
|
|
159
|
+
" {\"city\" => \"Berlin\", \"vacancies\" => 12500},\n",
|
|
160
|
+
" {\"city\" => \"Munich\", \"vacancies\" => 9800},\n",
|
|
161
|
+
" {\"city\" => \"Hamburg\", \"vacancies\" => 7200},\n",
|
|
162
|
+
" {\"city\" => \"Frankfurt\", \"vacancies\" => 6500},\n",
|
|
163
|
+
" {\"city\" => \"Cologne\", \"vacancies\" => 4800},\n",
|
|
164
|
+
" {\"city\" => \"Stuttgart\", \"vacancies\" => 4200},\n",
|
|
165
|
+
" {\"city\" => \"Dusseldorf\", \"vacancies\" => 3900},\n",
|
|
166
|
+
" {\"city\" => \"Leipzig\", \"vacancies\" => 2100}\n",
|
|
167
|
+
" ]\n",
|
|
168
|
+
" }\n",
|
|
169
|
+
"}\n",
|
|
170
|
+
"\n",
|
|
171
|
+
"nb.chart(<<~YAML, data: cities_data)\n",
|
|
172
|
+
" components:\n",
|
|
173
|
+
" - id: top_cities\n",
|
|
174
|
+
" type: chart\n",
|
|
175
|
+
" api: static\n",
|
|
176
|
+
" postprocess: |\n",
|
|
177
|
+
" $result = $result\n",
|
|
178
|
+
" .sort(function(a, b) { return b.vacancies - a.vacancies; })\n",
|
|
179
|
+
" .slice(0, 5);\n",
|
|
180
|
+
" highchartsData:\n",
|
|
181
|
+
" chart:\n",
|
|
182
|
+
" type: bar\n",
|
|
183
|
+
" title:\n",
|
|
184
|
+
" text: Top 5 Cities by Job Vacancies\n",
|
|
185
|
+
" colors: [\"#E87722\"]\n",
|
|
186
|
+
" series:\n",
|
|
187
|
+
" - name: Vacancies\n",
|
|
188
|
+
" data:\n",
|
|
189
|
+
" x: \"$cities.data.city\"\n",
|
|
190
|
+
" y: \"$cities.data.vacancies\"\n",
|
|
191
|
+
"YAML"
|
|
192
|
+
]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"cell_type": "markdown",
|
|
196
|
+
"id": "86f96998",
|
|
197
|
+
"metadata": {},
|
|
198
|
+
"source": [
|
|
199
|
+
"## 4. Score Component"
|
|
200
|
+
]
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
"cell_type": "code",
|
|
204
|
+
"execution_count": null,
|
|
205
|
+
"id": "d6c07d23",
|
|
206
|
+
"metadata": {},
|
|
207
|
+
"outputs": [],
|
|
208
|
+
"source": [
|
|
209
|
+
"kpi_data = {\n",
|
|
210
|
+
" \"kpi\" => {\n",
|
|
211
|
+
" \"data\" => [{\"avg_salary\" => 62100}],\n",
|
|
212
|
+
" \"meta\" => {\"median\" => 58000}\n",
|
|
213
|
+
" }\n",
|
|
214
|
+
"}\n",
|
|
215
|
+
"\n",
|
|
216
|
+
"nb.score(<<~YAML, data: kpi_data)\n",
|
|
217
|
+
" components:\n",
|
|
218
|
+
" - id: median_score\n",
|
|
219
|
+
" type: score\n",
|
|
220
|
+
" api: static\n",
|
|
221
|
+
" display:\n",
|
|
222
|
+
" value: \"$kpi.data.avg_salary\"\n",
|
|
223
|
+
" unit: \" EUR\"\n",
|
|
224
|
+
" header:\n",
|
|
225
|
+
" title: Average Salary\n",
|
|
226
|
+
"YAML"
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"cell_type": "markdown",
|
|
231
|
+
"id": "a40d7e17",
|
|
232
|
+
"metadata": {},
|
|
233
|
+
"source": [
|
|
234
|
+
"## 5. Templates: Reusable Chart Styles"
|
|
235
|
+
]
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"cell_type": "code",
|
|
239
|
+
"execution_count": null,
|
|
240
|
+
"id": "2492aa3e",
|
|
241
|
+
"metadata": {},
|
|
242
|
+
"outputs": [],
|
|
243
|
+
"source": [
|
|
244
|
+
"Trevl.template_store.register(\"branded_bar\", {\n",
|
|
245
|
+
" \"highchartsData\" => {\n",
|
|
246
|
+
" \"chart\" => {\"type\" => \"bar\"},\n",
|
|
247
|
+
" \"colors\" => [\"#003F85\", \"#E87722\"],\n",
|
|
248
|
+
" \"plotOptions\" => {\n",
|
|
249
|
+
" \"bar\" => {\"borderRadius\" => 6, \"groupPadding\" => 0.1}\n",
|
|
250
|
+
" },\n",
|
|
251
|
+
" \"legend\" => {\"enabled\" => true},\n",
|
|
252
|
+
" \"credits\" => {\"enabled\" => false}\n",
|
|
253
|
+
" }\n",
|
|
254
|
+
"})\n",
|
|
255
|
+
"\n",
|
|
256
|
+
"compare_data = {\n",
|
|
257
|
+
" \"compare\" => {\n",
|
|
258
|
+
" \"data\" => [\n",
|
|
259
|
+
" {\"region\" => \"North\", \"current\" => 55000, \"previous\" => 52000},\n",
|
|
260
|
+
" {\"region\" => \"South\", \"current\" => 48000, \"previous\" => 47500},\n",
|
|
261
|
+
" {\"region\" => \"East\", \"current\" => 43000, \"previous\" => 41000},\n",
|
|
262
|
+
" {\"region\" => \"West\", \"current\" => 51000, \"previous\" => 50000}\n",
|
|
263
|
+
" ]\n",
|
|
264
|
+
" }\n",
|
|
265
|
+
"}\n",
|
|
266
|
+
"\n",
|
|
267
|
+
"nb.chart(<<~YAML, data: compare_data)\n",
|
|
268
|
+
" components:\n",
|
|
269
|
+
" - id: region_compare\n",
|
|
270
|
+
" type: chart\n",
|
|
271
|
+
" api: static\n",
|
|
272
|
+
" template: branded_bar\n",
|
|
273
|
+
" highchartsData:\n",
|
|
274
|
+
" title:\n",
|
|
275
|
+
" text: Salary Comparison by Region\n",
|
|
276
|
+
" series:\n",
|
|
277
|
+
" - name: Current Year\n",
|
|
278
|
+
" data:\n",
|
|
279
|
+
" x: \"$compare.data.region\"\n",
|
|
280
|
+
" y: \"$compare.data.current\"\n",
|
|
281
|
+
" - name: Previous Year\n",
|
|
282
|
+
" data:\n",
|
|
283
|
+
" x: \"$compare.data.region\"\n",
|
|
284
|
+
" y: \"$compare.data.previous\"\n",
|
|
285
|
+
"YAML"
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
"cell_type": "code",
|
|
290
|
+
"execution_count": null,
|
|
291
|
+
"id": "dcbf126f-1d4a-490f-8e96-72f7b7be7a07",
|
|
292
|
+
"metadata": {},
|
|
293
|
+
"outputs": [],
|
|
294
|
+
"source": []
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
"metadata": {
|
|
298
|
+
"kernelspec": {
|
|
299
|
+
"display_name": "Ruby 3 (iruby kernel)",
|
|
300
|
+
"language": "ruby",
|
|
301
|
+
"name": "ruby3"
|
|
302
|
+
},
|
|
303
|
+
"language_info": {
|
|
304
|
+
"file_extension": ".rb",
|
|
305
|
+
"mimetype": "application/x-ruby",
|
|
306
|
+
"name": "ruby",
|
|
307
|
+
"version": "3.4.7"
|
|
308
|
+
}
|
|
309
|
+
},
|
|
310
|
+
"nbformat": 4,
|
|
311
|
+
"nbformat_minor": 5
|
|
312
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "34e8ac3b",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"# TREVL - Viz DSL for humans and robots 🤖 \n",
|
|
9
|
+
"\n",
|
|
10
|
+
"TREVL is a DSL for visualization. Let's dive in what that means! First, let's ensure we have it on board:"
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"cell_type": "code",
|
|
15
|
+
"execution_count": null,
|
|
16
|
+
"id": "fd72b046",
|
|
17
|
+
"metadata": {},
|
|
18
|
+
"outputs": [],
|
|
19
|
+
"source": [
|
|
20
|
+
"$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))\n",
|
|
21
|
+
"require 'trevl'\n",
|
|
22
|
+
"require 'trevl/notebook'\n",
|
|
23
|
+
"\n",
|
|
24
|
+
"puts \"TREVL v#{Trevl::VERSION} loaded\""
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"cell_type": "code",
|
|
29
|
+
"execution_count": null,
|
|
30
|
+
"id": "3d909b50-2824-4a9c-a8d5-6780d3aa1279",
|
|
31
|
+
"metadata": {},
|
|
32
|
+
"outputs": [],
|
|
33
|
+
"source": [
|
|
34
|
+
"Trevl::DataSource.all"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"cell_type": "code",
|
|
39
|
+
"execution_count": null,
|
|
40
|
+
"id": "63844182-5dbe-4bc9-b208-cf545769fb0d",
|
|
41
|
+
"metadata": {},
|
|
42
|
+
"outputs": [],
|
|
43
|
+
"source": [
|
|
44
|
+
"Trevl::DataSource.register(\"elections\", Trevl::DataSource::Static.new(\n",
|
|
45
|
+
" data: {\n",
|
|
46
|
+
" \"parties\" => {\n",
|
|
47
|
+
" \"data\" => [\n",
|
|
48
|
+
" {\"name\" => \"Grüne\", \"share\" => 6},\n",
|
|
49
|
+
" {\"name\" => \"AFD\", \"share\" => 16},\n",
|
|
50
|
+
" {\"name\" => \"SPD\", \"share\" => 11},\n",
|
|
51
|
+
" {\"name\" => \"CDU\", \"share\" => 22},\n",
|
|
52
|
+
" {\"name\" => \"Linke\", \"share\" => 5},\n",
|
|
53
|
+
" ]\n",
|
|
54
|
+
" }\n",
|
|
55
|
+
" }\n",
|
|
56
|
+
"))"
|
|
57
|
+
]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"cell_type": "code",
|
|
61
|
+
"execution_count": null,
|
|
62
|
+
"id": "0a740b54-1b4f-42aa-bb99-64f95353a5b2",
|
|
63
|
+
"metadata": {},
|
|
64
|
+
"outputs": [],
|
|
65
|
+
"source": [
|
|
66
|
+
"Trevl::DataSource.all"
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"cell_type": "code",
|
|
71
|
+
"execution_count": null,
|
|
72
|
+
"id": "984cad5c-7fed-47ba-ab49-c689a70fa5cf",
|
|
73
|
+
"metadata": {},
|
|
74
|
+
"outputs": [],
|
|
75
|
+
"source": [
|
|
76
|
+
"Trevl::DataSource.register(\"elections\", Trevl::DataSource::Static.new(\n",
|
|
77
|
+
" data: {\n",
|
|
78
|
+
" \"parties\" => {\n",
|
|
79
|
+
" \"data\" => [\n",
|
|
80
|
+
" {\"name\" => \"Grüne\", \"share\" => 6},\n",
|
|
81
|
+
" {\"name\" => \"AFD\", \"share\" => 16},\n",
|
|
82
|
+
" {\"name\" => \"SPD\", \"share\" => 11},\n",
|
|
83
|
+
" {\"name\" => \"CDU\", \"share\" => 22},\n",
|
|
84
|
+
" {\"name\" => \"Linke\", \"share\" => 5},\n",
|
|
85
|
+
" ]\n",
|
|
86
|
+
" }\n",
|
|
87
|
+
" }\n",
|
|
88
|
+
"))\n",
|
|
89
|
+
"\n",
|
|
90
|
+
"nb = Trevl::Notebook.new\n",
|
|
91
|
+
"\n",
|
|
92
|
+
"chart = nb.chart(<<~YAML)\n",
|
|
93
|
+
" components:\n",
|
|
94
|
+
" - id: election_results\n",
|
|
95
|
+
" type: chart\n",
|
|
96
|
+
" api: elections\n",
|
|
97
|
+
" highchartsData:\n",
|
|
98
|
+
" chart:\n",
|
|
99
|
+
" type: column\n",
|
|
100
|
+
" title:\n",
|
|
101
|
+
" text: Wahlergebnis - Kommunalwahl in Klein Datenhausen\n",
|
|
102
|
+
" series:\n",
|
|
103
|
+
" - name: Anteil in %\n",
|
|
104
|
+
" data:\n",
|
|
105
|
+
" x: \"$parties.data.name\"\n",
|
|
106
|
+
" y: \"$parties.data.share\"\n",
|
|
107
|
+
"YAML"
|
|
108
|
+
]
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"cell_type": "code",
|
|
112
|
+
"execution_count": null,
|
|
113
|
+
"id": "c48f917a-a068-491c-bad2-b06fa069c77d",
|
|
114
|
+
"metadata": {},
|
|
115
|
+
"outputs": [],
|
|
116
|
+
"source": [
|
|
117
|
+
"Trevl::DataSource.for(\"elections\").field_names(\"parties\")"
|
|
118
|
+
]
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"cell_type": "code",
|
|
122
|
+
"execution_count": null,
|
|
123
|
+
"id": "f3f44b55-36eb-4891-a13d-85373ef7c967",
|
|
124
|
+
"metadata": {},
|
|
125
|
+
"outputs": [],
|
|
126
|
+
"source": [
|
|
127
|
+
" chart.errors"
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
"cell_type": "code",
|
|
132
|
+
"execution_count": null,
|
|
133
|
+
"id": "83412406-5f44-40c8-a3b6-ad12b4705601",
|
|
134
|
+
"metadata": {},
|
|
135
|
+
"outputs": [],
|
|
136
|
+
"source": [
|
|
137
|
+
"chart.class"
|
|
138
|
+
]
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"cell_type": "code",
|
|
142
|
+
"execution_count": null,
|
|
143
|
+
"id": "2bf45618-4306-4822-8f6a-da38fd34107a",
|
|
144
|
+
"metadata": {},
|
|
145
|
+
"outputs": [],
|
|
146
|
+
"source": []
|
|
147
|
+
}
|
|
148
|
+
],
|
|
149
|
+
"metadata": {
|
|
150
|
+
"kernelspec": {
|
|
151
|
+
"display_name": "Ruby 3 (iruby kernel)",
|
|
152
|
+
"language": "ruby",
|
|
153
|
+
"name": "ruby3"
|
|
154
|
+
},
|
|
155
|
+
"language_info": {
|
|
156
|
+
"file_extension": ".rb",
|
|
157
|
+
"mimetype": "application/x-ruby",
|
|
158
|
+
"name": "ruby",
|
|
159
|
+
"version": "3.4.7"
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
"nbformat": 4,
|
|
163
|
+
"nbformat_minor": 5
|
|
164
|
+
}
|