mascot-vis 1.10.1 → 1.11.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/dist/mascot.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable */
2
- // version: 1.10.1
2
+ // version: 1.11.1
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,9 +256,22 @@
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
 
263
+ const categoricalColorSchemes = [
264
+ "schemeCategory10", "schemeAccent", "schemeDark2", "schemePaired", "schemePastel1", "schemePastel2", "schemeSet1", "schemeSet2", "schemeSet3", "schemeTableau10"
265
+ ];
266
+
267
+ const divergingColorSchemes = [
268
+ "schemeBrBG", "schemePRGn", "schemePiYG", "schemePuOr", "schemeRdBu", "schemeRdGy", "schemeRdYlBu", "schemeRdYlGn", "schemeSpectral"
269
+ ];
270
+
271
+ const sequentialColorSchemes = [
272
+ "schemeBlues", "schemeGreens", "schemeGreys", "schemeOranges", "schemePurples", "schemeReds", "schemeBuGn", "schemeBuPu", "schemeGnBu", "schemeOrRd", "schemePuBuGn", "schemePuBu", "schemePuRd", "schemeRdPu", "schemeYlGnBu", "schemeYlGn", "schemeYlOrBr", "schemeYlOrRd"
273
+ ];
274
+
262
275
  class Layout {
263
276
 
264
277
  constructor(args){
@@ -284,6 +297,8 @@
284
297
  this._colGap = "colGap" in args && args["colGap"] !== undefined ? args["colGap"] : 5;
285
298
  this._cellHorzAlignment = "horzCellAlignment" in args && this._validateCellAlignment("h", args["horzCellAlignment"]) ? args["horzCellAlignment"] : Alignment.Left;
286
299
  this._cellVertAlignment = "vertCellAlignment" in args && this._validateCellAlignment("v", args["vertCellAlignment"]) ? args["vertCellAlignment"] : Alignment.Bottom;
300
+ if (!this._numCols && !this._numRows)
301
+ this._numRows = 1;
287
302
  }
288
303
 
289
304
  _validateCellAlignment(orientation, v) {
@@ -651,6 +666,20 @@
651
666
  get horzCellAlignment() {
652
667
  return this._cellHorzAlignment;
653
668
  }
669
+
670
+ //accepts two formats: a two-element array, or a string
671
+ set direction(d) {
672
+ if (Array.isArray(d) && d.length === 2) {
673
+ this._dir = d;
674
+ } else {
675
+ this._dir = d.split("_");
676
+ }
677
+ this.run();
678
+ }
679
+
680
+ get direction() {
681
+ return this._dir.join("_");
682
+ }
654
683
  }
655
684
 
656
685
  GridLayout.direction = {
@@ -4144,7 +4173,16 @@
4144
4173
  if (this.scale) {
4145
4174
  this.scale.domain = Array.from(new Set(this.scale.domain.concat(this.data)));
4146
4175
  } else {
4147
- this.scale = createScale("ordinalColor", this._scheme ? this._scheme: "schemeCategory10");
4176
+ let args = {scheme: "schemeCategory10"};
4177
+ if (this._scheme) {
4178
+ if (categoricalColorSchemes.indexOf(this._scheme) >= 0) {
4179
+ args.scheme = this._scheme;
4180
+ } else if (divergingColorSchemes.indexOf(this._scheme) >= 0 || sequentialColorSchemes.indexOf(this._scheme) >= 0) {
4181
+ args.scheme = this._scheme;
4182
+ args.size = this.data.length;
4183
+ }
4184
+ }
4185
+ this.scale = createScale("ordinalColor", args);
4148
4186
  this.scale.domain = this.data;
4149
4187
  if (this._mapping) {
4150
4188
  let range = this.scale.domain.map(d => d in this._mapping ? this._mapping[d] : "black");
@@ -5311,6 +5349,7 @@
5311
5349
  r.push(f);
5312
5350
  }
5313
5351
  }
5352
+ r.sort((a,b) => this.getUniqueFieldValues(a).length - this.getUniqueFieldValues(b).length);
5314
5353
  return r;
5315
5354
  }
5316
5355
 
@@ -7055,6 +7094,12 @@
7055
7094
  return false;
7056
7095
  }
