umwelt-js 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.
package/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2023-present, the Umwelt contributors
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # umwelt-js
2
+
3
+ Embed the [Umwelt](https://umwelt-data.github.io/umwelt/) viewer in any web app. From a single
4
+ spec, `umwelt-js` renders three coordinated views of a dataset — a **visualization**, a
5
+ **sonification**, and an accessible, keyboard-navigable **textual structure** (powered by
6
+ [Olli](https://umwelt-data.github.io/olli/)). It renders internally with SolidJS, but you never
7
+ touch that: you hand it a spec and a container element.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install umwelt-js
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```js
18
+ import { createViewer } from 'umwelt-js';
19
+ import 'umwelt-js/style.css';
20
+
21
+ const spec = {
22
+ data: {
23
+ name: 'stocks.csv',
24
+ url: 'https://raw.githubusercontent.com/vega/vega-datasets/master/data/stocks.csv',
25
+ },
26
+ fields: [
27
+ { name: 'symbol', type: 'nominal' },
28
+ { name: 'date', type: 'temporal' },
29
+ { name: 'price', type: 'quantitative' },
30
+ ],
31
+ key: ['symbol', 'date'],
32
+ visual: {
33
+ units: [
34
+ {
35
+ name: 'vis_unit_0',
36
+ mark: 'line',
37
+ encoding: {
38
+ x: { field: 'date' },
39
+ y: { field: 'price' },
40
+ color: { field: 'symbol' },
41
+ },
42
+ },
43
+ ],
44
+ },
45
+ audio: {
46
+ units: [
47
+ {
48
+ name: 'audio_unit_0',
49
+ encoding: { pitch: { field: 'price' } },
50
+ traversal: [{ field: 'symbol' }, { field: 'date' }],
51
+ },
52
+ ],
53
+ },
54
+ };
55
+
56
+ const viewer = createViewer(spec, document.getElementById('umwelt-viewer'));
57
+ ```
58
+
59
+ Import `umwelt-js/style.css` once per page. You don't have to write specs by hand — author one in
60
+ the [editor](https://umwelt-data.github.io/umwelt/editor/) and copy the JSON from its Export tab,
61
+ or start from a [gallery example](https://umwelt-data.github.io/umwelt/gallery/).
62
+
63
+ ## API
64
+
65
+ `createViewer(spec, container)` mounts the viewer and returns an `UmweltViewer`:
66
+
67
+ | Method | Description |
68
+ | --- | --- |
69
+ | `updateSpec(newSpec)` | Replace the spec and re-render. |
70
+ | `getSpec()` | The current spec. |
71
+ | `getContainer()` | The container element. |
72
+ | `destroy()` | Unmount and release audio/event resources. The instance can't be reused afterward. |
73
+ | `getIsDestroyed()` | Whether `destroy()` has been called. |
74
+
75
+ Call `destroy()` before removing the container from the DOM (e.g. in your framework's unmount
76
+ hook). TypeScript users can import the spec/data types:
77
+
78
+ ```ts
79
+ import type { UmweltSpec, UmweltDataset, UmweltDatum, UmweltValue } from 'umwelt-js';
80
+ ```
81
+
82
+ ## Documentation
83
+
84
+ - [Quickstart](https://umwelt-data.github.io/umwelt/docs/quickstart)
85
+ - [Viewer API](https://umwelt-data.github.io/umwelt/docs/viewer-api)
86
+ - [UmweltSpec reference](https://umwelt-data.github.io/umwelt/docs/spec)
87
+
88
+ ## License
89
+
90
+ BSD-3-Clause © the Umwelt contributors. See [LICENSE](./LICENSE).
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ body{margin:0}._App_1uzho_5{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:flex;flex-direction:row;height:100vh;overflow:hidden}._App_1uzho_5 ._column_1uzho_14{flex:1;min-width:0;padding:1em;height:100%;overflow-y:auto;box-sizing:border-box}._App_1uzho_5 h1{margin-top:0}._App_1uzho_5 code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}._Editor_1uzho_29,._Viewer_1uzho_29{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}._Editor_1uzho_29 h1,._Viewer_1uzho_29 h1{margin-top:0}._Editor_1uzho_29 h2,._Editor_1uzho_29 h3,._Editor_1uzho_29 h4,._Editor_1uzho_29 h5,._Viewer_1uzho_29 h2,._Viewer_1uzho_29 h3,._Viewer_1uzho_29 h4,._Viewer_1uzho_29 h5{margin-bottom:.5em}._Editor_1uzho_29 h3,._Viewer_1uzho_29 h3{margin-top:1.5em}._Editor_1uzho_29 table,._Viewer_1uzho_29 table{display:block;width:100%;max-height:200px;overflow:auto}._Editor_1uzho_29 td,._Editor_1uzho_29 th,._Viewer_1uzho_29 td,._Viewer_1uzho_29 th{text-align:left;padding-right:5px}._Editor_1uzho_29 details>summary,._Viewer_1uzho_29 details>summary{cursor:pointer}._Editor_1uzho_29 input[type=checkbox],._Editor_1uzho_29 input[type=radio],._Viewer_1uzho_29 input[type=checkbox],._Viewer_1uzho_29 input[type=radio]{margin:0 .5em 0 0;position:relative;top:1px}._Editor_1uzho_29 ol,._Viewer_1uzho_29 ol{list-style:decimal;padding-left:1.2em}
@@ -0,0 +1,231 @@
1
+ import { Mark } from 'vega-lite/build/src/mark';
2
+ import { Sort } from 'vega-lite/build/src/sort';
3
+ import { LogicalComposition, FieldPredicate } from '@umwelt-data/umwelt-utils/predicate';
4
+ import { Dataset, Datum, MeasureType as MeasureType$1, DataValue } from '@umwelt-data/umwelt-utils/data';
5
+
6
+ type UmweltValue = DataValue;
7
+ type UmweltDatum = Datum;
8
+ type UmweltDataset = Dataset;
9
+ declare const aggregateOps: readonly ["mean", "median", "min", "max", "sum", "count"];
10
+ type UmweltAggregateOp = (typeof aggregateOps)[number];
11
+ declare const timeUnits: readonly ["year", "quarter", "month", "yearmonth", "day", "date", "hours", "minutes", "seconds"];
12
+ type UmweltTimeUnit = (typeof timeUnits)[number];
13
+ type ScaleDomain = {
14
+ domain?: UmweltValue[];
15
+ zero?: boolean;
16
+ nice?: boolean | number;
17
+ };
18
+ type ScaleRange = {
19
+ range?: number[] | string[];
20
+ };
21
+ type MeasureType = MeasureType$1;
22
+ interface UmweltDataSource {
23
+ name: string;
24
+ }
25
+ interface ExportableUmweltValuesDataSource {
26
+ name?: string;
27
+ values: UmweltDataset;
28
+ }
29
+ interface ExportableUmweltURLDataSource {
30
+ name?: string;
31
+ url: string;
32
+ }
33
+ interface ExportableUmweltNameDataSource {
34
+ name: string;
35
+ }
36
+ type ExportableUmweltDataSource = ExportableUmweltValuesDataSource | ExportableUmweltURLDataSource | ExportableUmweltNameDataSource;
37
+ type UmweltPredicate = LogicalComposition<FieldPredicate>;
38
+ declare const visualPropNames: readonly ["x", "y", "color", "shape", "size", "opacity", "order", "facet"];
39
+ declare const audioPropNames: readonly ["pitch", "duration", "volume"];
40
+ type VisualPropName = (typeof visualPropNames)[number];
41
+ type AudioPropName = (typeof audioPropNames)[number];
42
+ type EncodingPropName = VisualPropName | AudioPropName;
43
+ declare const NONE = "None";
44
+ type FieldName = string;
45
+ interface EncodingRef {
46
+ property: EncodingPropName;
47
+ unit: string;
48
+ }
49
+ interface FieldDef {
50
+ active: boolean;
51
+ name: FieldName;
52
+ type?: MeasureType;
53
+ encodings: EncodingRef[];
54
+ scale?: ScaleDomain;
55
+ timeUnit?: UmweltTimeUnit;
56
+ aggregate?: UmweltAggregateOp;
57
+ bin?: boolean;
58
+ sort?: Sort<any>;
59
+ }
60
+ interface VisualEncodingFieldDef {
61
+ field: FieldName;
62
+ /** overrides the field's measure type for this visual channel only
63
+ * (e.g. render a temporal field as a nominal color scale) */
64
+ type?: MeasureType;
65
+ scale?: ScaleDomain & ScaleRange;
66
+ timeUnit?: UmweltTimeUnit | typeof NONE;
67
+ aggregate?: UmweltAggregateOp | typeof NONE;
68
+ bin?: boolean;
69
+ sort?: Sort<any>;
70
+ }
71
+ interface AudioEncodingFieldDef {
72
+ field: FieldName;
73
+ /** overrides the field's measure type for this audio channel only */
74
+ type?: MeasureType;
75
+ scale?: ScaleDomain & ScaleRange;
76
+ timeUnit?: UmweltTimeUnit | typeof NONE;
77
+ aggregate?: UmweltAggregateOp | typeof NONE;
78
+ sort?: Sort<any>;
79
+ bin?: undefined;
80
+ }
81
+ interface AudioTraversalFieldDef {
82
+ field: FieldName;
83
+ /** overrides the field's measure type for this traversal only */
84
+ type?: MeasureType;
85
+ scale?: ScaleDomain & ScaleRange;
86
+ timeUnit?: UmweltTimeUnit | typeof NONE;
87
+ bin?: boolean;
88
+ aggregate?: undefined;
89
+ }
90
+ type VisualEncoding = {
91
+ [prop in VisualPropName]?: VisualEncodingFieldDef;
92
+ };
93
+ type VisualUnitSpec = {
94
+ name: string;
95
+ mark: Mark;
96
+ encoding: VisualEncoding;
97
+ };
98
+ type AudioEncoding = {
99
+ [prop in AudioPropName]?: AudioEncodingFieldDef;
100
+ };
101
+ type AudioTraversal = AudioTraversalFieldDef[];
102
+ type AudioUnitSpec = {
103
+ name: string;
104
+ encoding: AudioEncoding;
105
+ traversal: AudioTraversal;
106
+ };
107
+ declare const viewCompositions: string[];
108
+ type ViewComposition = (typeof viewCompositions)[number];
109
+ interface VisualSpec {
110
+ units: VisualUnitSpec[];
111
+ composition: ViewComposition;
112
+ }
113
+ interface AudioSpec {
114
+ units: AudioUnitSpec[];
115
+ composition: ViewComposition;
116
+ }
117
+ type TextNodeId = string;
118
+ interface TextFieldRef {
119
+ field: FieldName;
120
+ type?: MeasureType;
121
+ timeUnit?: UmweltTimeUnit | typeof NONE;
122
+ bin?: boolean;
123
+ }
124
+ interface TextGroupNode {
125
+ id: TextNodeId;
126
+ nodeType: 'group';
127
+ groupby: TextFieldRef[];
128
+ children: TextNode[];
129
+ }
130
+ interface TextPredicateNode {
131
+ id: TextNodeId;
132
+ nodeType: 'predicate';
133
+ predicate: UmweltPredicate;
134
+ name?: string;
135
+ reasoning?: string;
136
+ children: TextNode[];
137
+ }
138
+ type TextNode = TextGroupNode | TextPredicateNode;
139
+ interface TextSpec {
140
+ structures: Record<string, TextNode[]>;
141
+ }
142
+ interface UmweltSpec {
143
+ data: UmweltDataSource;
144
+ fields: FieldDef[];
145
+ key: FieldName[];
146
+ visual: VisualSpec;
147
+ audio: AudioSpec;
148
+ text: TextSpec;
149
+ }
150
+ type ExportableFieldDef = Omit<FieldDef, 'encodings' | 'active'>;
151
+ interface ExportableVisualSpec {
152
+ units: VisualUnitSpec[];
153
+ composition?: ViewComposition;
154
+ }
155
+ interface ExportableAudioSpec {
156
+ units: AudioUnitSpec[];
157
+ composition?: ViewComposition;
158
+ }
159
+ interface ExportableTextSpec {
160
+ structures: Record<string, TextNode[]>;
161
+ }
162
+ interface ExportableSpec extends Omit<UmweltSpec, 'fields' | 'data' | 'visual' | 'audio' | 'text'> {
163
+ data: ExportableUmweltDataSource;
164
+ fields: ExportableFieldDef[];
165
+ visual: ExportableVisualSpec;
166
+ audio: ExportableAudioSpec;
167
+ text?: ExportableTextSpec;
168
+ }
169
+
170
+ interface UmweltViewerOptions {
171
+ spec: ExportableSpec;
172
+ container: HTMLElement;
173
+ }
174
+ /**
175
+ * Framework-agnostic Umwelt viewer that can be embedded in any web application.
176
+ * Internally uses SolidJS but exposes a simple JavaScript API.
177
+ */
178
+ declare class UmweltViewer {
179
+ private options;
180
+ private disposal?;
181
+ private isDestroyed;
182
+ constructor(options: UmweltViewerOptions);
183
+ private mount;
184
+ /**
185
+ * Update the viewer with a new specification.
186
+ * This will re-render the entire viewer with the new data and configuration.
187
+ */
188
+ updateSpec(newSpec: ExportableSpec): void;
189
+ /**
190
+ * Get the current specification.
191
+ */
192
+ getSpec(): ExportableSpec;
193
+ /**
194
+ * Get the container element.
195
+ */
196
+ getContainer(): HTMLElement;
197
+ private cleanup;
198
+ /**
199
+ * Destroy the viewer and clean up all resources.
200
+ * The viewer cannot be used after calling this method.
201
+ */
202
+ destroy(): void;
203
+ /**
204
+ * Check if the viewer has been destroyed.
205
+ */
206
+ getIsDestroyed(): boolean;
207
+ }
208
+ /**
209
+ * Convenience function to create and mount an Umwelt viewer.
210
+ *
211
+ * @param spec The Umwelt specification defining the data and visualizations
212
+ * @param container The DOM element to render the viewer into
213
+ * @returns A new UmweltViewer instance
214
+ *
215
+ * @example
216
+ * ```javascript
217
+ * import { createViewer } from 'umwelt-js';
218
+ *
219
+ * const viewer = createViewer(mySpec, document.getElementById('viewer'));
220
+ *
221
+ * // Later update the data
222
+ * viewer.updateSpec(newSpec);
223
+ *
224
+ * // Clean up when done
225
+ * viewer.destroy();
226
+ * ```
227
+ */
228
+ declare function createViewer(spec: ExportableSpec, container: HTMLElement): UmweltViewer;
229
+
230
+ export { UmweltViewer, createViewer };
231
+ export type { UmweltDataset, UmweltDatum, ExportableSpec as UmweltSpec, UmweltValue, UmweltViewerOptions };