mascot-vis 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mascot.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // version: 1.10.1
2
+ // version: 1.11.0
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3'), require('pixi.js')) :
5
5
  typeof define === 'function' && define.amd ? define(['exports', 'd3', 'pixi.js'], factory) :
@@ -256,7 +256,8 @@
256
256
  INCORRECT_CONSTRAINT_INFO: "Constrain information is incorreclty passed",
257
257
  FEATURE_NOT_IMPLEMENTED: "This feature has not been implemented yet",
258
258
  LAYOUT_WITHOUT_TREE: "The layout can only be applied to a tree",
259
- UNSUPPORTED_FIELDTYPE: "Unsupported field type for encoding "
259
+ UNSUPPORTED_FIELDTYPE: "Unsupported field type for encoding ",
260
+ CANNOT_CLASSIFY: "Cannot classify items in "
260
261
  };
261
262
 
262
263
  class Layout {
@@ -284,6 +285,8 @@
284
285
  this._colGap = "colGap" in args && args["colGap"] !== undefined ? args["colGap"] : 5;
285
286
  this._cellHorzAlignment = "horzCellAlignment" in args && this._validateCellAlignment("h", args["horzCellAlignment"]) ? args["horzCellAlignment"] : Alignment.Left;
286
287
  this._cellVertAlignment = "vertCellAlignment" in args && this._validateCellAlignment("v", args["vertCellAlignment"]) ? args["vertCellAlignment"] : Alignment.Bottom;
288
+ if (!this._numCols && !this._numRows)
289
+ this._numRows = 1;
287
290
  }
288
291
 
289
292
  _validateCellAlignment(orientation, v) {
@@ -651,6 +654,20 @@
651
654
  get horzCellAlignment() {
652
655
  return this._cellHorzAlignment;
653
656
  }
657
+
658
+ //accepts two formats: a two-element array, or a string
659
+ set direction(d) {
660
+ if (Array.isArray(d) && d.length === 2) {
661
+ this._dir = d;
662
+ } else {
663
+ this._dir = d.split("_");
664
+ }
665
+ this.run();
666
+ }
667
+
668
+ get direction() {
669
+ return this._dir.join("_");
670
+ }
654
671
  }
655
672
 
656
673
  GridLayout.direction = {
@@ -5311,6 +5328,7 @@
5311
5328
  r.push(f);
5312
5329
  }
5313
5330
  }
5331
+ r.sort((a,b) => this.getUniqueFieldValues(a).length - this.getUniqueFieldValues(b).length);
5314
5332
  return r;
5315
5333
  }
5316
5334
 
@@ -8191,7 +8209,7 @@
8191
8209
  gl.forEach(l => l.updateLinePositions());
8192
8210
  },
8193
8211
 
