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.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/NOTICE +9 -0
  4. data/README.md +431 -0
  5. data/Rakefile +10 -0
  6. data/assets/trendence-logo.svg +17 -0
  7. data/assets/trevl-logo.svg +20 -0
  8. data/docs/screenshots/01_bar_chart.png +0 -0
  9. data/docs/screenshots/02_column_chart.png +0 -0
  10. data/docs/screenshots/03_line_chart.png +0 -0
  11. data/docs/screenshots/04_pie_chart.png +0 -0
  12. data/docs/screenshots/05_computed_fields.png +0 -0
  13. data/docs/screenshots/06_postprocess_top_n.png +0 -0
  14. data/docs/screenshots/10_multi_series.png +0 -0
  15. data/examples/01_bar_chart.yml +16 -0
  16. data/examples/02_column_chart.yml +19 -0
  17. data/examples/03_line_chart.yml +21 -0
  18. data/examples/04_pie_chart.yml +15 -0
  19. data/examples/05_computed_fields.yml +26 -0
  20. data/examples/06_postprocess_top_n.yml +21 -0
  21. data/examples/07_score_kpi.yml +13 -0
  22. data/examples/08_table.yml +14 -0
  23. data/examples/09_template_inheritance.yml +25 -0
  24. data/examples/10_multi_series.yml +23 -0
  25. data/lib/trevl/auth/bearer_token.rb +23 -0
  26. data/lib/trevl/configuration.rb +24 -0
  27. data/lib/trevl/core_ext/hash.rb +37 -0
  28. data/lib/trevl/data_source/api.rb +86 -0
  29. data/lib/trevl/data_source/base.rb +19 -0
  30. data/lib/trevl/data_source/cube.rb +70 -0
  31. data/lib/trevl/data_source/static.rb +30 -0
  32. data/lib/trevl/data_source.rb +38 -0
  33. data/lib/trevl/errors.rb +9 -0
  34. data/lib/trevl/highcharts_asset.rb +45 -0
  35. data/lib/trevl/html_renderer.rb +91 -0
  36. data/lib/trevl/notebook/display.rb +53 -0
  37. data/lib/trevl/notebook.rb +41 -0
  38. data/lib/trevl/processor.rb +106 -0
  39. data/lib/trevl/renderer/data_fetcher.rb +63 -0
  40. data/lib/trevl/renderer/ref_parser.rb +61 -0
  41. data/lib/trevl/renderer/transform.rb +104 -0
  42. data/lib/trevl/renderer.rb +345 -0
  43. data/lib/trevl/schema/component.json +337 -0
  44. data/lib/trevl/schema/document.json +41 -0
  45. data/lib/trevl/template_store.rb +38 -0
  46. data/lib/trevl/validator.rb +96 -0
  47. data/lib/trevl/version.rb +5 -0
  48. data/lib/trevl.rb +99 -0
  49. data/llms.txt +171 -0
  50. data/notebooks/demo.ipynb +312 -0
  51. data/notebooks/exploration.ipynb +164 -0
  52. data/scripts/generate_screenshots.rb +107 -0
  53. 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
+ }