@preschen/gen-vis 0.5.0 → 0.8.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.
package/README.md CHANGED
@@ -15,7 +15,7 @@ the styles, and provides two global functions:
15
15
  ```html
16
16
  <div class="genVis" data-def-file="/data/bev/def.json"></div>
17
17
 
18
- <script src="gen-vis-0.5.0.js"></script>
18
+ <script src="gen-vis-0.8.0.js"></script>
19
19
  <script>mountGenVisByClass('genVis')</script>
20
20
  ```
21
21
 
@@ -49,11 +49,49 @@ well.
49
49
  | `def` | `data-def` | the definition, an object or a JSON string |
50
50
  | `data` | `data-data` | the data as rows or a CSV/JSON string, if not given it is loaded from the `data` url of the definition |
51
51
  | `debug` | `data-debug` | shows the prepared definition |
52
+ | `state` | | the changes of the user, see [state](#state) |
52
53
 
53
54
  Every visualisation has its own state, several of them can be used on a page.
54
55
  If the props change, the visualisation is loaded again. Errors are shown in
55
56
  place of the visualisation.
56
57
 
58
+ ### State
59
+
60
+ The state holds what the user changed compared to the definition: the
61
+ globals of the form elements and the entries of the legends shown or hidden.
62
+
63
+ ```json
64
+ { "globals": { "column": "share" }, "visible": { "year": { "2019": true, "2022": false } } }
65
+ ```
66
+
67
+ The component emits `update:state` on every change of the user, so with
68
+ `v-model:state` the page can keep it, e.g. in the local storage. A given state
69
+ is applied when the visualisation is loaded, a new one (`null` for the
70
+ definition) is applied without loading it again. Globals, values and entries
71
+ the definition does not have (anymore) are ignored, new entries of the
72
+ definition keep their defaults.
73
+
74
+ ```html
75
+ <GenVis def-file="/data/bev/def.json" v-model:state="state"/>
76
+ ```
77
+
78
+ ### Styles
79
+
80
+ The styles of the package are in the cascade layer `gen-vis`, so every style
81
+ of the page overrides them, regardless of its specificity and of the order of
82
+ the styles, e.g.:
83
+
84
+ ```css
85
+ .formElement { display: block; margin: 6px 4px; }
86
+ .vis-header .subtitle { font-size: 15px; }
87
+ ```
88
+
89
+ The main classes are `vis`, `vis-header` (with `title` and `subtitle`),
90
+ `vis-form-elements` (with a `formElement` for every form element),
91
+ `vis-legends`, `facet-title` and `vis-footer`. Styles of the page which are in
92
+ a cascade layer themselves only override the package if their layer is
93
+ declared after it, e.g. `@layer gen-vis, page;`.
94
+
57
95
  ## Definition
58
96
 
59
97
  ```json
@@ -75,6 +113,19 @@ its `parent` (and its parent into its own parent), arrays are replaced, not
75
113
  merged. The merged definition is checked for common mistakes, e.g. unknown
76
114
  plot types, the findings are logged as warnings in the console.
77
115
 
116
+ `parent` can also be a list of definitions (mixins), merged in their order,
117
+ later ones override earlier ones, e.g. a chart type and a form element:
118
+
119
+ ```json
120
+ {
121
+ "parent": ["../shared/years.json", "../shared/scale-switch.json"],
122
+ "data": "data.csv"
123
+ }
124
+ ```
125
+
126
+ A parent shared by several mixins is merged once, before the first mixin
127
+ using it, so it does not override the mixins in between.
128
+
78
129
  The package contains a JSON Schema of the definitions, `schema.json`. With
79
130
  `"$schema"` in a definition, editors like VS Code complete and check it:
80
131
 
@@ -154,10 +205,13 @@ the definition refer to these names.
154
205
  `name` by default.
155
206
  - `props`: the categories and their props, e.g. colors. `common` props are
156
207
  used for all `manual` entries, `name` and `visible` are set by default. Only
157
- visible categories are shown.
208
+ visible categories are shown. The order of the `manual` entries is the order
209
+ of the legend, the facets and the stacks, not the order of the rows. Keys
210
+ which are integers, e.g. years, are ordered ascending by JavaScript.
158
211
  - `legend`: a toggle for every category, `symbol` draws svg `elements` (with
159
212
  props) of the given `size` before the name.
160
- - `stacked`: stacks the values of a vertical axis, see `stackedBar`.
213
+ - `stacked`: stacks the values of a vertical axis, see `stackedBar`, the first
214
+ category is at the bottom.
161
215
 
162
216
  ### `plot`
163
217
 
@@ -225,6 +279,31 @@ the column of an axis:
225
279
  }]
226
280
  ```
227
281
 
282
+ If the column depends on several form elements, it can be a template of the
283
+ globals, e.g. the values and their shares in the columns `twh`, `co2`,
284
+ `twh.share` and `co2.share`:
285
+
286
+ ```json
287
+ "globals": { "values": "twh", "share": "" },
288
+ "formElements": [{
289
+ "id": "values", "name": "Werte", "ref": "values", "type": "switch",
290
+ "values": [
291
+ { "id": "twh", "name": "TWh", "value": "twh" },
292
+ { "id": "co2", "name": "CO₂", "value": "co2" }
293
+ ]
294
+ }, {
295
+ "id": "share", "name": "Darstellung", "ref": "share", "type": "switch",
296
+ "values": [
297
+ { "id": "abs", "name": "Absolut", "value": "" },
298
+ { "id": "rel", "name": "Anteil", "value": ".share", "mapping": { "y": { "axis": { "format": ".0%" } } } }
299
+ ]
300
+ }],
301
+ "mapping": { "y": { "column": "{values}{share}" } }
302
+ ```
303
+
304
+ `{name}` is replaced by the value of the global, unknown globals are kept and
305
+ reported as warnings.
306
+
228
307
  ## Development
229
308
 
230
309
  ```sh
package/dist/gen-vis.js CHANGED
@@ -1,22 +1,22 @@
1
- (() => { const s = document.createElement("style"); s.textContent = ".hover[data-v-364032d4]{font-size:13px;position:absolute;top:0}.hover .title[data-v-364032d4]{text-align:center;border-bottom:2px solid #000;padding:1px 3px;font-weight:700}.hover[data-v-364032d4]{background-color:#fffc;top:40%}.hover[data-v-364032d4] table{border-collapse:collapse}.hover[data-v-364032d4] table tr.nearest{font-weight:700}.hover[data-v-364032d4] table tr td{text-align:left;padding:1px 5px}.hover[data-v-364032d4] table tr td.value,.hover[data-v-364032d4] table tr td.y{text-align:right}.hover[data-v-364032d4] table tr td:first-child{border-left:0}.hover[data-v-364032d4] table{margin-left:auto;margin-right:auto}.hover[data-v-364032d4]{pointer-events:none}.vis-inner[data-v-1f05a06e]{display:inline-block;position:relative}.vis-inner .debug[data-v-1f05a06e]{font-size:12px}.vis-inner[data-v-1f05a06e] svg g.axis-position-top g.tick line{transform:translateY(5px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-right g.tick line{transform:translate(-4px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-bottom g.tick line{transform:translateY(-4px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-left g.tick line{transform:translate(5px)}.vis-inner[data-v-1f05a06e] svg g.tick text,.vis-inner[data-v-1f05a06e] svg .axis-title{font-size:13px}.vis-inner[data-v-1f05a06e] svg g.group[data-visible=false],.vis-inner[data-v-1f05a06e] svg path[data-visible=false]{opacity:.01}.vis-inner[data-v-1f05a06e] svg g.grid{stroke:#ccc;stroke-width:.75px}.vis-inner[data-v-1f05a06e] svg g.hoverMarker line{stroke-width:.75px;stroke:#aaa}svg[data-v-ce0e972e]{margin-right:5px;display:inline-block}.legend .title[data-v-1bc8d55f]{margin:3px;font-size:13px;font-weight:700;position:relative}.legend .entries>div[data-v-1bc8d55f]{cursor:pointer;margin:0 5px;display:inline-block}.legend .entries>div[data-visible=false][data-v-1bc8d55f]{opacity:.3}.legend .entries>div span[data-v-1bc8d55f]{font-size:13px;display:inline-block;position:relative;top:-4px}.legend .entries>div.bold[data-v-1bc8d55f]{font-weight:700}.formElement[data-v-b7f59ae7]{margin:6px 4px;font-size:13px}.formElement .title[data-v-b7f59ae7]{margin-right:5px;font-weight:700;display:inline-block}.formElement .entries[data-v-b7f59ae7]{display:inline-block}.formElement .entries>div[data-v-b7f59ae7]{margin-right:5px;display:inline-block}.formElement .entries>div input[data-v-b7f59ae7]{display:inline-block;position:relative;top:1px}.vis[data-v-f8fa11d2] text,.vis[data-v-f8fa11d2] span,.vis[data-v-f8fa11d2] div{font-family:var(--gen-vis-font-family,Century Gothic, sans-serif)}.vis-header .title[data-v-f8fa11d2]{font-size:22px;font-weight:700}.vis-header .subtitle[data-v-f8fa11d2]{margin-top:3px;font-size:13px}.vis-header[data-v-f8fa11d2]{margin-bottom:10px}.vis-footer span[data-v-f8fa11d2]{font-size:13px}.facet-title[data-v-f8fa11d2]{margin-top:8px;font-size:13px;font-weight:700}.vis-error[data-v-a9d47434]{color:#b00;font-size:13px}\n/*$vite$:1*/"; document.head.appendChild(s); })();
2
- import { Fragment as e, createApp as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, markRaw as o, mergeProps as s, normalizeStyle as c, openBlock as l, reactive as u, renderList as d, resolveComponent as f, toDisplayString as p, toRaw as m } from "vue";
3
- import * as h from "d3";
4
- import g from "deepmerge";
1
+ (() => { const s = document.createElement("style"); s.textContent = "@layer gen-vis {\n.hover[data-v-364032d4]{font-size:13px;position:absolute;top:0}.hover .title[data-v-364032d4]{text-align:center;border-bottom:2px solid #000;padding:1px 3px;font-weight:700}.hover[data-v-364032d4]{background-color:#fffc;top:40%}.hover[data-v-364032d4] table{border-collapse:collapse}.hover[data-v-364032d4] table tr.nearest{font-weight:700}.hover[data-v-364032d4] table tr td{text-align:left;padding:1px 5px}.hover[data-v-364032d4] table tr td.value,.hover[data-v-364032d4] table tr td.y{text-align:right}.hover[data-v-364032d4] table tr td:first-child{border-left:0}.hover[data-v-364032d4] table{margin-left:auto;margin-right:auto}.hover[data-v-364032d4]{pointer-events:none}.vis-inner[data-v-1f05a06e]{display:inline-block;position:relative}.vis-inner .debug[data-v-1f05a06e]{font-size:12px}.vis-inner[data-v-1f05a06e] svg g.axis-position-top g.tick line{transform:translateY(5px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-right g.tick line{transform:translate(-4px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-bottom g.tick line{transform:translateY(-4px)}.vis-inner[data-v-1f05a06e] svg g.axis-position-left g.tick line{transform:translate(5px)}.vis-inner[data-v-1f05a06e] svg g.tick text,.vis-inner[data-v-1f05a06e] svg .axis-title{font-size:13px}.vis-inner[data-v-1f05a06e] svg g.group[data-visible=false],.vis-inner[data-v-1f05a06e] svg path[data-visible=false]{opacity:.01}.vis-inner[data-v-1f05a06e] svg g.grid{stroke:#ccc;stroke-width:.75px}.vis-inner[data-v-1f05a06e] svg g.hoverMarker line{stroke-width:.75px;stroke:#aaa}svg[data-v-ce0e972e]{margin-right:5px;display:inline-block}.legend .title[data-v-1bc8d55f]{margin:3px;font-size:13px;font-weight:700;position:relative}.legend .entries>div[data-v-1bc8d55f]{cursor:pointer;margin:0 5px;display:inline-block}.legend .entries>div[data-visible=false][data-v-1bc8d55f]{opacity:.3}.legend .entries>div span[data-v-1bc8d55f]{font-size:13px;display:inline-block;position:relative;top:-4px}.legend .entries>div.bold[data-v-1bc8d55f]{font-weight:700}.formElement[data-v-acf88417]{margin:2px 16px 2px 4px;font-size:13px;display:inline-block}.formElement .title[data-v-acf88417]{margin-right:5px;font-weight:700;display:inline-block}.formElement .entries[data-v-acf88417]{display:inline-block}.formElement .entries>div[data-v-acf88417]{margin-right:5px;display:inline-block}.formElement .entries>div input[data-v-acf88417]{display:inline-block;position:relative;top:1px}.vis[data-v-d870f406] text,.vis[data-v-d870f406] span,.vis[data-v-d870f406] div{font-family:var(--gen-vis-font-family,Century Gothic, sans-serif)}.vis-header .title[data-v-d870f406]{font-size:22px;font-weight:700}.vis-header .subtitle[data-v-d870f406]{margin-top:3px;font-size:13px}.vis-header[data-v-d870f406]{margin-bottom:10px}.vis-footer span[data-v-d870f406]{font-size:13px}.facet-title[data-v-d870f406]{margin-top:8px;font-size:13px;font-weight:700}.vis-error[data-v-7b1c318b]{color:#b00;font-size:13px}\n/*$vite$:1*/\n}"; document.head.appendChild(s); })();
2
+ import { Fragment as e, createApp as t, createBlock as n, createCommentVNode as r, createElementBlock as i, createElementVNode as a, markRaw as o, mergeProps as s, normalizeStyle as c, openBlock as l, reactive as u, renderList as d, resolveComponent as f, toDisplayString as p, toRaw as ee } from "vue";
3
+ import * as m from "d3";
4
+ import h from "deepmerge";
5
5
  //#region src/utils/data.js
6
- var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(e) ? JSON.parse(e) : h.csvParse(e)) : e, v = (e) => e == null || e === "", ee = {
6
+ var g = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(e) ? JSON.parse(e) : m.csvParse(e)) : e, _ = (e) => e == null || e === "", te = {
7
7
  numeric: (e) => {
8
- let t = v(e) ? NaN : +e;
8
+ let t = _(e) ? NaN : +e;
9
9
  return isNaN(t) ? null : t;
10
10
  },
11
11
  date: (e) => {
12
- let t = v(e) ? NaN : typeof e == "number" ? e : Date.parse(e);
12
+ let t = _(e) ? NaN : typeof e == "number" ? e : Date.parse(e);
13
13
  return isNaN(t) ? null : t;
14
14
  }
15
- }, te = (e, t) => {
15
+ }, ne = (e, t) => {
16
16
  let n = Object.keys(t.mapping).map((e) => ({
17
17
  name: e,
18
18
  column: t.mapping[e].column,
19
- convert: ee[t.mapping[e].type] ?? ((e) => e)
19
+ convert: te[t.mapping[e].type] ?? ((e) => e)
20
20
  }));
21
21
  return e.map((e) => {
22
22
  let t = {};
@@ -24,23 +24,35 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
24
24
  t[n.name] = n.convert(e[n.column]);
25
25
  }), t;
26
26
  });
27
- }, ne = (e, t) => {
28
- e.values = [...new Set(t.map((t) => t[e.dim]))], (e.mapping.type == "numeric" || e.mapping.type == "date") && (e.values = e.values.filter((e) => e !== null).sort((e, t) => e - t), e.extent = e.mapping.stacked ? h.extent(t.map((t) => t[`${e.dim}:st:e`])) : h.extent(e.values));
29
- }, re = (e, t, n = []) => {
30
- b(e, [...n, t.h]).forEach((e) => {
31
- let n = 0, r = 0;
32
- e.entries.forEach((e) => {
33
- let i = e[t.v];
34
- i >= 0 ? (e[`${t.v}:st:s`] = n, n += i, e[`${t.v}:st:e`] = n) : (e[`${t.v}:st:s`] = r, r += i, e[`${t.v}:st:e`] = r);
27
+ }, re = (e, t) => {
28
+ e.values = [...new Set(t.map((t) => t[e.dim]))], (e.mapping.type == "numeric" || e.mapping.type == "date") && (e.values = e.values.filter((e) => e !== null).sort((e, t) => e - t), e.extent = e.mapping.stacked ? m.extent(t.map((t) => t[`${e.dim}:st:e`])) : m.extent(e.values));
29
+ }, ie = (e) => {
30
+ let t = e.map(({ dim: e, keys: t }) => ({
31
+ dim: e,
32
+ rank: new Map(t.map((e, t) => [e, t]))
33
+ }));
34
+ return (e, n) => {
35
+ for (let { dim: r, rank: i } of t) {
36
+ let t = (i.get(e[r]) ?? Infinity) - (i.get(n[r]) ?? Infinity);
37
+ if (t) return t;
38
+ }
39
+ return 0;
40
+ };
41
+ }, ae = (e, t, n = [], r = null) => {
42
+ y(e, [...n, t.h]).forEach((e) => {
43
+ let n = 0, i = 0;
44
+ (r ? [...e.entries].sort(r) : e.entries).forEach((e) => {
45
+ let r = e[t.v];
46
+ r >= 0 ? (e[`${t.v}:st:s`] = n, n += r, e[`${t.v}:st:e`] = n) : (e[`${t.v}:st:s`] = i, i += r, e[`${t.v}:st:e`] = i);
35
47
  });
36
48
  });
37
- }, y = (e, t) => {
49
+ }, v = (e, t) => {
38
50
  e.forEach((e) => {
39
51
  Object.values(t).forEach((t) => {
40
52
  e[`${t.dim}:scaled`] = t.scale(e[t.dim]), e[`${t.dim}:scaled:min`] = t.scale(t.domain[0]), e[`${t.dim}:scaled:0`] = t.scale(0), e[`${t.dim}:scaled:max`] = t.scale(t.domain[1]), t.mapping.stacked && (e[`${t.dim}:st:e:scaled`] = t.scale(e[`${t.dim}:st:e`]), e[`${t.dim}:st:s:scaled`] = t.scale(e[`${t.dim}:st:s`]), e[`${t.dim}:st:h:scaled`] = e[`${t.dim}:st:s:scaled`] - e[`${t.dim}:st:e:scaled`]);
41
53
  });
42
54
  });
43
- }, b = (e, t) => {
55
+ }, y = (e, t) => {
44
56
  let n = /* @__PURE__ */ new Map();
45
57
  return e.forEach((e) => {
46
58
  let r = JSON.stringify(t.map((t) => e[t]));
@@ -49,14 +61,14 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
49
61
  entries: []
50
62
  }), n.get(r).entries.push(e);
51
63
  }), [...n.values()];
52
- }, x = (e, t) => t.length == 0 ? [...e] : e.filter((e) => t.reduce((t, n) => Array.isArray(n.key) ? t && n.key.includes(e[n.dim]) : typeof n.key == "function" ? t && n.key(e[n.dim]) : t && e[n.dim] == n.key, !0)), ie = (e, t, n) => t, S = (e) => g.all(e, { arrayMerge: ie }), C = (e, t) => e == t || JSON.stringify(e) == JSON.stringify(t), w = (e, t) => Object.fromEntries(Object.entries(e).map(([e, n], r) => [e, t(n, e)])), T = (e, t) => Array.isArray(e) ? e.map(t) : w(e, t), ae = (e, t, n, r) => e.map((e) => ({
64
+ }, b = (e, t) => t.length == 0 ? [...e] : e.filter((e) => t.reduce((t, n) => Array.isArray(n.key) ? t && n.key.includes(e[n.dim]) : typeof n.key == "function" ? t && n.key(e[n.dim]) : t && e[n.dim] == n.key, !0)), oe = (e, t, n) => t, x = (e) => h.all(e, { arrayMerge: oe }), S = (e, t) => e == t || JSON.stringify(e) == JSON.stringify(t), C = (e, t) => Object.fromEntries(Object.entries(e).map(([e, n], r) => [e, t(n, e)])), se = (e, t) => Array.isArray(e) ? e.map(t) : C(e, t), ce = (e, t, n, r) => e.map((e) => ({
53
65
  group: Object.keys(e.group).map((t) => ({
54
66
  dim: t,
55
67
  key: e.group[t]
56
68
  })),
57
69
  props: t._fill(Object.assign({}, n, ...Object.keys(e.group).map((t) => r[t].props[e.group[t]]))),
58
70
  values: e.entries
59
- })), oe = (e, t, n = !0, r = !1) => {
71
+ })), le = (e, t, n = !0, r = !1) => {
60
72
  if (e.value === void 0 || e.value === null || r) {
61
73
  if (e.prop == "ref") {
62
74
  let n = t[e.ref];
@@ -74,8 +86,8 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
74
86
  }
75
87
  }
76
88
  return n ? e.value : e;
77
- }, E = (e, t) => oe({ ...j(e) }, t, !0), D = (e, t, n = !0) => O(T(e, j), t, n), O = (e, t, n = !1) => T(e, (e) => oe({ ...e }, t, n)), k = (e) => e.prop !== void 0, A = (e) => Object.values(e).flatMap((e) => typeof e != "object" || !e ? [] : k(e) ? typeof e.ref == "string" ? [e.ref.split(":")[0]] : [] : A(e)), j = (e) => {
78
- if (typeof e == "object" && !Array.isArray(e) && e !== null) return k(e) ? e : w(e, j);
89
+ }, w = (e, t) => le({ ...O(e) }, t, !0), T = (e, t, n = !0) => E(se(e, O), t, n), E = (e, t, n = !1) => se(e, (e) => le({ ...e }, t, n)), D = (e) => e.prop !== void 0, ue = (e) => Object.values(e).flatMap((e) => typeof e != "object" || !e ? [] : D(e) ? typeof e.ref == "string" ? [e.ref.split(":")[0]] : [] : ue(e)), O = (e) => {
90
+ if (typeof e == "object" && !Array.isArray(e) && e !== null) return D(e) ? e : C(e, O);
79
91
  if (typeof e == "string" && e.charAt() == "@") {
80
92
  let t = e.substring(1);
81
93
  return {
@@ -88,7 +100,7 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
88
100
  prop: "fixed",
89
101
  value: e
90
102
  };
91
- }, M = (e) => {
103
+ }, k = (e) => {
92
104
  if (e.props) {
93
105
  let t = e.props;
94
106
  e.props = Object.fromEntries(Object.keys(t.manual).map((e) => {
@@ -97,19 +109,21 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
97
109
  }));
98
110
  }
99
111
  return e.scale && (e.scale.type ??= "linear", e.scale.domain ??= [null, null], e.scale.domainAbs || (e.scale.domainRel ??= e.scale.domain.map((e, t) => e === null ? (t == 0 ? -1 : 1) * .02 : 0)), e.scale.domainAbs ??= [0, 0], Array.isArray(e.scale.range) || (e.scale.orientation == "horizontal" ? e.scale.range = [0, "@width"] : e.scale.orientation == "vertical" && (e.scale.range = ["@height", 0]))), e.axis && (e.axis.padding ??= 3), e.hover !== void 0 && e.axis !== void 0 && (e.hover.format ??= e.axis.format), e.legend && (e.legend.props === void 0 && (e.legend.props = {}), "name" in e.legend.props || (e.legend.props.name = "@name")), e.hover && (e.hover.props === void 0 && (e.hover.props = {}), "name" in e.hover.props || (e.hover.props.name = "@name")), e;
100
- }, se = (e) => (Object.values(e.mapping).forEach(M), Array.isArray(e.plot) || (e.plot = [e.plot]), e.facets && Array.isArray(e.facets.dim) && (e.facets.dim = e.facets.dim[0]), e.plot.forEach((e, t) => {
112
+ }, de = (e) => (Object.values(e.mapping).forEach(k), Array.isArray(e.plot) || (e.plot = [e.plot]), e.facets && Array.isArray(e.facets.dim) && (e.facets.dim = e.facets.dim[0]), e.plot.forEach((e, t) => {
101
113
  e.categories ??= [], e.id ??= `plot-${t}`, e.highlightProps = Object.keys(e.props).filter((e) => e.startsWith("highlight-")).map((e) => e.substring(10));
102
114
  }), e.plot.forEach((e) => {
103
- e.props = w(e.props, j), e._fill = (t) => O(e.props, t);
104
- }), e), N = (e, t) => {
105
- let n = e.formElements ?? [], r = new Set(n.flatMap((e) => e.values.flatMap((e) => Object.keys(e.mapping ?? {}))));
115
+ e.props = C(e.props, O), e._fill = (t) => E(e.props, t);
116
+ }), e), A = (e) => typeof e == "string" ? [...e.matchAll(/\{(\w+)\}/g)].map((e) => e[1]) : [], fe = (e, t = {}) => e.replace(/\{(\w+)\}/g, (e, n) => n in t ? String(t[n]) : e), j = (e, t) => {
117
+ let n = e.formElements ?? [], r = /* @__PURE__ */ new Set([...n.flatMap((e) => e.values.flatMap((e) => Object.keys(e.mapping ?? {}))), ...Object.keys(t.mapping ?? {}).filter((e) => A(t.mapping[e].column).length > 0)]);
106
118
  if (r.size == 0) return !1;
107
- let i = n.map((t) => t.values.find((n) => C(n.value, e.globals?.[t.ref]))).filter((e) => e && e.mapping);
119
+ let i = n.map((t) => t.values.find((n) => S(n.value, e.globals?.[t.ref]))).filter((e) => e && e.mapping);
108
120
  return r.forEach((n) => {
109
- let r = i.filter((e) => e.mapping[n]).map((e) => e.mapping[n]), a = M(S([t.mapping[n] ?? {}, ...r]));
110
- e.mapping[n] && "props" in e.mapping[n] && (a.props = e.mapping[n].props), e.mapping[n] = a;
121
+ let r = i.filter((e) => e.mapping[n]).map((e) => e.mapping[n]), a = x([t.mapping[n] ?? {}, ...r]);
122
+ typeof a.column == "string" && (a.column = fe(a.column, e.globals));
123
+ let o = k(a);
124
+ e.mapping[n] && "props" in e.mapping[n] && (o.props = e.mapping[n].props), e.mapping[n] = o;
111
125
  }), !0;
112
- }, P = (e) => e.charAt(0).toUpperCase() + e.slice(1), F = {
126
+ }, M = (e) => e.charAt(0).toUpperCase() + e.slice(1), N = {
113
127
  de: {
114
128
  number: {
115
129
  decimal: ",",
@@ -250,35 +264,35 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
250
264
  year: "%Y"
251
265
  }
252
266
  }
253
- }, ce = Object.keys(F), I = {
267
+ }, pe = Object.keys(N), P = {
254
268
  time: [
255
- h.timeSecond,
256
- h.timeMinute,
257
- h.timeHour,
258
- h.timeDay,
259
- h.timeWeek,
260
- h.timeMonth,
261
- h.timeYear
269
+ m.timeSecond,
270
+ m.timeMinute,
271
+ m.timeHour,
272
+ m.timeDay,
273
+ m.timeWeek,
274
+ m.timeMonth,
275
+ m.timeYear
262
276
  ],
263
277
  utc: [
264
- h.utcSecond,
265
- h.utcMinute,
266
- h.utcHour,
267
- h.utcDay,
268
- h.utcWeek,
269
- h.utcMonth,
270
- h.utcYear
278
+ m.utcSecond,
279
+ m.utcMinute,
280
+ m.utcHour,
281
+ m.utcDay,
282
+ m.utcWeek,
283
+ m.utcMonth,
284
+ m.utcYear
271
285
  ]
272
- }, L = (e, t, n) => {
286
+ }, F = (e, t, n) => {
273
287
  let r = Object.fromEntries(Object.entries(t).map(([t, n]) => [t, e(n)])), [i, a, o, s, c, l, u] = n;
274
288
  return (e) => (i(e) < e ? r.millisecond : a(e) < e ? r.second : o(e) < e ? r.minute : s(e) < e ? r.hour : l(e) < e ? c(e) < e ? r.day : r.week : u(e) < e ? r.month : r.year)(e);
275
- }, le = (e = "de") => {
276
- let t = typeof e == "string" ? { base: e } : e, n = F[t.base ?? "de"];
277
- if (!n) throw Error(`Unknown locale '${t.base}', expected one of ${ce.map((e) => `'${e}'`).join(", ")}`);
278
- let r = h.formatLocale({
289
+ }, me = (e = "de") => {
290
+ let t = typeof e == "string" ? { base: e } : e, n = N[t.base ?? "de"];
291
+ if (!n) throw Error(`Unknown locale '${t.base}', expected one of ${pe.map((e) => `'${e}'`).join(", ")}`);
292
+ let r = m.formatLocale({
279
293
  ...n.number,
280
294
  ...t.number
281
- }), i = h.timeFormatLocale({
295
+ }), i = m.timeFormatLocale({
282
296
  ...n.time,
283
297
  ...t.time
284
298
  }), a = {
@@ -294,13 +308,13 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
294
308
  "pow",
295
309
  "sqrt"
296
310
  ].includes(t)) {
297
- let [t, i] = e.domain(), a = h.precisionFixed(h.tickStep(t, i, n));
311
+ let [t, i] = e.domain(), a = m.precisionFixed(m.tickStep(t, i, n));
298
312
  return r.format(`,.${Number.isFinite(a) ? a : 0}f`);
299
313
  }
300
- return t == "time" ? L(i.format, a, I.time) : t == "utc" ? L(i.utcFormat, a, I.utc) : null;
314
+ return t == "time" ? F(i.format, a, P.time) : t == "utc" ? F(i.utcFormat, a, P.utc) : null;
301
315
  }
302
316
  };
303
- }, R = [
317
+ }, I = [
304
318
  "svg:path",
305
319
  "svg:circle",
306
320
  "svg:line",
@@ -309,24 +323,24 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
309
323
  "base:area",
310
324
  "bar",
311
325
  "stackedBar"
312
- ], z = [
326
+ ], L = [
313
327
  "numeric",
314
328
  "date",
315
329
  "categorical"
316
- ], B = ["horizontal", "vertical"], V = [
330
+ ], R = ["horizontal", "vertical"], z = [
317
331
  "top",
318
332
  "bottom",
319
333
  "left",
320
334
  "right"
321
- ], H = [
335
+ ], B = [
322
336
  "fixed",
323
337
  "ref",
324
338
  "relative",
325
339
  "steps"
326
- ], U = (e) => e.map((e) => `'${e}'`).join(", "), W = (e, t, n) => {
340
+ ], V = (e) => e.map((e) => `'${e}'`).join(", "), H = (e, t, n) => {
327
341
  if (typeof e != "object" || !e || Array.isArray(e)) return;
328
342
  if ("prop" in e) {
329
- H.includes(e.prop) ? e.prop != "fixed" && typeof e.ref != "string" && n(t, `a '${e.prop}' prop needs a 'ref'`) : n(t, `unknown prop '${e.prop}', expected one of ${U(H)}`);
343
+ B.includes(e.prop) ? e.prop != "fixed" && typeof e.ref != "string" && n(t, `a '${e.prop}' prop needs a 'ref'`) : n(t, `unknown prop '${e.prop}', expected one of ${V(B)}`);
330
344
  return;
331
345
  }
332
346
  let r = [
@@ -335,30 +349,49 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
335
349
  "ref",
336
350
  "mode"
337
351
  ].filter((t) => t in e);
338
- if (r.length > 0) return n(t, `has ${U(r)} but no 'prop', so it is not evaluated`);
339
- Object.entries(e).forEach(([e, r]) => W(r, `${t}.${e}`, n));
340
- }, ue = (e) => {
352
+ if (r.length > 0) return n(t, `has ${V(r)} but no 'prop', so it is not evaluated`);
353
+ Object.entries(e).forEach(([e, r]) => H(r, `${t}.${e}`, n));
354
+ }, he = (e) => {
341
355
  let t = [], n = (e, n) => t.push(`${e}: ${n}`), r = e.mapping ?? {};
342
356
  e.mapping || n("mapping", "missing"), Object.entries(r).forEach(([e, t]) => {
343
357
  let r = `mapping.${e}`;
344
- if (typeof t.column != "string" && n(r, "no 'column'"), t.type !== void 0 && !z.includes(t.type) && n(`${r}.type`, `unknown type '${t.type}', expected one of ${U(z)}`), t.props && !t.props.manual && n(`${r}.props`, "expected 'manual' (and optional 'common') entries"), t.scale) {
345
- let e = t.scale.type ?? "linear", i = h[`scale${P(e)}`];
346
- typeof i == "function" ? typeof i().ticks == "function" != ["numeric", "date"].includes(t.type) && n(`${r}.scale.type`, `a ${e} scale does not fit the type '${t.type}'`) : n(`${r}.scale.type`, `unknown d3 scale '${e}'`), t.scale.orientation !== void 0 && !B.includes(t.scale.orientation) && n(`${r}.scale.orientation`, `unknown orientation '${t.scale.orientation}', expected one of ${U(B)}`);
358
+ if (typeof t.column != "string" && n(r, "no 'column'"), t.type !== void 0 && !L.includes(t.type) && n(`${r}.type`, `unknown type '${t.type}', expected one of ${V(L)}`), t.props && !t.props.manual && n(`${r}.props`, "expected 'manual' (and optional 'common') entries"), t.scale) {
359
+ let e = t.scale.type ?? "linear", i = m[`scale${M(e)}`];
360
+ typeof i == "function" ? typeof i().ticks == "function" != ["numeric", "date"].includes(t.type) && n(`${r}.scale.type`, `a ${e} scale does not fit the type '${t.type}'`) : n(`${r}.scale.type`, `unknown d3 scale '${e}'`), t.scale.orientation !== void 0 && !R.includes(t.scale.orientation) && n(`${r}.scale.orientation`, `unknown orientation '${t.scale.orientation}', expected one of ${V(R)}`);
347
361
  }
348
- t.axis && (t.scale || n(`${r}.axis`, "an axis needs a 'scale'"), V.includes(t.axis.position) || n(`${r}.axis.position`, `unknown position '${t.axis.position}', expected one of ${U(V)}`), W(t.axis.ticks, `${r}.axis.ticks`, n));
362
+ t.axis && (t.scale || n(`${r}.axis`, "an axis needs a 'scale'"), z.includes(t.axis.position) || n(`${r}.axis.position`, `unknown position '${t.axis.position}', expected one of ${V(z)}`), H(t.axis.ticks, `${r}.axis.ticks`, n));
349
363
  });
350
364
  let i = [].concat(e.plot ?? []);
351
365
  if (i.length == 0 && n("plot", "missing"), i.forEach((e, t) => {
352
366
  let i = `plot[${t}]`;
353
- R.includes(e.type) || n(`${i}.type`, `unknown type '${e.type}', expected one of ${U(R)}`), (e.categories ?? []).filter((e) => !(e in r)).forEach((e) => n(`${i}.categories`, `unknown mapping '${e}'`)), W(e.props, `${i}.props`, n);
367
+ I.includes(e.type) || n(`${i}.type`, `unknown type '${e.type}', expected one of ${V(I)}`), (e.categories ?? []).filter((e) => !(e in r)).forEach((e) => n(`${i}.categories`, `unknown mapping '${e}'`)), H(e.props, `${i}.props`, n);
354
368
  }), e.facets) {
355
369
  let t = [].concat(e.facets.dim ?? []);
356
370
  t.length != 1 && n("facets.dim", "expected the name of one mapping"), t.filter((e) => !(e in r)).forEach((e) => n("facets.dim", `unknown mapping '${e}'`));
357
371
  }
358
- return W(e.options?.height, "options.height", n), W(e.facets?.cols, "facets.cols", n), t;
372
+ let a = (t, r) => A(t).filter((t) => !(t in (e.globals ?? {}))).forEach((e) => n(r, `unknown global '${e}' in the column template`));
373
+ return Object.entries(r).forEach(([e, t]) => a(t.column, `mapping.${e}.column`)), (e.formElements ?? []).forEach((e, t) => (e.values ?? []).forEach((e, n) => Object.entries(e.mapping ?? {}).forEach(([e, r]) => a(r.column, `formElements[${t}].values[${n}].mapping.${e}.column`)))), H(e.options?.height, "options.height", n), H(e.facets?.cols, "facets.cols", n), t;
374
+ }, U = (e) => ({
375
+ globals: Object.fromEntries((e.formElements ?? []).map((t) => [t.ref, e.globals?.[t.ref]])),
376
+ visible: Object.fromEntries(Object.entries(e.mapping).filter(([e, t]) => t.legend && t.props).map(([e, t]) => [e, Object.fromEntries(Object.entries(t.props).map(([e, t]) => [e, t.visible]))]))
377
+ }), ge = (e, t) => {
378
+ let n = {}, r = Object.fromEntries(Object.entries(e.globals).filter(([e, n]) => !S(n, t.globals[e])));
379
+ Object.keys(r).length > 0 && (n.globals = r);
380
+ let i = Object.fromEntries(Object.entries(e.visible).map(([e, n]) => [e, Object.fromEntries(Object.entries(n).filter(([n, r]) => r != t.visible[e]?.[n]))]).filter(([e, t]) => Object.keys(t).length > 0));
381
+ return Object.keys(i).length > 0 && (n.visible = i), n;
382
+ }, W = (e, t) => {
383
+ Object.entries(t?.globals ?? {}).forEach(([t, n]) => {
384
+ let r = (e.formElements ?? []).filter((e) => e.ref == t).flatMap((e) => e.values).find((e) => S(e.value, n));
385
+ r && e.globals && (e.globals[t] = r.value);
386
+ }), Object.entries(t?.visible ?? {}).forEach(([t, n]) => {
387
+ let r = e.mapping[t];
388
+ r?.legend && r.props && Object.entries(n).forEach(([e, t]) => {
389
+ e in r.props && (r.props[e].visible = !!t);
390
+ });
391
+ });
359
392
  }, G = (e, t = document.baseURI) => new URL(e, t).href, K = async (e) => {
360
393
  try {
361
- return await h.text(e);
394
+ return await m.text(e);
362
395
  } catch (t) {
363
396
  throw Error(`Could not load '${e}': ${t.message}`);
364
397
  }
@@ -368,43 +401,52 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
368
401
  } catch (e) {
369
402
  throw Error(`Invalid JSON in definition ${t}: ${e.message}`);
370
403
  }
371
- }, de = async (e, t, n = K) => {
372
- let r = [e], i = /* @__PURE__ */ new Set();
373
- for (; e.parent;) {
374
- if (t = G(e.parent, t), i.has(t)) throw Error(`Cyclic parent definition '${t}'`);
375
- i.add(t), e = q(await n(t), `'${t}'`), r.unshift(e);
376
- }
377
- return S(r);
378
- }, J = (e) => o(Array.from(m(e))), fe = async ({ def: e = null, defUrl: t = null, data: n = null }) => {
379
- let r;
380
- e === null ? (r = G(t), e = q(await K(r), `'${r}'`)) : typeof e == "string" && (e = q(e, "attribute"));
381
- let i = await de(JSON.parse(JSON.stringify(e)), r);
382
- ue(i).forEach((e) => console.warn(`gen-vis ${r ?? "inline definition"}: ${e}`));
383
- let a = se(JSON.parse(JSON.stringify(i)));
384
- if (N(a, i), n === null) {
385
- if (!i.data) throw Error("No data given, neither in the definition nor as attribute.");
386
- n = await K(G(i.data, r));
404
+ }, _e = async (e, t, n = K) => {
405
+ let r = [], i = /* @__PURE__ */ new Set(), a = async (e, t, o) => {
406
+ for (let r of [e.parent ?? []].flat()) {
407
+ let e = G(r, t);
408
+ if (o.includes(e)) throw Error(`Cyclic parent definition '${e}'`);
409
+ i.has(e) || (i.add(e), await a(q(await n(e), `'${e}'`), e, [...o, e]));
410
+ }
411
+ r.push(e);
412
+ };
413
+ return await a(e, t, []), x(r);
414
+ }, J = (e) => o(Array.from(ee(e))), ve = async ({ def: e = null, defUrl: t = null, data: n = null, state: r = null }) => {
415
+ let i;
416
+ e === null ? (i = G(t), e = q(await K(i), `'${i}'`)) : typeof e == "string" && (e = q(e, "attribute"));
417
+ let a = await _e(JSON.parse(JSON.stringify(e)), i);
418
+ he(a).forEach((e) => console.warn(`gen-vis ${i ?? "inline definition"}: ${e}`));
419
+ let s = de(JSON.parse(JSON.stringify(a))), c = U(s);
420
+ if (W(s, r), j(s, a), n === null) {
421
+ if (!a.data) throw Error("No data given, neither in the definition nor as attribute.");
422
+ n = await K(G(a.data, i));
387
423
  }
388
- let s = J(_(n));
424
+ let l = J(g(n));
389
425
  return {
390
- defUrl: r ?? null,
391
- defOrg: i,
392
- locale: o(le(i.options?.locale)),
393
- rows: s,
394
- def: a,
395
- data: J(te(s, a))
426
+ defUrl: i ?? null,
427
+ defOrg: a,
428
+ locale: o(me(a.options?.locale)),
429
+ rows: l,
430
+ def: s,
431
+ defaults: c,
432
+ data: J(ne(l, s))
396
433
  };
397
- }, pe = class {
434
+ }, ye = class {
398
435
  defUrl = null;
399
436
  defOrg = null;
400
437
  locale = null;
401
438
  def = null;
402
439
  rows = null;
403
440
  data = null;
441
+ defaults = null;
404
442
  runs = 0;
443
+ stateSets = 0;
405
444
  get loaded() {
406
445
  return this.def !== null && this.data !== null;
407
446
  }
447
+ get state() {
448
+ return this.loaded ? ge(U(this.def), this.defaults) : null;
449
+ }
408
450
  get axis() {
409
451
  let e = {};
410
452
  return this.mappingNamesWithKey("scale").forEach((t) => {
@@ -428,31 +470,34 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
428
470
  let t = ++this.runs;
429
471
  this.def = this.data = null;
430
472
  try {
431
- let n = await fe(e);
473
+ let n = await ve(e);
432
474
  t == this.runs && Object.assign(this, n);
433
475
  } catch (e) {
434
476
  if (t == this.runs) throw e;
435
477
  }
436
478
  }
437
479
  applyFormElements() {
438
- N(this.def, this.defOrg) && (this.data = J(te(this.rows, this.def)));
480
+ j(this.def, this.defOrg) && (this.data = J(ne(this.rows, this.def)));
439
481
  }
440
- }, me = () => u(new pe()), Y = (e, t) => {
441
- let n = e.mapping.scale, r = h[`scale${P(n.type)}`]();
442
- if (r.range(D(n.range, t)), e.extent) {
482
+ setState(e) {
483
+ W(this.def, this.defaults), W(this.def, e), this.applyFormElements(), this.stateSets++;
484
+ }
485
+ }, be = () => u(new ye()), xe = (e, t) => {
486
+ let n = e.mapping.scale, r = m[`scale${M(n.type)}`]();
487
+ if (r.range(T(n.range, t)), e.extent) {
443
488
  e.domain = [...n.domain], e.domainRel = [...n.domainRel ? n.domainRel : [0, 0]], e.domainAbs = n.domainAbs, e.domain[0] ??= e.extent[0], e.domain[1] ??= e.extent[1];
444
489
  let t = e.domain[1] - e.domain[0];
445
- e.domain[0] += t * e.domainRel[0], e.domain[1] += t * e.domainRel[1], e.domain[0] += e.domainAbs[0], e.domain[1] += e.domainAbs[1], r.invertCustom = (t) => e.values[h.bisectCenter(e.values, r.invert(t))];
490
+ e.domain[0] += t * e.domainRel[0], e.domain[1] += t * e.domainRel[1], e.domain[0] += e.domainAbs[0], e.domain[1] += e.domainAbs[1], r.invertCustom = (t) => e.values[m.bisectCenter(e.values, r.invert(t))];
446
491
  } else e.domain = e.values, n.padding ??= .4, r.padding(n.padding), r.invertCustom = (e) => {
447
492
  let t = Math.floor(e / r.step());
448
493
  return r.domain()[Math.max(0, Math.min(t, r.domain().length - 1))];
449
494
  };
450
495
  r.domain(e.domain), e.scale = r;
451
- }, X = function(e) {
452
- let t = h.select(this);
496
+ }, Y = function(e) {
497
+ let t = m.select(this);
453
498
  Object.entries(e).forEach(([e, n], r) => {
454
499
  if (n instanceof Object) {
455
- if (!k(n)) return;
500
+ if (!D(n)) return;
456
501
  n = n.value;
457
502
  }
458
503
  if (e == "text") {
@@ -461,14 +506,14 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
461
506
  }
462
507
  t.attr(e, n);
463
508
  });
464
- }, he = function(e) {
465
- let t = h.select(this);
509
+ }, X = function(e) {
510
+ let t = m.select(this);
466
511
  e.group.forEach((e) => {
467
512
  t.attr(`data-group-${e.dim}`, e.key);
468
513
  }), e.group.forEach((e) => {
469
514
  t.attr(`data-visible-${e.dim}`, e.visible);
470
515
  }), t.attr("data-visible", e.group.reduce((e, t) => e && t.visible, !0));
471
- }, ge = (e, t, n) => {
516
+ }, Se = (e, t, n) => {
472
517
  let r = t.categories.filter((e) => e in n).map((e) => ({
473
518
  attr: `data-group-${e}`,
474
519
  value: String(n[e])
@@ -479,12 +524,12 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
479
524
  }, Z = (e, t, n = null) => {
480
525
  t.filter((e) => e.highlightProps.length > 0).forEach((t) => {
481
526
  e.selectAll(`g.plotGroup.${t.id} .highlight`).classed("highlight", !1).each(function() {
482
- let e = h.select(this);
527
+ let e = m.select(this);
483
528
  t.highlightProps.forEach((t) => e.attr(t, e.attr(`default-${t}`)));
484
529
  });
485
- let r = n && ge(e, t, n);
530
+ let r = n && Se(e, t, n);
486
531
  r && r.classed("highlight", !0).raise().each(function() {
487
- let e = h.select(this);
532
+ let e = m.select(this);
488
533
  t.highlightProps.forEach((t) => {
489
534
  e.attr(`default-${t}`, e.attr(t)).attr(t, e.attr(`highlight-${t}`));
490
535
  });
@@ -494,7 +539,7 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
494
539
  let n = e.__vccOpts || e;
495
540
  for (let [e, r] of t) n[e] = r;
496
541
  return n;
497
- }, _e = {
542
+ }, Ce = {
498
543
  props: [
499
544
  "title",
500
545
  "axis",
@@ -516,14 +561,14 @@ var _ = (e) => typeof e == "string" ? (e = e.replace(/^/, ""), /^\s*\[/.test(
516
561
  watch: { data: "render" },
517
562
  methods: { render() {
518
563
  if (!this.$refs.entries || !this.data) return;
519
- let e = [...this.data].sort((e, t) => t.entries[this.axis.v.col].value - e.entries[this.axis.v.col].value), t = h.select(this.$refs.entries).selectAll("tr.entry").data(e).join("tr").attr("class", "entry").classed("nearest", (e) => e.nearest);
564
+ let e = [...this.data].sort((e, t) => t.entries[this.axis.v.col].value - e.entries[this.axis.v.col].value), t = m.select(this.$refs.entries).selectAll("tr.entry").data(e).join("tr").attr("class", "entry").classed("nearest", (e) => e.nearest);
520
565
  t.selectAll("td").remove(), t.selectAll("td").data((e) => Object.entries(e.entries)).join("td").attr("class", (e) => e[0]).html((e) => typeof e[1] == "object" ? e[1].name : e[1]);
521
566
  } }
522
- }, ve = { class: "title" }, ye = {
567
+ }, we = { class: "title" }, Te = {
523
568
  class: "entries",
524
569
  ref: "entries"
525
570
  };
526
- function be(e, t, n, o, s, u) {
571
+ function Ee(e, t, n, o, s, u) {
527
572
  return n.axis && n.axis.h ? (l(), i("div", {
528
573
  key: 0,
529
574
  class: "hover",
@@ -532,9 +577,9 @@ function be(e, t, n, o, s, u) {
532
577
  left: u.left,
533
578
  transform: u.transform
534
579
  })
535
- }, [a("div", ve, p(n.axis.h.name), 1), a("table", ye, null, 512)], 4)) : r("", !0);
580
+ }, [a("div", we, p(n.axis.h.name), 1), a("table", Te, null, 512)], 4)) : r("", !0);
536
581
  }
537
- var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]]), Se = (...e) => e.every((e) => Number.isFinite(e)), Ce = {
582
+ var De = /*#__PURE__*/ Q(Ce, [["render", Ee], ["__scopeId", "data-v-364032d4"]]), Oe = (...e) => e.every((e) => Number.isFinite(e)), ke = {
538
583
  props: [
539
584
  "filter",
540
585
  "shared",
@@ -566,12 +611,12 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
566
611
  };
567
612
  }
568
613
  },
569
- components: { Hover: xe },
614
+ components: { Hover: De },
570
615
  created() {
571
616
  this.def = this.store.def;
572
617
  },
573
618
  mounted() {
574
- this.inner = h.select(this.$refs.inner), this.scales(), this.axis(), this.plot(), this.hoverInit();
619
+ this.inner = m.select(this.$refs.inner), this.scales(), this.axis(), this.plot(), this.hoverInit();
575
620
  },
576
621
  unmounted() {
577
622
  document.removeEventListener("pointerdown", this.hideOnPointerOutside);
@@ -579,23 +624,23 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
579
624
  methods: {
580
625
  plot() {
581
626
  this.def.plot.forEach((e) => {
582
- let t = ae(b(this.data, e.categories), e, this.relativeBases, this.def.mapping), n = this.inner.append("g").classed("plotGroup", !0).classed(e.id, !0);
627
+ let t = ce(y(this.data, e.categories), e, this.relativeBases, this.def.mapping), n = this.inner.append("g").classed("plotGroup", !0).classed(e.id, !0);
583
628
  this[e.type](t, n);
584
629
  });
585
630
  },
586
631
  _groupwise: function(e, t) {
587
632
  return t.classed("paths", !0).selectAll("path").data(e).enter().append("path").each(function(e) {
588
- X.call(this, e.props);
589
- }).each(he);
633
+ Y.call(this, e.props);
634
+ }).each(X);
590
635
  },
591
636
  _pointwise(e, t, n, r = (e) => e) {
592
- return t.classed(n, !0).selectAll("g.group").data(e).enter().append("g").attr("class", "group").each(he).selectAll(n).data((e) => {
593
- let t = A(e.props);
594
- return e.values.filter((e) => t.every((t) => e[t] !== null)).map((t) => r(O(e.props, t)));
595
- }).enter().append(n).each(X);
637
+ return t.classed(n, !0).selectAll("g.group").data(e).enter().append("g").attr("class", "group").each(X).selectAll(n).data((e) => {
638
+ let t = ue(e.props);
639
+ return e.values.filter((e) => t.every((t) => e[t] !== null)).map((t) => r(E(e.props, t)));
640
+ }).enter().append(n).each(Y);
596
641
  },
597
642
  "svg:path": function(e, t) {
598
- this._groupwise(e, t).attr("d", (e) => h.line().defined((e) => Se(e.x, e.y)).x((e) => e.x).y((e) => e.y)(e.values.map((t) => O(e.props.d, t, !0))));
643
+ this._groupwise(e, t).attr("d", (e) => m.line().defined((e) => Oe(e.x, e.y)).x((e) => e.x).y((e) => e.y)(e.values.map((t) => E(e.props.d, t, !0))));
599
644
  },
600
645
  "svg:circle": function(e, t) {
601
646
  this._pointwise(e, t, "circle");
@@ -610,7 +655,7 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
610
655
  this._pointwise(e, t, "text");
611
656
  },
612
657
  "base:area": function(e, t) {
613
- this._groupwise(e, t).attr("d", (e) => h.area().defined((e) => Se(e.x, e.y0, e.y1)).x((e) => e.x).y1((e) => e.y1).y0((e) => e.y0)(e.values.map((t) => O(e.props.d, t, !0))));
658
+ this._groupwise(e, t).attr("d", (e) => m.area().defined((e) => Oe(e.x, e.y0, e.y1)).x((e) => e.x).y1((e) => e.y1).y0((e) => e.y0)(e.values.map((t) => E(e.props.d, t, !0))));
614
659
  },
615
660
  bar(e, t) {
616
661
  let n = this;
@@ -618,15 +663,15 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
618
663
  let t = e.height.parts[0], r = n.info[t].scale(0);
619
664
  if (e.width === void 0) {
620
665
  let t = e.cx.parts[0];
621
- e.width = j(n.info[t].scale.step() * (1 - n.info[t].scale.padding()));
666
+ e.width = O(n.info[t].scale.step() * (1 - n.info[t].scale.padding()));
622
667
  }
623
- return e.x = j(e.cx.value - e.width.value / 2), delete e.cx, e.y = j(e.height.value), e.height = j(r - e.height.value), e;
668
+ return e.x = O(e.cx.value - e.width.value / 2), delete e.cx, e.y = O(e.height.value), e.height = O(r - e.height.value), e;
624
669
  });
625
670
  },
626
671
  stackedBar(e, t) {
627
672
  e.forEach((e) => {
628
673
  let t = e.props.x.ref, n = e.props.y.ref;
629
- e.props.x = j(`@${t}:scaled`), e.props.y = j(`@${n}:st:e:scaled`), e.props.height = j(`@${n}:st:h:scaled`), e.props.transform = j(`translate(-${e.props.width.value / 2} 0)`);
674
+ e.props.x = O(`@${t}:scaled`), e.props.y = O(`@${n}:st:e:scaled`), e.props.height = O(`@${n}:st:h:scaled`), e.props.transform = O(`translate(-${e.props.width.value / 2} 0)`);
630
675
  }), this._pointwise(e, t, "rect", (e) => (e.height.value < 0 && (e.y.value += e.height.value, e.height.value = -e.height.value), e));
631
676
  },
632
677
  scales() {
@@ -636,18 +681,18 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
636
681
  dim: t,
637
682
  mapping: this.store.mapping(t)
638
683
  };
639
- ne(n, this.data), Y(n, {
684
+ re(n, this.data), xe(n, {
640
685
  width: this.innerWidth,
641
686
  height: this.innerHeight
642
687
  }), e[t] = n;
643
- }), y(this.data, e), this.info = {
688
+ }), v(this.data, e), this.info = {
644
689
  ...this.shared,
645
690
  ...e
646
691
  };
647
692
  },
648
693
  axis() {
649
694
  this.store.mappingNamesWithKey("axis").forEach((e) => {
650
- let t = this.store.mapping(e), n = t.axis, r = this.info[e].scale, i = E(n.ticks, this.relativeBases), a = h[`axis${P(n.position)}`](r).tickSizeInner(9).tickSizeOuter(0).ticks(i).tickPadding(n.padding);
695
+ let t = this.store.mapping(e), n = t.axis, r = this.info[e].scale, i = w(n.ticks, this.relativeBases), a = m[`axis${M(n.position)}`](r).tickSizeInner(9).tickSizeOuter(0).ticks(i).tickPadding(n.padding);
651
696
  if (n.format) a.tickFormat(this.store.formatter(t.scale.type)(n.format));
652
697
  else if (!n.values) {
653
698
  let e = this.store.locale.tickFormat(r, t.scale.type, i);
@@ -678,18 +723,18 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
678
723
  name: t,
679
724
  formatter: this.store.formatter(n.scale.type)(r)
680
725
  }];
681
- })), r = this.store.mappingNamesWithKey("hover").filter((e) => e != t.h && e != t.v && this.store.mapping(e).props), i = h.select(this.$refs.hoverMarker).select("line"), a = () => {
726
+ })), r = this.store.mappingNamesWithKey("hover").filter((e) => e != t.h && e != t.v && this.store.mapping(e).props), i = m.select(this.$refs.hoverMarker).select("line"), a = () => {
682
727
  e.hover.visible = !1, Z(e.inner, e.def.plot);
683
728
  };
684
729
  this.hideOnPointerOutside = (t) => {
685
730
  e.hover.visible && !e.$refs.svg.contains(t.target) && a();
686
731
  }, document.addEventListener("pointerdown", this.hideOnPointerOutside), this.inner.append("rect").attr("class", "events").attr("width", this.innerWidth).attr("height", this.innerHeight).attr("opacity", 0).style("touch-action", "pan-y").on("pointerdown pointermove", function(t) {
687
732
  e.hover.visible = !0;
688
- let a = h.pointer(t), o = e.info[n.h.name], s = o.scale.invertCustom(a[0]);
733
+ let a = m.pointer(t), o = e.info[n.h.name], s = o.scale.invertCustom(a[0]);
689
734
  if (s === void 0) return;
690
735
  let c = o.scale(s);
691
736
  i.attr("x1", c).attr("x2", c).attr("y1", 0).attr("y2", e.innerHeight);
692
- let l = x(e.data, [{
737
+ let l = b(e.data, [{
693
738
  dim: n.h.name,
694
739
  key: s
695
740
  }]).filter((e) => e[n.v.name] !== null).map((t) => {
@@ -699,16 +744,16 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
699
744
  nearest: !1
700
745
  };
701
746
  return r.forEach((n) => {
702
- i.entries[n] = D(e.store.mapping(n).hover.props, e.store.prop(n, t[n]));
747
+ i.entries[n] = T(e.store.mapping(n).hover.props, e.store.prop(n, t[n]));
703
748
  }), i.entries[n.v.name] = {
704
749
  value: t[n.v.name],
705
750
  name: n.v.formatter(t[n.v.name])
706
751
  }, i;
707
752
  }), u = e.info[n.v.name].scale.invert(a[1]), d = n.v.name, f;
708
- f = e.store.mapping(d).stacked ? h.least(l, (e) => {
709
- let [t, n] = h.extent([e.data[`${d}:st:s`], e.data[`${d}:st:e`]]);
753
+ f = e.store.mapping(d).stacked ? m.least(l, (e) => {
754
+ let [t, n] = m.extent([e.data[`${d}:st:s`], e.data[`${d}:st:e`]]);
710
755
  return u < t ? t - u : u > n ? u - n : 0;
711
- }) : h.least(l, (e) => Math.abs(e.data[d] - u)), f && (f.nearest = !0), Z(e.inner, e.def.plot, f?.data), e.hover.data = l, e.hover.axis = {
756
+ }) : m.least(l, (e) => Math.abs(e.data[d] - u)), f && (f.nearest = !0), Z(e.inner, e.def.plot, f?.data), e.hover.data = l, e.hover.axis = {
712
757
  h: {
713
758
  col: n.h.name,
714
759
  value: c,
@@ -724,12 +769,12 @@ var xe = /*#__PURE__*/ Q(_e, [["render", be], ["__scopeId", "data-v-364032d4"]])
724
769
  }).on("pointercancel", a);
725
770
  }
726
771
  }
727
- }, we = ["width", "height"], Te = ["transform"], Ee = ["visibility"], De = {
772
+ }, Ae = ["width", "height"], je = ["transform"], Me = ["visibility"], Ne = {
728
773
  key: 0,
729
774
  class: "debug"
730
775
  };
731
- function Oe(e, t, o, s, u, d) {
732
- let m = f("hover");
776
+ function Pe(e, t, o, s, u, d) {
777
+ let ee = f("hover");
733
778
  return l(), i("div", {
734
779
  style: c(`width: ${o.width}px;`),
735
780
  class: "vis-inner"
@@ -746,8 +791,8 @@ function Oe(e, t, o, s, u, d) {
746
791
  visibility: e.hover.visible ? "visible" : "hidden",
747
792
  class: "hoverMarker",
748
793
  ref: "hoverMarker"
749
- }, [...t[0] ||= [a("line", null, null, -1)]], 8, Ee)], 8, Te)], 8, we)),
750
- a("div", { style: c(`transform: translate(${o.margins.left}px, ${o.margins.top + d.innerHeight / 2}px); position: absolute; top: 0; left: 0;`) }, [e.hover.visible ? (l(), n(m, {
794
+ }, [...t[0] ||= [a("line", null, null, -1)]], 8, Me)], 8, je)], 8, Ae)),
795
+ a("div", { style: c(`transform: translate(${o.margins.left}px, ${o.margins.top + d.innerHeight / 2}px); position: absolute; top: 0; left: 0;`) }, [e.hover.visible ? (l(), n(ee, {
751
796
  key: 0,
752
797
  data: e.hover.data,
753
798
  side: e.hover.side,
@@ -757,41 +802,41 @@ function Oe(e, t, o, s, u, d) {
757
802
  "side",
758
803
  "axis"
759
804
  ])) : r("", !0)], 4),
760
- e.debug ? (l(), i("span", De, p(e.debug), 1)) : r("", !0)
805
+ e.debug ? (l(), i("span", Ne, p(e.debug), 1)) : r("", !0)
761
806
  ], 4);
762
807
  }
763
- var ke = /*#__PURE__*/ Q(Ce, [["render", Oe], ["__scopeId", "data-v-1f05a06e"]]), Ae = {
808
+ var Fe = /*#__PURE__*/ Q(ke, [["render", Pe], ["__scopeId", "data-v-1f05a06e"]]), Ie = {
764
809
  props: ["info", "props"],
765
810
  mounted() {
766
- let e = h.select(this.$refs.legendSymbol);
811
+ let e = m.select(this.$refs.legendSymbol);
767
812
  this.info.elements.forEach((t) => {
768
813
  let n = e.append(t.type);
769
- X.call(n.node(), D(t.props, this.props));
814
+ Y.call(n.node(), T(t.props, this.props));
770
815
  });
771
816
  }
772
- }, je = ["width", "height"];
773
- function Me(e, t, n, r, a, o) {
817
+ }, Le = ["width", "height"];
818
+ function Re(e, t, n, r, a, o) {
774
819
  return l(), i("svg", {
775
820
  width: n.info.size,
776
821
  height: n.info.size,
777
822
  ref: "legendSymbol"
778
- }, null, 8, je);
823
+ }, null, 8, Le);
779
824
  }
780
825
  //#endregion
781
826
  //#region src/comp/Legend.vue
782
- var Ne = {
827
+ var ze = {
783
828
  props: ["legend"],
784
829
  inject: ["store"],
785
830
  data: () => ({
786
831
  info: {},
787
832
  entries: []
788
833
  }),
789
- components: { LegendSymbol: /* @__PURE__ */ Q(Ae, [["render", Me], ["__scopeId", "data-v-ce0e972e"]]) },
834
+ components: { LegendSymbol: /* @__PURE__ */ Q(Ie, [["render", Re], ["__scopeId", "data-v-ce0e972e"]]) },
790
835
  mounted() {
791
836
  this.info = this.store.mapping(this.legend), this.entries = Object.keys(this.info.props).map((e) => ({
792
837
  key: e,
793
838
  props: this.info.props[e],
794
- filled: D(this.info.legend.props, this.info.props[e])
839
+ filled: T(this.info.legend.props, this.info.props[e])
795
840
  }));
796
841
  },
797
842
  methods: { switched(e) {
@@ -801,35 +846,38 @@ var Ne = {
801
846
  selected: e.props.visible
802
847
  });
803
848
  } }
804
- }, Pe = ["data-dim"], Fe = { class: "title" }, Ie = { class: "entries" }, Le = [
849
+ }, Be = ["data-dim"], Ve = { class: "title" }, He = { class: "entries" }, Ue = [
805
850
  "data-visible",
806
851
  "data-key",
807
852
  "onClick",
808
853
  "onMouseenter"
809
- ], Re = ["innerHTML"];
810
- function ze(t, o, c, u, m, h) {
811
- let g = f("LegendSymbol");
854
+ ], We = ["innerHTML"];
855
+ function Ge(t, o, c, u, ee, m) {
856
+ let h = f("LegendSymbol");
812
857
  return l(), i("div", {
813
858
  class: "legend",
814
859
  "data-dim": c.legend
815
- }, [a("div", Fe, p(t.info.name), 1), a("div", Ie, [(l(!0), i(e, null, d(t.entries, (e) => (l(), i("div", s({
860
+ }, [a("div", Ve, p(t.info.name), 1), a("div", He, [(l(!0), i(e, null, d(t.entries, (e) => (l(), i("div", s({
816
861
  "data-visible": e.props.visible,
817
862
  "data-key": e.key
818
863
  }, { ref_for: !0 }, Object.assign({ ...e.filled }, { name: null }), {
819
- onClick: (t) => h.switched(e),
864
+ onClick: (t) => m.switched(e),
820
865
  onMouseenter: (n) => t.$emit("highlight", {
821
866
  dim: this.legend,
822
867
  key: e.key
823
868
  }),
824
869
  onMouseleave: o[0] ||= (e) => t.$emit("highlight", {})
825
- }), [t.info.legend.symbol ? (l(), n(g, {
870
+ }), [t.info.legend.symbol ? (l(), n(h, {
826
871
  key: 0,
827
872
  info: t.info.legend.symbol,
828
873
  props: e.props
829
- }, null, 8, ["info", "props"])) : r("", !0), a("span", { innerHTML: e.filled.name }, null, 8, Re)], 16, Le))), 256))])], 8, Pe);
874
+ }, null, 8, ["info", "props"])) : r("", !0), a("span", { innerHTML: e.filled.name }, null, 8, We)], 16, Ue))), 256))])], 8, Be);
830
875
  }
831
- var Be = /*#__PURE__*/ Q(Ne, [["render", ze], ["__scopeId", "data-v-1bc8d55f"]]), Ve = {
876
+ var Ke = /*#__PURE__*/ Q(ze, [["render", Ge], ["__scopeId", "data-v-1bc8d55f"]]), qe = 0, Je = {
832
877
  props: ["element", "globals"],
878
+ created() {
879
+ this.uid = `gen-vis-form-${qe++}`;
880
+ },
833
881
  computed: { vg() {
834
882
  return this.globals[this.element.ref];
835
883
  } },
@@ -838,35 +886,36 @@ var Be = /*#__PURE__*/ Q(Ne, [["render", ze], ["__scopeId", "data-v-1bc8d55f"]])
838
886
  this.globals[this.element.ref] = e.value, this.$emit("changeSelected", {});
839
887
  },
840
888
  equal(e) {
841
- return C(e, this.vg);
889
+ return S(e, this.vg);
842
890
  }
843
891
  }
844
- }, He = ["id"], Ue = { class: "title" }, We = {
892
+ }, Ye = ["id"], Xe = { class: "title" }, Ze = {
845
893
  key: 0,
846
894
  class: "entries"
847
- }, Ge = ["id", "onClick"], Ke = [
895
+ }, Qe = ["id", "onClick"], $e = [
848
896
  "name",
849
897
  "value",
850
898
  "checked"
851
- ], qe = ["for"];
852
- function Je(t, n, o, s, c, u) {
899
+ ], et = ["for"];
900
+ function tt(t, n, o, s, c, u) {
853
901
  return l(), i("div", {
854
902
  class: "formElement",
855
903
  id: `container-${o.element.id}`
856
- }, [a("div", Ue, p(o.element.name) + ":", 1), o.element.type == "switch" ? (l(), i("div", We, [(l(!0), i(e, null, d(o.element.values, (e) => (l(), i("div", {
904
+ }, [a("div", Xe, p(o.element.name) + ":", 1), o.element.type == "switch" ? (l(), i("div", Ze, [(l(!0), i(e, null, d(o.element.values, (e) => (l(), i("div", {
857
905
  id: `container-${e.id}`,
858
906
  onClick: (t) => u.switched(e)
859
907
  }, [a("input", {
860
908
  type: "radio",
861
- name: o.element.id,
909
+ name: `${t.uid}-${o.element.id}`,
862
910
  value: e.id,
863
911
  checked: u.equal(e.value)
864
- }, null, 8, Ke), a("label", { for: e.id }, p(e.name), 9, qe)], 8, Ge))), 256))])) : r("", !0)], 8, He);
912
+ }, null, 8, $e), a("label", { for: e.id }, p(e.name), 9, et)], 8, Qe))), 256))])) : r("", !0)], 8, Ye);
865
913
  }
866
914
  //#endregion
867
915
  //#region src/comp/Vis.vue
868
- var Ye = {
916
+ var nt = {
869
917
  inject: ["store"],
918
+ emits: ["stateChanged"],
870
919
  data: () => ({
871
920
  initialized: !1,
872
921
  options: {},
@@ -897,10 +946,13 @@ var Ye = {
897
946
  }
898
947
  },
899
948
  components: {
900
- Facet: ke,
901
- LegendEntry: Be,
902
- FormElement: /* @__PURE__ */ Q(Ve, [["render", Je], ["__scopeId", "data-v-b7f59ae7"]])
949
+ Facet: Fe,
950
+ LegendEntry: Ke,
951
+ FormElement: /* @__PURE__ */ Q(Je, [["render", tt], ["__scopeId", "data-v-acf88417"]])
903
952
  },
953
+ watch: { "store.stateSets"() {
954
+ this.dataInit(), this.scales();
955
+ } },
904
956
  mounted() {
905
957
  this.baseInit(), this.dataInit(), this.scales(), this.store.def.options.width || (this.resizeObserver = new ResizeObserver(() => {
906
958
  clearTimeout(this.resizeTimeout), this.resizeTimeout = setTimeout(this.resized, 100);
@@ -915,7 +967,7 @@ var Ye = {
915
967
  },
916
968
  measure() {
917
969
  let e = this.store.def.options;
918
- this.options.width = e.width || this.$refs.vis.getBoundingClientRect().width, this.options.height = E(e.height, { totalWidth: this.options.width });
970
+ this.options.width = e.width || this.$refs.vis.getBoundingClientRect().width, this.options.height = w(e.height, { totalWidth: this.options.width });
919
971
  },
920
972
  resized() {
921
973
  let e = this.$refs.vis?.getBoundingClientRect().width;
@@ -926,12 +978,19 @@ var Ye = {
926
978
  if (this.filter = this.store.mappingNamesWithKey("props").map((e) => ({
927
979
  dim: e,
928
980
  key: Object.keys(this.store.mapping(e).props).filter((t) => this.store.mapping(e).props[t].visible)
929
- })), this.data = o(x(this.store.data, this.filter)), t.v && this.store.mapping(t.v).stacked && re(this.data, t, e.facets ? [e.facets.dim] : []), e.facets) {
981
+ })), this.data = o(b(this.store.data, this.filter)), t.v && this.store.mapping(t.v).stacked) {
982
+ let n = ie(this.filter.map((e) => ({
983
+ dim: e.dim,
984
+ keys: e.key
985
+ })));
986
+ ae(this.data, t, e.facets ? [e.facets.dim] : [], n);
987
+ }
988
+ if (e.facets) {
930
989
  this.facets.margins = this.options.margins, this.facets.height = this.options.height;
931
- let t = E(e.facets.cols, { totalWidth: this.options.width });
990
+ let t = w(e.facets.cols, { totalWidth: this.options.width });
932
991
  this.facets.width = this.options.width / t;
933
- let n = e.facets.dim, r = b(this.data, [n]);
934
- this.facets.entries = r.filter((e) => Object.keys(this.store.mapping(n).props).includes(e.group[n])).map((e) => ({
992
+ let n = e.facets.dim, r = Object.keys(this.store.mapping(n).props), i = y(this.data, [n]);
993
+ this.facets.entries = i.filter((e) => r.includes(e.group[n])).sort((e, t) => r.indexOf(e.group[n]) - r.indexOf(t.group[n])).map((e) => ({
935
994
  filter: {
936
995
  dim: e.group[n],
937
996
  key: n,
@@ -944,70 +1003,70 @@ var Ye = {
944
1003
  scales() {
945
1004
  let e = this.store.def;
946
1005
  if (e.facets && e.facets.scales) {
947
- let t = E(e.facets.scales, e.globals).map((e) => {
1006
+ let t = w(e.facets.scales, e.globals).map((e) => {
948
1007
  let t = {
949
1008
  dim: e,
950
1009
  mapping: this.store.mapping(e)
951
1010
  };
952
- return ne(t, this.data), Y(t, {
1011
+ return re(t, this.data), xe(t, {
953
1012
  width: this.facets.width - (this.facets.margins.left + this.facets.margins.right),
954
1013
  height: this.facets.height - (this.facets.margins.top + this.facets.margins.bottom)
955
1014
  }), t;
956
1015
  });
957
- y(this.data, t), this.facets.shared = Object.fromEntries(t.map((e) => [e.dim, e]));
1016
+ v(this.data, t), this.facets.shared = Object.fromEntries(t.map((e) => [e.dim, e]));
958
1017
  }
959
1018
  this.initialized = !0;
960
1019
  },
961
1020
  changeSelected(e) {
962
- this.dataInit(), this.scales();
1021
+ this.dataInit(), this.scales(), this.$emit("stateChanged");
963
1022
  },
964
1023
  formChanged(e) {
965
1024
  this.store.applyFormElements(), this.changeSelected(e);
966
1025
  },
967
1026
  highlight(e) {
968
- Z(h.select(this.$refs.vis), this.store.def.plot, { [e.dim]: e.key });
1027
+ Z(m.select(this.$refs.vis), this.store.def.plot, { [e.dim]: e.key });
969
1028
  }
970
1029
  }
971
- }, Xe = { class: "vis-header" }, Ze = { class: "title" }, Qe = { class: "subtitle" }, $e = {
1030
+ }, rt = { class: "vis-header" }, it = { class: "title" }, at = { class: "subtitle" }, ot = {
972
1031
  ref: "form",
973
1032
  class: "vis-form-elements"
974
- }, et = {
1033
+ }, st = {
975
1034
  ref: "legends",
976
1035
  class: "vis-legends"
977
- }, tt = {
1036
+ }, ct = {
978
1037
  key: 0,
979
1038
  class: "vis-body"
980
- }, nt = { class: "vis-footer" }, rt = ["innerHTML"];
981
- function it(t, o, s, u, m, h) {
982
- let g = f("form-element"), _ = f("legend-entry"), v = f("facet");
1039
+ }, lt = { class: "vis-footer" }, ut = ["innerHTML"];
1040
+ function dt(t, o, s, u, ee, m) {
1041
+ let h = f("form-element"), g = f("legend-entry"), _ = f("facet");
983
1042
  return l(), i("div", {
984
1043
  class: "vis",
985
1044
  ref: "vis",
986
1045
  style: c({ "--gen-vis-font-family": t.options.fontFamily })
987
1046
  }, [
988
- a("div", Xe, [a("div", Ze, p(t.options.title), 1), a("div", Qe, p(t.options.subtitle), 1)]),
989
- a("div", $e, [(l(!0), i(e, null, d(t.formElements, (e) => (l(), n(g, {
1047
+ a("div", rt, [a("div", it, p(t.options.title), 1), a("div", at, p(t.options.subtitle), 1)]),
1048
+ a("div", ot, [(l(!0), i(e, null, d(t.formElements, (e) => (l(), n(h, {
990
1049
  element: e,
991
1050
  globals: t.globals,
992
- onChangeSelected: h.formChanged
1051
+ onChangeSelected: m.formChanged
993
1052
  }, null, 8, [
994
1053
  "element",
995
1054
  "globals",
996
1055
  "onChangeSelected"
997
1056
  ]))), 256))], 512),
998
- a("div", et, [(l(!0), i(e, null, d(t.legends, (e) => (l(), n(_, {
1057
+ a("div", st, [(l(!0), i(e, null, d(t.legends, (e) => (l(), n(g, {
999
1058
  legend: e,
1000
- onChangeSelected: h.changeSelected,
1001
- onHighlight: h.highlight
1059
+ onChangeSelected: m.changeSelected,
1060
+ onHighlight: m.highlight
1002
1061
  }, null, 8, [
1003
1062
  "legend",
1004
1063
  "onChangeSelected",
1005
1064
  "onHighlight"
1006
1065
  ]))), 256))], 512),
1007
- t.initialized ? (l(), i("div", tt, [t.facets.entries.length > 0 ? (l(!0), i(e, { key: 0 }, d(t.facets.entries, (e) => (l(), i("div", { style: c(`width: ${t.facets.width}px; display: inline-block;`) }, [a("div", {
1066
+ t.initialized ? (l(), i("div", ct, [t.facets.entries.length > 0 ? (l(!0), i(e, { key: 0 }, d(t.facets.entries, (e) => (l(), i("div", { style: c(`width: ${t.facets.width}px; display: inline-block;`) }, [a("div", {
1008
1067
  class: "facet-title",
1009
1068
  style: c(`margin-left: ${t.facets.margins.left}px`)
1010
- }, p(e.filter.name), 5), (l(), n(v, {
1069
+ }, p(e.filter.name), 5), (l(), n(_, {
1011
1070
  key: e.data,
1012
1071
  data: e.data,
1013
1072
  shared: t.facets.shared,
@@ -1020,7 +1079,7 @@ function it(t, o, s, u, m, h) {
1020
1079
  "height",
1021
1080
  "width",
1022
1081
  "margins"
1023
- ]))], 4))), 256)) : (l(), n(v, {
1082
+ ]))], 4))), 256)) : (l(), n(_, {
1024
1083
  key: t.data,
1025
1084
  data: t.data,
1026
1085
  shared: {},
@@ -1033,12 +1092,12 @@ function it(t, o, s, u, m, h) {
1033
1092
  "width",
1034
1093
  "margins"
1035
1094
  ]))])) : r("", !0),
1036
- a("div", nt, [a("span", { innerHTML: t.options.footer }, null, 8, rt)])
1095
+ a("div", lt, [a("span", { innerHTML: t.options.footer }, null, 8, ut)])
1037
1096
  ], 4);
1038
1097
  }
1039
1098
  //#endregion
1040
1099
  //#region src/comp/App.vue
1041
- var at = {
1100
+ var ft = {
1042
1101
  name: "GenVis",
1043
1102
  props: {
1044
1103
  debug: {
@@ -1056,20 +1115,29 @@ var at = {
1056
1115
  data: {
1057
1116
  type: [Array, String],
1058
1117
  default: null
1118
+ },
1119
+ state: {
1120
+ type: Object,
1121
+ default: null
1059
1122
  }
1060
1123
  },
1124
+ emits: ["update:state"],
1061
1125
  data: () => ({
1062
- store: me(),
1126
+ store: be(),
1063
1127
  error: null
1064
1128
  }),
1065
1129
  provide() {
1066
1130
  return { store: this.store };
1067
1131
  },
1068
- components: { VisBase: /* @__PURE__ */ Q(Ye, [["render", it], ["__scopeId", "data-v-f8fa11d2"]]) },
1132
+ components: { VisBase: /* @__PURE__ */ Q(nt, [["render", dt], ["__scopeId", "data-v-d870f406"]]) },
1069
1133
  watch: {
1070
1134
  def: "init",
1071
1135
  defFile: "init",
1072
- data: "init"
1136
+ data: "init",
1137
+ state: {
1138
+ handler: "syncState",
1139
+ deep: !0
1140
+ }
1073
1141
  },
1074
1142
  mounted() {
1075
1143
  this.init();
@@ -1084,44 +1152,51 @@ var at = {
1084
1152
  await this.store.init({
1085
1153
  def: this.def,
1086
1154
  defUrl: this.defFile,
1087
- data: this.data
1088
- });
1155
+ data: this.data,
1156
+ state: this.state
1157
+ }), this.syncState();
1089
1158
  } catch (e) {
1090
1159
  this.showError(e);
1091
1160
  }
1092
1161
  },
1162
+ syncState() {
1163
+ this.store.loaded && !S(this.state ?? {}, this.store.state) && this.store.setState(this.state);
1164
+ },
1093
1165
  showError(e) {
1094
1166
  console.error(e), this.error = e.message;
1095
1167
  }
1096
1168
  }
1097
- }, ot = { class: "vis-outer" }, st = {
1169
+ }, pt = { class: "vis-outer" }, mt = {
1098
1170
  key: 0,
1099
1171
  class: "vis-error"
1100
- }, ct = { key: 2 }, lt = { style: {
1172
+ }, ht = { key: 2 }, gt = { style: {
1101
1173
  height: "500px",
1102
1174
  overflow: "auto",
1103
1175
  "font-size": "11px"
1104
- } }, ut = { style: {
1176
+ } }, _t = { style: {
1105
1177
  height: "500px",
1106
1178
  overflow: "auto",
1107
1179
  "font-size": "11px"
1108
1180
  } };
1109
- function dt(e, t, o, s, c, u) {
1181
+ function vt(e, t, o, s, c, u) {
1110
1182
  let d = f("vis-base");
1111
- return l(), i("div", ot, [e.error ? (l(), i("div", st, p(e.error), 1)) : e.store.loaded ? (l(), n(d, { key: 1 })) : r("", !0), o.debug && e.store.def ? (l(), i("div", ct, [
1112
- t[0] ||= a("h3", null, "prepared:", -1),
1113
- a("pre", lt, p(JSON.stringify(e.store.def, null, 4)), 1),
1114
- t[1] ||= a("h3", null, "org:", -1),
1115
- a("pre", ut, p(JSON.stringify(e.store.defOrg, null, 4)), 1)
1183
+ return l(), i("div", pt, [e.error ? (l(), i("div", mt, p(e.error), 1)) : e.store.loaded ? (l(), n(d, {
1184
+ key: 1,
1185
+ onStateChanged: t[0] ||= (t) => e.$emit("update:state", e.store.state)
1186
+ })) : r("", !0), o.debug && e.store.def ? (l(), i("div", ht, [
1187
+ t[1] ||= a("h3", null, "prepared:", -1),
1188
+ a("pre", gt, p(JSON.stringify(e.store.def, null, 4)), 1),
1189
+ t[2] ||= a("h3", null, "org:", -1),
1190
+ a("pre", _t, p(JSON.stringify(e.store.defOrg, null, 4)), 1)
1116
1191
  ])) : r("", !0)]);
1117
1192
  }
1118
- var $ = /*#__PURE__*/ Q(at, [["render", dt], ["__scopeId", "data-v-a9d47434"]]), ft = { install(e) {
1193
+ var $ = /*#__PURE__*/ Q(ft, [["render", vt], ["__scopeId", "data-v-7b1c318b"]]), yt = { install(e) {
1119
1194
  e.component("GenVis", $);
1120
- } }, pt = (e) => {
1195
+ } }, bt = (e) => {
1121
1196
  let n = Object.fromEntries(e.getAttributeNames().filter((e) => e.startsWith("data-")).map((t) => [t.substring(5), e.getAttribute(t)]));
1122
1197
  return t($, n).mount(e);
1123
- }, mt = (e) => {
1124
- for (let t of document.getElementsByClassName(e)) t.classList.contains("gen-vis-attached") || (t.classList.add("gen-vis-attached"), pt(t));
1198
+ }, xt = (e) => {
1199
+ for (let t of document.getElementsByClassName(e)) t.classList.contains("gen-vis-attached") || (t.classList.add("gen-vis-attached"), bt(t));
1125
1200
  };
1126
1201
  //#endregion
1127
- export { $ as GenVis, ft as default, mt as mountGenVisByClass, pt as mountGenVisElement };
1202
+ export { $ as GenVis, yt as default, xt as mountGenVisByClass, bt as mountGenVisElement };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@preschen/gen-vis",
3
- "version": "0.5.0",
3
+ "version": "0.8.0",
4
4
  "description": "A declarative d3 visualisation library",
5
5
  "type": "module",
6
6
  "main": "dist/gen-vis.js",
package/schema.json CHANGED
@@ -8,8 +8,11 @@
8
8
  "properties": {
9
9
  "$schema": { "type": "string" },
10
10
  "parent": {
11
- "type": "string",
12
- "description": "Url of the definition this one is deep merged into, relative to this definition. Arrays are replaced, not merged."
11
+ "oneOf": [
12
+ { "type": "string" },
13
+ { "type": "array", "items": { "type": "string" } }
14
+ ],
15
+ "description": "Url of the definition this one is deep merged into, relative to this definition, or a list of them (mixins) merged in their order, later ones override earlier ones. Arrays are replaced, not merged."
13
16
  },
14
17
  "data": {
15
18
  "type": "string",
@@ -229,7 +232,10 @@
229
232
  "type": "object",
230
233
  "additionalProperties": false,
231
234
  "properties": {
232
- "column": { "type": "string" },
235
+ "column": {
236
+ "type": "string",
237
+ "description": "The column of the data, can be a template of globals, e.g. \"{values}{share}\", see formElements."
238
+ },
233
239
  "type": {
234
240
  "enum": ["numeric", "date", "categorical"],
235
241
  "description": "Missing and invalid numeric and date values are null, dates are parsed with Date.parse or are timestamps."