@hpcc-js/marshaller 2.28.6 → 2.28.7
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 +43 -43
- package/dist/index.es6.js +19 -19
- package/dist/index.es6.js.map +1 -1
- package/dist/index.js +17 -17
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/package.json +16 -16
- package/src/__package__.ts +3 -3
- package/src/dashy.css +239 -239
- package/src/dashy.ts +521 -521
- package/src/ddl1/DDLApi.ts +229 -229
- package/src/ddl1/FlyoutButton.ts +120 -120
- package/src/ddl1/Graph.ts +93 -93
- package/src/ddl1/HTML.ts +77 -77
- package/src/ddl1/HipieDDL.ts +2437 -2437
- package/src/ddl1/HipieDDLMixin.ts +380 -380
- package/src/ddl1/Tabbed.ts +91 -91
- package/src/ddl1/TargetMarshaller.ts +57 -57
- package/src/ddl2/PopupManager.ts +89 -89
- package/src/ddl2/activities/activity.ts +431 -431
- package/src/ddl2/activities/databomb.ts +237 -237
- package/src/ddl2/activities/datasource.ts +52 -52
- package/src/ddl2/activities/dspicker.ts +106 -106
- package/src/ddl2/activities/filter.ts +542 -542
- package/src/ddl2/activities/form.ts +153 -153
- package/src/ddl2/activities/groupby.ts +439 -439
- package/src/ddl2/activities/hipiepipeline.ts +114 -114
- package/src/ddl2/activities/limit.ts +49 -49
- package/src/ddl2/activities/logicalfile.ts +62 -62
- package/src/ddl2/activities/nullview.ts +12 -12
- package/src/ddl2/activities/project.ts +764 -764
- package/src/ddl2/activities/rest.ts +568 -568
- package/src/ddl2/activities/roxie.ts +490 -490
- package/src/ddl2/activities/sampledata.json +16264 -16264
- package/src/ddl2/activities/sort.ts +176 -176
- package/src/ddl2/activities/wuresult.ts +395 -395
- package/src/ddl2/dashboard.css +13 -13
- package/src/ddl2/dashboard.ts +330 -330
- package/src/ddl2/dashboardDockPanel.ts +123 -123
- package/src/ddl2/dashboardGrid.ts +202 -202
- package/src/ddl2/ddl.ts +410 -410
- package/src/ddl2/ddleditor.ts +60 -60
- package/src/ddl2/dsTable.ts +238 -238
- package/src/ddl2/dvTable.ts +31 -31
- package/src/ddl2/graphadapter.ts +297 -297
- package/src/ddl2/javascriptadapter.ts +354 -354
- package/src/ddl2/model/element.ts +398 -398
- package/src/ddl2/model/visualization.ts +351 -351
- package/src/ddl2/model/vizChartPanel.ts +149 -149
- package/src/ddl2/pipelinePanel.css +4 -4
- package/src/ddl2/pipelinePanel.ts +465 -465
- package/src/index.ts +26 -26
package/src/ddl2/dashboard.ts
CHANGED
|
@@ -1,330 +1,330 @@
|
|
|
1
|
-
import { Button, Spacer, ToggleButton, Widget } from "@hpcc-js/common";
|
|
2
|
-
import { DDL1, DDL2, isDDL2Schema, upgrade } from "@hpcc-js/ddl-shim";
|
|
3
|
-
import { ChartPanel } from "@hpcc-js/layout";
|
|
4
|
-
import { text as d3Text } from "d3-fetch";
|
|
5
|
-
import { Activity } from "./activities/activity";
|
|
6
|
-
import { Databomb } from "./activities/databomb";
|
|
7
|
-
import { DSPicker } from "./activities/dspicker";
|
|
8
|
-
import { Filters } from "./activities/filter";
|
|
9
|
-
import { Form, FormField } from "./activities/form";
|
|
10
|
-
import { GroupBy } from "./activities/groupby";
|
|
11
|
-
import { Limit } from "./activities/limit";
|
|
12
|
-
import { Project } from "./activities/project";
|
|
13
|
-
import { Sort } from "./activities/sort";
|
|
14
|
-
import { DashboardDockPanel } from "./dashboardDockPanel";
|
|
15
|
-
import { DashboardGrid } from "./dashboardGrid";
|
|
16
|
-
import { DDLAdapter } from "./ddl";
|
|
17
|
-
import { JavaScriptAdapter } from "./javascriptadapter";
|
|
18
|
-
import { Element, ElementContainer } from "./model/element";
|
|
19
|
-
|
|
20
|
-
import "../../src/ddl2/dashboard.css";
|
|
21
|
-
|
|
22
|
-
export interface IDockPanel {
|
|
23
|
-
layoutObj(_: object | null): this;
|
|
24
|
-
layout();
|
|
25
|
-
widgets();
|
|
26
|
-
activate(element: Element);
|
|
27
|
-
hideSingleTabs(bool?: boolean);
|
|
28
|
-
syncWidgets();
|
|
29
|
-
syncPopups();
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export class Dashboard extends ChartPanel {
|
|
33
|
-
|
|
34
|
-
private _dockPanel: IDockPanel;
|
|
35
|
-
|
|
36
|
-
private _designModeButton = new ToggleButton().faChar("fa-object-group").tooltip("Design Mode...")
|
|
37
|
-
.selected(true)
|
|
38
|
-
.on("click", () => {
|
|
39
|
-
if (this._dockPanel instanceof DashboardGrid) {
|
|
40
|
-
this._dockPanel
|
|
41
|
-
.designMode(this._designModeButton.selected())
|
|
42
|
-
.lazyRender()
|
|
43
|
-
;
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
private _addButton = new Button().faChar("fa-plus").tooltip("Add...")
|
|
48
|
-
.on("click", () => {
|
|
49
|
-
const newElem = new Element(this._ec);
|
|
50
|
-
this._ec.append(newElem);
|
|
51
|
-
this.renderPromise().then(() => {
|
|
52
|
-
newElem.refresh().then(() => {
|
|
53
|
-
this.activate(newElem);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
private _removeButton = new Button().faChar("fa-minus").tooltip("Remove...")
|
|
59
|
-
.enabled(false)
|
|
60
|
-
.on("click", () => {
|
|
61
|
-
const elem = this._prevActive;
|
|
62
|
-
if (elem && window.confirm(`Remove Widget "${elem.id()}"?`)) {
|
|
63
|
-
this._ec.clear(elem.id());
|
|
64
|
-
this.renderPromise().then(() => {
|
|
65
|
-
this.vizActivation(undefined);
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
private _reloadButton = new Button().faChar("fa-refresh").tooltip("Reload...")
|
|
71
|
-
.on("click", () => {
|
|
72
|
-
const json = this.save();
|
|
73
|
-
this._ec.clear();
|
|
74
|
-
this.vizActivation(undefined);
|
|
75
|
-
this.renderPromise().then(() => {
|
|
76
|
-
this.restore(json);
|
|
77
|
-
this.renderPromise().then(() => {
|
|
78
|
-
this._ec.refresh().then(() => {
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
private _addSamples = new Button().faChar("fa-database").tooltip("Add Samples")
|
|
85
|
-
.on("click", () => {
|
|
86
|
-
Promise.all([
|
|
87
|
-
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/airports.csv"),
|
|
88
|
-
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/carriers.csv"),
|
|
89
|
-
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/stats.csv")
|
|
90
|
-
]).then(([airports, carriers, stats]) => {
|
|
91
|
-
const popupElement = this.addForm("popup", {
|
|
92
|
-
type: "form",
|
|
93
|
-
id: "global_filter",
|
|
94
|
-
fields: [{
|
|
95
|
-
type: "string",
|
|
96
|
-
id: "Airport"
|
|
97
|
-
}, {
|
|
98
|
-
type: "string",
|
|
99
|
-
id: "Airline"
|
|
100
|
-
}]
|
|
101
|
-
});
|
|
102
|
-
popupElement.visualization()
|
|
103
|
-
.title("Global Filter")
|
|
104
|
-
.visibility("flyout")
|
|
105
|
-
.chartType("FieldForm")
|
|
106
|
-
;
|
|
107
|
-
const airportsElement = this.addDatabomb("airports", airports, "csv",
|
|
108
|
-
[
|
|
109
|
-
new FormField().fieldID("code").type("string"),
|
|
110
|
-
new FormField().fieldID("name").type("string"),
|
|
111
|
-
new FormField().fieldID("count").type("number")
|
|
112
|
-
],
|
|
113
|
-
new Filters(this._ec).remoteFilter([
|
|
114
|
-
new Filters.Filter().source(popupElement.id()).mappings([new Filters.Mapping().remoteField("Airport").localField("code").nullable(true)])
|
|
115
|
-
]),
|
|
116
|
-
new Sort().column([new Sort.Column().fieldID("count").descending(true)])
|
|
117
|
-
);
|
|
118
|
-
airportsElement.chartPanel().title("Airports");
|
|
119
|
-
const carrierElement = this.addDatabomb("carriers", carriers, "csv",
|
|
120
|
-
[
|
|
121
|
-
new FormField().fieldID("code").type("string"),
|
|
122
|
-
new FormField().fieldID("name").type("string"),
|
|
123
|
-
new FormField().fieldID("count").type("number")
|
|
124
|
-
],
|
|
125
|
-
new Filters(this._ec).remoteFilter([
|
|
126
|
-
new Filters.Filter().source(popupElement.id()).mappings([new Filters.Mapping().remoteField("Airline").localField("code").nullable(true)])
|
|
127
|
-
]),
|
|
128
|
-
new Sort().column([new Sort.Column().fieldID("count").descending(true)])
|
|
129
|
-
);
|
|
130
|
-
carrierElement.chartPanel().title("Airlines");
|
|
131
|
-
const statsElement = this.addDatabomb("stats", stats, "csv",
|
|
132
|
-
[],
|
|
133
|
-
new Filters(this._ec).remoteFilter([
|
|
134
|
-
new Filters.Filter().source(airportsElement.id()).mappings([new Filters.Mapping().remoteField("code").localField("airport")]),
|
|
135
|
-
new Filters.Filter().source(carrierElement.id()).mappings([new Filters.Mapping().remoteField("code").localField("carrier").nullable(true)])
|
|
136
|
-
]));
|
|
137
|
-
statsElement.chartPanel().title("Stats");
|
|
138
|
-
return Promise.all([
|
|
139
|
-
popupElement.refresh(),
|
|
140
|
-
airportsElement.refresh(),
|
|
141
|
-
carrierElement.refresh(),
|
|
142
|
-
statsElement.refresh()
|
|
143
|
-
]);
|
|
144
|
-
}).then(() => {
|
|
145
|
-
this.render();
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
addDatabomb(label: string, payload: string, format: "csv" | "tsv" | "json" = "csv", databombFields: FormField[], ...activities: Activity[]): Element {
|
|
150
|
-
const databomb = new Databomb().id(label).format(format).payload(payload);
|
|
151
|
-
if (databombFields.length > 0) {
|
|
152
|
-
databomb.databombFields(databombFields);
|
|
153
|
-
}
|
|
154
|
-
this._ec.appendDatasource(databomb);
|
|
155
|
-
const newElem = new Element(this._ec);
|
|
156
|
-
const ds = newElem.hipiePipeline().datasource();
|
|
157
|
-
if (ds instanceof DSPicker) {
|
|
158
|
-
ds.datasourceID(databomb.id());
|
|
159
|
-
}
|
|
160
|
-
for (const activity of activities) {
|
|
161
|
-
if (activity instanceof Filters) {
|
|
162
|
-
newElem.hipiePipeline().filters(activity);
|
|
163
|
-
} else if (activity instanceof Project) {
|
|
164
|
-
newElem.hipiePipeline().project(activity);
|
|
165
|
-
} else if (activity instanceof GroupBy) {
|
|
166
|
-
newElem.hipiePipeline().groupBy(activity);
|
|
167
|
-
} else if (activity instanceof Sort) {
|
|
168
|
-
newElem.hipiePipeline().sort(activity);
|
|
169
|
-
} else if (activity instanceof Limit) {
|
|
170
|
-
newElem.hipiePipeline().limit(activity);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
this._ec.append(newElem);
|
|
174
|
-
return newElem;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
addForm(label: string, ddl: DDL2.IForm): Element {
|
|
178
|
-
const databomb = new Form().id(label).fromDDL(ddl);
|
|
179
|
-
this._ec.appendDatasource(databomb);
|
|
180
|
-
const newElem = new Element(this._ec);
|
|
181
|
-
const ds = newElem.hipiePipeline().datasource();
|
|
182
|
-
if (ds instanceof DSPicker) {
|
|
183
|
-
ds.datasourceID(databomb.id());
|
|
184
|
-
}
|
|
185
|
-
this._ec.append(newElem);
|
|
186
|
-
return newElem;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
static create(target: string, ddl: DDL2.Schema): Promise<Dashboard> {
|
|
190
|
-
return new Promise((resolve, reject) => {
|
|
191
|
-
const ec = new ElementContainer();
|
|
192
|
-
const dashboard = new Dashboard(ec)
|
|
193
|
-
.target(target)
|
|
194
|
-
.hideSingleTabs(true)
|
|
195
|
-
.titleVisible(false)
|
|
196
|
-
.restore(ddl)
|
|
197
|
-
.render(w => {
|
|
198
|
-
ec.refresh().then(() => {
|
|
199
|
-
resolve(dashboard);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
constructor(private _ec: ElementContainer) {
|
|
206
|
-
super();
|
|
207
|
-
this._ec.on("vizStateChanged", (viz) => {
|
|
208
|
-
this.vizStateChanged(viz);
|
|
209
|
-
});
|
|
210
|
-
this.buttons([this._designModeButton, new Spacer(), this._addButton, this._removeButton, new Spacer(), this._reloadButton, new Spacer(), this._addSamples]);
|
|
211
|
-
this.ensureDockPanel("dock");
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
ensureDockPanel(mode: "dock" | "grid" = "dock") {
|
|
215
|
-
if ((mode === "dock" && !(this._dockPanel instanceof DashboardDockPanel)) || (mode === "grid" && !(this._dockPanel instanceof DashboardGrid))) {
|
|
216
|
-
this._dockPanel = (mode === "dock" ? new DashboardDockPanel(this._ec) : new DashboardGrid(this._ec).designMode(this.titleVisible()))
|
|
217
|
-
.on("vizActivation", (elem: Element) => {
|
|
218
|
-
this.vizActivation(elem);
|
|
219
|
-
})
|
|
220
|
-
;
|
|
221
|
-
this.widget(this._dockPanel as any);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
elementContainer(): ElementContainer {
|
|
226
|
-
return this._ec;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
private _hipieProps;
|
|
230
|
-
hipieProps(): DDL2.IProperties;
|
|
231
|
-
hipieProps(_: DDL2.IProperties): this;
|
|
232
|
-
hipieProps(_?: DDL2.IProperties): DDL2.IProperties | this {
|
|
233
|
-
if (!arguments.length) return this._hipieProps;
|
|
234
|
-
this._hipieProps = _;
|
|
235
|
-
return this;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
ddl(): DDL2.Schema;
|
|
239
|
-
ddl(_: DDL2.Schema): this;
|
|
240
|
-
ddl(_?: DDL2.Schema): DDL2.Schema | this {
|
|
241
|
-
const ddlAdapter = new DDLAdapter(this);
|
|
242
|
-
if (!arguments.length) return ddlAdapter.write();
|
|
243
|
-
this._ec.clear();
|
|
244
|
-
ddlAdapter.read(_);
|
|
245
|
-
return this;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Used to delay load a layout after a render...
|
|
249
|
-
layoutObj(_: object | null): this {
|
|
250
|
-
this._dockPanel.layoutObj(_);
|
|
251
|
-
return this;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
save(): DDL2.Schema {
|
|
255
|
-
const ddlAdapter = new DDLAdapter(this);
|
|
256
|
-
return ddlAdapter.write();
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
restore(_: DDL2.Schema, render: boolean = false): this {
|
|
260
|
-
this.ensureDockPanel(_ && _.properties && _.properties.layout instanceof Array ? "grid" : "dock");
|
|
261
|
-
const ddlAdapter = new DDLAdapter(this);
|
|
262
|
-
ddlAdapter.read(_);
|
|
263
|
-
if (render) {
|
|
264
|
-
this.renderPromise().then(() => {
|
|
265
|
-
this._ec.refresh();
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
return this;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
importDDL(ddl: DDL1.DDLSchema | DDL2.Schema, baseUrl?: string, wuid?: string, dermatologyJson: object = {}): this {
|
|
272
|
-
const ddl2: DDL2.Schema = isDDL2Schema(ddl) ? ddl : upgrade(ddl, baseUrl, wuid, true, dermatologyJson);
|
|
273
|
-
return this.restore(ddl2, true);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
javascript(): string {
|
|
277
|
-
const jsAdapter = new JavaScriptAdapter(this);
|
|
278
|
-
return jsAdapter.createJavaScript();
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
layout() {
|
|
282
|
-
return this._dockPanel.layout();
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
widgets(): Widget[] {
|
|
286
|
-
return this._dockPanel.widgets();
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
activate(element: Element) {
|
|
290
|
-
this._dockPanel.activate(element);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
hideSingleTabs(): boolean;
|
|
294
|
-
hideSingleTabs(_: boolean): this;
|
|
295
|
-
hideSingleTabs(_?: boolean): boolean | this {
|
|
296
|
-
if (!arguments.length) return this._dockPanel.hideSingleTabs();
|
|
297
|
-
this._dockPanel.hideSingleTabs(_);
|
|
298
|
-
return this;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
updateButtonState() {
|
|
302
|
-
this._designModeButton.enabled(this._dockPanel instanceof DashboardGrid).render();
|
|
303
|
-
this._removeButton.enabled(this._prevActive !== undefined).render();
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
update(domNode: HTMLElement, element) {
|
|
307
|
-
this._dockPanel.syncWidgets();
|
|
308
|
-
super.update(domNode, element);
|
|
309
|
-
this.updateButtonState();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
private _prevActive: Element;
|
|
313
|
-
vizActivation(viz: Element) {
|
|
314
|
-
this._prevActive = viz;
|
|
315
|
-
this._removeButton.enabled(viz !== undefined).render();
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
vizStateChanged(viz: Element) {
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
render(callback?): this {
|
|
322
|
-
this._dockPanel.syncPopups();
|
|
323
|
-
return super.render(w => {
|
|
324
|
-
if (callback) {
|
|
325
|
-
callback(w);
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
Dashboard.prototype._class += " dashboard_dashboard";
|
|
1
|
+
import { Button, Spacer, ToggleButton, Widget } from "@hpcc-js/common";
|
|
2
|
+
import { DDL1, DDL2, isDDL2Schema, upgrade } from "@hpcc-js/ddl-shim";
|
|
3
|
+
import { ChartPanel } from "@hpcc-js/layout";
|
|
4
|
+
import { text as d3Text } from "d3-fetch";
|
|
5
|
+
import { Activity } from "./activities/activity";
|
|
6
|
+
import { Databomb } from "./activities/databomb";
|
|
7
|
+
import { DSPicker } from "./activities/dspicker";
|
|
8
|
+
import { Filters } from "./activities/filter";
|
|
9
|
+
import { Form, FormField } from "./activities/form";
|
|
10
|
+
import { GroupBy } from "./activities/groupby";
|
|
11
|
+
import { Limit } from "./activities/limit";
|
|
12
|
+
import { Project } from "./activities/project";
|
|
13
|
+
import { Sort } from "./activities/sort";
|
|
14
|
+
import { DashboardDockPanel } from "./dashboardDockPanel";
|
|
15
|
+
import { DashboardGrid } from "./dashboardGrid";
|
|
16
|
+
import { DDLAdapter } from "./ddl";
|
|
17
|
+
import { JavaScriptAdapter } from "./javascriptadapter";
|
|
18
|
+
import { Element, ElementContainer } from "./model/element";
|
|
19
|
+
|
|
20
|
+
import "../../src/ddl2/dashboard.css";
|
|
21
|
+
|
|
22
|
+
export interface IDockPanel {
|
|
23
|
+
layoutObj(_: object | null): this;
|
|
24
|
+
layout();
|
|
25
|
+
widgets();
|
|
26
|
+
activate(element: Element);
|
|
27
|
+
hideSingleTabs(bool?: boolean);
|
|
28
|
+
syncWidgets();
|
|
29
|
+
syncPopups();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class Dashboard extends ChartPanel {
|
|
33
|
+
|
|
34
|
+
private _dockPanel: IDockPanel;
|
|
35
|
+
|
|
36
|
+
private _designModeButton = new ToggleButton().faChar("fa-object-group").tooltip("Design Mode...")
|
|
37
|
+
.selected(true)
|
|
38
|
+
.on("click", () => {
|
|
39
|
+
if (this._dockPanel instanceof DashboardGrid) {
|
|
40
|
+
this._dockPanel
|
|
41
|
+
.designMode(this._designModeButton.selected())
|
|
42
|
+
.lazyRender()
|
|
43
|
+
;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
private _addButton = new Button().faChar("fa-plus").tooltip("Add...")
|
|
48
|
+
.on("click", () => {
|
|
49
|
+
const newElem = new Element(this._ec);
|
|
50
|
+
this._ec.append(newElem);
|
|
51
|
+
this.renderPromise().then(() => {
|
|
52
|
+
newElem.refresh().then(() => {
|
|
53
|
+
this.activate(newElem);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
private _removeButton = new Button().faChar("fa-minus").tooltip("Remove...")
|
|
59
|
+
.enabled(false)
|
|
60
|
+
.on("click", () => {
|
|
61
|
+
const elem = this._prevActive;
|
|
62
|
+
if (elem && window.confirm(`Remove Widget "${elem.id()}"?`)) {
|
|
63
|
+
this._ec.clear(elem.id());
|
|
64
|
+
this.renderPromise().then(() => {
|
|
65
|
+
this.vizActivation(undefined);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
private _reloadButton = new Button().faChar("fa-refresh").tooltip("Reload...")
|
|
71
|
+
.on("click", () => {
|
|
72
|
+
const json = this.save();
|
|
73
|
+
this._ec.clear();
|
|
74
|
+
this.vizActivation(undefined);
|
|
75
|
+
this.renderPromise().then(() => {
|
|
76
|
+
this.restore(json);
|
|
77
|
+
this.renderPromise().then(() => {
|
|
78
|
+
this._ec.refresh().then(() => {
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
private _addSamples = new Button().faChar("fa-database").tooltip("Add Samples")
|
|
85
|
+
.on("click", () => {
|
|
86
|
+
Promise.all([
|
|
87
|
+
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/airports.csv"),
|
|
88
|
+
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/carriers.csv"),
|
|
89
|
+
d3Text("https://raw.githubusercontent.com/hpcc-systems/Visualization/trunk/utils/data/data/stats.csv")
|
|
90
|
+
]).then(([airports, carriers, stats]) => {
|
|
91
|
+
const popupElement = this.addForm("popup", {
|
|
92
|
+
type: "form",
|
|
93
|
+
id: "global_filter",
|
|
94
|
+
fields: [{
|
|
95
|
+
type: "string",
|
|
96
|
+
id: "Airport"
|
|
97
|
+
}, {
|
|
98
|
+
type: "string",
|
|
99
|
+
id: "Airline"
|
|
100
|
+
}]
|
|
101
|
+
});
|
|
102
|
+
popupElement.visualization()
|
|
103
|
+
.title("Global Filter")
|
|
104
|
+
.visibility("flyout")
|
|
105
|
+
.chartType("FieldForm")
|
|
106
|
+
;
|
|
107
|
+
const airportsElement = this.addDatabomb("airports", airports, "csv",
|
|
108
|
+
[
|
|
109
|
+
new FormField().fieldID("code").type("string"),
|
|
110
|
+
new FormField().fieldID("name").type("string"),
|
|
111
|
+
new FormField().fieldID("count").type("number")
|
|
112
|
+
],
|
|
113
|
+
new Filters(this._ec).remoteFilter([
|
|
114
|
+
new Filters.Filter().source(popupElement.id()).mappings([new Filters.Mapping().remoteField("Airport").localField("code").nullable(true)])
|
|
115
|
+
]),
|
|
116
|
+
new Sort().column([new Sort.Column().fieldID("count").descending(true)])
|
|
117
|
+
);
|
|
118
|
+
airportsElement.chartPanel().title("Airports");
|
|
119
|
+
const carrierElement = this.addDatabomb("carriers", carriers, "csv",
|
|
120
|
+
[
|
|
121
|
+
new FormField().fieldID("code").type("string"),
|
|
122
|
+
new FormField().fieldID("name").type("string"),
|
|
123
|
+
new FormField().fieldID("count").type("number")
|
|
124
|
+
],
|
|
125
|
+
new Filters(this._ec).remoteFilter([
|
|
126
|
+
new Filters.Filter().source(popupElement.id()).mappings([new Filters.Mapping().remoteField("Airline").localField("code").nullable(true)])
|
|
127
|
+
]),
|
|
128
|
+
new Sort().column([new Sort.Column().fieldID("count").descending(true)])
|
|
129
|
+
);
|
|
130
|
+
carrierElement.chartPanel().title("Airlines");
|
|
131
|
+
const statsElement = this.addDatabomb("stats", stats, "csv",
|
|
132
|
+
[],
|
|
133
|
+
new Filters(this._ec).remoteFilter([
|
|
134
|
+
new Filters.Filter().source(airportsElement.id()).mappings([new Filters.Mapping().remoteField("code").localField("airport")]),
|
|
135
|
+
new Filters.Filter().source(carrierElement.id()).mappings([new Filters.Mapping().remoteField("code").localField("carrier").nullable(true)])
|
|
136
|
+
]));
|
|
137
|
+
statsElement.chartPanel().title("Stats");
|
|
138
|
+
return Promise.all([
|
|
139
|
+
popupElement.refresh(),
|
|
140
|
+
airportsElement.refresh(),
|
|
141
|
+
carrierElement.refresh(),
|
|
142
|
+
statsElement.refresh()
|
|
143
|
+
]);
|
|
144
|
+
}).then(() => {
|
|
145
|
+
this.render();
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
addDatabomb(label: string, payload: string, format: "csv" | "tsv" | "json" = "csv", databombFields: FormField[], ...activities: Activity[]): Element {
|
|
150
|
+
const databomb = new Databomb().id(label).format(format).payload(payload);
|
|
151
|
+
if (databombFields.length > 0) {
|
|
152
|
+
databomb.databombFields(databombFields);
|
|
153
|
+
}
|
|
154
|
+
this._ec.appendDatasource(databomb);
|
|
155
|
+
const newElem = new Element(this._ec);
|
|
156
|
+
const ds = newElem.hipiePipeline().datasource();
|
|
157
|
+
if (ds instanceof DSPicker) {
|
|
158
|
+
ds.datasourceID(databomb.id());
|
|
159
|
+
}
|
|
160
|
+
for (const activity of activities) {
|
|
161
|
+
if (activity instanceof Filters) {
|
|
162
|
+
newElem.hipiePipeline().filters(activity);
|
|
163
|
+
} else if (activity instanceof Project) {
|
|
164
|
+
newElem.hipiePipeline().project(activity);
|
|
165
|
+
} else if (activity instanceof GroupBy) {
|
|
166
|
+
newElem.hipiePipeline().groupBy(activity);
|
|
167
|
+
} else if (activity instanceof Sort) {
|
|
168
|
+
newElem.hipiePipeline().sort(activity);
|
|
169
|
+
} else if (activity instanceof Limit) {
|
|
170
|
+
newElem.hipiePipeline().limit(activity);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
this._ec.append(newElem);
|
|
174
|
+
return newElem;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
addForm(label: string, ddl: DDL2.IForm): Element {
|
|
178
|
+
const databomb = new Form().id(label).fromDDL(ddl);
|
|
179
|
+
this._ec.appendDatasource(databomb);
|
|
180
|
+
const newElem = new Element(this._ec);
|
|
181
|
+
const ds = newElem.hipiePipeline().datasource();
|
|
182
|
+
if (ds instanceof DSPicker) {
|
|
183
|
+
ds.datasourceID(databomb.id());
|
|
184
|
+
}
|
|
185
|
+
this._ec.append(newElem);
|
|
186
|
+
return newElem;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
static create(target: string, ddl: DDL2.Schema): Promise<Dashboard> {
|
|
190
|
+
return new Promise((resolve, reject) => {
|
|
191
|
+
const ec = new ElementContainer();
|
|
192
|
+
const dashboard = new Dashboard(ec)
|
|
193
|
+
.target(target)
|
|
194
|
+
.hideSingleTabs(true)
|
|
195
|
+
.titleVisible(false)
|
|
196
|
+
.restore(ddl)
|
|
197
|
+
.render(w => {
|
|
198
|
+
ec.refresh().then(() => {
|
|
199
|
+
resolve(dashboard);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
constructor(private _ec: ElementContainer) {
|
|
206
|
+
super();
|
|
207
|
+
this._ec.on("vizStateChanged", (viz) => {
|
|
208
|
+
this.vizStateChanged(viz);
|
|
209
|
+
});
|
|
210
|
+
this.buttons([this._designModeButton, new Spacer(), this._addButton, this._removeButton, new Spacer(), this._reloadButton, new Spacer(), this._addSamples]);
|
|
211
|
+
this.ensureDockPanel("dock");
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
ensureDockPanel(mode: "dock" | "grid" = "dock") {
|
|
215
|
+
if ((mode === "dock" && !(this._dockPanel instanceof DashboardDockPanel)) || (mode === "grid" && !(this._dockPanel instanceof DashboardGrid))) {
|
|
216
|
+
this._dockPanel = (mode === "dock" ? new DashboardDockPanel(this._ec) : new DashboardGrid(this._ec).designMode(this.titleVisible()))
|
|
217
|
+
.on("vizActivation", (elem: Element) => {
|
|
218
|
+
this.vizActivation(elem);
|
|
219
|
+
})
|
|
220
|
+
;
|
|
221
|
+
this.widget(this._dockPanel as any);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
elementContainer(): ElementContainer {
|
|
226
|
+
return this._ec;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
private _hipieProps;
|
|
230
|
+
hipieProps(): DDL2.IProperties;
|
|
231
|
+
hipieProps(_: DDL2.IProperties): this;
|
|
232
|
+
hipieProps(_?: DDL2.IProperties): DDL2.IProperties | this {
|
|
233
|
+
if (!arguments.length) return this._hipieProps;
|
|
234
|
+
this._hipieProps = _;
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
ddl(): DDL2.Schema;
|
|
239
|
+
ddl(_: DDL2.Schema): this;
|
|
240
|
+
ddl(_?: DDL2.Schema): DDL2.Schema | this {
|
|
241
|
+
const ddlAdapter = new DDLAdapter(this);
|
|
242
|
+
if (!arguments.length) return ddlAdapter.write();
|
|
243
|
+
this._ec.clear();
|
|
244
|
+
ddlAdapter.read(_);
|
|
245
|
+
return this;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Used to delay load a layout after a render...
|
|
249
|
+
layoutObj(_: object | null): this {
|
|
250
|
+
this._dockPanel.layoutObj(_);
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
save(): DDL2.Schema {
|
|
255
|
+
const ddlAdapter = new DDLAdapter(this);
|
|
256
|
+
return ddlAdapter.write();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
restore(_: DDL2.Schema, render: boolean = false): this {
|
|
260
|
+
this.ensureDockPanel(_ && _.properties && _.properties.layout instanceof Array ? "grid" : "dock");
|
|
261
|
+
const ddlAdapter = new DDLAdapter(this);
|
|
262
|
+
ddlAdapter.read(_);
|
|
263
|
+
if (render) {
|
|
264
|
+
this.renderPromise().then(() => {
|
|
265
|
+
this._ec.refresh();
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return this;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
importDDL(ddl: DDL1.DDLSchema | DDL2.Schema, baseUrl?: string, wuid?: string, dermatologyJson: object = {}): this {
|
|
272
|
+
const ddl2: DDL2.Schema = isDDL2Schema(ddl) ? ddl : upgrade(ddl, baseUrl, wuid, true, dermatologyJson);
|
|
273
|
+
return this.restore(ddl2, true);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
javascript(): string {
|
|
277
|
+
const jsAdapter = new JavaScriptAdapter(this);
|
|
278
|
+
return jsAdapter.createJavaScript();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
layout() {
|
|
282
|
+
return this._dockPanel.layout();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
widgets(): Widget[] {
|
|
286
|
+
return this._dockPanel.widgets();
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
activate(element: Element) {
|
|
290
|
+
this._dockPanel.activate(element);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
hideSingleTabs(): boolean;
|
|
294
|
+
hideSingleTabs(_: boolean): this;
|
|
295
|
+
hideSingleTabs(_?: boolean): boolean | this {
|
|
296
|
+
if (!arguments.length) return this._dockPanel.hideSingleTabs();
|
|
297
|
+
this._dockPanel.hideSingleTabs(_);
|
|
298
|
+
return this;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
updateButtonState() {
|
|
302
|
+
this._designModeButton.enabled(this._dockPanel instanceof DashboardGrid).render();
|
|
303
|
+
this._removeButton.enabled(this._prevActive !== undefined).render();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
update(domNode: HTMLElement, element) {
|
|
307
|
+
this._dockPanel.syncWidgets();
|
|
308
|
+
super.update(domNode, element);
|
|
309
|
+
this.updateButtonState();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
private _prevActive: Element;
|
|
313
|
+
vizActivation(viz: Element) {
|
|
314
|
+
this._prevActive = viz;
|
|
315
|
+
this._removeButton.enabled(viz !== undefined).render();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
vizStateChanged(viz: Element) {
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
render(callback?): this {
|
|
322
|
+
this._dockPanel.syncPopups();
|
|
323
|
+
return super.render(w => {
|
|
324
|
+
if (callback) {
|
|
325
|
+
callback(w);
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
Dashboard.prototype._class += " dashboard_dashboard";
|