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
@@ -1,100 +0,0 @@
1
- /**
2
- * Binding data to thickness for arcs and rings
3
- */
4
- import {DataType} from "../util/Constants";
5
- import ArcPath from "../item/mark/ArcPath";
6
- import Scale from "../core/Scale";
7
-
8
- function addToTree(node, arc) {
9
- let itm = node.item;
10
- if (arc.innerRadius === itm.outerRadius && itm.sweepOver(arc)) {
11
- node.children.push({item: arc, children: []});
12
- return;
13
- } else if (node.children && node.children.length > 0 && arc.innerRadius > itm.outerRadius && itm.sweepOver(arc)) {
14
- for (let c of node.children)
15
- addToTree(c, arc);
16
- }
17
- }
18
-
19
- function accumulateThickness(node, offset, data, scale) {
20
- let itm = node.item;
21
- itm.innerRadius = offset;
22
- itm.outerRadius = offset + scale.map(data[itm.id]);
23
- if (node.children && node.children.length > 0) {
24
- for (let c of node.children) {
25
- accumulateThickness(c, itm.outerRadius, data, scale);
26
- }
27
- }
28
- }
29
-
30
- export function bindToThickness(encoding){
31
-
32
- encoding._query = function() {
33
- this.data = {};
34
-
35
- let field = this.field, items = this.items;
36
- let dataScopes = items.map(d => d.dataScope);
37
-
38
- switch (this.datatable.getFieldType(field)) {
39
- case DataType.Boolean:
40
- break;
41
-
42
- case DataType.Date:
43
- for (let i = 0; i < items.length; i++) {
44
- this.data[items[i].id] = dataScopes[i].getFieldValue(field);
45
- }
46
- //this.data = dataScopes.map(d => d.getFieldValue(field));
47
- break;
48
-
49
- case DataType.String:
50
- try {
51
- for (let i = 0; i < items.length; i++) {
52
- this.data[items[i].id] = dataScopes[i].getFieldValue(field);
53
- }
54
- //this.data = dataScopes.map(d => d.getFieldValue(field));
55
- } catch (error) {
56
- throw new Error("Cannot bind " + this.channel + " to " + field + " : " + error);
57
- }
58
- break;
59
-
60
- default: //integer or number
61
- for (let i = 0; i < items.length; i++) {
62
- this.data[items[i].id] = dataScopes[i].aggregateNumericalField(field, this.aggregator);
63
- }
64
- //this.data = dataScopes.map(d => d.aggregateNumericalField(field, this.aggregator));
65
- break;
66
- }
67
- }
68
-
69
- encoding._map = function() {
70
- let data = this.data;
71
- if (!this.scale){
72
- this.scale = new Scale(this.scaleType);
73
- this.scale.domain = [0, Math.max(...Object.values(data))];
74
- let min = 1, max = this.rangeExtent ? min + this.rangeExtent : Math.max(...(this.items.map(d => d.outerRadius)));
75
- this.scale._setRange([min, max]);
76
- }
77
- this.scale._addEncoding(this);
78
- }
79
-
80
-
81
-
82
- encoding._apply = function() {
83
- //sort items by centroid
84
- this.items.sort((a, b) => (a.innerRadius+a.outerRadius)/2 - (b.innerRadius+b.outerRadius)/2);
85
- let outer = Math.min(...this.items.map(d => d.innerRadius));
86
- let tree = {item: new ArcPath({outerRadius: outer, startAngle: 0, endAngle: 360}), children: []};
87
- for (let itm of this.items) {
88
- addToTree(tree, itm);
89
- }
90
-
91
- for (let node of tree.children)
92
- accumulateThickness(node, node.item.innerRadius, this.data, this.scale);
93
-
94
- // //relayout if needed
95
- // this.scene._relayoutAncestors(this.anyItem, this.items);
96
- }
97
-
98
- encoding.run();
99
- return encoding;
100
- }
@@ -1,129 +0,0 @@
1
- import { ConstraintType, ItemType } from "../util/Constants";
2
- import { getPeers } from "../util/ItemUtil";
3
-
4
- export default class AffixConstraint {
5
-
6
- constructor(item, baseItem, scene, channel, itemAnchor, baseAnchor, offset) {
7
- this.item = item;
8
- this.baseItem = baseItem;
9
- this.scene = scene;
10
- this.channel = channel;
11
- this.itemAnchor = itemAnchor;
12
- this.baseAnchor = baseAnchor;
13
- this.offset = offset;
14
- this.type = ConstraintType.Affix;
15
- this.id = this.type + "_" + this.item.classId + "_" + this.baseItem.classId + "_" + channel;
16
- }
17
-
18
- apply() {
19
- let items = getPeers(this.item, this.scene), baseItems = getPeers(this.baseItem, this.scene);
20
- //console.log(items.map(d => d.text), baseItems.map(d => d.dataScope.getFieldValue("event_attribute")));
21
- let ia = this.itemAnchor,
22
- ba = this.baseAnchor;
23
-
24
- let isText = this.item.type == ItemType.PointText ? true : false;
25
- if (this.channel == "radialDistance") {
26
- for (let i = 0; i < items.length; i++) {
27
- let dist, base = baseItems[i], item = items[i];
28
- if (base.type == ItemType.Arc || base.type == ItemType.Ring)
29
- dist = ba == "top" ? base.outerRadius + this.offset : ba == "bottom" ? base.innerRadius + this.offset : (base.outerRadius + base.innerRadius)/2 + this.offset;
30
- else if (base.type == ItemType.Circle)
31
- dist = ba == "top" ? base.radius + this.offset : ba == "bottom" ? this.offset : base.radius/2 + this.offset;
32
- item._doTranslate( base.x - item.x, base.y - dist - item.bounds[ia] );
33
- if (item._rotate) {
34
- item._rotate = [item._rotate[0], base.x, base.y];
35
- } else {
36
- item._rotate = [0, base.x, base.y];
37
- }
38
- }
39
- } else if (this.channel == "angle") {
40
- for (let i = 0; i < items.length; i++) {
41
- let angle, base = baseItems[i], item = items[i];
42
- if (base.type == ItemType.Arc) {
43
- angle = ba == "left" ? base.endAngle + this.offset : ba == "center" ? base.startAngle + base.angle/2 + this.offset : base.startAngle + this.offset;
44
- } else {
45
- angle = 90;
46
- }
47
- // switch (ba) {
48
- // case "left":
49
- // angle = base.endAngle ? base.endAngle + this.offset : 90;
50
- // break;
51
- // case "center":
52
- // angle = base.startAngle ? base.startAngle + base.angle/2 + this.offset : 90;
53
- // break;
54
- // case "right":
55
- // angle = base.startAngle ? base.startAngle + this.offset : 90;
56
- // break;
57
- // }
58
- if (item._rotate) {
59
- item._rotate[0] = 90 - angle;
60
- } else {
61
- item._doTranslate( base.x - item.bounds[ia], base.y - items[i].y );
62
- item._rotate = [90 - angle, baseItems[i].x, baseItems[i].y];
63
- }
64
- }
65
- } else {
66
- let frac;
67
- if (this.baseItem.type == ItemType.Link) {
68
- switch(ba) {
69
- case "left":
70
- case "top":
71
- frac = 0;
72
- break;
73
- case "center":
74
- case "middle":
75
- frac = 0.5;
76
- break;
77
- case "right":
78
- case "bottom":
79
- frac = 1;
80
- break;
81
- }
82
- }
83
- for (let i = 0; i < items.length; i++) {
84
- let p = this.baseItem.type == ItemType.Link ? baseItems[i].getPointAt(frac)[this.channel] : baseItems[i].bounds[ba] + this.offset;
85
- if (isText) {
86
- items[i].anchor[this.channel == "x" ? 0 : 1] = this.itemAnchor;
87
- items[i][this.channel] = p;
88
- } else {
89
- if (this.channel == "x")
90
- items[i]._doTranslate(p - items[i].bounds[ia], 0);
91
- else
92
- items[i]._doTranslate(0, p - items[i].bounds[ia]);
93
- }
94
- }
95
- }
96
-
97
- this.item.getScene()._updateAncestorBounds(this.item);
98
- this.baseItem.getScene()._updateAncestorBounds(this.baseItem);
99
-
100
- // if (isText) {
101
- // for (let i = 0; i < items.length; i++) {
102
- // items[i].anchor[this.channel == "x" ? 0 : 1] = this.itemAnchor;
103
- // let p = baseItems[i].bounds[ba] + this.offset;
104
- // items[i][this.channel] = p;
105
- // }
106
- // } else {
107
- // for (let i = 0; i < items.length; i++) {
108
- // let d = baseItems[i].bounds[ba] + this.offset - items[i].bounds[ia];
109
- // if (this.channel == "x")
110
- // items[i]._doTranslate(d, 0);
111
- // else
112
- // items[i]._doTranslate(0, d);
113
- // }
114
- // }
115
- }
116
-
117
- toJSON() {
118
- let json = {};
119
- json.item = this.item.id;
120
- json.baseItem = this.baseItem.id;
121
- json.channel = this.channel;
122
- json.itemAnchor = this.itemAnchor;
123
- json.baseAnchor = this.baseAnchor;
124
- json.offset = this.offset;
125
- json.type = "affixation";
126
- json.id = this.id;
127
- return json;
128
- }
129
- }
@@ -1,58 +0,0 @@
1
- import { Alignment, ConstraintType, LayoutType, Orientation } from "../util/Constants";
2
- import * as d3 from "d3";
3
-
4
- export default class AlignConstraint {
5
-
6
- constructor(items, d) {
7
- //TODO: check if d is a value in the Alignment (refer to const Alignment in Constants.js)
8
- //if not, throw a new error (add an error type in Errors, also defined in Constants.js)
9
-
10
- this.direction = d;
11
- this.items = items;
12
- this.type = ConstraintType.Align;
13
- this._orientation = [Alignment.Top, Alignment.Middle, Alignment.Bottom].indexOf(d) >= 0 ? Orientation.Vertical : Orientation.Horizontal;
14
- this._itemIds = this.items.map(d => d.classId).sort().join("_");
15
- this.id = this.type + "_" + this._itemIds + "_" + this._orientation;
16
- }
17
-
18
- get orientation() {
19
- return this._orientation;
20
- }
21
-
22
- apply() {
23
- let baseline, dir = this.direction;
24
- if (this.direction == Alignment.Top || this.direction == Alignment.Left)
25
- baseline = Math.min(...this.items.map(d => d.bounds[dir]));
26
- else if ((this.direction == Alignment.Bottom || this.direction == Alignment.Right))
27
- baseline = Math.max(...this.items.map(d => d.bounds[dir]));
28
- else if (this.direction == Alignment.Center || this.direction == Alignment.Middle)
29
- baseline = d3.mean(this.items.map(d => d.bounds[dir]));
30
-
31
- let delta = this.items.map(d => baseline - d.bounds[dir]),
32
- axis = dir == Alignment.Top || dir == Alignment.Middle || dir == Alignment.Bottom ? "y" : "x";
33
- this.items.forEach((d,i) => {
34
- if (d.parent && d.parent.layout && d.parent.layout.type == LayoutType.Stack){
35
- let dx = axis == "x" ? delta[i] : 0,
36
- dy = axis == "y" ? delta[i] : 0;
37
- d.parent._doTranslate(dx, dy);
38
- } else {
39
- let dx = axis == "x" ? delta[i] : 0,
40
- dy = axis == "y" ? delta[i] : 0;
41
- d._doTranslate(dx, dy);
42
- }
43
- });
44
- //TODO: update bounds
45
- let itms = {};
46
- this.items.forEach(d => itms[d.classId] = d);
47
- Object.values(itms).forEach(d => d.getScene()._updateAncestorBounds(d));
48
- }
49
-
50
- toJSON() {
51
- let json = {};
52
- json.items = this.items.map(d => d.id);
53
- json.direction = this.direction;
54
- json.type = this.type;
55
- json.id = this.id;
56
- return json;
57
- }
58
- }
@@ -1,336 +0,0 @@
1
- import {getPeers, getClosestLayout, getTopLevelLayout, CheckAreaOrien, getCellBoundsInGridLayout, getEncodingKey, getTopLevelCollection, isMark} from "../util/ItemUtil";
2
- import {Alignment, DataType, LayoutType} from "../util/Constants";
3
- import {ItemType, Orientation} from "../util/Constants";
4
- import * as d3 from 'd3';
5
-
6
- export default class Encoding {
7
-
8
- constructor(items, scene, channel, field, args) {
9
- this.items = items;
10
- this.anyItem = this.items[0];
11
- this._axes = [];
12
- this.scene = scene;
13
- this.channel = channel;
14
- this.field = field;
15
- this._aggregator = args.aggregator;
16
- this.datatable = args.datatable;
17
- this.scale = args.scale;
18
- //flipScale, scale type and includeZero will be ignored if reusing a scale
19
- //these should be considered properties of a scale, not encoding
20
- //same for scheme and mapping
21
- if (this.scale) {
22
- this._flipScale = this.scale.isFlipped;
23
- this.scaleType = this.scale.type;
24
- this._includeZero = this.scale.includeZero;
25
- } else {
26
- this._flipScale = args.flipScale;
27
- this.scaleType = args.scaleType;
28
- this._includeZero = args.includeZero;
29
- }
30
- this._mapping = args.mapping;
31
- this.rangeExtent = args.rangeExtent;
32
- this._scheme = args.scheme;
33
- this.range = args.range;
34
-
35
- if (this.channel == "angle") {
36
- this.startAngle = "startAngle" in args ? args.startAngle : 90;
37
- // this.angleDirection = "angleDirection" in args ? args.angleDirection : "clockwise";
38
- }
39
-
40
- //get the data needed for the mapping
41
- this._query = undefined;
42
-
43
- //construct/modify scales
44
- this._map = undefined;
45
-
46
- //apply mapping
47
- this._apply = undefined;
48
- }
49
-
50
- get axes() {
51
- return this._axes;
52
- }
53
-
54
- get id() {
55
- return ["enc", getEncodingKey(this.anyItem), this.channel, this.field].join("-");
56
- }
57
-
58
- set aggregator(a) {
59
- this._aggregator = a;
60
- //this.scale = undefined;
61
- this.run();
62
- }
63
-
64
- get aggregator() {
65
- return this._aggregator;
66
- }
67
-
68
- toJSON() {
69
- let json = {};
70
- json.anyItem = this.anyItem.id;
71
- json.items = this.items.map(d => d.id);
72
- if (this.data)
73
- json.data = this.data;
74
- if (this._rectNegativeValues)
75
- json._rectNegativeValues = true;
76
- json.args = {};
77
- json.args.channel = this.channel;
78
- json.args.field = this.field;
79
- json.args.aggregator = this.aggregator;
80
- json.args.datatable = this.datatable.id;
81
- json.args.scale = this.scale.id;
82
- //json.args.includeZero = this._includeZero;
83
- //json.args.flip = this.flip;
84
- json.args.mapping = this._mapping;
85
- json.args.rangeExtent = this.rangeExtent;
86
- json.args.scheme = this._scheme;
87
- json.args.scaleType = this.scaleType;
88
- json.args.range = this.range;
89
-
90
- if (this.channel == "angle") {
91
- json.args.startAngle = this.startAngle;
92
- //json.args.angleDirection = this.angleDirection;
93
- }
94
-
95
- return json;
96
- }
97
-
98
- run() {
99
- this._query();
100
- this._map();
101
- this._apply();
102
- }
103
-
104
- get dataTable() {
105
- return this.datatable;
106
- }
107
-
108
- _inferTickValues() {
109
- let enc = this, domain = enc.scale.domain, range = enc.scale.range;
110
- // if (this.datatable.getFieldType(this.field) == DataType.String)
111
- // return domain;
112
- let minPxInterval;
113
- //let minTickIntervalPx = 40, minLabelIntervalPx = 80;
114
- switch (enc.scale.type) {
115
- case "linear":
116
- case "log": {
117
- //handle the case where the marks are stacked
118
- let r = Math.abs(range[0] - range[1]);
119
- if (enc.channel == "width" || enc.channel == "height") {
120
- // let layout = getClosestLayout(enc.anyItem);
121
- // if (layout && layout.type == LayoutType.Stack) {
122
- // let c = layout.group, colls = getPeers(c, enc.scene);
123
- // r = Math.max(...colls.map(d => d.bounds[enc.channel])) ;
124
- // domain[1] = enc.scale.invert(r); // Math.ceil(enc.scale.invert(r)); do not ceil, it can amplify small difference in invert calculation due to imprecision/roundoff in bounding box calculation
125
- // }
126
- let layout = getTopLevelLayout(enc.anyItem, "stack");
127
- if (layout) {
128
- let c = layout.group, colls = getPeers(c, enc.scene);
129
- r = Math.max(...colls.map(d => d.refBounds[enc.channel]));
130
- domain[1] = enc.scale.invert(r); // Math.ceil(enc.scale.invert(r)); do not ceil, it can amplify small difference in invert calculation due to imprecision/roundoff in bounding box calculation
131
- }
132
- }
133
- minPxInterval = enc.channel == "width" || enc.channel == "x" ? 45 : 30;
134
- let n = Math.max(2, Math.floor(r/minPxInterval));
135
- let ticks;
136
- if (enc.scale.type === "log") {
137
- ticks = [];
138
- let d3Ticks = enc.scale._scale.ticks();
139
- //number of ticks is not configurable for d3 log scales,
140
- //use the solution posted here: https://github.com/d3/d3/issues/72
141
- for (let d of d3Ticks) {
142
- let x = Math.log(d) / Math.log(10) + 1e-6;
143
- if (Math.abs(x - Math.floor(x)) < n/d3Ticks.length)
144
- ticks.push(d);
145
- }
146
- } else {
147
- ticks = d3.ticks(domain[0], domain[1], n);
148
- }
149
- return ticks;
150
- }
151
- case "point": {
152
- minPxInterval = enc.channel == "width" || enc.channel == "x" ? 80 : 30;
153
- let domainValueIntervalPx = Math.floor(enc.scale.rangeExtent/domain.length);
154
- let m = Math.ceil(minPxInterval/domainValueIntervalPx);
155
- return enc.channel == "x" ? domain.filter((d, i) => i % m == 0) : domain;
156
- }
157
- case "time": {
158
- minPxInterval = enc.channel == "width" || enc.channel == "x" ? 80 : 30;
159
- let numIntervals = Math.floor((range[1] - range[0])/minPxInterval),
160
- timeInterval = Math.ceil( (domain[1] - domain[0])/numIntervals )/1000;
161
-
162
- let units = [1, 60, 3600, 86400, 2628003, 31536000],
163
- intervals = [d3.timeSeconds, d3.timeMinutes, d3.timeHours, d3.timeDays, d3.timeMonths, d3.timeYears];
164
-
165
- let tn, tInterval;
166
- for (let i = 0; i < units.length - 1; i++) {
167
- if (timeInterval >= units[i] && timeInterval < units[i+1]) {
168
- tn = Math.floor(timeInterval/units[i]);
169
- tInterval = intervals[i];
170
- return tInterval(domain[0], domain[1], tn);
171
- }
172
- }
173
- if (timeInterval > units[units.length-1]) {
174
- tn = Math.floor(timeInterval/units[units.length-1]);
175
- tInterval = intervals[units.length-1];
176
- return tInterval(domain[0], domain[1], tn);
177
- }
178
- return [];
179
- }
180
- default:
181
- return [];
182
- }
183
- }
184
-
185
- //optional itm specifies which scale range to get in the case of small multiples
186
- getScaleRange(itm) {
187
- let item = itm ? itm : this.anyItem;
188
- if (item.type == ItemType.Area || (item.type == "vertex" && item.parent.type == ItemType.Area)) {
189
- let area = item.type == ItemType.Area ? item : item.parent;
190
- let AreaOrientation = CheckAreaOrien(area);
191
- let layout = getClosestLayout(area);
192
- let alignment;
193
- if (layout) {
194
- if (AreaOrientation == Orientation.Vertical) {
195
- alignment = layout.horzCellAlignment === Alignment.Left;
196
- } else {
197
- alignment = layout.vertCellAlignment === Alignment.Bottom;
198
- }
199
- // alignment = AreaOrientation == Orientation.Vertical ?
200
- // (layout.type == LayoutType.Stack ?
201
- // layout._horzCellAlignment == Alignment.Left : layout._cellHorzAlignment == Alignment.Left)
202
- // : (layout.type == LayoutType.Stack ? layout._vertCellAlignment == Alignment.Bottom : layout._cellVertAlignment == Alignment.Bottom)
203
- }
204
- else {
205
- alignment = AreaOrientation == Orientation.Vertical ? area.baseline == Alignment.Left : area.baseline == Alignment.Bottom;
206
- }
207
- // let DomainToBaseline = this.scale.domain[1] > this.scale.domain[0] ? "default" : "opposite"; // controlling the alignment for the axis and the chart
208
- let cb = getCellBoundsInGridLayout(area);
209
- if (cb) {
210
- switch (this.channel) {
211
- case "x":
212
- return [cb.left, cb.left + this.scale.rangeExtent];
213
- case "width":
214
- return alignment ? [cb.left, cb.left + this.scale.rangeExtent] : [cb.right, cb.right - this.scale.rangeExtent];
215
- case "y":
216
- return [cb.bottom, cb.bottom - this.scale.rangeExtent];
217
- case "height":
218
- return alignment ? [cb.bottom, cb.bottom - this.scale.rangeExtent] : [cb.top + this.scale.rangeExtent, cb.top];
219
- }
220
- } else if (layout && layout.type === "stack") {
221
- cb = layout.group.bounds;
222
- switch (this.channel) {
223
- case "x":
224
- return [cb.left, cb.left + this.scale.rangeExtent];
225
- case "width":
226
- return alignment ? [cb.left, cb.left + this.scale.rangeExtent] : [cb.right, cb.right - this.scale.rangeExtent];
227
- case "y":
228
- return [cb.bottom, cb.bottom - this.scale.rangeExtent];
229
- case "height":
230
- return alignment ? [cb.bottom, cb.bottom - this.scale.rangeExtent] : [cb.top + this.scale.rangeExtent, cb.top];
231
- }
232
- }
233
- if (AreaOrientation == Orientation.Horizontal){
234
- switch (this.channel) {
235
- case "width":
236
- case "height": {
237
- let vertices = this._vertices; // getPeers(item.firstVertex, this.scene);
238
- let offset = alignment ? Math.max(...vertices.map(d => d["y"])) : Math.min(...vertices.map(d => d["y"]));
239
- return alignment ? [offset, offset - this.scale.rangeExtent] : [offset + this.scale.rangeExtent, offset];
240
- }
241
- case "x":
242
- case "y": {
243
- let vertices = getPeers(area.firstVertex, this.scene);
244
- let offset = Math.min(...vertices.map(d => d["x"]));
245
- return [offset, offset + this.scale.rangeExtent];
246
- }
247
- }
248
- } else if (AreaOrientation == Orientation.Vertical){
249
- switch (this.channel) {
250
- case "x":
251
- case "y": {
252
- let vertices = getPeers(area.firstVertex, this.scene);
253
- let offset = Math.max(...vertices.map(d => d["y"]));
254
- return [offset, offset - this.scale.rangeExtent];
255
- }
256
- case "height":
257
- case "width": {
258
- let vertices = getPeers(area.firstVertex, this.scene);
259
- let offset = alignment ? Math.min(...vertices.map(d => d["x"])) : Math.max(...vertices.map(d => d["x"]));
260
- return alignment ? [offset, offset + this.scale.rangeExtent] : [offset - this.scale.rangeExtent, offset];
261
- }
262
- }
263
- }
264
- } else if (this.channel == "x") {
265
- let layout = getClosestLayout(item);
266
- if (layout && layout.type == LayoutType.Grid){
267
- let cellBounds = layout.cellBounds;
268
- let parentPeers = item.parent.parent.children;
269
- let idx = parentPeers.findIndex(d => item.parent == d || item.parent.parent == d );
270
- return [cellBounds[idx].left, cellBounds[idx].left + this.scale.rangeExtent];
271
- } else if (item.type == "vertex" || item.type == "segment") {
272
- let offset = this.scale.offset;
273
- return [offset, offset + this.scale.rangeExtent];
274
- } else {
275
- let offset = this.scale.offset;
276
- return [offset, offset + this.scale.rangeExtent];
277
- }
278
-
279
- } else if (this.channel == "y") {
280
- let layout = getClosestLayout(item);
281
- if (layout && layout.type == LayoutType.Grid){
282
- let cellBounds = layout.cellBounds;
283
- let parentPeers = item.parent.parent.children;
284
- let idx = parentPeers.findIndex(d => item.parent == d || item.parent.parent == d );
285
- // if (isMark(item)) //need to take into account of mark size, cannot based in bounds bottom alone (e.g., calendar heatmap)
286
- // return [cellBounds[idx].bottom - item.bounds.height/2, cellBounds[idx].bottom - item.bounds.height/2 - this.scale.rangeExtent];
287
- // else
288
- return [cellBounds[idx].bottom, cellBounds[idx].bottom - this.scale.rangeExtent];
289
- } else if (item.type == "vertex" || item.type == "segment") {
290
- let offset = this.scale.offset;
291
- return [offset+ this.scale.rangeExtent, offset];
292
- } else {
293
- let offset = this.scale.offset;
294
- return [offset+ this.scale.rangeExtent, offset];
295
- }
296
-
297
- } else if (this.channel == "width") {
298
- let layout = getTopLevelLayout(item);
299
- if (layout.type === "grid") {
300
- let cellBounds = layout.cellBounds;
301
- let parentPeers = item.parent.parent.children;
302
- let idx = parentPeers.findIndex(d => item.parent == d || item.parent.parent == d );
303
- // return [cellBounds[idx].left, cellBounds[idx].left + this.scale.rangeExtent];
304
- return [cellBounds[idx].left, cellBounds[idx].right];
305
- } else if (layout.type === "stack" && layout.orientation == "horizontal") {
306
- return [layout.group.bounds.left, layout.group.bounds.right];
307
- } else {
308
- let items = getPeers(item, this.scene);
309
- let offset = Math.min(...items.map(d => d.bounds.left));
310
- return [offset, offset + this.scale.rangeExtent];
311
- }
312
- } else if (this.channel == "height") {
313
- let c = getTopLevelCollection(item);
314
- //let layout = getTopLevelLayout(item, "grid");
315
- if (c && c.layout && ["grid", "stack"].indexOf(c.layout.type) >= 0){
316
- let cellBounds = c.layout.cellBounds;
317
- let parentPeers = item.parent.parent.children;
318
- let idx = parentPeers.findIndex(d => item.parent === d || item.parent.parent === d );
319
- //return [cellBounds[idx].bottom, cellBounds[idx].bottom - this.scale.rangeExtent];
320
- //do not use rangeExtent because of possible stacking
321
- return [cellBounds[idx].bottom, cellBounds[idx].bottom - cellBounds[idx].height];
322
- } else {
323
- let items = getPeers(item, this.scene);
324
- //TODO: handle cases where items are aligned top
325
- let offset = Math.max(...items.map(d => d.refBounds.bottom));
326
- return [offset, offset - this.scale.rangeExtent];
327
- }
328
- } else if (this.channel == "radialDistance") {
329
- let polygon = item.parent;
330
- return [polygon.x, polygon.x + this.scale.rangeExtent];
331
- } else {
332
- return this.scale.range;
333
- }
334
- }
335
-
336
- }