mascot-vis 3.0.0 → 3.0.2
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/dist/mascot-esm.js +186 -0
- package/package.json +3 -6
- package/dist/mascot-es.js +0 -27745
- package/dist/mascot-min.js +0 -186
- package/dist/mascot-umd.js +0 -27781
- package/js/depGraphVis.js +0 -66
- package/src-new-ts/action/createElement.ts +0 -91
- package/src-new-ts/action/encode.js +0 -20
- package/src-new-ts/action/repeat.js +0 -128
- package/src-new-ts/action/traverseScene.js +0 -41
- package/src-new-ts/data/Network.js +0 -2
- package/src-new-ts/data/Scope.js +0 -135
- package/src-new-ts/data/Table.js +0 -263
- package/src-new-ts/data/Tree.js +0 -3
- package/src-new-ts/data/field.ts +0 -115
- package/src-new-ts/data/import.ts +0 -96
- package/src-new-ts/data/predicate.ts +0 -82
- package/src-new-ts/depgraph/DepGraph.js +0 -178
- package/src-new-ts/depgraph/Edge.js +0 -9
- package/src-new-ts/depgraph/SceneGraph2DepGraph.js +0 -110
- package/src-new-ts/depgraph/Signal.js +0 -12
- package/src-new-ts/depgraph/operator/BoundsEvaluator.js +0 -30
- package/src-new-ts/depgraph/operator/Dataflow.js +0 -41
- package/src-new-ts/depgraph/operator/DomainBuilder.js +0 -50
- package/src-new-ts/depgraph/updateDepGraph.js +0 -45
- package/src-new-ts/depgraph/variable/BoundsVar.js +0 -81
- package/src-new-ts/depgraph/variable/ChannelVar.js +0 -17
- package/src-new-ts/depgraph/variable/DataScopeVar.js +0 -12
- package/src-new-ts/depgraph/variable/DomainVar.js +0 -15
- package/src-new-ts/depgraph/variable/FieldVar.js +0 -17
- package/src-new-ts/depgraph/variable/LayoutParameter.js +0 -8
- package/src-new-ts/depgraph/variable/ScaleVar.js +0 -13
- package/src-new-ts/depgraph/variable/Variable.js +0 -39
- package/src-new-ts/element/gradient/LinearGradient.js +0 -37
- package/src-new-ts/element/group/Collection.js +0 -109
- package/src-new-ts/element/group/Group.js +0 -307
- package/src-new-ts/element/group/Scene.js +0 -98
- package/src-new-ts/element/mark/CircleMark.ts +0 -85
- package/src-new-ts/element/mark/Mark.ts +0 -233
- package/src-new-ts/element/mark/PathMark.js +0 -483
- package/src-new-ts/element/mark/Segment.js +0 -29
- package/src-new-ts/element/mark/Vertex.js +0 -118
- package/src-new-ts/encode/Scale.ts +0 -115
- package/src-new-ts/index.ts +0 -19
- package/src-new-ts/layout/Layout.ts +0 -3
- package/src-new-ts/render/CanvasRenderer.ts +0 -24
- package/src-new-ts/render/SVGRenderer.js +0 -316
- package/src-new-ts/util.ts +0 -3
- package/src-old/action/Classify.js +0 -53
- package/src-old/action/Densify.js +0 -199
- package/src-old/action/Partition.js +0 -531
- package/src-old/action/Repeat.js +0 -106
- package/src-old/action/Repopulate.js +0 -44
- package/src-old/action/Stratify.js +0 -156
- package/src-old/basic/Gradient.js +0 -37
- package/src-old/basic/Point.js +0 -51
- package/src-old/basic/Rectangle.js +0 -63
- package/src-old/bind/bindToAngle.js +0 -56
- package/src-old/bind/bindToAreaMark.js +0 -360
- package/src-old/bind/bindToColor.js +0 -114
- package/src-old/bind/bindToLink.js +0 -81
- package/src-old/bind/bindToPosition.js +0 -283
- package/src-old/bind/bindToRadialDistance.js +0 -62
- package/src-old/bind/bindToSize.js +0 -235
- package/src-old/bind/bindToText.js +0 -60
- package/src-old/bind/bindToThickness.js +0 -100
- package/src-old/constraint/AffixConstraint.js +0 -129
- package/src-old/constraint/AlignConstraint.js +0 -58
- package/src-old/core/Encoding.js +0 -336
- package/src-old/core/Scale.js +0 -322
- package/src-old/core/SceneLoader.js +0 -290
- package/src-old/core/SceneValidator.js +0 -232
- package/src-old/core/SpecExecutor.js +0 -113
- package/src-old/core/SpecGenerator.js +0 -350
- package/src-old/data/DataImporter.js +0 -64
- package/src-old/data/DataScope.js +0 -124
- package/src-old/data/DataTable.js +0 -338
- package/src-old/data/Network.js +0 -106
- package/src-old/data/Tree.js +0 -251
- package/src-old/data/transform/Bin.js +0 -46
- package/src-old/data/transform/Filter.js +0 -48
- package/src-old/data/transform/Groupby.js +0 -18
- package/src-old/data/transform/KDE.js +0 -58
- package/src-old/data/transform/Sort.js +0 -14
- package/src-old/data/transform/Split.js +0 -5
- package/src-old/data/transform/partition.js +0 -46
- package/src-old/history/UndoRedoStack +0 -0
- package/src-old/index.js +0 -271
- package/src-old/indexSVG.js +0 -259
- package/src-old/interaction/Interaction.js +0 -91
- package/src-old/interaction/MouseEvent.js +0 -8
- package/src-old/interaction/Selection.js +0 -9
- package/src-old/interaction/brush.js +0 -362
- package/src-old/item/Segment.js +0 -29
- package/src-old/item/Vertex.js +0 -118
- package/src-old/item/composite/Collection.js +0 -106
- package/src-old/item/composite/Glyph.js +0 -19
- package/src-old/item/composite/Group.js +0 -310
- package/src-old/item/composite/Scene.js +0 -1251
- package/src-old/item/mark/ArcPath.js +0 -181
- package/src-old/item/mark/AreaPath.js +0 -78
- package/src-old/item/mark/CirclePath.js +0 -102
- package/src-old/item/mark/EllipsePath.js +0 -5
- package/src-old/item/mark/Image.js +0 -101
- package/src-old/item/mark/LinkPath.js +0 -118
- package/src-old/item/mark/Mark.js +0 -163
- package/src-old/item/mark/Path.js +0 -494
- package/src-old/item/mark/PointText.js +0 -201
- package/src-old/item/mark/PolygonPath.js +0 -64
- package/src-old/item/mark/RectPath.js +0 -88
- package/src-old/item/mark/RingPath.js +0 -92
- package/src-old/item/refs/Axis.js +0 -362
- package/src-old/item/refs/EncodingAxis.js +0 -515
- package/src-old/item/refs/Gridlines.js +0 -144
- package/src-old/item/refs/LayoutAxis.js +0 -316
- package/src-old/item/refs/Legend.js +0 -273
- package/src-old/layout/Circular.js +0 -95
- package/src-old/layout/Force.js +0 -52
- package/src-old/layout/Grid.js +0 -423
- package/src-old/layout/Layout.js +0 -13
- package/src-old/layout/Packing.js +0 -56
- package/src-old/layout/Stack.js +0 -264
- package/src-old/layout/Strata.js +0 -88
- package/src-old/layout/Sugiyama.js +0 -59
- package/src-old/layout/TidyTree.js +0 -105
- package/src-old/layout/Treemap.js +0 -87
- package/src-old/renderer/SVGInteractionHandler.js +0 -241
- package/src-old/renderer/SVGRenderer.js +0 -325
- package/src-old/renderer/WebGLRenderer.js +0 -1097
- package/src-old/renderer/WebGLRenderer2.js +0 -249
- package/src-old/renderer/threejs/Line2.js +0 -18
- package/src-old/renderer/threejs/LineGeometry.js +0 -77
- package/src-old/renderer/threejs/LineMaterial.js +0 -605
- package/src-old/renderer/threejs/LineSegments2.js +0 -281
- package/src-old/renderer/threejs/LineSegmentsGeometry.js +0 -226
- package/src-old/renderer/threejs/Wireframe.js +0 -51
- package/src-old/renderer/threejs/WireframeGeometry2.js +0 -16
- package/src-old/scale/areaSize.js +0 -0
- package/src-old/scale/domain.js +0 -38
- package/src-old/util/Constants.js +0 -180
- package/src-old/util/DataUtil.js +0 -35
- package/src-old/util/ItemUtil.js +0 -586
- package/src-old/util/Numerical.js +0 -33
- package/tests/demo-tests/README.md +0 -80
- package/tests/demo-tests/SVG2PNG.js +0 -56
- package/tests/demo-tests/demos2CanvasPNGs.js +0 -69
- package/tests/demo-tests/demos2ScenesSVGs.js +0 -100
- package/tests/demo-tests/pathElementWorker.js +0 -91
- package/tests/demo-tests/pixelTest.js +0 -62
- package/tests/demo-tests/renderDemos.html +0 -132
- package/tests/demo-tests/serializationTest.js +0 -36
- package/tests/demo-tests/serializeDemos.html +0 -134
- package/tests/unit-tests/README.md +0 -4
- package/tests/unit-tests/jasmine-browser.json +0 -21
- package/tests/unit-tests/jasmine.json +0 -14
- package/tests/unit-tests/testSpec.js +0 -274
package/src-new-ts/data/Table.js
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import * as d3 from "d3";
|
|
2
|
-
import { generateUniqueID } from "../util.js";
|
|
3
|
-
import { ElementType } from "../action/createElement.js";
|
|
4
|
-
import { FieldType } from "./field.ts";
|
|
5
|
-
import { getFileName } from "./import.js";
|
|
6
|
-
import { inferType } from "./field.ts";
|
|
7
|
-
import { summarize } from "./field.ts";
|
|
8
|
-
|
|
9
|
-
export default class DataTable {
|
|
10
|
-
|
|
11
|
-
constructor(data, url, fTypes) {
|
|
12
|
-
this.url = url;
|
|
13
|
-
//this.name = _getFileName(url);
|
|
14
|
-
this._id = ElementType.DataTable + generateUniqueID();
|
|
15
|
-
this._data = data;
|
|
16
|
-
this._rawData = JSON.parse(JSON.stringify(data));
|
|
17
|
-
//remember the original date values after parsing them
|
|
18
|
-
this._dateMap = new Map();
|
|
19
|
-
this._fields = Object.keys(this.data[0]);
|
|
20
|
-
this._newField = 0;
|
|
21
|
-
if (fTypes) {
|
|
22
|
-
this._fieldTypes = fTypes;
|
|
23
|
-
} else {
|
|
24
|
-
this._fieldTypes = {};
|
|
25
|
-
for (let f of this._fields) {
|
|
26
|
-
this._fieldTypes[f] = inferType(this.data.map(d => d[f]));
|
|
27
|
-
if (f.toLowerCase() == "year" && this._fieldTypes[f] == FieldType.Integer)
|
|
28
|
-
this._fieldTypes[f] = FieldType.Date;
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
//fix null values, cast type and summarize
|
|
32
|
-
this._validate(this.data, this._fieldTypes);
|
|
33
|
-
|
|
34
|
-
this._fieldSummaries = {};
|
|
35
|
-
for (let f of this._fields) {
|
|
36
|
-
this._fieldSummaries[f] = summarize(this.data.map(d => d[f]), this._fieldTypes[f]);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
//add row id
|
|
40
|
-
if (this._fields.indexOf(MSCRowID) < 0) {
|
|
41
|
-
this._addField(MSCRowID, FieldType.String, this.data.map((d, i) => "r" + i));
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
get id() {
|
|
46
|
-
return this._id;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get name() {
|
|
50
|
-
if (this.url)
|
|
51
|
-
return getFileName(this.url);
|
|
52
|
-
else
|
|
53
|
-
return this.id;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
get data() {
|
|
57
|
-
return this._data;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
//only tracking one transform away
|
|
61
|
-
// set sourceDataTable(dt) {
|
|
62
|
-
// this._sourceDataTable = dt;
|
|
63
|
-
// }
|
|
64
|
-
|
|
65
|
-
// get sourceDataTable() {
|
|
66
|
-
// return this._sourceDataTable;
|
|
67
|
-
// }
|
|
68
|
-
|
|
69
|
-
getEncodableFields(channel) {
|
|
70
|
-
switch (channel) {
|
|
71
|
-
case "x":
|
|
72
|
-
case "y":
|
|
73
|
-
case "width":
|
|
74
|
-
case "height":
|
|
75
|
-
case "radius":
|
|
76
|
-
case "fillColor":
|
|
77
|
-
case "strokeColor":
|
|
78
|
-
case "text":
|
|
79
|
-
return this.numericFields.concat(this.nonNumericFields);
|
|
80
|
-
case "area":
|
|
81
|
-
case "strokeWidth":
|
|
82
|
-
default:
|
|
83
|
-
return this.numericFields;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
toJSON() {
|
|
88
|
-
let json = {};
|
|
89
|
-
json.data = this.rawData;
|
|
90
|
-
json.fieldTypes = this._fieldTypes;
|
|
91
|
-
json.url = this.url;
|
|
92
|
-
json.id = this.id;
|
|
93
|
-
json.sourceDataTable = this._sourceDataTable;
|
|
94
|
-
json.transform = this._transform;
|
|
95
|
-
json.dateMap = {};
|
|
96
|
-
return json;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
setValueOrder(field, values) {
|
|
100
|
-
this._fieldSummaries[field].unique = values;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
_addField(name, type, values) {
|
|
104
|
-
this.data.forEach((d, i) => d[name] = values[i]);
|
|
105
|
-
this._fieldTypes[name] = type;
|
|
106
|
-
this._fields.push(name);
|
|
107
|
-
this._fieldSummaries[name] = summarize(values, type);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
getFieldType(f) {
|
|
111
|
-
return this._fieldTypes[f];
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
get fields() {
|
|
115
|
-
return this._fields;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
getFieldSummary(f) {
|
|
119
|
-
return this._fieldSummaries[f];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
getFieldValues(f) {
|
|
123
|
-
return this.data.map(d => d[f]);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
getUniqueFieldValues(f) {
|
|
127
|
-
return this._fieldSummaries[f].unique;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
getRowCount() {
|
|
131
|
-
return this.data.length;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
hasField(f) {
|
|
135
|
-
return this._fields.indexOf(f) >= 0;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
//date values are parsed and stored as number of milliseconds
|
|
139
|
-
parseFieldAsDate(field, format) {
|
|
140
|
-
//TODO: validate field and format
|
|
141
|
-
let parse = d3.timeParse(format);
|
|
142
|
-
for (let row of this.data) {
|
|
143
|
-
let v = row[field];
|
|
144
|
-
if (v == null || v == undefined) {
|
|
145
|
-
v = "";
|
|
146
|
-
row[field] = (new Date(1899, 11, 31)).getTime();
|
|
147
|
-
} else {
|
|
148
|
-
row[field] = parse(v).getTime();
|
|
149
|
-
}
|
|
150
|
-
this._dateMap.set(row[field], v);
|
|
151
|
-
}
|
|
152
|
-
this._fieldTypes[field] = FieldType.Date;
|
|
153
|
-
this._fieldSummaries[field] = summarize(this.data.map(d => d[field]), FieldType.Date);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
//TODO: need to return the true raw value from the input file
|
|
157
|
-
getRawValue(col, v) {
|
|
158
|
-
if (this.getFieldType(col) === FieldType.Date)
|
|
159
|
-
return this._dateMap.get(v).toString();
|
|
160
|
-
else
|
|
161
|
-
return v;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
get nonNumericFields() {
|
|
165
|
-
let r = [];
|
|
166
|
-
for (let f in this._fieldTypes) {
|
|
167
|
-
if (this._fieldTypes[f] != FieldType.Number && this._fieldTypes[f] != FieldType.Integer && f != DataTable.RowID) {
|
|
168
|
-
r.push(f);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
r.sort((a, b) => this.getUniqueFieldValues(a).length - this.getUniqueFieldValues(b).length);
|
|
172
|
-
return r;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
get numericFields() {
|
|
176
|
-
let r = [];
|
|
177
|
-
for (let f in this._fieldTypes) {
|
|
178
|
-
if ((this._fieldTypes[f] === FieldType.Number || this._fieldTypes[f] === FieldType.Integer) && f != DataTable.RowID) {
|
|
179
|
-
r.push(f);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
return r;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
getFieldsByType(t) {
|
|
186
|
-
let r = [];
|
|
187
|
-
for (let f in this._fieldTypes) {
|
|
188
|
-
if ((this._fieldTypes[f] === t) && f != DataTable.RowID) {
|
|
189
|
-
r.push(f);
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
return r;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// transform(type, fields, params) {
|
|
196
|
-
// let args = params ? params : {};
|
|
197
|
-
// switch (type) {
|
|
198
|
-
// case "kde":
|
|
199
|
-
// return kde(this, fields, args);
|
|
200
|
-
// case "bin":
|
|
201
|
-
// return bin(this, fields, args);
|
|
202
|
-
// case "sort":
|
|
203
|
-
// return sort(this, fields, args);
|
|
204
|
-
// case "filter":
|
|
205
|
-
// return filter(this, fields);
|
|
206
|
-
// }
|
|
207
|
-
// }
|
|
208
|
-
|
|
209
|
-
summarize() {
|
|
210
|
-
for (let f of this._fields) {
|
|
211
|
-
this._fieldSummaries[f] = summarize(this.data.map(d => d[f]), this._fieldTypes[f]);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
_validate(data, fieldTypes) {
|
|
216
|
-
//date values are parsed and stored as number of milliseconds
|
|
217
|
-
for (let row of data) {
|
|
218
|
-
for (let f in fieldTypes) {
|
|
219
|
-
let type = fieldTypes[f], v = row[f], realv = undefined;
|
|
220
|
-
if (row[f] == null || row[f] == undefined) {
|
|
221
|
-
switch (type) {
|
|
222
|
-
case FieldType.Boolean:
|
|
223
|
-
realv = false;
|
|
224
|
-
break;
|
|
225
|
-
case FieldType.Date:
|
|
226
|
-
realv = (new Date(1899, 11, 31)).getTime();
|
|
227
|
-
break;
|
|
228
|
-
case FieldType.String:
|
|
229
|
-
realv = "";
|
|
230
|
-
break;
|
|
231
|
-
default:
|
|
232
|
-
realv = 0;
|
|
233
|
-
break;
|
|
234
|
-
}
|
|
235
|
-
} else {
|
|
236
|
-
switch (type) {
|
|
237
|
-
case FieldType.Boolean:
|
|
238
|
-
realv = v;
|
|
239
|
-
break;
|
|
240
|
-
case FieldType.Date:
|
|
241
|
-
if (Number.isInteger(v)) { //year
|
|
242
|
-
realv = (new Date(v, 0)).getTime();
|
|
243
|
-
} else {
|
|
244
|
-
realv = (new Date(v + "")).getTime();
|
|
245
|
-
}
|
|
246
|
-
this._dateMap.set(realv, v);
|
|
247
|
-
break;
|
|
248
|
-
case FieldType.String:
|
|
249
|
-
realv = v.toString();
|
|
250
|
-
break;
|
|
251
|
-
default:
|
|
252
|
-
realv = v;
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
row[f] = realv;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
export const MSCRowID = "mascot_rowId";export const MSCNodeID = "id";
|
|
263
|
-
|
package/src-new-ts/data/Tree.js
DELETED
package/src-new-ts/data/field.ts
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import * as d3 from "d3";
|
|
2
|
-
|
|
3
|
-
interface NodeTable {
|
|
4
|
-
hasField(field: string): boolean;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface Tree {
|
|
8
|
-
nodeTable: NodeTable;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface DataStructure {
|
|
12
|
-
name: string;
|
|
13
|
-
hasField(field: string): boolean;
|
|
14
|
-
tree?: Tree;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function validateField(field: string, dt: DataStructure): boolean {
|
|
18
|
-
if (dt.hasField(field))
|
|
19
|
-
return true;
|
|
20
|
-
else if (dt.tree && dt.tree.nodeTable.hasField(field.split(".")[1]))
|
|
21
|
-
return true;
|
|
22
|
-
else
|
|
23
|
-
throw new Error(`Field ${field} does not exist in the table ${dt.name}`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
export enum FieldType {
|
|
29
|
-
Boolean = 'Boolean',
|
|
30
|
-
Date = 'Date',
|
|
31
|
-
String = 'String',
|
|
32
|
-
Number = 'Number', // Assuming there's a case for Number based on the default case in summarize function
|
|
33
|
-
Integer= 'integer'
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
interface Summary {
|
|
37
|
-
trueCount?: number;
|
|
38
|
-
falseCount?: number;
|
|
39
|
-
min?: number | Date;
|
|
40
|
-
max?: number | Date;
|
|
41
|
-
extent?: [number | Date, number | Date];
|
|
42
|
-
mean?: number;
|
|
43
|
-
median?: number;
|
|
44
|
-
unique: Array<any>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export function inferType(values: any[]): FieldType {
|
|
48
|
-
let types = Object.values(FieldType) as string[];
|
|
49
|
-
for (let i = 0; i < values.length; i++) {
|
|
50
|
-
let v = values[i];
|
|
51
|
-
if (v == null) continue;
|
|
52
|
-
for (let j = 0; j < types.length; j++) {
|
|
53
|
-
// Casting the type to keyof typeof isValidType ensures that the string is considered a valid key of isValidType
|
|
54
|
-
const typeCheckKey = types[j] as keyof typeof isValidType;
|
|
55
|
-
if (!isValidType[typeCheckKey](v)) {
|
|
56
|
-
types.splice(j, 1);
|
|
57
|
-
j -= 1;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (types.length === 1) {
|
|
61
|
-
// Assuming the types array initially contains strings that are keys of the FieldType enum,
|
|
62
|
-
// we need to cast the return value back to FieldType for proper typing.
|
|
63
|
-
return FieldType[types[0] as keyof typeof FieldType];
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
// Returning the first element as FieldType after ensuring it's a valid key of the FieldType enum.
|
|
67
|
-
return FieldType[types[0] as keyof typeof FieldType];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
export const isValidType = {
|
|
72
|
-
boolean: function (x: any): boolean {
|
|
73
|
-
return x === 'true' || x === 'false' || x === true || x === false || Object.prototype.toString.call(x) == '[object Boolean]';
|
|
74
|
-
},
|
|
75
|
-
integer: function (x: any): boolean {
|
|
76
|
-
return isValidType.number(x) && (x = +x) === ~~x;
|
|
77
|
-
},
|
|
78
|
-
number: function (x: any): boolean {
|
|
79
|
-
return !isNaN(+x) && Object.prototype.toString.call(x) != '[object Date]';
|
|
80
|
-
},
|
|
81
|
-
date: function (x: any): boolean {
|
|
82
|
-
let d = new Date(x);
|
|
83
|
-
return d !== undefined && !isNaN(d.getTime());
|
|
84
|
-
},
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function summarize(values: Array<any>, type: FieldType): Summary {
|
|
88
|
-
let s: Summary = { unique: [] };
|
|
89
|
-
switch (type) {
|
|
90
|
-
case FieldType.Boolean:
|
|
91
|
-
s.trueCount = values.filter(d => d).length;
|
|
92
|
-
s.falseCount = values.filter(d => !d).length;
|
|
93
|
-
break;
|
|
94
|
-
case FieldType.Date:
|
|
95
|
-
// Assuming d3 methods are strongly typed elsewhere or using any as a fallback
|
|
96
|
-
s.min = d3.min(values) as Date;
|
|
97
|
-
s.max = d3.max(values) as Date;
|
|
98
|
-
s.extent = [s.min, s.max];
|
|
99
|
-
s.unique = [...new Set(values)];
|
|
100
|
-
break;
|
|
101
|
-
case FieldType.String:
|
|
102
|
-
s.unique = [...new Set(values)];
|
|
103
|
-
break;
|
|
104
|
-
default:
|
|
105
|
-
// Assuming these values are numbers for min, max, mean, and median calculations
|
|
106
|
-
s.min = d3.min(values) as number;
|
|
107
|
-
s.max = d3.max(values) as number;
|
|
108
|
-
s.extent = [s.min, s.max];
|
|
109
|
-
s.mean = d3.mean(values) as number;
|
|
110
|
-
s.median = d3.median(values) as number;
|
|
111
|
-
s.unique = [...new Set(values)];
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
return s;
|
|
115
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import * as d3 from "d3";
|
|
2
|
-
import DataTable from "./Table.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function makeRequest(method: string, url: string): Promise<string> {
|
|
6
|
-
return fetch(url, { method: method })
|
|
7
|
-
.then(response => {
|
|
8
|
-
if (!response.ok) { // if not (>= 200 and < 300)
|
|
9
|
-
console.log(response.status)
|
|
10
|
-
return Promise.reject({
|
|
11
|
-
status: response.status,
|
|
12
|
-
statusText: response.statusText
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
return response.text();
|
|
16
|
-
})
|
|
17
|
-
.catch(error => {
|
|
18
|
-
console.log(error);
|
|
19
|
-
return Promise.reject({
|
|
20
|
-
status: error.status || 0,
|
|
21
|
-
statusText: error.statusText || 'Unknown Error'
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export async function importCSV(url: string): Promise<DataTable> {
|
|
28
|
-
let data: string = await makeRequest("GET", url);
|
|
29
|
-
// Assuming d3.csvParse returns an array of objects with unknown shapes,
|
|
30
|
-
// and DataTable can accept this array directly.
|
|
31
|
-
let parsed = d3.csvParse(data.trim(), d3.autoType);
|
|
32
|
-
return new DataTable(parsed, url);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// export async function importTreejson(url) {
|
|
36
|
-
// let data = await makeRequest("GET", url);
|
|
37
|
-
// return new Tree(JSON.parse(data), url);
|
|
38
|
-
// }
|
|
39
|
-
|
|
40
|
-
// export async function importGraphjson(url) {
|
|
41
|
-
// let data = await makeRequest("GET", url);
|
|
42
|
-
// return new Network(JSON.parse(data), url);
|
|
43
|
-
// }
|
|
44
|
-
|
|
45
|
-
function validResponse(request: XMLHttpRequest): string | ArrayBuffer | null {
|
|
46
|
-
var type = request.responseType;
|
|
47
|
-
return type && type !== 'text' ?
|
|
48
|
-
request.response : // possibly ArrayBuffer or null on error
|
|
49
|
-
request.responseText; // string or '' on error
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export function csvSync(url: string, callback?: (data: DataTable) => void): DataTable | undefined {
|
|
54
|
-
let async = Boolean(callback);
|
|
55
|
-
var request = new XMLHttpRequest();
|
|
56
|
-
request.open('GET', url, async);
|
|
57
|
-
request.send();
|
|
58
|
-
if (!async) {
|
|
59
|
-
let response = validResponse(request);
|
|
60
|
-
// Type check to ensure response is a string before calling trim
|
|
61
|
-
if (typeof response === "string") {
|
|
62
|
-
let data = d3.csvParse(response.trim(), d3.autoType);
|
|
63
|
-
const dataTable = new DataTable(data, url);
|
|
64
|
-
if (callback) {
|
|
65
|
-
callback(dataTable);
|
|
66
|
-
}
|
|
67
|
-
return dataTable;
|
|
68
|
-
} else {
|
|
69
|
-
//TODO: throw errors based on response
|
|
70
|
-
throw new Error('Invalid response');
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
request.onload = () => {
|
|
74
|
-
let response = validResponse(request);
|
|
75
|
-
// Ensure onload, the response is treated as a string
|
|
76
|
-
if (typeof response === "string") {
|
|
77
|
-
let data = d3.csvParse(response.trim(), d3.autoType);
|
|
78
|
-
if (callback) {
|
|
79
|
-
callback(new DataTable(data, url));
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
//TODO: handle asynchronous errors
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function getFileName(url: string): string {
|
|
89
|
-
var startIndex = (url.indexOf('\\') >= 0 ? url.lastIndexOf('\\') : url.lastIndexOf('/'));
|
|
90
|
-
var filename = url.substring(startIndex);
|
|
91
|
-
if (filename.indexOf('\\') === 0 || filename.indexOf('/') === 0) {
|
|
92
|
-
filename = filename.substring(1);
|
|
93
|
-
}
|
|
94
|
-
return filename;
|
|
95
|
-
}
|
|
96
|
-
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
interface Predicate {
|
|
2
|
-
field?: string;
|
|
3
|
-
value?: any;
|
|
4
|
-
interval?: [number, number];
|
|
5
|
-
values?: any[];
|
|
6
|
-
channel?: string;
|
|
7
|
-
type?: string;
|
|
8
|
-
id?: string | number;
|
|
9
|
-
classId?: string | number;
|
|
10
|
-
fields?: string[];
|
|
11
|
-
operator?: '==' | '>' | '>=' | '<' | '<=';
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface Element {
|
|
15
|
-
dataScope?: {
|
|
16
|
-
getFieldValue: (field: string) => any;
|
|
17
|
-
hasField: (field: string) => boolean;
|
|
18
|
-
};
|
|
19
|
-
[key: string]: any; // For properties like 'type', 'id', 'classId', etc.
|
|
20
|
-
}
|
|
21
|
-
export function matchCriteria(cpnt: Element, predicates: Predicate[]): boolean {
|
|
22
|
-
for (let p of predicates) {
|
|
23
|
-
if (!evaluatePredicate(cpnt, p))
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function evaluatePredicate(elem: Element, p: Predicate): boolean {
|
|
30
|
-
// Example of using optional chaining (?.) and nullish coalescing (??)
|
|
31
|
-
if ("field" in p && p.field) { // Checking if 'field' is a property in 'p' and it's not null/undefined
|
|
32
|
-
const dataScope = elem.dataScope;
|
|
33
|
-
if (!dataScope) return false;
|
|
34
|
-
|
|
35
|
-
let f = p.field;
|
|
36
|
-
if ("value" in p) {
|
|
37
|
-
return dataScope.getFieldValue(f) === p.value;
|
|
38
|
-
} else if ("interval" in p && p.interval) {
|
|
39
|
-
let v = dataScope.getFieldValue(f);
|
|
40
|
-
return v >= p.interval[0] && v <= p.interval[1];
|
|
41
|
-
} else if ("values" in p && p.values) {
|
|
42
|
-
return p.values.includes(dataScope.getFieldValue(f));
|
|
43
|
-
} else {
|
|
44
|
-
return dataScope.hasField(f);
|
|
45
|
-
}
|
|
46
|
-
} else if ("channel" in p && p.channel) {
|
|
47
|
-
let c = p.channel;
|
|
48
|
-
let elemValue = elem[c]; // Direct access since 'c' is now guaranteed to be a property in 'elem'
|
|
49
|
-
if ("value" in p) {
|
|
50
|
-
return elemValue === p.value;
|
|
51
|
-
} else if ("interval" in p && p.interval) {
|
|
52
|
-
return elemValue >= p.interval[0] && elemValue <= p.interval[1];
|
|
53
|
-
} else if ("values" in p && p.values) {
|
|
54
|
-
return p.values.includes(elemValue);
|
|
55
|
-
}
|
|
56
|
-
} else if ("type" in p) {
|
|
57
|
-
return elem.type === p.type;
|
|
58
|
-
} else if ("id" in p) {
|
|
59
|
-
return elem.id === p.id;
|
|
60
|
-
} else if ("classId" in p) {
|
|
61
|
-
return elem.classId === p.classId;
|
|
62
|
-
} else if ("fields" in p && p.fields && p.operator) {
|
|
63
|
-
if (!elem.dataScope) return false;
|
|
64
|
-
let [f1, f2] = p.fields;
|
|
65
|
-
let v1 = elem.dataScope.getFieldValue(f1), v2 = elem.dataScope.getFieldValue(f2);
|
|
66
|
-
switch (p.operator) {
|
|
67
|
-
case "==":
|
|
68
|
-
return v1 == v2;
|
|
69
|
-
case ">":
|
|
70
|
-
return v1 > v2;
|
|
71
|
-
case ">=":
|
|
72
|
-
return v1 >= v2;
|
|
73
|
-
case "<":
|
|
74
|
-
return v1 < v2;
|
|
75
|
-
case "<=":
|
|
76
|
-
return v1 <= v2;
|
|
77
|
-
default:
|
|
78
|
-
return false; // Handling the default case if the operator doesn't match
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return false;
|
|
82
|
-
}
|