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 +29 -0
- package/README.md +90 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.js +1867 -0
- package/package.json +80 -0
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}
|
package/dist/index.d.ts
ADDED
|
@@ -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 };
|