mascot-vis 1.9.2 → 1.10.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.9.2
2
+ // version: 1.10.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) :
@@ -2832,16 +2832,17 @@
2832
2832
  let scopes = line2Scopes[p.id];
2833
2833
  let x1 = p.vertices[0].x, y1 = p.vertices[0].y, x2 = p.vertices[1].x, y2 = p.vertices[1].y;
2834
2834
 
2835
- p.classId = compnt.id;
2836
- p.vertices[0].x = x1;
2837
- p.vertices[0].y = y1;
2838
- p.vertices[1].x = x1 + (x2 - x1)/max;
2839
- p.vertices[1].y = y1 + (y2 - y1)/max;
2840
- p.dataScope = scopes[0];
2841
- coll.addChild(p);
2835
+ // p.classId = compnt.id;
2836
+ // p.vertices[0].x = x1;
2837
+ // p.vertices[0].y = y1;
2838
+ // p.vertices[1].x = x1 + (x2 - x1)/max;
2839
+ // p.vertices[1].y = y1 + (y2 - y1)/max;
2840
+ // p.dataScope = scopes[0];
2841
+ // coll.addChild(p);
2842
2842
 
2843
- for (let i = 1; i < scopes.length; i++) {
2843
+ for (let i = 0; i < scopes.length; i++) {
2844
2844
  let c = p.duplicate();
2845
+ c.classId = compnt.id;
2845
2846
  c.vertices[0].x = x1 + (x2 - x1) * i /max;
2846
2847
  c.vertices[0].y = y1 + (y2 - y1) * i /max;
2847
2848
  c.vertices[1].x = x1 + (x2 - x1) * (i + 1)/max;
@@ -2850,6 +2851,8 @@
2850
2851
  coll.addChild(c);
2851
2852
  }
2852
2853
 
2854
+ parent.removeChild(p);
2855
+
2853
2856
  if (p == compnt)
2854
2857
  toReturn = coll;
2855
2858
  }
@@ -2896,13 +2899,14 @@
2896
2899
 
2897
2900
  let wd = orientation == Orientation.Horizontal ? bounds.width/max : bounds.width,
2898
2901
  ht = orientation == Orientation.Horizontal ? bounds.height : bounds.height/max;
2899
- p.classId = compnt.id;
2900
- p.resize(wd, ht);
2901
- p.dataScope = scopes[0];
2902
- coll.addChild(p);
2902
+ // p.classId = compnt.id;
2903
+ //p.resize(wd, ht);
2904
+ //p.dataScope = scopes[0];
2905
+ //coll.addChild(p);
2903
2906
 
2904
- for (let i = 1; i < scopes.length; i++) {
2907
+ for (let i = 0; i < scopes.length; i++) {
2905
2908
  let c = p.duplicate();
2909
+ c.classId = compnt.id;
2906
2910
  c.resize(wd, ht);
2907
2911
  c.dataScope = scopes[i];
2908
2912
  coll.addChild(c);
@@ -2910,21 +2914,14 @@
2910
2914
 
2911
2915
  coll.layout = new StackLayout({orientation: orientation, left: left, top: top});
2912
2916
 
2917
+ parent.removeChild(p);
2918
+
2913
2919
  if (p == compnt)
2914
2920
  toReturn = coll;
2915
2921
  }
2916
2922
 
2917
2923
  scene._reapplySizeBindings(toReturn);
2918
2924
 
2919
- //update axis item argument
2920
- let axes = scene.getRelatedAxes(compnt);
2921
- for (let a of axes) {
2922
- if (a._item.classId === compnt.classId) {
2923
- a._item = toReturn;
2924
- a._items = getPeers(toReturn, scene);
2925
- }
2926
- }
2927
-
2928
2925
  return toReturn;
2929
2926
  }
2930
2927
 
@@ -2956,17 +2953,19 @@
2956
2953
 
2957
2954
  let wd = orientation == Orientation.Horizontal ? p.width/ds.length : p.width,
2958
2955
  ht = orientation == Orientation.Horizontal ? p.height : p.height/ds.length;
2959
-
2960
- p.classId = compnt.id;
2961
- p.resizeArea(wd, ht);
2962
- coll.addChild(p);
2956
+ // p.classId = compnt.id;
2957
+ // p.resizeArea(wd, ht);
2958
+ // coll.addChild(p);
2963
2959
 