7057
7096
 
7097
+ _doTranslate(dx, dy) {
7098
+ super._doTranslate(dx, dy);
7099
+ this._x += dx;
7100
+ this._y += dy;
7101
+ }
7102
+
7058
7103
  }
7059
7104
 
7060
7105
  class Glyph extends Group {
@@ -7317,7 +7362,13 @@
7317
7362
  this.direction = d;
7318
7363
  this.items = items;
7319
7364
  this.type = ConstraintType.Align;
7320
- this.id = this.type + "_" + [...new Set(this.items.map(d => d.classId))].join("_");
7365
+ this._orientation = [Alignment.Top, Alignment.Middle, Alignment.Bottom].indexOf(d) >= 0 ? Orientation.Vertical : Orientation.Horizontal;
7366
+ this._itemIds = this.items.map(d => d.classId).sort().join("_");
7367
+ this.id = this.type + "_" + this._itemIds + "_" + this._orientation;
7368
+ }
7369
+
7370
+ get orientation() {
7371
+ return this._orientation;
7321
7372
  }
7322
7373
 
7323
7374
  apply() {
@@ -7330,7 +7381,7 @@
7330
7381
  baseline = d3__namespace.mean(this.items.map(d => d.bounds[dir]));
7331
7382
 
7332
7383
  let delta = this.items.map(d => baseline - d.bounds[dir]),
7333
- axis = dir == Alignment.TOP || dir == Alignment.Middle || dir == Alignment.Bottom ? "y" : "x";
7384
+ axis = dir == Alignment.Top || dir == Alignment.Middle || dir == Alignment.Bottom ? "y" : "x";
7334
7385
  this.items.forEach((d,i) => {
7335
7386
  if (d.parent && d.parent.layout && d.parent.layout.type == LayoutType.Stack){
7336
7387
  let dx = axis == "x" ? delta[i] : 0,
@@ -8191,7 +8242,7 @@
8191
8242
  gl.forEach(l => l.updateLinePositions());
8192
8243
  },
8193
8244
 
8194
- layoutChanged: function(item, peers, reGenerateAxes) {
8245
+ layoutChanged: function(item, peers, props) {
8195
8246
  let scene = item.getScene();
8196
8247
  scene._relayoutAncestors(item, peers);
8197
8248
 
@@ -8203,6 +8254,36 @@
8203
8254
  for (let i of items)
8204
8255
  i.getScene()._reapplyConstraints(i);
8205
8256
 
8257
+ let reGenerateAxes = false;
8258
+ for (let p of props) {
8259
+ if (["numRows", "numCols", "layout", "childrenOrder"].indexOf(p) >= 0) {
8260
+ reGenerateAxes = true;
8261
+ break;
8262
+ }
8263
+ }
8264
+
8265
+ //if grid layout changes to a single column or row, or stack layout's orientation changes, update axis channel
8266
+ let updateChannel = false, channel;
8267
+ if (item.layout) {
8268
+ if (item.layout.type === LayoutType.Grid && (item.layout.numRows === 1 || item.layout.numCols === 1)) {
8269
+ updateChannel = true;
8270
+ channel = item.layout.numRows === 1 ? "x" : "y";
8271
+ } else if (item.layout.type === LayoutType.Stack && props.indexOf("orientation") >= 0) {
8272
+ updateChannel = true;
8273
+ channel = item.layout.orientation === Orientation.Horizontal ? "x" : "y";
8274
+ }
8275
+ }
8276
+ if (updateChannel) {
8277
+ let axes = scene.getRelatedAxes(item).filter(d => d instanceof LayoutAxis && d._item.parent.classId === item.classId);
8278
+ for (let a of axes) {
8279
+ scene.removeItem(a);
8280
+ let args = a.toJSON().args;
8281
+ delete args["orientation"];
8282
+ args.item = item.firstChild;
8283
+ scene.axis(channel, a.field, args);
8284
+ }
8285
+ }
8286
+
8206
8287
  if (reGenerateAxes) {
8207
8288
  scene.reCreateRelatedAxes(item);
8208
8289
  } else {
@@ -8993,6 +9074,42 @@
8993
9074
  }
8994
9075
  }
8995
9076
 
9077
+ function classifyCollectionChildren(scene, c, field, layout) {
9078
+ let peers = getPeers(c, scene);
9079
+ for (let p of peers) {
9080
+ let collections = {}, cid, items = p.children;
9081
+ for (let item of items) {
9082
+ let v = item.dataScope.getFieldValue(field);
9083
+ if (!(v in collections)) {
9084
+ collections[v] = [];
9085
+ }
9086
+ collections[v].push(item);
9087
+ }
9088
+ let tbl = items[0].dataScope._dt; //results = []; //,
9089
+ for (let v in collections) {
9090
+ let coll = scene.collection();
9091
+ p.addChild(coll);
9092
+ if (cid === undefined)
9093
+ cid = coll.id;
9094
+ coll.classId = cid;
9095
+ coll.dataScope = p.dataScope ? p.dataScope.cross(field, v) : new DataScope(tbl).cross(field, v);
9096
+ for (let c of collections[v]) {
9097
+ coll.addChild(c);
9098
+ }
9099
+ // if (layout)
9100
+ // coll.layout = layout;
9101
+ //results.push(coll);
9102
+ }
9103
+ // if (oldParent.children.length === 0) {
9104
+ // oldParent.parent.removeChild(oldParent);
9105
+ // }
9106
+ }
9107
+
9108
+ if (layout)
9109
+ scene.setProperties(c.firstChild, {layout: layout});
9110
+ //return results;
9111
+ }
9112
+
8996
9113
  class Scene extends Group{
8997
9114
 
8998
9115
  constructor(args){
@@ -9241,6 +9358,23 @@
9241
9358
  return collection;
9242
9359
  }
9243
9360
 
9361
+ classify(item, param){
9362
+ if (!canClassify(item)){
9363
+ throw Errors.CANNOT_CLASSIFY + item.type;
9364
+ }
9365
+
9366
+ let args = param ? param : {},
9367
+ field = args["field"] ? args["field"] : DataTable.RowID,
9368
+ dt = item.firstChild.dataScope.dataTable,
9369
+ layout = args.layout;
9370
+ validateField(field, dt);
9371
+
9372
+ classifyCollectionChildren(this, item, field, layout);
9373
+
9374
+ //SceneValidator.markDivided(item, collection);
9375
+ return item;
9376
+ }
9377
+
9244
9378
  _validateEncodeArgs(item, args) {
9245
9379
  if (!item || !("channel" in args) || !("field" in args)) {
9246
9380
  throw Errors.INCOMPLETE_BINDING_INFO;
@@ -9423,6 +9557,24 @@
9423
9557
  this.constraints = {};
9424
9558
  }
9425
9559
 
9560
+ removeConstraint(c) {
9561
+ delete this.constraints[c.id];
9562
+ }
9563
+
9564
+ getRelatedConstraints(items) {
9565
+ let cstrs = [];
9566
+ for (let cid in this.constraints) {
9567
+ let c = this.constraints[cid];
9568
+ switch (c.type) {
9569
+ case ConstraintType.Align:
9570
+ if (c._itemIds === items.map(d => d.classId).sort().join("_"))
9571
+ cstrs.push(c);
9572
+ break;
9573
+ }
9574
+ }
9575
+ return cstrs;
9576
+ }
9577
+
9426
9578
  // alignInCell(item, direction) {
9427
9579
  // //TODO replace grid.vertCellAlignment and grid.horzCellAlignment
9428
9580
  // }
@@ -9785,36 +9937,6 @@
9785
9937
  p[method](...args);
9786
9938
  }
9787
9939
 
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
9940
  getEncodingByItem(item, channel) {
9819
9941
  let enc = this.encodings[getEncodingKey(item)];
9820
9942
  if (enc && enc[channel]) {
@@ -9931,6 +10053,7 @@
9931
10053
  }
9932
10054
  }
9933
10055
 
10056
+ //invoke SceneValidator accordingly
9934
10057
  let props = Object.keys(result).filter(d => result[d]);
9935
10058
  let sizeProps = ["width", "height", "fontSize", "area", "radius"];
9936
10059
  for (let s of sizeProps) {
@@ -9939,17 +10062,15 @@
9939
10062
  break;
9940
10063
  }
9941
10064
  }
10065
+
9942
10066
  if (props.indexOf("baseline") >=0 && item.type === ItemType.Area)
9943
10067
  SceneValidator.areaRebased(item, peers);
9944
10068
 
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
- }
10069
+ let layoutProps = ["layout", "rowGap", "colGap", "numRows", "numCols", "orientation", "vertCellAlignment", "horzCellAlignment", "direction", "childrenOrder"];
10070
+ let changed = props.filter(d => layoutProps.indexOf(d) >= 0);
10071
+ if (changed.length > 0)
10072
+ SceneValidator.layoutChanged(peers[0], peers, changed);
10073
+
9953
10074
  return result;
9954
10075
  //TODO: relayout if needed (typically Layout or setProperty should happen before encoding)
9955
10076
  }
@@ -10569,7 +10690,7 @@
10569
10690
  this._scale = d3__namespace.scaleOrdinal();
10570
10691
  break;
10571
10692
  case "ordinalColor":
10572
- this._scale = d3__namespace.scaleOrdinal(args && typeof(args) == "string"? d3__namespace[args] : d3__namespace.schemeCategory10);
10693
+ this._scale = d3__namespace.scaleOrdinal(args? args.size ? d3__namespace[args.scheme][args.size] : d3__namespace[args.scheme] : d3__namespace.schemeCategory10);
10573
10694
  break;
10574
10695
  case "power":
10575
10696
  this._scale = d3__namespace.scalePow().exponent(2);
@@ -23970,8 +24091,13 @@
23970
24091
  if (!item.children || item.children.length == 0) {
23971
24092
  return item.contains(x, y) && item.type !== ItemType.Scene ? item : null
23972
24093
  }
23973
- for (let i = item.children.length - 1; i >= 0; i--) {
23974
- let c = item.children[i];
24094
+ let children = item.children;
24095
+ if (item.type === ItemType.Scene) {
24096
+ children = children.slice();
24097
+ children.sort((a,b) => isGuide(a) ? 1 : isGuide(b) ? -1 : 0 );
24098
+ }
24099
+ for (let i = children.length - 1; i >= 0; i--) {
24100
+ let c = children[i];
23975
24101
  if (c.contains(x, y))
23976
24102
  return c;
23977
24103
  }
@@ -24031,6 +24157,20 @@
24031
24157
  }
24032
24158
  }
24033
24159
 
24160
+ function canClassify(item) {
24161
+ if (item.type !== ItemType.Collection) return false;
24162
+ if (item.children.length < 2) return false;
24163
+ // if (!Array.isArray(items)) return false;
24164
+ // if (items.length < 1) return false;
24165
+ // for (let i of items) {
24166
+ // if (!i.dataScope)
24167
+ // return false;
24168
+ // }
24169
+ // let tbls = uniqueStrings(items.map(d => d.dataScope.dataTable.name));
24170
+ // if (tbls.length > 1) return false;
24171
+ return true;
24172
+ }
24173
+
24034
24174
  function getPeersInScene(item) {
24035
24175
  if (item.type == "vertex" || item.type == "segment") {
24036
24176
  return getPeers(item, item.parent.getScene());
@@ -24039,6 +24179,7 @@
24039
24179
  }
24040
24180
  }
24041
24181
 
24182
+ exports.canClassify = canClassify;
24042
24183
  exports.canDensify = canDensify;
24043
24184
  exports.canDivide = canDivide;
24044
24185
  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.1",
4
4
  "description": "Manipulable Semantic Components in Data Visualization",
5
5
  "scripts": {
6
6
  "build": "rollup --config",