mascot-vis 3.0.0 → 3.0.1

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.
Files changed (152) hide show
  1. package/package.json +1 -2
  2. package/js/depGraphVis.js +0 -66
  3. package/src-new-ts/action/createElement.ts +0 -91
  4. package/src-new-ts/action/encode.js +0 -20
  5. package/src-new-ts/action/repeat.js +0 -128
  6. package/src-new-ts/action/traverseScene.js +0 -41
  7. package/src-new-ts/data/Network.js +0 -2
  8. package/src-new-ts/data/Scope.js +0 -135
  9. package/src-new-ts/data/Table.js +0 -263
  10. package/src-new-ts/data/Tree.js +0 -3
  11. package/src-new-ts/data/field.ts +0 -115
  12. package/src-new-ts/data/import.ts +0 -96
  13. package/src-new-ts/data/predicate.ts +0 -82
  14. package/src-new-ts/depgraph/DepGraph.js +0 -178
  15. package/src-new-ts/depgraph/Edge.js +0 -9
  16. package/src-new-ts/depgraph/SceneGraph2DepGraph.js +0 -110
  17. package/src-new-ts/depgraph/Signal.js +0 -12
  18. package/src-new-ts/depgraph/operator/BoundsEvaluator.js +0 -30
  19. package/src-new-ts/depgraph/operator/Dataflow.js +0 -41
  20. package/src-new-ts/depgraph/operator/DomainBuilder.js +0 -50
  21. package/src-new-ts/depgraph/updateDepGraph.js +0 -45
  22. package/src-new-ts/depgraph/variable/BoundsVar.js +0 -81
  23. package/src-new-ts/depgraph/variable/ChannelVar.js +0 -17
  24. package/src-new-ts/depgraph/variable/DataScopeVar.js +0 -12
  25. package/src-new-ts/depgraph/variable/DomainVar.js +0 -15
  26. package/src-new-ts/depgraph/variable/FieldVar.js +0 -17
  27. package/src-new-ts/depgraph/variable/LayoutParameter.js +0 -8
  28. package/src-new-ts/depgraph/variable/ScaleVar.js +0 -13
  29. package/src-new-ts/depgraph/variable/Variable.js +0 -39
  30. package/src-new-ts/element/gradient/LinearGradient.js +0 -37
  31. package/src-new-ts/element/group/Collection.js +0 -109
  32. package/src-new-ts/element/group/Group.js +0 -307
  33. package/src-new-ts/element/group/Scene.js +0 -98
  34. package/src-new-ts/element/mark/CircleMark.ts +0 -85
  35. package/src-new-ts/element/mark/Mark.ts +0 -233
  36. package/src-new-ts/element/mark/PathMark.js +0 -483
  37. package/src-new-ts/element/mark/Segment.js +0 -29
  38. package/src-new-ts/element/mark/Vertex.js +0 -118
  39. package/src-new-ts/encode/Scale.ts +0 -115
  40. package/src-new-ts/index.ts +0 -19
  41. package/src-new-ts/layout/Layout.ts +0 -3
  42. package/src-new-ts/render/CanvasRenderer.ts +0 -24
  43. package/src-new-ts/render/SVGRenderer.js +0 -316
  44. package/src-new-ts/util.ts +0 -3
  45. package/src-old/action/Classify.js +0 -53
  46. package/src-old/action/Densify.js +0 -199
  47. package/src-old/action/Partition.js +0 -531
  48. package/src-old/action/Repeat.js +0 -106
  49. package/src-old/action/Repopulate.js +0 -44
  50. package/src-old/action/Stratify.js +0 -156
  51. package/src-old/basic/Gradient.js +0 -37
  52. package/src-old/basic/Point.js +0 -51
  53. package/src-old/basic/Rectangle.js +0 -63
  54. package/src-old/bind/bindToAngle.js +0 -56
  55. package/src-old/bind/bindToAreaMark.js +0 -360
  56. package/src-old/bind/bindToColor.js +0 -114
  57. package/src-old/bind/bindToLink.js +0 -81
  58. package/src-old/bind/bindToPosition.js +0 -283
  59. package/src-old/bind/bindToRadialDistance.js +0 -62
  60. package/src-old/bind/bindToSize.js +0 -235
  61. package/src-old/bind/bindToText.js +0 -60
  62. package/src-old/bind/bindToThickness.js +0 -100
  63. package/src-old/constraint/AffixConstraint.js +0 -129
  64. package/src-old/constraint/AlignConstraint.js +0 -58
  65. package/src-old/core/Encoding.js +0 -336
  66. package/src-old/core/Scale.js +0 -322
  67. package/src-old/core/SceneLoader.js +0 -290
  68. package/src-old/core/SceneValidator.js +0 -232
  69. package/src-old/core/SpecExecutor.js +0 -113
  70. package/src-old/core/SpecGenerator.js +0 -350
  71. package/src-old/data/DataImporter.js +0 -64
  72. package/src-old/data/DataScope.js +0 -124
  73. package/src-old/data/DataTable.js +0 -338
  74. package/src-old/data/Network.js +0 -106
  75. package/src-old/data/Tree.js +0 -251
  76. package/src-old/data/transform/Bin.js +0 -46
  77. package/src-old/data/transform/Filter.js +0 -48
  78. package/src-old/data/transform/Groupby.js +0 -18
  79. package/src-old/data/transform/KDE.js +0 -58
  80. package/src-old/data/transform/Sort.js +0 -14
  81. package/src-old/data/transform/Split.js +0 -5
  82. package/src-old/data/transform/partition.js +0 -46
  83. package/src-old/history/UndoRedoStack +0 -0
  84. package/src-old/index.js +0 -271
  85. package/src-old/indexSVG.js +0 -259
  86. package/src-old/interaction/Interaction.js +0 -91
  87. package/src-old/interaction/MouseEvent.js +0 -8
  88. package/src-old/interaction/Selection.js +0 -9
  89. package/src-old/interaction/brush.js +0 -362
  90. package/src-old/item/Segment.js +0 -29
  91. package/src-old/item/Vertex.js +0 -118
  92. package/src-old/item/composite/Collection.js +0 -106
  93. package/src-old/item/composite/Glyph.js +0 -19
  94. package/src-old/item/composite/Group.js +0 -310
  95. package/src-old/item/composite/Scene.js +0 -1251
  96. package/src-old/item/mark/ArcPath.js +0 -181
  97. package/src-old/item/mark/AreaPath.js +0 -78
  98. package/src-old/item/mark/CirclePath.js +0 -102
  99. package/src-old/item/mark/EllipsePath.js +0 -5
  100. package/src-old/item/mark/Image.js +0 -101
  101. package/src-old/item/mark/LinkPath.js +0 -118
  102. package/src-old/item/mark/Mark.js +0 -163
  103. package/src-old/item/mark/Path.js +0 -494
  104. package/src-old/item/mark/PointText.js +0 -201
  105. package/src-old/item/mark/PolygonPath.js +0 -64
  106. package/src-old/item/mark/RectPath.js +0 -88
  107. package/src-old/item/mark/RingPath.js +0 -92
  108. package/src-old/item/refs/Axis.js +0 -362
  109. package/src-old/item/refs/EncodingAxis.js +0 -515
  110. package/src-old/item/refs/Gridlines.js +0 -144
  111. package/src-old/item/refs/LayoutAxis.js +0 -316
  112. package/src-old/item/refs/Legend.js +0 -273
  113. package/src-old/layout/Circular.js +0 -95
  114. package/src-old/layout/Force.js +0 -52
  115. package/src-old/layout/Grid.js +0 -423
  116. package/src-old/layout/Layout.js +0 -13
  117. package/src-old/layout/Packing.js +0 -56
  118. package/src-old/layout/Stack.js +0 -264
  119. package/src-old/layout/Strata.js +0 -88
  120. package/src-old/layout/Sugiyama.js +0 -59
  121. package/src-old/layout/TidyTree.js +0 -105
  122. package/src-old/layout/Treemap.js +0 -87
  123. package/src-old/renderer/SVGInteractionHandler.js +0 -241
  124. package/src-old/renderer/SVGRenderer.js +0 -325
  125. package/src-old/renderer/WebGLRenderer.js +0 -1097
  126. package/src-old/renderer/WebGLRenderer2.js +0 -249
  127. package/src-old/renderer/threejs/Line2.js +0 -18
  128. package/src-old/renderer/threejs/LineGeometry.js +0 -77
  129. package/src-old/renderer/threejs/LineMaterial.js +0 -605
  130. package/src-old/renderer/threejs/LineSegments2.js +0 -281
  131. package/src-old/renderer/threejs/LineSegmentsGeometry.js +0 -226
  132. package/src-old/renderer/threejs/Wireframe.js +0 -51
  133. package/src-old/renderer/threejs/WireframeGeometry2.js +0 -16
  134. package/src-old/scale/areaSize.js +0 -0
  135. package/src-old/scale/domain.js +0 -38
  136. package/src-old/util/Constants.js +0 -180
  137. package/src-old/util/DataUtil.js +0 -35
  138. package/src-old/util/ItemUtil.js +0 -586
  139. package/src-old/util/Numerical.js +0 -33
  140. package/tests/demo-tests/README.md +0 -80
  141. package/tests/demo-tests/SVG2PNG.js +0 -56
  142. package/tests/demo-tests/demos2CanvasPNGs.js +0 -69
  143. package/tests/demo-tests/demos2ScenesSVGs.js +0 -100
  144. package/tests/demo-tests/pathElementWorker.js +0 -91
  145. package/tests/demo-tests/pixelTest.js +0 -62
  146. package/tests/demo-tests/renderDemos.html +0 -132
  147. package/tests/demo-tests/serializationTest.js +0 -36
  148. package/tests/demo-tests/serializeDemos.html +0 -134
  149. package/tests/unit-tests/README.md +0 -4
  150. package/tests/unit-tests/jasmine-browser.json +0 -21
  151. package/tests/unit-tests/jasmine.json +0 -14
  152. package/tests/unit-tests/testSpec.js +0 -274
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mascot-vis",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "Manipulable Semantic Components in Data Visualization",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,7 +28,6 @@
28
28
  "csv-parser": "^3.0.0",