2964
- for (let i = 1; i < ds.length; i++) {
2960
+ for (let i = 0; i < ds.length; i++) {
2965
2961
  let c = p.duplicate();
2962
+ c.classId = compnt.id;
2966
2963
  c.resizeArea(wd, ht);
2967
2964
  coll.addChild(c);
2968
2965
  }
2969
2966
 
2967
+ parent.removeChild(p);
2968
+
2970
2969
  for (let i = 0; i < coll.children.length; i++) {
2971
2970
  let child = coll.children[i];
2972
2971
  if (child.dataScope) {
@@ -3156,7 +3155,7 @@
3156
3155
  coll.addChild(pie);
3157
3156
  }
3158
3157
 
3159
- coll.layout = layout("stack", {direction: Direction.Clockwise});
3158
+ coll.layout = layout("stack", {orientation: Orientation.Angular, direction: Direction.Clockwise});
3160
3159
  // Replace original circle w/ coll of pies
3161
3160
  parent.removeChild(p);
3162
3161
  parent.addChild(coll);
@@ -3971,6 +3970,8 @@
3971
3970
  } else {
3972
3971
  if (this.scale.offset === undefined)
3973
3972
  this.scale.offset = Math.min(...items.map(d => d[channel]));
3973
+ if (this.items[0].type === ItemType.PointText)
3974
+ this.items.forEach(d => d.horzAnchor = "center");
3974
3975
  for (let i = 0; i < this.items.length; i++) {
3975
3976
  let peer = this.items[i];
3976
3977
  let dx = this.scale.offset + this.scale.map(this.data[i]) - peer[channel],
@@ -4015,6 +4016,8 @@
4015
4016
  } else {
4016
4017
  if (this.scale.offset === undefined)
4017
4018
  this.scale.offset = Math.min(...items.map(d => d.bounds.y));
4019
+ if (this.items[0].type === ItemType.PointText)
4020
+ this.items.forEach(d => d.vertAnchor = "middle");
4018
4021
  for (let i = 0; i < this.items.length; i++) {
4019
4022
  let peer = this.items[i];
4020
4023
  let dx = 0,
@@ -4759,13 +4762,26 @@
4759
4762
  let layout = getTopLevelLayout(enc.anyItem, "stack");
4760
4763
  if (layout) {
4761
4764
  let c = layout.group, colls = getPeers(c, enc.scene);
4762
- r = Math.max(...colls.map(d => d.bounds[enc.channel])) ;
4765
+ r = Math.max(...colls.map(d => d.refBounds[enc.channel]));
4763
4766
  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
4764
4767
  }
4765
4768
  }
4766
4769
  minPxInterval = enc.channel == "width" || enc.channel == "x" ? 45 : 30;
4767
- let n = Math.floor(r/minPxInterval); //, step = d3.tickStep(domain[0], domain[1], n);
4768
- let ticks = enc.scale.type === "log" ? enc.scale._scale.ticks(n) : d3__namespace.ticks(domain[0], domain[1], n);
4770
+ let n = Math.max(2, Math.floor(r/minPxInterval));
4771
+ let ticks;
4772
+ if (enc.scale.type === "log") {
4773
+ ticks = [];
4774
+ let d3Ticks = enc.scale._scale.ticks();
4775
+ //number of ticks is not configurable for d3 log scales,
4776
+ //use the solution posted here: https://github.com/d3/d3/issues/72
4777
+ for (let d of d3Ticks) {
4778
+ let x = Math.log(d) / Math.log(10) + 1e-6;
4779
+ if (Math.abs(x - Math.floor(x)) < n/d3Ticks.length)
4780
+ ticks.push(d);
4781
+ }
4782
+ } else {
4783
+ ticks = d3__namespace.ticks(domain[0], domain[1], n);
4784
+ }
4769
4785
  return ticks;
4770
4786
  }
4771
4787
  case "point": {
@@ -4927,9 +4943,10 @@
4927
4943
  return [offset, offset + this.scale.rangeExtent];
4928
4944
  }
4929
4945
  } else if (this.channel == "height") {
4930
- let layout = getTopLevelLayout(item, "grid");
4931
- if (layout) {
4932
- let cellBounds = layout.cellBounds;
4946
+ let c = getTopLevelCollection(item);
4947
+ //let layout = getTopLevelLayout(item, "grid");
4948
+ if (c && c.layout && ["grid", "stack"].indexOf(c.layout.type) >= 0){
4949
+ let cellBounds = c.layout.cellBounds;
4933
4950
  let parentPeers = item.parent.parent.children;
4934
4951
  let idx = parentPeers.findIndex(d => item.parent === d || item.parent.parent === d );
4935
4952
  //return [cellBounds[idx].bottom, cellBounds[idx].bottom - this.scale.rangeExtent];
@@ -4938,7 +4955,7 @@
4938
4955
  } else {
4939
4956
  let items = getPeers(item, this.scene);
4940
4957
  //TODO: handle cases where items are aligned top
4941
- let offset = Math.max(...items.map(d => d.bounds.bottom));
4958
+ let offset = Math.min(...items.map(d => d.refBounds.bottom));
4942
4959
  return [offset, offset - this.scale.rangeExtent];
4943
4960
  }
4944
4961
  } else if (this.channel == "radialDistance") {
@@ -5171,6 +5188,7 @@
5171
5188
  case "radius":
5172
5189
  case "fillColor":
5173
5190
  case "strokeColor":
5191
+ case "text":
5174
5192
  return this.numericFields.concat(this.nonNumericFields);
5175
5193
  case "area":
5176
5194
  case "strokeWidth":
@@ -5578,6 +5596,24 @@
5578
5596
  this._updateBounds();
5579
5597
  }
5580
5598
 
5599
+ get horzAnchor() {
5600
+ return this.attrs["anchor"][0];
5601
+ }
5602
+
5603
+ get vertAnchor() {
5604
+ return this.attrs["anchor"][1];
5605
+ }
5606
+
5607
+ set horzAnchor(a) {
5608
+ this.attrs["anchor"][0] = a;
5609
+ this._updateBounds();
5610
+ }
5611
+
5612
+ set vertAnchor(a) {
5613
+ this.attrs["anchor"][1] = a;
5614
+ this._updateBounds();
5615
+ }
5616
+
5581
5617
  //return integer
5582
5618
  get fontSize() {
5583
5619
  return parseFloat(this.styles["fontSize"]);
@@ -7095,6 +7131,7 @@
7095
7131
  copyPropertiesTo(target) {
7096
7132
  super.copyPropertiesTo(target);
7097
7133
  target._baseline = this._baseline;
7134
+ target._orientation = this._orientation;
7098
7135
  }
7099
7136
 
7100
7137
  resizeArea(wd, ht) {
@@ -7645,14 +7682,17 @@
7645
7682
  }
7646
7683
 
7647
7684
  contains(x, y) {
7648
- let svgData = this.getSVGPathData();
7649
- if (svgData !== "") {
7650
- let ctx = CanvasProvider.getContext(),
7651
- p = new Path2D(svgData);
7652
- ctx.lineWidth = Math.max(this.strokeWidth, 2.5);
7653
- ctx.stroke(p);
7654
- return ctx.isPointInPath(p, x, y);
7655
- }
7685
+ let irregular2Ds = [ItemType.Arc, ItemType.Pie, ItemType.Polygon, ItemType.Area];
7686
+ if (irregular2Ds.indexOf(this.firstChild.type) >= 0) {
7687
+ let svgData = this.getSVGPathData();
7688
+ if (svgData !== "") {
7689
+ let ctx = CanvasProvider.getContext(),
7690
+ p = new Path2D(svgData);
7691
+ ctx.lineWidth = Math.max(this.strokeWidth, 2.5);
7692
+ ctx.stroke(p);
7693
+ return ctx.isPointInPath(p, x, y);
7694
+ }
7695
+ }
7656
7696
  if (!this._bounds) {
7657
7697
  this._updateBounds();
7658
7698
  }
@@ -8247,7 +8287,17 @@
8247
8287
  },
8248
8288
 
8249
8289
  markDivided: function(path, collection) {
8290
+ //update axis item argument
8250
8291
  let scene = collection.getScene();
8292
+ let axes = scene.getRelatedAxes(path);
8293
+ for (let a of axes) {
8294
+ if (a._item.classId === path.classId) {
8295
+ a._item = collection;
8296
+ a._items = getPeers(collection, scene);
8297
+ }
8298
+ }
8299
+
8300
+ //update encoding item
8251
8301
  let e = scene.encodings[getEncodingKey(path)];
8252
8302
  if (e) {
8253
8303
  scene.encodings[getEncodingKey(collection)] = {};
@@ -8260,7 +8310,7 @@
8260
8310
  scene.encodings[getEncodingKey(collection)][channel] = enc;
8261
8311
  delete scene.encodings[getEncodingKey(path)][channel];
8262
8312
  }
8263
- if (Object.keys(e) === 0)
8313
+ if (Object.keys(e).length === 0)
8264
8314
  delete scene.encodings[getEncodingKey(path)];
8265
8315
  }
8266
8316
  //TODO: update constraints
@@ -8429,7 +8479,8 @@
8429
8479
  encoding._apply = function() {
8430
8480
  //sort items by centroid
8431
8481
  this.items.sort((a, b) => (a.innerRadius+a.outerRadius)/2 - (b.innerRadius+b.outerRadius)/2);
8432
- let tree = {item: new ArcPath({outerRadius: 0, startAngle: 0, endAngle: 360}), children: []};
8482
+ let outer = Math.min(...this.items.map(d => d.innerRadius));
8483
+ let tree = {item: new ArcPath({outerRadius: outer, startAngle: 0, endAngle: 360}), children: []};
8433
8484
  for (let itm of this.items) {
8434
8485
  addToTree(tree, itm);
8435
8486
  }
@@ -9214,8 +9265,15 @@
9214
9265
  let arr = Array.isArray(itm) ? itm : [itm];
9215
9266
  let encs = [], scale;
9216
9267
  for (let item of arr) {
9217
- this._validateEncodeArgs(item, args);
9218
9268
  let items;
9269
+ if ([ItemType.Pie, ItemType.Arc].indexOf(itm.type) >= 0 && args.channel === "angle") {
9270
+ let parent = itm.parent;
9271
+ if (parent.type === ItemType.Collection && parent.layout && parent.layout.orientation === Orientation.Angular) {
9272
+ encs.push(this._encodeWithinCollection(item, args));
9273
+ continue;
9274
+ }
9275
+ }
9276
+ this._validateEncodeArgs(item, args);
9219
9277
  if (item.type == "vertex" && item.parent.type == ItemType.Area){
9220
9278
  let areas = getPeers(item.parent, this);
9221
9279
  items = [];
@@ -9320,7 +9378,7 @@
9320
9378
  return encoding;
9321
9379
  }
9322
9380
 
9323
- encodeWithinCollection(item, args) {
9381
+ _encodeWithinCollection(item, args) {
9324
9382
  this._validateEncodeArgs(item, args);
9325
9383
  let peersByGroup = getPeersGroupedByParent(item, this);
9326
9384
  let encs = [];
@@ -9376,11 +9434,20 @@
9376
9434
  //optional arguments include orientation, x-coordinate, y-coordinate, tickFormat, strokeColor,
9377
9435
  axis(channel, field, params) {
9378
9436
  //need to figure out if item has the corresponding encoding, or if item position is determined by layout
9379
- let enc = this.getEncodingByField(field, channel), args = params ? params : {};
9437
+ let args = params ? params : {}, enc = args.item ? this.getEncodingByItem(args.item, channel) : this.getEncodingByField(field, channel);
9380
9438
  if (enc) {
9381
9439
  if (enc.datatable.getFieldType(field) === DataType.Date && !("labelFormat" in args)) {
9382
9440
  args.labelFormat = "%m/%d/%y";
9383
9441
  }
9442
+ if (enc.channel === "width") {
9443
+ let existingChannels = this.children.filter(d => d.type === ItemType.Axis).map(d => d.channel);
9444
+ if (!("orientation" in args))
9445
+ args.orientation = existingChannels.indexOf("x") >= 0? "top" : "bottom";
9446
+ } else if (enc.channel === "height") {
9447
+ let existingChannels = this.children.filter(d => d.type === ItemType.Axis).map(d => d.channel);
9448
+ if (!("orientation" in args))
9449
+ args.orientation = existingChannels.indexOf("y") >= 0? "right" : "left";
9450
+ }
9384
9451
  let axis = new EncodingAxis(enc, args.item? args.item : enc.anyItem, args);
9385
9452
  if ("tickValues" in args) {
9386
9453
  axis.tickValues = args["tickValues"];
@@ -9542,6 +9609,8 @@
9542
9609
  removeEncoding(enc) {
9543
9610
  let key = getEncodingKey(enc.anyItem);
9544
9611
  delete this.encodings[key][enc.channel];
9612
+ if (Object.keys(this.encodings[key]).length === 0)
9613
+ delete this.encodings[key];
9545
9614
  let toRemove = [];
9546
9615
  for (let c of this.children) {
9547
9616
  if (isGuide(c) && c.encoding && c.encoding === enc){
@@ -9568,6 +9637,7 @@
9568
9637
 
9569
9638
  reCreateRelatedAxes(item) {
9570
9639
  let axes = this.getRelatedAxes(item);
9640
+ let layoutAxisClassIds = [];
9571
9641
  axes.forEach(a => {
9572
9642
  let args = a.toJSON().args;
9573
9643
  if (args.item)
@@ -9575,7 +9645,15 @@
9575
9645
  delete args["tickValues"];
9576
9646
  delete args["labelValues"];
9577
9647
  this.removeItem(a);
9578
- this.axis(a.channel, a.field, args);
9648
+ if (a instanceof LayoutAxis) {
9649
+ if (layoutAxisClassIds.indexOf(a.classId)< 0) {
9650
+ this.axis(a.channel, a.field, args);
9651
+ layoutAxisClassIds.push(a.classId);
9652
+ }
9653
+ } else {
9654
+ this.axis(a.channel, a.field, args);
9655
+ }
9656
+ //toCreate.push({channel: a.channel, field: a.field, args: a.args});
9579
9657
  });
9580
9658
  this._updateBounds();
9581
9659
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mascot-vis",
3
- "version": "1.9.2",
3
+ "version": "1.10.0",
4
4
  "description": "Manipulable Semantic Components in Data Visualization",
5
5
  "scripts": {
6
6
  "build": "rollup --config",