juxscript 1.1.162 → 1.1.165
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/index.d.ts +5 -0
- package/index.d.ts.map +1 -1
- package/index.js +5 -0
- package/lib/components/dataframe.d.ts +110 -0
- package/lib/components/dataframe.d.ts.map +1 -0
- package/lib/components/dataframe.js +292 -0
- package/lib/components/dataframe.ts +363 -0
- package/lib/components/dropdown-menu.d.ts +42 -0
- package/lib/components/dropdown-menu.d.ts.map +1 -0
- package/lib/components/dropdown-menu.js +177 -0
- package/lib/components/dropdown-menu.ts +214 -0
- package/lib/components/table.d.ts +2 -2
- package/lib/components/table.d.ts.map +1 -1
- package/lib/components/table.ts +5 -6
- package/lib/facades/dataframe.jux +0 -0
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ import { datepicker } from './lib/components/datepicker.js';
|
|
|
12
12
|
import { dialog } from './lib/components/dialog.js';
|
|
13
13
|
import { divider } from './lib/components/divider.js';
|
|
14
14
|
import { dropdown } from './lib/components/dropdown.js';
|
|
15
|
+
import { dropdownMenu } from './lib/components/dropdown-menu.js';
|
|
16
|
+
import { dataframe } from './lib/components/dataframe.js';
|
|
15
17
|
import { element } from './lib/components/element.js';
|
|
16
18
|
import { fileupload } from './lib/components/fileupload.js';
|
|
17
19
|
import { grid } from './lib/components/grid.js';
|
|
@@ -52,6 +54,7 @@ export { tabularDriver } from './lib/storage/TabularDriver.js';
|
|
|
52
54
|
export { DataFrame } from './lib/storage/DataFrame.js';
|
|
53
55
|
export { indexedDBDriver } from './lib/storage/IndexedDBDriver.js';
|
|
54
56
|
export { fileStorage } from './lib/storage/FileStorage.js';
|
|
57
|
+
export { dataframe } from './lib/components/dataframe.js';
|
|
55
58
|
import { VStack, vstack } from './lib/components/stack/VStack.js';
|
|
56
59
|
import { HStack, hstack } from './lib/components/stack/HStack.js';
|
|
57
60
|
import { ZStack, zstack } from './lib/components/stack/ZStack.js';
|
|
@@ -72,10 +75,12 @@ export declare const jux: {
|
|
|
72
75
|
code: typeof code;
|
|
73
76
|
container: typeof container;
|
|
74
77
|
data: typeof data;
|
|
78
|
+
dataframe: typeof dataframe;
|
|
75
79
|
datepicker: typeof datepicker;
|
|
76
80
|
dialog: typeof dialog;
|
|
77
81
|
divider: typeof divider;
|
|
78
82
|
dropdown: typeof dropdown;
|
|
83
|
+
dropdownMenu: typeof dropdownMenu;
|
|
79
84
|
element: typeof element;
|
|
80
85
|
fileupload: typeof fileupload;
|
|
81
86
|
grid: typeof grid;
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
|
package/index.js
CHANGED
|
@@ -12,6 +12,8 @@ import { datepicker } from './lib/components/datepicker.js';
|
|
|
12
12
|
import { dialog } from './lib/components/dialog.js';
|
|
13
13
|
import { divider } from './lib/components/divider.js';
|
|
14
14
|
import { dropdown } from './lib/components/dropdown.js';
|
|
15
|
+
import { dropdownMenu } from './lib/components/dropdown-menu.js';
|
|
16
|
+
import { dataframe } from './lib/components/dataframe.js';
|
|
15
17
|
import { element } from './lib/components/element.js';
|
|
16
18
|
import { fileupload } from './lib/components/fileupload.js';
|
|
17
19
|
import { grid } from './lib/components/grid.js';
|
|
@@ -55,6 +57,7 @@ export { tabularDriver } from './lib/storage/TabularDriver.js';
|
|
|
55
57
|
export { DataFrame } from './lib/storage/DataFrame.js';
|
|
56
58
|
export { indexedDBDriver } from './lib/storage/IndexedDBDriver.js';
|
|
57
59
|
export { fileStorage } from './lib/storage/FileStorage.js';
|
|
60
|
+
export { dataframe } from './lib/components/dataframe.js';
|
|
58
61
|
// Import Stack components (already added earlier)
|
|
59
62
|
import { VStack, vstack } from './lib/components/stack/VStack.js';
|
|
60
63
|
import { HStack, hstack } from './lib/components/stack/HStack.js';
|
|
@@ -78,10 +81,12 @@ export const jux = {
|
|
|
78
81
|
code,
|
|
79
82
|
container,
|
|
80
83
|
data,
|
|
84
|
+
dataframe,
|
|
81
85
|
datepicker,
|
|
82
86
|
dialog,
|
|
83
87
|
divider,
|
|
84
88
|
dropdown,
|
|
89
|
+
dropdownMenu,
|
|
85
90
|
element,
|
|
86
91
|
fileupload,
|
|
87
92
|
grid,
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { BaseComponent, BaseState } from './base/BaseComponent.js';
|
|
2
|
+
import { DataFrame } from '../storage/DataFrame.js';
|
|
3
|
+
import { TabularDriver } from '../storage/TabularDriver.js';
|
|
4
|
+
import { FileUpload } from './fileupload.js';
|
|
5
|
+
import { Table } from './table.js';
|
|
6
|
+
export interface DataFrameOptions {
|
|
7
|
+
dbName?: string;
|
|
8
|
+
storeName?: string;
|
|
9
|
+
striped?: boolean;
|
|
10
|
+
hoverable?: boolean;
|
|
11
|
+
sortable?: boolean;
|
|
12
|
+
filterable?: boolean;
|
|
13
|
+
paginated?: boolean;
|
|
14
|
+
rowsPerPage?: number;
|
|
15
|
+
style?: string;
|
|
16
|
+
class?: string;
|
|
17
|
+
}
|
|
18
|
+
type DataFrameState = BaseState & {
|
|
19
|
+
loaded: boolean;
|
|
20
|
+
sourceName: string;
|
|
21
|
+
rowCount: number;
|
|
22
|
+
colCount: number;
|
|
23
|
+
};
|
|
24
|
+
export declare class DataFrameComponent extends BaseComponent<DataFrameState> {
|
|
25
|
+
private _df;
|
|
26
|
+
private _driver;
|
|
27
|
+
private _table;
|
|
28
|
+
private _tableOptions;
|
|
29
|
+
private _uploadRef;
|
|
30
|
+
private _storageKey;
|
|
31
|
+
private _pendingSource;
|
|
32
|
+
constructor(id: string, options?: DataFrameOptions);
|
|
33
|
+
protected getTriggerEvents(): readonly string[];
|
|
34
|
+
protected getCallbackEvents(): readonly string[];
|
|
35
|
+
/**
|
|
36
|
+
* Load from IndexedDB by storage key
|
|
37
|
+
*/
|
|
38
|
+
fromStorage(key: string): this;
|
|
39
|
+
/**
|
|
40
|
+
* Load from a FileUpload component — auto-wires change event
|
|
41
|
+
*/
|
|
42
|
+
fromUpload(upload: FileUpload): this;
|
|
43
|
+
/**
|
|
44
|
+
* Load from raw data — array of objects or Record<string, any[]>
|
|
45
|
+
*/
|
|
46
|
+
fromData(data: Record<string, any>[] | Record<string, any[]>): this;
|
|
47
|
+
/**
|
|
48
|
+
* Apply a transform to the current DataFrame and update the table
|
|
49
|
+
*/
|
|
50
|
+
apply(fn: (df: DataFrame) => DataFrame): this;
|
|
51
|
+
/**
|
|
52
|
+
* Filter rows
|
|
53
|
+
*/
|
|
54
|
+
filter(predicate: (row: Record<string, any>, index: number) => boolean): this;
|
|
55
|
+
/**
|
|
56
|
+
* Select columns
|
|
57
|
+
*/
|
|
58
|
+
select(...cols: string[]): this;
|
|
59
|
+
/**
|
|
60
|
+
* Sort by column
|
|
61
|
+
*/
|
|
62
|
+
sort(col: string, descending?: boolean): this;
|
|
63
|
+
/**
|
|
64
|
+
* Show first N rows
|
|
65
|
+
*/
|
|
66
|
+
head(n?: number): this;
|
|
67
|
+
/**
|
|
68
|
+
* Show last N rows
|
|
69
|
+
*/
|
|
70
|
+
tail(n?: number): this;
|
|
71
|
+
/**
|
|
72
|
+
* Add a computed column
|
|
73
|
+
*/
|
|
74
|
+
withColumn(name: string, fn: (row: Record<string, any>, index: number) => any): this;
|
|
75
|
+
/**
|
|
76
|
+
* Where clause
|
|
77
|
+
*/
|
|
78
|
+
where(col: string, op: '==' | '!=' | '>' | '<' | '>=' | '<=' | 'contains' | 'startsWith' | 'endsWith', value: any): this;
|
|
79
|
+
/** Get the underlying DataFrame */
|
|
80
|
+
get df(): DataFrame | null;
|
|
81
|
+
/** Get the underlying TabularDriver */
|
|
82
|
+
get driver(): TabularDriver;
|
|
83
|
+
/** Get the internal Table component */
|
|
84
|
+
get table(): Table | null;
|
|
85
|
+
/** Get describe() stats */
|
|
86
|
+
describe(): Record<string, any> | null;
|
|
87
|
+
/** Export to CSV string */
|
|
88
|
+
toCSV(delimiter?: string): string;
|
|
89
|
+
/** Export to row objects */
|
|
90
|
+
toRows(): Record<string, any>[];
|
|
91
|
+
/** Get shape */
|
|
92
|
+
get shape(): [number, number];
|
|
93
|
+
/** Get column names */
|
|
94
|
+
get columns(): string[];
|
|
95
|
+
/** Save current DataFrame to IndexedDB */
|
|
96
|
+
save(key?: string): Promise<string | null>;
|
|
97
|
+
striped(v: boolean): this;
|
|
98
|
+
hoverable(v: boolean): this;
|
|
99
|
+
sortable(v: boolean): this;
|
|
100
|
+
filterable(v: boolean): this;
|
|
101
|
+
paginated(v: boolean): this;
|
|
102
|
+
rowsPerPage(v: number): this;
|
|
103
|
+
private _setDataFrame;
|
|
104
|
+
private _updateTable;
|
|
105
|
+
update(prop: string, value: any): void;
|
|
106
|
+
render(targetId?: string | HTMLElement | BaseComponent<any>): this;
|
|
107
|
+
}
|
|
108
|
+
export declare function dataframe(id: string, options?: DataFrameOptions): DataFrameComponent;
|
|
109
|
+
export {};
|
|
110
|
+
//# sourceMappingURL=dataframe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataframe.d.ts","sourceRoot":"","sources":["dataframe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { BaseComponent } from './base/BaseComponent.js';
|
|
2
|
+
import { DataFrame } from '../storage/DataFrame.js';
|
|
3
|
+
import { TabularDriver } from '../storage/TabularDriver.js';
|
|
4
|
+
import { Table } from './table.js';
|
|
5
|
+
const TRIGGER_EVENTS = [];
|
|
6
|
+
const CALLBACK_EVENTS = ['load', 'error', 'transform'];
|
|
7
|
+
export class DataFrameComponent extends BaseComponent {
|
|
8
|
+
constructor(id, options = {}) {
|
|
9
|
+
super(id, {
|
|
10
|
+
visible: true,
|
|
11
|
+
disabled: false,
|
|
12
|
+
loading: false,
|
|
13
|
+
style: options.style ?? '',
|
|
14
|
+
class: options.class ?? '',
|
|
15
|
+
loaded: false,
|
|
16
|
+
sourceName: '',
|
|
17
|
+
rowCount: 0,
|
|
18
|
+
colCount: 0
|
|
19
|
+
});
|
|
20
|
+
this._df = null;
|
|
21
|
+
this._table = null;
|
|
22
|
+
this._uploadRef = null;
|
|
23
|
+
this._storageKey = null;
|
|
24
|
+
this._pendingSource = null;
|
|
25
|
+
this._driver = new TabularDriver(options.dbName ?? 'jux-dataframes', options.storeName ?? 'frames');
|
|
26
|
+
this._tableOptions = {
|
|
27
|
+
striped: options.striped ?? true,
|
|
28
|
+
hoverable: options.hoverable ?? true,
|
|
29
|
+
sortable: options.sortable ?? true,
|
|
30
|
+
filterable: options.filterable ?? true,
|
|
31
|
+
paginated: options.paginated ?? true,
|
|
32
|
+
rowsPerPage: options.rowsPerPage ?? 25
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
getTriggerEvents() { return TRIGGER_EVENTS; }
|
|
36
|
+
getCallbackEvents() { return CALLBACK_EVENTS; }
|
|
37
|
+
/* ═══════════════════════════════════════════════════
|
|
38
|
+
* DATA SOURCES
|
|
39
|
+
* ═══════════════════════════════════════════════════ */
|
|
40
|
+
/**
|
|
41
|
+
* Load from IndexedDB by storage key
|
|
42
|
+
*/
|
|
43
|
+
fromStorage(key) {
|
|
44
|
+
this._storageKey = key;
|
|
45
|
+
this._pendingSource = async () => {
|
|
46
|
+
this.state.loading = true;
|
|
47
|
+
try {
|
|
48
|
+
let df = await this._driver.loadByName(key);
|
|
49
|
+
if (!df) {
|
|
50
|
+
this._triggerCallback('error', 'No table found with key: ' + key, null, this);
|
|
51
|
+
this.state.loading = false;
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this._setDataFrame(df, 'storage: ' + key);
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
this._triggerCallback('error', err.message, null, this);
|
|
58
|
+
this.state.loading = false;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Load from a FileUpload component — auto-wires change event
|
|
65
|
+
*/
|
|
66
|
+
fromUpload(upload) {
|
|
67
|
+
this._uploadRef = upload;
|
|
68
|
+
this._pendingSource = async () => {
|
|
69
|
+
// Wire upload's change event to parse incoming files
|
|
70
|
+
upload.bind('change', async (files) => {
|
|
71
|
+
if (!files || files.length === 0)
|
|
72
|
+
return;
|
|
73
|
+
const file = files[0];
|
|
74
|
+
this.state.loading = true;
|
|
75
|
+
try {
|
|
76
|
+
const df = await this._driver.streamFile(file);
|
|
77
|
+
// Auto-persist to IndexedDB
|
|
78
|
+
await this._driver.store(file.name, df, { source: file.name });
|
|
79
|
+
this._setDataFrame(df, 'upload: ' + file.name);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
this._triggerCallback('error', err.message, null, this);
|
|
83
|
+
this.state.loading = false;
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Load from raw data — array of objects or Record<string, any[]>
|
|
91
|
+
*/
|
|
92
|
+
fromData(data) {
|
|
93
|
+
this._pendingSource = async () => {
|
|
94
|
+
this.state.loading = true;
|
|
95
|
+
try {
|
|
96
|
+
const df = new DataFrame(data);
|
|
97
|
+
this._setDataFrame(df, 'inline data');
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
this._triggerCallback('error', err.message, null, this);
|
|
101
|
+
this.state.loading = false;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
/* ═══════════════════════════════════════════════════
|
|
107
|
+
* TRANSFORM API (returns new DataFrameComponent view)
|
|
108
|
+
* ═══════════════════════════════════════════════════ */
|
|
109
|
+
/**
|
|
110
|
+
* Apply a transform to the current DataFrame and update the table
|
|
111
|
+
*/
|
|
112
|
+
apply(fn) {
|
|
113
|
+
if (!this._df)
|
|
114
|
+
return this;
|
|
115
|
+
const result = fn(this._df);
|
|
116
|
+
this._setDataFrame(result, this.state.sourceName + ' (transformed)');
|
|
117
|
+
this._triggerCallback('transform', result, null, this);
|
|
118
|
+
return this;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Filter rows
|
|
122
|
+
*/
|
|
123
|
+
filter(predicate) {
|
|
124
|
+
return this.apply(df => df.filter(predicate));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Select columns
|
|
128
|
+
*/
|
|
129
|
+
select(...cols) {
|
|
130
|
+
return this.apply(df => df.select(...cols));
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Sort by column
|
|
134
|
+
*/
|
|
135
|
+
sort(col, descending) {
|
|
136
|
+
return this.apply(df => df.sort(col, descending));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Show first N rows
|
|
140
|
+
*/
|
|
141
|
+
head(n = 5) {
|
|
142
|
+
return this.apply(df => df.head(n));
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Show last N rows
|
|
146
|
+
*/
|
|
147
|
+
tail(n = 5) {
|
|
148
|
+
return this.apply(df => df.tail(n));
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Add a computed column
|
|
152
|
+
*/
|
|
153
|
+
withColumn(name, fn) {
|
|
154
|
+
return this.apply(df => df.withColumn(name, fn));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Where clause
|
|
158
|
+
*/
|
|
159
|
+
where(col, op, value) {
|
|
160
|
+
return this.apply(df => df.where(col, op, value));
|
|
161
|
+
}
|
|
162
|
+
/* ═══════════════════════════════════════════════════
|
|
163
|
+
* ACCESSORS
|
|
164
|
+
* ═══════════════════════════════════════════════════ */
|
|
165
|
+
/** Get the underlying DataFrame */
|
|
166
|
+
get df() { return this._df; }
|
|
167
|
+
/** Get the underlying TabularDriver */
|
|
168
|
+
get driver() { return this._driver; }
|
|
169
|
+
/** Get the internal Table component */
|
|
170
|
+
get table() { return this._table; }
|
|
171
|
+
/** Get describe() stats */
|
|
172
|
+
describe() {
|
|
173
|
+
return this._df?.describe() ?? null;
|
|
174
|
+
}
|
|
175
|
+
/** Export to CSV string */
|
|
176
|
+
toCSV(delimiter) {
|
|
177
|
+
return this._df?.toCSV(delimiter) ?? '';
|
|
178
|
+
}
|
|
179
|
+
/** Export to row objects */
|
|
180
|
+
toRows() {
|
|
181
|
+
return this._df?.toRows() ?? [];
|
|
182
|
+
}
|
|
183
|
+
/** Get shape */
|
|
184
|
+
get shape() {
|
|
185
|
+
return this._df?.shape ?? [0, 0];
|
|
186
|
+
}
|
|
187
|
+
/** Get column names */
|
|
188
|
+
get columns() {
|
|
189
|
+
return this._df?.columns ?? [];
|
|
190
|
+
}
|
|
191
|
+
/** Save current DataFrame to IndexedDB */
|
|
192
|
+
async save(key) {
|
|
193
|
+
if (!this._df)
|
|
194
|
+
return null;
|
|
195
|
+
const name = key ?? this._storageKey ?? this._id;
|
|
196
|
+
return this._driver.store(name, this._df);
|
|
197
|
+
}
|
|
198
|
+
/* ═══════════════════════════════════════════════════
|
|
199
|
+
* TABLE OPTIONS (fluent, pre-render)
|
|
200
|
+
* ═══════════════════════════════════════════════════ */
|
|
201
|
+
striped(v) { this._tableOptions.striped = v; return this; }
|
|
202
|
+
hoverable(v) { this._tableOptions.hoverable = v; return this; }
|
|
203
|
+
sortable(v) { this._tableOptions.sortable = v; return this; }
|
|
204
|
+
filterable(v) { this._tableOptions.filterable = v; return this; }
|
|
205
|
+
paginated(v) { this._tableOptions.paginated = v; return this; }
|
|
206
|
+
rowsPerPage(v) { this._tableOptions.rowsPerPage = v; return this; }
|
|
207
|
+
/* ═══════════════════════════════════════════════════
|
|
208
|
+
* INTERNAL
|
|
209
|
+
* ═══════════════════════════════════════════════════ */
|
|
210
|
+
_setDataFrame(df, sourceName) {
|
|
211
|
+
this._df = df;
|
|
212
|
+
this.state.loaded = true;
|
|
213
|
+
this.state.loading = false;
|
|
214
|
+
this.state.sourceName = sourceName;
|
|
215
|
+
this.state.rowCount = df.height;
|
|
216
|
+
this.state.colCount = df.width;
|
|
217
|
+
// Clean __EMPTY columns from xlsx artifacts
|
|
218
|
+
const cleanCols = df.columns.filter(c => !c.startsWith('__EMPTY'));
|
|
219
|
+
if (cleanCols.length < df.columns.length) {
|
|
220
|
+
this._df = df.select(...cleanCols);
|
|
221
|
+
}
|
|
222
|
+
this._updateTable();
|
|
223
|
+
this._triggerCallback('load', this._df, null, this);
|
|
224
|
+
}
|
|
225
|
+
_updateTable() {
|
|
226
|
+
if (!this._table || !this._df)
|
|
227
|
+
return;
|
|
228
|
+
this._table.columns(this._df.columns).rows(this._df.toRows());
|
|
229
|
+
}
|
|
230
|
+
update(prop, value) { }
|
|
231
|
+
/* ═══════════════════════════════════════════════════
|
|
232
|
+
* RENDER
|
|
233
|
+
* ═══════════════════════════════════════════════════ */
|
|
234
|
+
render(targetId) {
|
|
235
|
+
const container = this._setupContainer(targetId);
|
|
236
|
+
const { style, class: className } = this.state;
|
|
237
|
+
const wrapper = document.createElement('div');
|
|
238
|
+
wrapper.className = 'jux-dataframe';
|
|
239
|
+
wrapper.id = this._id;
|
|
240
|
+
if (className)
|
|
241
|
+
wrapper.className += ` ${className}`;
|
|
242
|
+
if (style)
|
|
243
|
+
wrapper.setAttribute('style', style);
|
|
244
|
+
// Status bar
|
|
245
|
+
const statusBar = document.createElement('div');
|
|
246
|
+
statusBar.className = 'jux-dataframe-status';
|
|
247
|
+
statusBar.id = `${this._id}-status`;
|
|
248
|
+
statusBar.style.cssText = 'font-size:13px;color:#888;margin-bottom:8px;';
|
|
249
|
+
statusBar.textContent = 'No data loaded.';
|
|
250
|
+
wrapper.appendChild(statusBar);
|
|
251
|
+
container.appendChild(wrapper);
|
|
252
|
+
// Create internal table
|
|
253
|
+
this._table = new Table(`${this._id}-table`, {
|
|
254
|
+
striped: this._tableOptions.striped,
|
|
255
|
+
hoverable: this._tableOptions.hoverable,
|
|
256
|
+
sortable: this._tableOptions.sortable,
|
|
257
|
+
filterable: this._tableOptions.filterable,
|
|
258
|
+
paginated: this._tableOptions.paginated,
|
|
259
|
+
rowsPerPage: this._tableOptions.rowsPerPage
|
|
260
|
+
});
|
|
261
|
+
this._table.render(wrapper);
|
|
262
|
+
// Watch state for status updates
|
|
263
|
+
const origUpdate = this.update.bind(this);
|
|
264
|
+
this.update = (prop, value) => {
|
|
265
|
+
origUpdate(prop, value);
|
|
266
|
+
if (prop === 'loaded' || prop === 'loading' || prop === 'rowCount' || prop === 'colCount' || prop === 'sourceName') {
|
|
267
|
+
const el = document.getElementById(`${this._id}-status`);
|
|
268
|
+
if (el) {
|
|
269
|
+
if (this.state.loading) {
|
|
270
|
+
el.textContent = '⏳ Loading...';
|
|
271
|
+
}
|
|
272
|
+
else if (this.state.loaded) {
|
|
273
|
+
el.textContent = `✅ ${this.state.sourceName} — ${this.state.rowCount} rows × ${this.state.colCount} cols`;
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
el.textContent = 'No data loaded.';
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
// Execute pending data source
|
|
282
|
+
if (this._pendingSource) {
|
|
283
|
+
this._pendingSource();
|
|
284
|
+
this._pendingSource = null;
|
|
285
|
+
}
|
|
286
|
+
this._wireStandardEvents(wrapper);
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
export function dataframe(id, options = {}) {
|
|
291
|
+
return new DataFrameComponent(id, options);
|
|
292
|
+
}
|