29
29
  "d3": "^7.9.0",
30
30
  "jsdom": "^22.1.0",
31
- "mascot-vis": "^2.1.0",
32
31
  "pixi.js": "6.0.4",
33
32
  "svelte-jsoneditor": "^0.3.58"
34
33
  },
package/js/depGraphVis.js DELETED
@@ -1,66 +0,0 @@
1
- function visualizeDepGraph(dg) {
2
- var g = new dagre.graphlib.Graph();
3
- g.setGraph({});
4
- g.setDefaultEdgeLabel(function() { return {}; });
5
- g.graph().rankdir = "LR";
6
-
7
- setupGraph(g, dg);
8
- dagre.layout(g);
9
- renderDepGraph(g);
10
- }
11
-
12
- function renderDepGraph(g) {
13
- document.getElementById("depGraphVis").style.visibility = "visible";
14
- let svg = d3.select("#depGraphVis");
15
- svg.selectAll("*").remove();
16
-
17
- svg.selectAll("path").data(g.edges()).enter().append("path")
18
- .attr("d", e => getPathData(g.node(e.v), g.edge(e).points, g.node(e.w))).style("stroke", "#ccc").style("fill", "none");
19
-
20
- svg.selectAll("rect").data(g.nodes()).enter().append("rect")
21
- .attr("x", d => g.node(d).x - g.node(d).width/2).attr("y", d => g.node(d).y - g.node(d).height/2)
22
- .attr("width", d => g.node(d).width).attr("height", d => g.node(d).height)
23
- .style("stroke", "#ccc").style("fill", d => g.node(d).type == "op" ? "yellow" : "white");
24
-
25
- svg.selectAll("text").data(g.nodes()).enter().append("text")
26
- .attr("x", d => g.node(d).x - g.node(d).width/2).attr("y", d => g.node(d).y + g.node(d).height/2).text(d => g.node(d).label);
27
-
28
- let bbox = svg.node().getBBox(),
29
- vb = [bbox.x - 10, bbox.y - 10, bbox.width + 20, bbox.height + 20];
30
- svg.attr("viewBox", vb.join(" "));
31
- }
32
-
33
- function getPathData(source, points, target) {
34
- let str = "M " + source.x + " " + source.y;
35
- //"M " + points[0].x + " " + points[0].y;
36
- for (let i = 0; i < points.length; i++)
37
- str += " L " + points[i].x + " " + points[i].y;
38
- str += " L " + target.x + " " + target.y;
39
- return str;
40
- }
41
-
42
- function setupGraph(g, dg) {
43
- let temp = d3.select("#depGraphVis").append("text");
44
- for (let varType in dg._variables) {
45
- for (let varId in dg._variables[varType]) {
46
- let v = dg._variables[varType][varId],
47
- label = v.channel ? v.channel : varType;
48
- label += v.element ? ": " + v.element.type : "";
49
- temp.text(label);
50
- g.setNode(varId, {type: "var", label: label, width: temp.node().getBBox().width, height: temp.node().getBBox().height});
51
- }
52
- }
53
-
54
- for (let opType in dg._operators) {
55
- for (let opId in dg._operators[opType]) {
56
- let v = dg._operators[opType][opId],
57
- label = opType;
58
- temp.text(label);
59
- g.setNode(opId, {type: "op", label: label, width: temp.node().getBBox().width, height: temp.node().getBBox().height});
60
- }
61
- }
62
-
63
- for (let e of dg._edges) {
64
- g.setEdge(e.fromNode.id, e.toNode.id);
65
- }
66
- }
@@ -1,91 +0,0 @@
1
- // Assuming Collection.ts exists with a default export of Collection class
2
- import Collection from "../element/group/Collection";
3
- // Assuming Circle.ts exists with a default export of Circle class
4
- import Circle from "../element/mark/CircleMark";
5
- import Mark, {MarkArgs} from "../element/mark/Mark";
6
-
7
-
8
-
9
-
10
- // Updated to use TypeScript syntax for function parameter types
11
- export function duplicateMark(mark: Mark): Mark | null {
12
- let m = createMark({ type: mark.type });
13
- if (m === null) {
14
- // Handle the case where m is null, possibly by returning null or throwing an error
15
- console.error("Failed to create a mark of type", mark.type);
16
- return null; // or throw new Error("Failed to create a mark.");
17
- }
18
-
19
- mark.copyPropertiesTo(m);
20
- m.classId = mark.classId;
21
- if (mark.dataScope) {
22
- // Ensure m is not null before accessing its properties
23
- m.dataScope = mark.dataScope.clone();
24
- }
25
- return m;
26
- }
27
-
28
- // Ensure args conforms to the MarkArgs interface
29
- export function createMark(args: MarkArgs) {
30
- let m: Mark | null = null;
31
- switch (args.type) {
32
- case ElementType.Circle:
33
- m = new Circle(args);
34
- break;
35
- default:
36
- break;
37
- }
38
- return m;
39
- }
40
-
41
- // Define a type for the `scene` parameter
42
- interface Scene {
43
- addChild(child: Collection): void;
44
- _itemMap: { [id: string]: Collection };
45
- }
46
-
47
- export function createCollection(scene: Scene) {
48
- let c = new Collection();
49
- scene.addChild(c);
50
- scene._itemMap[c.id] = c;
51
- return c;
52
- }
53
-
54
- // Using enum for PrimitiveMark
55
- export enum PrimitiveMark {
56
- Rect = "rect",
57
- Circle = "circle",
58
- Line = "line",
59
- Ring = "ring",
60
- Path = "path",
61
- Image = "image",
62
- PointText = "pointText"
63
- }
64
-
65
- // Using enum for ElementType
66
- export enum ElementType {
67
- Mark = "Mark",
68
- Area = "Area",
69
- Rect = "Rect",
70
- Ellipse = "Ellipse",
71
- Circle = "Circle",
72
- Pie = "Pie",
73
- Ring = "Ring",
74
- Arc = "Arc",
75
- Line = "Line",
76
- Path = "Path",
77
- Image = "Image",
78
- PointText = "PointText",
79
- Collection = "Collection",
80
- Group = "Group",
81
- Scene = "Scene",
82
- Axis = "Axis",
83
- Glyph = "Glyph",
84
- Legend = "Legend",
85
- Polygon = "Polygon",
86
- Gridlines = "Gridlines",
87
- LinearGradient = "LinearGradient",
88
- Link = "Link",
89
- DataTable = "Datatable",
90
- Layout = "Layout"
91
- };
@@ -1,20 +0,0 @@
1
- /**
2
- refer to validateRepeatArguments in action/repeat.js as well as
3
- _validateEncodeArgs in src/item/group/Scene.js as examples
4
- */
5
- export function validateEncodeArguments(elem, param) {
6
- //the elem should have a data scope
7
- //the param should have a field and a channel
8
- if (!elem || !("channel" in param) || !("field" in param)) {
9
- throw new Error("Incomplete information to do repeat. You must specify an item, a categorical data field and a data table");
10
- }
11
- //the field should be a valid column name in the elem's data scope
12
- let datatable = elem.dataScope && elem.dataScope.dataTable;
13
- if (!datatable || !datatable.hasField(param.field)) {
14
- throw new Error("Data field does not exist in the data table");
15
- }
16
- //the channel should be a valid channel for the given elem
17
- if (!["x", "y", "fillColor"].includes(param.channel)) {
18
- throw new Error("Channel Not Supported");
19
- }
20
- }
@@ -1,128 +0,0 @@
1
- import DataScope from "../data/Scope.js";
2
- import DataTable, { MSCRowID } from "../data/Table.js";
3
- import { FieldType, validateField } from "../data/field.js";
4
- import { MSCNodeID } from "../data/Table.js";
5
- import { ElementType } from "./createElement.js";
6
- import { isMark } from "../element/mark/Mark.js";
7
- import { createCollection } from "./createElement.js";
8
- import Tree from "../data/Tree.js";
9
- import Network from "../data/Network.js";
10
- import Layout from "../layout/Layout.js";
11
- import { duplicateMark } from "./createElement.js";
12
-
13
- export function validateRepeatArguments(elem, data, param) {
14
- if (!elem || data === undefined) {
15
- throw new Error("Incomplete information to do repeat. You must specify an item, a categorical data field and a data table");
16
- }
17
-
18
- if (data instanceof Tree || data instanceof Network) {
19
- if (!Array.isArray(elem) || elem.length !== 2)
20
- throw new Error("To repeat with a tree or a network, you need to provide two marks, one for node and one for link");
21
- } else if (data instanceof DataTable) {
22
- validateField(param["field"], data);
23
- }
24
-
25
- if (param.layout && !(param.layout instanceof Layout)) {
26
- throw new Error("Invalid layout: " + param.layout);
27
- }
28
- }
29
-
30
- export function repeatable(obj) {
31
- if (Array.isArray(obj)) {
32
- if (obj.length === 1) {
33
- return elementRepeatable(obj[0]);
34
- } else {
35
- for (let c of obj) {
36
- if (!isMark(c) || c.dataScope)
37
- return false;
38
- }
39
- }
40
- return true;
41
- } else {
42
- return elementRepeatable(obj);
43
- }
44
- }
45
-
46
- export function elementRepeatable(elem) {
47
- if ((isMark(elem) || elem.type == ElementType.Glyph) && !elem.dataScope)
48
- return true;
49
- else if (elem.type === ElementType.Collection)
50
- return elem.firstChild.dataScope.numTuples > 1;
51
- return false;
52
- }
53
-
54
- export function repeatElement(scene, elem, field, datatable) {
55
- let type = datatable.getFieldType(field);
56
-
57
- if (type != FieldType.String && type != FieldType.Date && type != FieldType.Integer) {
58
- throw new Error("Repeat only works on a string or date field: " + field + " is " + type);
59
- }
60
-
61
- if (!repeatable(elem)) {
62
- throw new Error("The " + elem.type + " is not repeatable");
63
- }
64
-
65
- return _doRepeat(scene, elem, field, datatable);
66
- }
67
-
68
- function _doRepeat(scene, elem, field, datatable) {
69
- let ds = datatable.getFieldSummary(field).unique.map(d => elem.dataScope ? elem.dataScope.cross(field, d) : new DataScope(datatable).cross(field, d));
70
- ds = ds.filter(d => !d.isEmpty());
71
- let coll = createCollection(scene);
72
- coll.dataScope = elem.dataScope ? elem.dataScope.clone() : new DataScope(datatable);
73
-
74
- coll.addChild(elem);
75
-
76
- for (let i = 1; i < ds.length; i++) {
77
- let c = duplicateMark(elem);
78
- coll.addChild(c);
79
- }
80
-
81
- coll.children.forEach((d, i) => d.dataScope = ds[i]);
82
- //TODO: turn the folllwing into getter and setter
83
- // if (!scene.cellAlign.hasOwnProperty(compnt.classId)) {
84
- // scene.cellAlign[compnt.classId] = {x: Alignment.Left, y: Alignment.Bottom};
85
- // }
86
- //scene._reapplySizeBindings(elem);
87
- return coll;
88
- }
89
-
90
- export function repeatNodeLink(scene, node, link, data) {
91
- let nodeDS = data.nodeTable.getFieldSummary(MSCNodeID).unique.map(d => node.dataScope ? node.dataScope.cross(MSCNodeID, d) : new DataScope(data.nodeTable).cross(MSCNodeID, d));
92
- let linkColl = scene.collection(), nodeColl = scene.collection(), id2node = {};
93
- nodeColl.dataScope = node.dataScope ? node.dataScope.clone() : new (data.nodeTable);
94
-
95
- //do not initialize classId here, initialize in scene.mark/glyph/new Collection()
96
- // compnt.classId = compnt.id;
97
- nodeColl.addChild(node);
98
- for (let i = 1; i < nodeDS.length; i++) {
99
- let c = node.duplicate();
100
- nodeColl.addChild(c);
101
- }
102
-
103
- nodeColl.children.forEach((d, i) => {
104
- d.dataScope = nodeDS[i];
105
- id2node[d.dataScope.getFieldValue(MSCNodeID)] = d;
106
- });
107
-
108
- let linkDS = data.linkTable.getFieldSummary(MSCRowID).unique.map(d => link.dataScope ? link.dataScope.cross(MSCRowID, d) : new DataScope(data.linkTable).cross(MSCRowID, d));
109
- linkColl.dataScope = link.dataScope ? link.dataScope.clone() : new DataScope(data.linkTable);
110
-
111
- linkColl.addChild(link);
112
- for (let i = 1; i < linkDS.length; i++) {
113
- let c = link.duplicate();
114
- linkColl.addChild(c);
115
- }
116
-
117
- linkColl.children.forEach((d, i) => d.dataScope = linkDS[i]);
118
- let s = data.type === "tree" ? "parent" : "source", t = data.type === "tree" ? "child" : "target";
119
- for (let l of linkColl.children) {
120
- let sid = l.dataScope.getFieldValue(s),
121
- tid = l.dataScope.getFieldValue(t);
122
- l.source = id2node[sid];
123
- l.target = id2node[tid];
124
- l._updateBounds();
125
- }
126
-
127
- return [nodeColl, linkColl];
128
- }
@@ -1,41 +0,0 @@
1
- import { matchCriteria } from "../data/predicate.js";
2
- import { ElementType } from "./createElement.js";
3
-
4
- export function getPeers(elem) {
5
- let scene = getScene(elem);
6
- return elem.classId ? findItems(scene, [{ "classId": elem.classId }]) : [];
7
- }
8
-
9
- export function findItems(container, predicates) {
10
- let result = [];
11
- findItemsRecursive(container, predicates, result);
12
- return result;
13
- }
14
-
15
- function findItemsRecursive(itm, predicates, result) {
16
- if (!itm) return;
17
- if (itm.type == "axis" || itm.type == "legend" || itm.type == "gridlines") return;
18
- if (matchCriteria(itm, predicates)) {
19
- result.push(itm);
20
- }
21
-
22
- if (itm.vertices) {
23
- for (let i of itm.vertices.concat(itm.segments)) {
24
- if (matchCriteria(i, predicates))
25
- result.push(i);
26
- }
27
- } else if (itm.children && itm.children.length > 0) {
28
- for (let c of itm.children)
29
- findItemsRecursive(c, predicates, result);
30
- }
31
- }
32
-
33
- export function getScene(elem) {
34
- let p = elem;
35
- while (p) {
36
- if (p.type == ElementType.Scene)
37
- return p;
38
- else
39
- p = p.parent;
40
- }
41
- }
@@ -1,2 +0,0 @@
1
- export default class Network {
2
- }
@@ -1,135 +0,0 @@
1
- import * as d3 from 'd3';
2
- import { MSCRowID } from './Table.js';
3
-
4
- export default class DataScope {
5
-
6
- constructor(datatable) {
7
- this._field2value = {};
8
- this._dt = datatable;
9
- this._tuples = this._dt.data;
10
- }
11
-
12
- toJSON() {
13
- let json = {};
14
- json.dt = this._dt.id;
15
- json.f2v = Object.assign({}, this._field2value);
16
- json.tuples = this._tuples.map(d => parseInt(d[MSCRowID].substring(1)));
17
- return json;
18
- }
19
-
20
- isFullTable() {
21
- return Object.keys(this._field2value).length === 0;
22
- }
23
-
24
- isEmpty() {
25
- return this._tuples.length == 0;
26
- }
27
-
28
- get numTuples() {
29
- return this._tuples.length;
30
- }
31
-
32
- get fields() {
33
- return Object.keys(this._field2value);
34
- }
35
-
36
- get dataTable() {
37
- return this._dt;
38
- }
39
-
40
- get filters() {
41
- return this._field2value;
42
- }
43
-
44
- merge(ds) {
45
- let r = new DataScope(this._dt);
46
- for (let field in ds._field2value) {
47
- r = r.cross(field, ds._field2value[field]);
48
- }
49
- for (let field in this._field2value) {
50
- r = r.cross(field, this._field2value[field]);
51
- }
52
- return r;
53
- }
54
-
55
- cross(field, value) {
56
- let ds = this.clone();
57
- ds._field2value[field] = value;
58
- ds._updateTuples(field, value);
59
- return ds;
60
- }
61
-
62
- clone() {
63
- let ds = new DataScope(this._dt);
64
- ds._field2value = Object.assign({}, this._field2value);
65
- ds._tuples = this._tuples.map(d => d);
66
- return ds;
67
- }
68
-
69
- getFieldValue(field) {
70
- let values = this._tuples.map(d => d[field]);
71
- values = [...new Set(values)];
72
- if (values.length > 1) {
73
- //throw new Error(Errors.MULTIPLE_VALUES_PER_FIELD);
74
- //TODO: how to handle this?
75
- }
76
- return values[0];
77
- }
78
-
79
- getUniqueFieldValues(field) {
80
- let values = this._tuples.map(d => d[field]);
81
- return [...new Set(values)];
82
- }
83
-
84
- hasField(field) {
85
- return (field in this._field2value);
86
- }
87
-
88
- getFieldType(field) {
89
- return this._dt.getFieldType(field);
90
- }
91
-
92
- aggregateNumericalField(field, aggregator) {
93
- let values = this._tuples.map(d => d[field]);
94
- switch (aggregator) {
95
- case Aggregator.Max:
96
- return Math.max(...values);
97
- case Aggregator.Min:
98
- return Math.min(...values);
99
- case Aggregator.Avg:
100
- case Aggregator.Mean:
101
- return d3.mean(values);
102
- case Aggregator.Median:
103
- return d3.median(values);
104
- case Aggregator.Count:
105
- return values.length;
106
- case Aggregator.Percentile25:
107
- return d3.quantile(values, 0.25);
108
- case Aggregator.Percentile75:
109
- return d3.quantile(values, 0.75);
110
- case Aggregator.Sum:
111
- default:
112
- return d3.sum(values);
113
- }
114
- }
115
-
116
- _updateTuples(field, value) {
117
- this._tuples = this._tuples.filter(d => d[field] == value);
118
- }
119
-
120
- get tuples() {
121
- return this._tuples;
122
- }
123
- }
124
-
125
- export const Aggregator = {
126
- Max: "max",
127
- Min: "min",
128
- Avg: "avg",
129
- Median: "median",
130
- Sum: "sum",
131
- Count: "count",
132
- Mean: "mean",
133
- Percentile25: "percentile 25",
134
- Percentile75: "percentile 75"
135
- }