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.
- package/package.json +1 -2
- 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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mascot-vis",
|
|
3
|
-
"version": "3.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
|
-
}
|
package/src-new-ts/data/Scope.js
DELETED
|
@@ -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
|
-
}
|