8194
- layoutChanged: function(item, peers, reGenerateAxes) {
8212
+ layoutChanged: function(item, peers, props) {
8195
8213
  let scene = item.getScene();
8196
8214
  scene._relayoutAncestors(item, peers);
8197
8215
 
@@ -8203,6 +8221,36 @@
8203
8221
  for (let i of items)
8204
8222
  i.getScene()._reapplyConstraints(i);
8205
8223
 
8224
+ let reGenerateAxes = false;
8225
+ for (let p of props) {
8226
+ if (["numRows", "numCols", "layout", "childrenOrder"].indexOf(p) >= 0) {
8227
+ reGenerateAxes = true;
8228
+ break;
8229
+ }
8230
+ }
8231
+
8232
+ //if grid layout changes to a single column or row, or stack layout's orientation changes, update axis channel
8233
+ let updateChannel = false, channel;
8234
+ if (item.layout) {
8235
+ if (item.layout.type === LayoutType.Grid && (item.layout.numRows === 1 || item.layout.numCols === 1)) {
8236
+ updateChannel = true;
8237
+ channel = item.layout.numRows === 1 ? "x" : "y";
8238
+ } else if (item.layout.type === LayoutType.Stack && props.indexOf("orientation") >= 0) {
8239
+ updateChannel = true;
8240
+ channel = item.layout.orientation === Orientation.Horizontal ? "x" : "y";
8241
+ }
8242
+ }
8243
+ if (updateChannel) {
8244
+ let axes = scene.getRelatedAxes(item).filter(d => d instanceof LayoutAxis && d._item.parent.classId === item.classId);
8245
+ for (let a of axes) {
8246
+ scene.removeItem(a);
8247
+ let args = a.toJSON().args;
8248
+ delete args["orientation"];
8249
+ args.item = item.firstChild;
8250
+ scene.axis(channel, a.field, args);
8251
+ }
8252
+ }
8253
+
8206
8254
  if (reGenerateAxes) {
8207
8255
  scene.reCreateRelatedAxes(item);
8208
8256
  } else {
@@ -8993,6 +9041,42 @@
8993
9041
  }
8994
9042
  }
8995
9043
 
9044
+ function classifyCollectionChildren(scene, c, field, layout) {
9045
+ let peers = getPeers(c, scene);
9046
+ for (let p of peers) {
9047
+ let collections = {}, cid, items = p.children;
9048
+ for (let item of items) {
9049
+ let v = item.dataScope.getFieldValue(field);
9050
+ if (!(v in collections)) {
9051
+ collections[v] = [];
9052
+ }
9053
+ collections[v].push(item);
9054
+ }
9055
+ let tbl = items[0].dataScope._dt; //results = []; //,
9056
+ for (let v in collections) {
9057
+ let coll = scene.collection();
9058
+ p.addChild(coll);
9059
+ if (cid === undefined)
9060
+ cid = coll.id;
9061
+ coll.classId = cid;
9062
+ coll.dataScope = p.dataScope ? p.dataScope.cross(field, v) : new DataScope(tbl).cross(field, v);
9063
+ for (let c of collections[v]) {
9064
+ coll.addChild(c);
9065
+ }
9066
+ // if (layout)
9067
+ // coll.layout = layout;
9068
+ //results.push(coll);
9069
+ }
9070
+ // if (oldParent.children.length === 0) {
9071
+ // oldParent.parent.removeChild(oldParent);
9072
+ // }
9073
+ }
9074
+
9075
+ if (layout)
9076
+ scene.setProperties(c.firstChild, {layout: layout});
9077
+ //return results;
9078
+ }
9079
+
8996
9080
  class Scene extends Group{
8997
9081
 
8998
9082
  constructor(args){
@@ -9241,6 +9325,23 @@
9241
9325
  return collection;
9242
9326
  }
9243
9327
 
9328
+ classify(item, param){
9329
+ if (!canClassify(item)){
9330
+ throw Errors.CANNOT_CLASSIFY + item.type;
9331
+ }
9332
+
9333
+ let args = param ? param : {},
9334
+ field = args["field"] ? args["field"] : DataTable.RowID,
9335
+ dt = item.firstChild.dataScope.dataTable,
9336
+ layout = args.layout;
9337
+ validateField(field, dt);
9338
+
9339
+ classifyCollectionChildren(this, item, field, layout);
9340
+
9341
+ //SceneValidator.markDivided(item, collection);
9342
+ return item;
9343
+ }
9344
+
9244
9345
  _validateEncodeArgs(item, args) {
9245
9346
  if (!item || !("channel" in args) || !("field" in args)) {
9246
9347
  throw Errors.INCOMPLETE_BINDING_INFO;
@@ -9785,36 +9886,6 @@
9785
9886
  p[method](...args);
9786
9887
  }
9787
9888
 
9788
- classify(items, field, parent){
9789
- let collections = {}, cid, oldParent = items[0].parent;
9790
- for (let item of items) {
9791
- let v = item.dataScope.getFieldValue(field);
9792
- if (!(v in collections)) {
9793
- collections[v] = [];
9794
- }
9795
- collections[v].push(item);
9796
- }
9797
- let results = [], tbl = items[0].dataScope._dt;
9798
- for (let v in collections) {
9799
- let coll = this.collection();
9800
- parent.addChild(coll);
9801
- if (cid === undefined)
9802
- cid = coll.id;
9803
- coll.classId = cid;
9804
- coll.dataScope = new DataScope(tbl).cross(field, v);
9805
- for (let c of collections[v]) {
9806
- coll.addChild(c);
9807
- }
9808
- results.push(coll);
9809
- }
9810
-
9811
- if (oldParent.children.length === 0) {
9812
- oldParent.parent.removeChild(oldParent);
9813
- }
9814
-
9815
- return results;
9816
- }
9817
-
9818
9889
  getEncodingByItem(item, channel) {
9819
9890
  let enc = this.encodings[getEncodingKey(item)];
9820
9891
  if (enc && enc[channel]) {
@@ -9931,6 +10002,7 @@
9931
10002
  }
9932
10003
  }
9933
10004
 
10005
+ //invoke SceneValidator accordingly
9934
10006
  let props = Object.keys(result).filter(d => result[d]);
9935
10007
  let sizeProps = ["width", "height", "fontSize", "area", "radius"];
9936
10008
  for (let s of sizeProps) {
@@ -9939,17 +10011,15 @@
9939
10011
  break;
9940
10012
  }
9941
10013
  }
10014
+
9942
10015
  if (props.indexOf("baseline") >=0 && item.type === ItemType.Area)
9943
10016
  SceneValidator.areaRebased(item, peers);
9944
10017
 
9945
- let layoutProps = ["layout", "rowGap", "colGap", "numRows", "numCols", "vertCellAlignment", "horzCellAlignment"];
9946
- for (let l of layoutProps) {
9947
- if (props.indexOf(l) >= 0) {
9948
- let reGenerateAxes = (props.indexOf("numRows") >= 0 || props.indexOf("numCols") >= 0 || props.indexOf("layout") >= 0);
9949
- SceneValidator.layoutChanged(peers[0], peers, reGenerateAxes);
9950
- break;
9951
- }
9952
- }
10018
+ let layoutProps = ["layout", "rowGap", "colGap", "numRows", "numCols", "orientation", "vertCellAlignment", "horzCellAlignment", "direction", "childrenOrder"];
10019
+ let changed = props.filter(d => layoutProps.indexOf(d) >= 0);
10020
+ if (changed.length > 0)
10021
+ SceneValidator.layoutChanged(peers[0], peers, changed);
10022
+
9953
10023
  return result;
9954
10024
  //TODO: relayout if needed (typically Layout or setProperty should happen before encoding)
9955
10025
  }
@@ -24031,6 +24101,20 @@
24031
24101
  }
