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.
Files changed (156) hide show
  1. package/dist/mascot-esm.js +186 -0
  2. package/package.json +3 -6
  3. package/dist/mascot-es.js +0 -27745
  4. package/dist/mascot-min.js +0 -186
  5. package/dist/mascot-umd.js +0 -27781
  6. package/js/depGraphVis.js +0 -66
  7. package/src-new-ts/action/createElement.ts +0 -91
  8. package/src-new-ts/action/encode.js +0 -20
  9. package/src-new-ts/action/repeat.js +0 -128
  10. package/src-new-ts/action/traverseScene.js +0 -41
  11. package/src-new-ts/data/Network.js +0 -2
  12. package/src-new-ts/data/Scope.js +0 -135
  13. package/src-new-ts/data/Table.js +0 -263
  14. package/src-new-ts/data/Tree.js +0 -3
  15. package/src-new-ts/data/field.ts +0 -115
  16. package/src-new-ts/data/import.ts +0 -96
  17. package/src-new-ts/data/predicate.ts +0 -82
  18. package/src-new-ts/depgraph/DepGraph.js +0 -178
  19. package/src-new-ts/depgraph/Edge.js +0 -9
  20. package/src-new-ts/depgraph/SceneGraph2DepGraph.js +0 -110
  21. package/src-new-ts/depgraph/Signal.js +0 -12
  22. package/src-new-ts/depgraph/operator/BoundsEvaluator.js +0 -30
  23. package/src-new-ts/depgraph/operator/Dataflow.js +0 -41
  24. package/src-new-ts/depgraph/operator/DomainBuilder.js +0 -50
  25. package/src-new-ts/depgraph/updateDepGraph.js +0 -45
  26. package/src-new-ts/depgraph/variable/BoundsVar.js +0 -81
  27. package/src-new-ts/depgraph/variable/ChannelVar.js +0 -17
  28. package/src-new-ts/depgraph/variable/DataScopeVar.js +0 -12
  29. package/src-new-ts/depgraph/variable/DomainVar.js +0 -15
  30. package/src-new-ts/depgraph/variable/FieldVar.js +0 -17
  31. package/src-new-ts/depgraph/variable/LayoutParameter.js +0 -8
  32. package/src-new-ts/depgraph/variable/ScaleVar.js +0 -13
  33. package/src-new-ts/depgraph/variable/Variable.js +0 -39
  34. package/src-new-ts/element/gradient/LinearGradient.js +0 -37
  35. package/src-new-ts/element/group/Collection.js +0 -109
  36. package/src-new-ts/element/group/Group.js +0 -307
  37. package/src-new-ts/element/group/Scene.js +0 -98
  38. package/src-new-ts/element/mark/CircleMark.ts +0 -85
  39. package/src-new-ts/element/mark/Mark.ts +0 -233
  40. package/src-new-ts/element/mark/PathMark.js +0 -483
  41. package/src-new-ts/element/mark/Segment.js +0 -29
  42. package/src-new-ts/element/mark/Vertex.js +0 -118
  43. package/src-new-ts/encode/Scale.ts +0 -115
  44. package/src-new-ts/index.ts +0 -19
  45. package/src-new-ts/layout/Layout.ts +0 -3
  46. package/src-new-ts/render/CanvasRenderer.ts +0 -24
  47. package/src-new-ts/render/SVGRenderer.js +0 -316
  48. package/src-new-ts/util.ts +0 -3
  49. package/src-old/action/Classify.js +0 -53
  50. package/src-old/action/Densify.js +0 -199
  51. package/src-old/action/Partition.js +0 -531
  52. package/src-old/action/Repeat.js +0 -106
  53. package/src-old/action/Repopulate.js +0 -44
  54. package/src-old/action/Stratify.js +0 -156
  55. package/src-old/basic/Gradient.js +0 -37
  56. package/src-old/basic/Point.js +0 -51
  57. package/src-old/basic/Rectangle.js +0 -63
  58. package/src-old/bind/bindToAngle.js +0 -56
  59. package/src-old/bind/bindToAreaMark.js +0 -360
  60. package/src-old/bind/bindToColor.js +0 -114
  61. package/src-old/bind/bindToLink.js +0 -81
  62. package/src-old/bind/bindToPosition.js +0 -283
  63. package/src-old/bind/bindToRadialDistance.js +0 -62
  64. package/src-old/bind/bindToSize.js +0 -235
  65. package/src-old/bind/bindToText.js +0 -60
  66. package/src-old/bind/bindToThickness.js +0 -100
  67. package/src-old/constraint/AffixConstraint.js +0 -129
  68. package/src-old/constraint/AlignConstraint.js +0 -58
  69. package/src-old/core/Encoding.js +0 -336
  70. package/src-old/core/Scale.js +0 -322
  71. package/src-old/core/SceneLoader.js +0 -290
  72. package/src-old/core/SceneValidator.js +0 -232
  73. package/src-old/core/SpecExecutor.js +0 -113
  74. package/src-old/core/SpecGenerator.js +0 -350
  75. package/src-old/data/DataImporter.js +0 -64
  76. package/src-old/data/DataScope.js +0 -124
  77. package/src-old/data/DataTable.js +0 -338
  78. package/src-old/data/Network.js +0 -106
  79. package/src-old/data/Tree.js +0 -251
  80. package/src-old/data/transform/Bin.js +0 -46
  81. package/src-old/data/transform/Filter.js +0 -48
  82. package/src-old/data/transform/Groupby.js +0 -18
  83. package/src-old/data/transform/KDE.js +0 -58
  84. package/src-old/data/transform/Sort.js +0 -14
  85. package/src-old/data/transform/Split.js +0 -5
  86. package/src-old/data/transform/partition.js +0 -46
  87. package/src-old/history/UndoRedoStack +0 -0
  88. package/src-old/index.js +0 -271
  89. package/src-old/indexSVG.js +0 -259
  90. package/src-old/interaction/Interaction.js +0 -91
  91. package/src-old/interaction/MouseEvent.js +0 -8
  92. package/src-old/interaction/Selection.js +0 -9
  93. package/src-old/interaction/brush.js +0 -362
  94. package/src-old/item/Segment.js +0 -29
  95. package/src-old/item/Vertex.js +0 -118
  96. package/src-old/item/composite/Collection.js +0 -106
  97. package/src-old/item/composite/Glyph.js +0 -19
  98. package/src-old/item/composite/Group.js +0 -310
  99. package/src-old/item/composite/Scene.js +0 -1251
  100. package/src-old/item/mark/ArcPath.js +0 -181
  101. package/src-old/item/mark/AreaPath.js +0 -78
  102. package/src-old/item/mark/CirclePath.js +0 -102
  103. package/src-old/item/mark/EllipsePath.js +0 -5
  104. package/src-old/item/mark/Image.js +0 -101
  105. package/src-old/item/mark/LinkPath.js +0 -118
  106. package/src-old/item/mark/Mark.js +0 -163
  107. package/src-old/item/mark/Path.js +0 -494
  108. package/src-old/item/mark/PointText.js +0 -201
  109. package/src-old/item/mark/PolygonPath.js +0 -64
  110. package/src-old/item/mark/RectPath.js +0 -88
  111. package/src-old/item/mark/RingPath.js +0 -92
  112. package/src-old/item/refs/Axis.js +0 -362
  113. package/src-old/item/refs/EncodingAxis.js +0 -515
  114. package/src-old/item/refs/Gridlines.js +0 -144
  115. package/src-old/item/refs/LayoutAxis.js +0 -316
  116. package/src-old/item/refs/Legend.js +0 -273
  117. package/src-old/layout/Circular.js +0 -95
  118. package/src-old/layout/Force.js +0 -52
  119. package/src-old/layout/Grid.js +0 -423
  120. package/src-old/layout/Layout.js +0 -13
  121. package/src-old/layout/Packing.js +0 -56
  122. package/src-old/layout/Stack.js +0 -264
  123. package/src-old/layout/Strata.js +0 -88
  124. package/src-old/layout/Sugiyama.js +0 -59
  125. package/src-old/layout/TidyTree.js +0 -105
  126. package/src-old/layout/Treemap.js +0 -87
  127. package/src-old/renderer/SVGInteractionHandler.js +0 -241
  128. package/src-old/renderer/SVGRenderer.js +0 -325
  129. package/src-old/renderer/WebGLRenderer.js +0 -1097
  130. package/src-old/renderer/WebGLRenderer2.js +0 -249
  131. package/src-old/renderer/threejs/Line2.js +0 -18
  132. package/src-old/renderer/threejs/LineGeometry.js +0 -77
  133. package/src-old/renderer/threejs/LineMaterial.js +0 -605
  134. package/src-old/renderer/threejs/LineSegments2.js +0 -281
  135. package/src-old/renderer/threejs/LineSegmentsGeometry.js +0 -226
  136. package/src-old/renderer/threejs/Wireframe.js +0 -51
  137. package/src-old/renderer/threejs/WireframeGeometry2.js +0 -16
  138. package/src-old/scale/areaSize.js +0 -0
  139. package/src-old/scale/domain.js +0 -38
  140. package/src-old/util/Constants.js +0 -180
  141. package/src-old/util/DataUtil.js +0 -35
  142. package/src-old/util/ItemUtil.js +0 -586
  143. package/src-old/util/Numerical.js +0 -33
  144. package/tests/demo-tests/README.md +0 -80
  145. package/tests/demo-tests/SVG2PNG.js +0 -56
  146. package/tests/demo-tests/demos2CanvasPNGs.js +0 -69
  147. package/tests/demo-tests/demos2ScenesSVGs.js +0 -100
  148. package/tests/demo-tests/pathElementWorker.js +0 -91
  149. package/tests/demo-tests/pixelTest.js +0 -62
  150. package/tests/demo-tests/renderDemos.html +0 -132
  151. package/tests/demo-tests/serializationTest.js +0 -36
  152. package/tests/demo-tests/serializeDemos.html +0 -134
  153. package/tests/unit-tests/README.md +0 -4
  154. package/tests/unit-tests/jasmine-browser.json +0 -21
  155. package/tests/unit-tests/jasmine.json +0 -14
  156. 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
- }