24032
24102
  }
24033
24103
 
24104
+ function canClassify(item) {
24105
+ if (item.type !== ItemType.Collection) return false;
24106
+ if (item.children.length < 2) return false;
24107
+ // if (!Array.isArray(items)) return false;
24108
+ // if (items.length < 1) return false;
24109
+ // for (let i of items) {
24110
+ // if (!i.dataScope)
24111
+ // return false;
24112
+ // }
24113
+ // let tbls = uniqueStrings(items.map(d => d.dataScope.dataTable.name));
24114
+ // if (tbls.length > 1) return false;
24115
+ return true;
24116
+ }
24117
+
24034
24118
  function getPeersInScene(item) {
24035
24119
  if (item.type == "vertex" || item.type == "segment") {
24036
24120
  return getPeers(item, item.parent.getScene());
@@ -24039,6 +24123,7 @@
24039
24123
  }
24040
24124
  }
24041
24125
 
24126
+ exports.canClassify = canClassify;
24042
24127
  exports.canDensify = canDensify;
24043
24128
  exports.canDivide = canDivide;
24044
24129
  exports.canRepeat = canRepeat;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mascot-vis",
3
- "version": "1.10.1",
3
+ "version": "1.11.0",
4
4
  "description": "Manipulable Semantic Components in Data Visualization",
5
5
  "scripts": {
6
6
  "build": "rollup --config",