mascot-vis 2.0.0 → 2.1.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,10 +1,10 @@
1
1
  /* eslint-disable */
2
- // version: 2.0.0
2
+ // version: 2.1.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) :
6
6
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msc = {}, global.d3, global.PIXI));
7
- }(this, (function (exports, d3, PIXI) { 'use strict';
7
+ }(this, (function (exports, d3$1, PIXI) { 'use strict';
8
8
 
9
9
  function _interopNamespace(e) {
10
10
  if (e && e.__esModule) return e;
@@ -26,7 +26,7 @@
26
26
  return Object.freeze(n);
27
27
  }
28
28
 
29
- var d3__namespace = /*#__PURE__*/_interopNamespace(d3);
29
+ var d3__namespace = /*#__PURE__*/_interopNamespace(d3$1);
30
30
  var PIXI__namespace = /*#__PURE__*/_interopNamespace(PIXI);
31
31
 
32
32
  class Rectangle {
@@ -129,7 +129,7 @@
129
129
  Radial: "radial"
130
130
  };
131
131
 
132
- const Direction = {
132
+ const Direction$1 = {
133
133
  Up: "up",
134
134
  Down: "down",
135
135
  Left: "left",
@@ -1453,6 +1453,19 @@
1453
1453
  return cmpnt instanceof Path;
1454
1454
  }
1455
1455
 
1456
+ function itemIsRepeatable(itm) {
1457
+ // if (!itm.dataScope)
1458
+ // return true;
1459
+ // else if (itm)
1460
+ // return itm.dataScope.numTuples.length > 1;
1461
+ if ((isMark(itm) || itm.type == ItemType.Glyph) && !itm.dataScope)
1462
+ return true;
1463
+ else if (itm.type === ItemType.Collection)
1464
+ return itm.firstChild.dataScope.numTuples > 1;
1465
+
1466
+ return false;
1467
+ }
1468
+
1456
1469
  const ItemCounter = {
1457
1470
  "area" : 0,
1458
1471
  "rect" : 0,
@@ -2705,8 +2718,8 @@
2705
2718
  _stackArcs() {
2706
2719
  let group = this.group;
2707
2720
  let startAngle = this.startAngle ? this.startAngle : 90,
2708
- dir = this._direction ? this._direction : Direction.Clockwise;
2709
- if (dir === Direction.Clockwise) {
2721
+ dir = this._direction ? this._direction : Direction$1.Clockwise;
2722
+ if (dir === Direction$1.Clockwise) {
2710
2723
  for (let c of group.children) {
2711
2724
  let temp = normalizeAngle(startAngle - c.angle);
2712
2725
  c.adjustAngle(temp, startAngle);
@@ -3221,7 +3234,7 @@
3221
3234
  // Add to collection
3222
3235
  coll.addChild(arc);
3223
3236
  }
3224
- coll.layout = layout("stack", {direction: Direction.Clockwise});
3237
+ coll.layout = layout("stack", {direction: Direction$1.Clockwise});
3225
3238
  // Replace original circle w/ coll of pies
3226
3239
  parent.removeChild(p);
3227
3240
  parent.addChild(coll);
@@ -3284,7 +3297,7 @@
3284
3297
  coll.addChild(pie);
3285
3298
  }
3286
3299
 
3287
- coll.layout = layout("stack", {orientation: Orientation.Angular, direction: Direction.Clockwise});
3300
+ coll.layout = layout("stack", {orientation: Orientation.Angular, direction: Direction$1.Clockwise});
3288
3301
  // Replace original circle w/ coll of pies
3289
3302
  parent.removeChild(p);
3290
3303
  parent.addChild(coll);
@@ -7229,13 +7242,15 @@
7229
7242
  let scale = this.encoding.scale;
7230
7243
  let dt = new DataTable(scale.domain.map(d => ({"category": d, "value": scale.map(d)})));
7231
7244
  let longestText = dt.getUniqueFieldValues("category").sort((a,b) => b.length - a.length)[0];
7245
+ let mark = this.encoding.anyItem;
7246
+ let sw = isPath(mark) && mark.closed ? mark.strokeWidth : 0;
7232
7247
  if (this._orientation === Orientation.Vertical) {
7233
7248
  let titleSize = 0;
7234
7249
  if (this._showTitle) {
7235
7250
  this.addChild(new PointText({fillColor: this._textColor, "fontSize": this._fontSize, "text": f, x: this._x, y: this._y, "anchor": ["left", "top"]}));
7236
7251
  titleSize = parseFloat(this._fontSize) + 5;
7237
7252
  }
7238
- let rect = scene.mark("rect", {"top": this._y + 2 + titleSize, "left": this._x, "width": 10, "height": 10, "strokeWidth": 0, opacity: this.encoding.anyItem.opacity});
7253
+ let rect = scene.mark("rect", {"top": this._y + 2 + titleSize, "left": this._x, "width": 10, "height": 10, "strokeWidth": sw, "strokeColor": mark.strokeColor, "opacity": mark.opacity});
7239
7254
  let text = scene.mark("text", {text: longestText, fillColor: this._textColor, "fontSize": this._fontSize, x: this._x + 20, y: this._y + titleSize, "anchor": ["left", "top"]});
7240
7255
  let glyph = scene.glyph(rect, text);
7241
7256
  let coll = scene.repeat(glyph, dt);
@@ -7245,7 +7260,7 @@
7245
7260
  this.addChild(coll);
7246
7261
  } else {
7247
7262
  //do not show title for now
7248
- let rect = scene.mark("rect", {"top": this._y, "left": this._x, "width": 10, "height": 10, "strokeWidth": 0, opacity: this.encoding.anyItem.opacity});
7263
+ let rect = scene.mark("rect", {"top": this._y, "left": this._x, "width": 10, "height": 10, "strokeWidth": sw, "strokeColor": mark.strokeColor, "opacity": this.encoding.anyItem.opacity});
7249
7264
  let text = scene.mark("text", {text: longestText, fillColor: this._textColor, "fontSize": this._fontSize, x: this._x + 15, y: this._y, "anchor": ["left", "top"]});
7250
7265
  let glyph = scene.glyph(rect, text);
7251
7266
  let coll = scene.repeat(glyph, dt);
@@ -9052,8 +9067,8 @@
9052
9067
  }
9053
9068
 
9054
9069
  function _doCircleStratify(scene, compnt, dir, sz, tree) {
9055
- let toReturn, direction = dir ? dir : Direction.Outward, size = sz ? sz : 50;
9056
- if (direction !== Direction.Inward && direction !== Direction.Outward) {
9070
+ let toReturn, direction = dir ? dir : Direction$1.Outward, size = sz ? sz : 50;
9071
+ if (direction !== Direction$1.Inward && direction !== Direction$1.Outward) {
9057
9072
  throw Errors.UNKNOWN_DIRECTION + " " + direction;
9058
9073
  }
9059
9074
  let peers = getPeers(compnt, scene);
@@ -9124,8 +9139,8 @@
9124
9139
  }
9125
9140
 
9126
9141
  function _doRectStratify(scene, compnt, dir, sz, tree) {
9127
- let toReturn, direction = dir ? dir : Direction.Down, size = sz ? sz : 50;
9128
- if ([Direction.Up, Direction.Down, Direction.Left, Direction.Right].indexOf(direction) < 0) {
9142
+ let toReturn, direction = dir ? dir : Direction$1.Down, size = sz ? sz : 50;
9143
+ if ([Direction$1.Up, Direction$1.Down, Direction$1.Left, Direction$1.Right].indexOf(direction) < 0) {
9129
9144
  throw Errors.UNKNOWN_DIRECTION + " " + direction;
9130
9145
  }
9131
9146
  let peers = getPeers(compnt, scene);
@@ -9157,10 +9172,10 @@
9157
9172
  if (children.length === 0) return;
9158
9173
  let x, y, width;
9159
9174
  switch (direction) {
9160
- case Direction.Up:
9161
- case Direction.Down:
9162
- case Direction.Left:
9163
- case Direction.Right:
9175
+ case Direction$1.Up:
9176
+ case Direction$1.Down:
9177
+ case Direction$1.Left:
9178
+ case Direction$1.Right:
9164
9179
  default:
9165
9180
  x = compnt.left;
9166
9181
  y = compnt.bottom;
@@ -9190,95 +9205,6 @@
9190
9205
  }
9191
9206
  }
9192
9207
 
9193
- class Interaction {
9194
-
9195
- constructor(listener, eventType, selDef, targetDef) {
9196
- this._listener = listener;
9197
- this._eventType = eventType;
9198
- this._selDef = selDef;
9199
- this._targetDef = targetDef;
9200
- }
9201
-
9202
- getCallbackFunction(scene, handler) {
9203
- let i = this;
9204
- return function(e){
9205
- e.stopPropagation();
9206
- let sel = handler._getSelection(e, i.selectionDef, i._listener, scene.getItem(d3__namespace.select(this).attr("id")));
9207
- let targets = getPeers(i.targetDef.item, scene);
9208
- let predicates;
9209
- if (i.selectionDef.remember) {
9210
- handler.addGlobalPredicate(scene, sel.predicate);
9211
- predicates = handler.getGlobalPredicates(scene);
9212
- } else {
9213
- predicates = handler.getGlobalPredicates(scene).concat([sel.predicate]);
9214
- }
9215
- for (let t of targets) {
9216
- let selected = true;
9217
- for (let p of predicates) {
9218
- if (!evaluatePredicate(t, p)) {
9219
- selected = false;
9220
- break;
9221
- }
9222
- }
9223
- for (let c in i.targetDef.effect) {
9224
- if (!(c in t.staticProperties))
9225
- t.staticProperties[c] = t[c];
9226
- if (selected) {
9227
- t[c] = i.targetDef.effect[c].selected;
9228
- } else if ("unselected" in i.targetDef.effect[c]) {
9229
- t[c] = i.targetDef.effect[c].unselected;
9230
- } else if (c in t.staticProperties) {
9231
- t[c] = t.staticProperties[c];
9232
- }
9233
- }
9234
- }
9235
- // console.log(handler.getGlobalPredicates(scene));
9236
- handler._renderer.render(scene, {visualOnly: true});
9237
- }
9238
- }
9239
-
9240
- getRestoreFunction(scene, handler, clearGlobalPredicates) {
9241
- let i = this;
9242
- return function(){
9243
- let targets = getPeers(i.targetDef.item, scene);
9244
- if (i.targetDef.effect) {
9245
- for (let t of targets) {
9246
- for (let c in i.targetDef.effect)
9247
- t[c] = t.staticProperties[c];
9248
- //delete t.staticProperties[c];
9249
- }
9250
- } else {
9251
- for (let t of targets) {
9252
- for (let c in t.staticProperties)
9253
- t[c] = t.staticProperties[c];
9254
- //t.staticProperties = {};
9255
- }
9256
- }
9257
-
9258
- if (clearGlobalPredicates)
9259
- handler._globalPredicates = {};
9260
-
9261
- handler._renderer.render(scene, {visualOnly: true});
9262
- }
9263
- }
9264
-
9265
- get listener() {
9266
- return this._listener;
9267
- }
9268
-
9269
- get selectionDef() {
9270
- return this._selDef;
9271
- }
9272
-
9273
- get targetDef() {
9274
- return this._targetDef;
9275
- }
9276
-
9277
- get eventType() {
9278
- return this._eventType;
9279
- }
9280
- }
9281
-
9282
9208
  function classifyCollectionChildren(scene, c, field, layout) {
9283
9209
  let peers = getPeers(c, scene);
9284
9210
  for (let p of peers) {
@@ -9315,9 +9241,9 @@
9315
9241
  //return results;
9316
9242
  }
9317
9243
 
9318
- class Scene extends Group{
9244
+ class Scene extends Group {
9319
9245
 
9320
- constructor(args){
9246
+ constructor(args) {
9321
9247
  super();
9322
9248
  if (args && args.fillColor) {
9323
9249
  this.fillColor = args.fillColor;
@@ -9329,6 +9255,7 @@
9329
9255
  this.constraints = {};
9330
9256
  this._itemMap = {};
9331
9257
  this._interactions = [];
9258
+ this._interactionsObj = {};
9332
9259
  }
9333
9260
 
9334
9261
  clear() {
@@ -9350,10 +9277,10 @@
9350
9277
  }
9351
9278
 
9352
9279
  mark(type, param) {
9353
- let args = param === undefined ? {} : param;
9280
+ let args = param === undefined ? {} : param;
9354
9281
  let m = null;
9355
9282
  args.type = type;
9356
- switch(type) {
9283
+ switch (type) {
9357
9284
  case ItemType.Rect: {
9358
9285
  if (!("top" in args))
9359
9286
  args.top = 0;
@@ -9376,7 +9303,7 @@
9376
9303
  break;
9377
9304
  }
9378
9305
  case ItemType.Area:
9379
- if (args !== undefined && "x1" in args && "y1" in args && "x2" in args && "y2" in args) {
9306
+ if (args !== undefined && "x1" in args && "y1" in args && "x2" in args && "y2" in args) {
9380
9307
  let x1 = args["x1"], y1 = args["y1"], x2 = args["x2"], y2 = args["y2"];
9381
9308
  // args.vertices contains all the vertices on two boundary lines
9382
9309
  args.vertices = [[x1, y1], [x2, y1], [x2, y2], [x1, y2]];
@@ -9389,7 +9316,7 @@
9389
9316
  break;
9390
9317
  case ItemType.Line: {
9391
9318
  //it is possible to create a skeleton line without x1, y1, x2, y2 args, e.g. when duplicating
9392
- if (args !== undefined && "x1" in args && "y1" in args && "x2" in args && "y2" in args) {
9319
+ if (args !== undefined && "x1" in args && "y1" in args && "x2" in args && "y2" in args) {
9393
9320
  let x1 = args["x1"], y1 = args["y1"], x2 = args["x2"], y2 = args["y2"];
9394
9321
  args.vertices = [[x1, y1], [x2, y2]];
9395
9322
  //remove x1, y1, x2, y2 and compute these values at rendering time
@@ -9406,7 +9333,7 @@
9406
9333
  case ItemType.Path:
9407
9334
  m = new Path(args);
9408
9335
  break;
9409
- case ItemType.Circle:
9336
+ case ItemType.Circle:
9410
9337
  m = new CirclePath(args);
9411
9338
  break;
9412
9339
  case ItemType.Ring:
@@ -9451,7 +9378,7 @@
9451
9378
  return m;
9452
9379
  }
9453
9380
 
9454
- glyph(...args){
9381
+ glyph(...args) {
9455
9382
  let g = new Glyph(args);
9456
9383
  g.classId = g.id;
9457
9384
  this.addChild(g);
@@ -9471,7 +9398,7 @@
9471
9398
  }
9472
9399
 
9473
9400
  repeat(item, data, param) {
9474
- if (!item || data === undefined){
9401
+ if (!item || data === undefined) {
9475
9402
  throw Errors.INCOMPLETE_REPEAT_INFO;
9476
9403
  }
9477
9404
 
@@ -9481,8 +9408,8 @@
9481
9408
  return repeatNodeLink(this, item[0], item[1], data);
9482
9409
  } else {
9483
9410
  let args = param ? param : {},
9484
- field = args["field"] ? args["field"] : DataTable.RowID,
9485
- callback = args["callback"];
9411
+ field = args["field"] ? args["field"] : DataTable.RowID,
9412
+ callback = args["callback"];
9486
9413
 
9487
9414
  validateField(field, data);
9488
9415
 
@@ -9494,7 +9421,7 @@
9494
9421
  }
9495
9422
 
9496
9423
  repopulate(item, table, param) {
9497
- if (!item || table === undefined){
9424
+ if (!item || table === undefined) {
9498
9425
  throw Errors.INCOMPLETE_REPEAT_INFO;
9499
9426
  }
9500
9427
 
@@ -9506,11 +9433,11 @@
9506
9433
  }
9507
9434
 
9508
9435
  densify(item, table, param) {
9509
- if (!item || table === undefined){
9436
+ if (!item || table === undefined) {
9510
9437
  throw Errors.INCOMPLETE_PARTITION_INFO;
9511
9438
  }
9512
9439
 
9513
- let args = param ? param : {},
9440
+ let args = param ? param : {},
9514
9441
  orientation = args["orientation"],
9515
9442
  field = args["field"] ? args["field"] : DataTable.RowID,
9516
9443
  //following two are for circle densification
@@ -9519,7 +9446,7 @@
9519
9446
  callback = args["callback"];
9520
9447
 
9521
9448
  validateField(field, table);
9522
-
9449
+
9523
9450
  let newItem = densifyItem(this, item, orientation, field, table, callback, startAngle, direction);
9524
9451
  SceneValidator.markDensified(item, newItem);
9525
9452
  return newItem;
@@ -9537,14 +9464,14 @@
9537
9464
  let args = param ? param : {},
9538
9465
  direction = args["direction"],
9539
9466
  size = args["size"];
9540
-
9467
+
9541
9468
  let collection = stratifyItem(this, item, direction, size, data);
9542
9469
  //SceneValidator.markDivided(item, collection);
9543
9470
  return collection;
9544
9471
  }
9545
9472
 
9546
9473
  divide(item, data, param) {
9547
- if (!item || data == undefined){
9474
+ if (!item || data == undefined) {
9548
9475
  throw Errors.INCOMPLETE_PARTITION_INFO;
9549
9476
  }
9550
9477
 
@@ -9554,7 +9481,7 @@
9554
9481
  callback = args["callback"];
9555
9482
 
9556
9483
  validateField(field, data);
9557
-
9484
+
9558
9485
  let collection = divideItem(this, item, orientation, field, data, callback);
9559
9486
  if (args.layout)
9560
9487
  collection.layout = args.layout;
@@ -9563,8 +9490,8 @@
9563
9490
  return collection;
9564
9491
  }
9565
9492
 
9566
- classify(item, param){
9567
- if (!canClassify(item)){
9493
+ classify(item, param) {
9494
+ if (!canClassify(item)) {
9568
9495
  throw Errors.CANNOT_CLASSIFY + item.type;
9569
9496
  }
9570
9497
 
@@ -9573,7 +9500,7 @@
9573
9500
  dt = item.firstChild.dataScope.dataTable,
9574
9501
  layout = args.layout;
9575
9502
  validateField(field, dt);
9576
-
9503
+
9577
9504
  classifyCollectionChildren(this, item, field, layout);
9578
9505
 
9579
9506
  //SceneValidator.markDivided(item, collection);
@@ -9595,11 +9522,11 @@
9595
9522
  } else if (!item.dataScope) {
9596
9523
  throw Errors.BIND_WITHOUT_DATASCOPE;
9597
9524
  }
9598
-
9525
+
9599
9526
 
9600
9527
  let datatable = args.table ? args.table : item.dataScope ? item.dataScope._dt : item.parent.dataScope._dt;
9601
9528
 
9602
- let ft= datatable.getFieldType(field);
9529
+ let ft = datatable.getFieldType(field);
9603
9530
  if (args.channel === "fillGradient" && [DataType.String, DataType.Boolean, DataType.Date].indexOf(ft) >= 0)
9604
9531
  throw Errors.UNSUPPORTED_FIELDTYPE + args.channel + ": " + ft;
9605
9532
 
@@ -9609,7 +9536,7 @@
9609
9536
 
9610
9537
  //supports encoding one single item or an array of items (which will use the same scale)
9611
9538
  encode(itm, args) {
9612
- let arr = Array.isArray(itm) ? itm : [itm];
9539
+ let arr = Array.isArray(itm) ? itm : [itm];
9613
9540
  let encs = [], scale;
9614
9541
  for (let item of arr) {
9615
9542
  let items;
@@ -9621,12 +9548,12 @@
9621
9548
  }
9622
9549
  }
9623
9550
  this._validateEncodeArgs(item, args);
9624
- if (item.type == "vertex" && item.parent.type == ItemType.Area){
9551
+ if (item.type == "vertex" && item.parent.type == ItemType.Area) {
9625
9552
  let areas = getPeers(item.parent, this);
9626
9553
  items = [];
9627
- let firstHalf = item.parent.vertices.indexOf(item) < item.parent.vertices.length/2;
9628
- for (let area of areas){
9629
- items = firstHalf ? items.concat(area.vertices.slice(0, area.vertices.length/2)) : items.concat(area.vertices.slice(area.vertices.length/2));
9554
+ let firstHalf = item.parent.vertices.indexOf(item) < item.parent.vertices.length / 2;
9555
+ for (let area of areas) {
9556
+ items = firstHalf ? items.concat(area.vertices.slice(0, area.vertices.length / 2)) : items.concat(area.vertices.slice(area.vertices.length / 2));
9630
9557
  }
9631
9558
  } else {
9632
9559
  items = getPeers(item, this);
@@ -9642,8 +9569,8 @@
9642
9569
  if (!scale)
9643
9570
  scale = enc.scale;
9644
9571
  encs.push(enc);
9645
- }
9646
-
9572
+ }
9573
+
9647
9574
  return encs.length > 1 ? encs : encs[0];
9648
9575
  }
9649
9576
 
@@ -9651,7 +9578,7 @@
9651
9578
  let item = items[0],
9652
9579
  channel = args["channel"],
9653
9580
  field = args["field"];
9654
-
9581
+
9655
9582
  if (!("datatable" in args))
9656
9583
  args.datatable = item.dataScope ? item.dataScope.dataTable : item.parent.dataScope.dataTable;
9657
9584
  if (!("aggregator" in args))
@@ -9698,7 +9625,7 @@
9698
9625
  case "fillGradient":
9699
9626
  if (item.type === ItemType.Area)
9700
9627
  bindToAreaMark(encoding);
9701
- break;
9628
+ break;
9702
9629
  case "angle":
9703
9630
  bindToAngle(encoding);
9704
9631
  break;
@@ -9716,7 +9643,7 @@
9716
9643
  break;
9717
9644
  }
9718
9645
 
9719
- if (!("_remember" in args) || args._remember == true)
9646
+ if (!("_remember" in args) || args._remember == true)
9720
9647
  this._registerBinding(encoding);
9721
9648
 
9722
9649
  if (channel.indexOf("Color") < 0)
@@ -9749,7 +9676,7 @@
9749
9676
  //if so, do nothing and return false
9750
9677
  if (!canAlign(items, direction, this)) return false;
9751
9678
  let c = new AlignConstraint(items, direction);
9752
- if (c.id in this.constraints){
9679
+ if (c.id in this.constraints) {
9753
9680
  console.warn('constraint has been added');
9754
9681
  return false;
9755
9682
  }
@@ -9790,7 +9717,7 @@
9790
9717
  itemAnchor = "itemAnchor" in args ? args.itemAnchor : (channel == "x" || channel == "angle") ? "center" : "middle",
9791
9718
  baseAnchor = "baseAnchor" in args ? args.baseAnchor : (channel == "x" || channel == "angle") ? "center" : "middle";
9792
9719
  let c = new AffixConstraint(item, baseItem, this, channel, itemAnchor, baseAnchor, offset);
9793
- if (c.id in this.constraints);
9720
+ if (c.id in this.constraints) ;
9794
9721
  this.constraints[c.id] = c;
9795
9722
  c.apply();
9796
9723
  }
@@ -9807,13 +9734,13 @@
9807
9734
  if (enc.channel === "width") {
9808
9735
  let existingChannels = this.children.filter(d => d.type === ItemType.Axis).map(d => d.channel);
9809
9736
  if (!("orientation" in args))
9810
- args.orientation = existingChannels.indexOf("x") >= 0? "top" : "bottom";
9737
+ args.orientation = existingChannels.indexOf("x") >= 0 ? "top" : "bottom";
9811
9738
  } else if (enc.channel === "height") {
9812
9739
  let existingChannels = this.children.filter(d => d.type === ItemType.Axis).map(d => d.channel);
9813
9740
  if (!("orientation" in args))
9814
- args.orientation = existingChannels.indexOf("y") >= 0? "right" : "left";
9741
+ args.orientation = existingChannels.indexOf("y") >= 0 ? "right" : "left";
9815
9742
  }
9816
- let axis = new EncodingAxis(enc, args.item? args.item : enc.anyItem, args);
9743
+ let axis = new EncodingAxis(enc, args.item ? args.item : enc.anyItem, args);
9817
9744
  if ("tickValues" in args) {
9818
9745
  axis.tickValues = args["tickValues"];
9819
9746
  axis.labelValues = args["tickValues"];
@@ -9821,15 +9748,15 @@
9821
9748
  axis.tickValues = enc._inferTickValues();
9822
9749
  axis.labelValues = enc._inferTickValues();
9823
9750
  }
9824
-
9751
+
9825
9752
  this.addChildAt(axis, 0);
9826
9753
  this._itemMap[axis.id] = axis;
9827
9754
  this._updateBounds();
9828
9755
  return axis;
9829
- }
9830
-
9756
+ }
9757
+
9831
9758
  //TODO: find out item from the field
9832
- let item = args.item? args.item : findItems(this, [{"field": field}])[0];
9759
+ let item = args.item ? args.item : findItems(this, [{ "field": field }])[0];
9833
9760
  if (item === undefined) {
9834
9761
  console.warn(Warnings.INCORRECT_AXIS_INFO + field);
9835
9762
  return;
@@ -9845,7 +9772,7 @@
9845
9772
  // if (args.item)
9846
9773
  // groups = [args.item.parent];
9847
9774
  for (let c of groups) {
9848
- let itm = findItems(c, [{"field": field}])[0];
9775
+ let itm = findItems(c, [{ "field": field }])[0];
9849
9776
  let items = getPeers(itm, c);
9850
9777
  if (itm.dataScope.dataTable.getFieldType(field) === DataType.Date && !("labelFormat" in args)) {
9851
9778
  args.labelFormat = "%m/%d/%y";
@@ -9888,7 +9815,7 @@
9888
9815
  if (found) break;
9889
9816
  else p = p.children[0];
9890
9817
  }
9891
-
9818
+
9892
9819
  //handle axis if the updated item is a group/collection
9893
9820
  let allChildren = getAllChildren(item);
9894
9821
  let map = {};
@@ -9978,7 +9905,7 @@
9978
9905
  delete this.encodings[key];
9979
9906
  let toRemove = [];
9980
9907
  for (let c of this.children) {
9981
- if (isGuide(c) && c.encoding && c.encoding === enc){
9908
+ if (isGuide(c) && c.encoding && c.encoding === enc) {
9982
9909
  toRemove.push(c);
9983
9910
  }
9984
9911
  }
@@ -10011,7 +9938,7 @@
10011
9938
  delete args["labelValues"];
10012
9939
  this.removeItem(a);
10013
9940
  if (a instanceof LayoutAxis) {
10014
- if (layoutAxisClassIds.indexOf(a.classId)< 0) {
9941
+ if (layoutAxisClassIds.indexOf(a.classId) < 0) {
10015
9942
  this.axis(a.channel, a.field, args);
10016
9943
  layoutAxisClassIds.push(a.classId);
10017
9944
  }
@@ -10035,12 +9962,12 @@
10035
9962
  this._updateBounds();
10036
9963
  }
10037
9964
 
10038
- legend(channel, field, param){
9965
+ legend(channel, field, param) {
10039
9966
  let args = param ? param : {};
10040
9967
  let enc = this.getEncodingByField(field, channel);
10041
9968
  if (!enc)
10042
9969
  throw Errors.INCORRECT_LEGEND_INFO + field;
10043
-
9970
+
10044
9971
  if (!("x" in args))
10045
9972
  args["x"] = 100;
10046
9973
  if (!("y" in args))
@@ -10052,17 +9979,17 @@
10052
9979
  return legend;
10053
9980
  }
10054
9981
 
10055
- gridlines(channel, field, params){
9982
+ gridlines(channel, field, params) {
10056
9983
  let enc = this.getEncodingByField(field, channel), args = params ? params : {};
10057
9984
  if (!enc) return false;
10058
9985
  let gl = new Gridlines(enc, args.item ? args.item : enc.anyItem, args);
10059
-
9986
+
10060
9987
  if ("values" in args) {
10061
9988
  gl.values = args["values"];
10062
9989
  } else {
10063
9990
  gl.values = enc._inferTickValues();
10064
9991
  }
10065
-
9992
+
10066
9993
  this.addChildAt(gl, 0);
10067
9994
  this._itemMap[gl.id] = gl;
10068
9995
  this._updateBounds();
@@ -10136,7 +10063,7 @@
10136
10063
  return gl;
10137
10064
  }
10138
10065
 
10139
- propagate(item, method, ...args){
10066
+ propagate(item, method, ...args) {
10140
10067
  let peers = getPeers(item, this);
10141
10068
  for (let p of peers)
10142
10069
  p[method](...args);
@@ -10242,12 +10169,12 @@
10242
10169
  else
10243
10170
  peers.forEach(d => d.resize(d.bounds.width, args[p], undefined, args["yRef"]));
10244
10171
  } else if (item.type == ItemType.Circle && p == "radius") {
10245
- peers.forEach(d => d.resize(args[p]*2, args[p]*2, args["xRef"], args["yRef"]));
10172
+ peers.forEach(d => d.resize(args[p] * 2, args[p] * 2, args["xRef"], args["yRef"]));
10246
10173
  } else {
10247
10174
  peers.forEach(d => d[p] = args[p]);
10248
10175
  }
10249
10176
  }
10250
-
10177
+
10251
10178
  } else if (item.type == "collection" || item.type == "group") {
10252
10179
  for (let c of peers) {
10253
10180
  for (let p in args) {
@@ -10268,7 +10195,7 @@
10268
10195
  }
10269
10196
  }
10270
10197
 
10271
- if (props.indexOf("baseline") >=0 && item.type === ItemType.Area)
10198
+ if (props.indexOf("baseline") >= 0 && item.type === ItemType.Area)
10272
10199
  SceneValidator.areaRebased(item, peers);
10273
10200
 
10274
10201
  let layoutProps = ["layout", "rowGap", "colGap", "numRows", "numCols", "orientation", "vertCellAlignment", "horzCellAlignment", "direction", "childrenOrder"];
@@ -10281,7 +10208,7 @@
10281
10208
  }
10282
10209
 
10283
10210
  _canTranslate(item) {
10284
- let r = {x: true, y: true};
10211
+ let r = { x: true, y: true };
10285
10212
  if (item.type == ItemType.Axis) {
10286
10213
  if (item.channel === "x" || item.channel === "width")
10287
10214
  r.x = false;
@@ -10315,9 +10242,9 @@
10315
10242
  _updateAncestorBounds(cpnt, cpntPeers) {
10316
10243
  let peers = cpntPeers ? cpntPeers : getPeers(cpnt, this);
10317
10244
  let parents = getParents(peers);
10318
-
10245
+
10319
10246
  while (parents.length > 0) {
10320
- for (let p of parents) {
10247
+ for (let p of parents) {
10321
10248
  if (p.children && p.children.length > 0) {
10322
10249
  p._updateBounds();
10323
10250
  } else if (p.vertices) {
@@ -10377,7 +10304,7 @@
10377
10304
  for (let p of parents) {
10378
10305
  if (p.layout) {
10379
10306
  p.layout.run();
10380
- }
10307
+ }
10381
10308
  if (p.children && p.children.length > 0) {
10382
10309
  p._updateBounds();
10383
10310
  }
@@ -10389,13 +10316,13 @@
10389
10316
  }
10390
10317
  }
10391
10318
 
10392
- _reapplySizeBindings(compnt){
10319
+ _reapplySizeBindings(compnt) {
10393
10320
  let sizeChannels = ["width", "height"];
10394
10321
  for (let classId in this.encodings) {
10395
- if (compnt.classId != classId) continue;
10322
+ if (compnt.classId != classId) continue;
10396
10323
  let encodings = this.encodings[classId];
10397
10324
  //TODO: re-use bindSpec and adjust scale accordingly
10398
- let peers = findItems(this, [{"classId": classId}]);
10325
+ let peers = findItems(this, [{ "classId": classId }]);
10399
10326
  for (let channel of sizeChannels) {
10400
10327
  let encoding = encodings[channel];
10401
10328
  if (!encoding) continue;
@@ -10460,7 +10387,7 @@
10460
10387
  break;
10461
10388
  } else if (c.children && c.children.length > 0) {
10462
10389
  let itm = c.firstChild;
10463
- while(itm) {
10390
+ while (itm) {
10464
10391
  if (itm.dataScope) {
10465
10392
  tables[itm.dataScope.dataTable.id] = itm.dataScope.dataTable;
10466
10393
  break;
@@ -10489,38 +10416,579 @@
10489
10416
  }
10490
10417
  }
10491
10418
 
10492
- addInteraction(listener, eventType, selDef, targetDef) {
10493
- let i = new Interaction(listener, eventType, selDef, targetDef);
10494
- this._interactions.push(i);
10419
+ addInteraction(obj) {
10420
+ // let i = new Interaction(listener, eventType, selDef, targetDef);
10421
+ this._interactions.push(obj);
10422
+ this._interactionsObj[obj['event']] = obj;
10495
10423
  }
10496
10424
  }
10497
10425
 
10426
+ const Direction = {
10427
+ North: 'N',
10428
+ South: 'S',
10429
+ East: 'E',
10430
+ West: 'W',
10431
+ NorthEast: 'NE',
10432
+ NorthWest: 'NW',
10433
+ SouthEast: 'SE',
10434
+ SouthWest: 'SW',
10435
+ Move: 'M'
10436
+ };
10437
+
10438
+ class Brush {
10439
+
10440
+ // Resize Corners and handling Bounds
10441
+
10442
+ SVG = null;
10443
+ drag = false;
10444
+ selection = [];
10445
+ mouseDown = false;
10446
+ rectSvg = null;
10447
+ bounds = null;
10448
+ brushColor = '#9c3131';
10449
+
10450
+ dir = null;
10451
+ bb = [];
10452
+ mouseDownEvent = null;
10453
+
10454
+ constructor(id, brushColor, bounds = null) {
10455
+ this.SVG = d3.select("#" + id).style('cursor', 'crosshair');
10456
+ this.brushColor = brushColor;
10457
+ if (bounds) {
10458
+ this.bounds = bounds;
10459
+ }
10460
+ }
10461
+
10462
+ brush() {
10463
+ document.addEventListener(
10464
+ 'mousedown', ($e) => {
10465
+ this.mouseDownEvent = $e;
10466
+ if (!this.rectSvg) {
10467
+ this.appendRectangles(this.brushColor);
10468
+ }
10469
+ if (this.bounds) {
10470
+ if (!($e.layerX >= this.bounds.left && $e.layerX <= this.bounds.left + this.bounds.width
10471
+ && $e.layerY >= this.bounds.top && $e.layerY <= this.bounds.top + this.bounds.height))
10472
+ return;
10473
+ }
10474
+ this.drag = false;
10475
+ this.mouseDown = true;
10476
+ this.selection = [$e.layerX, $e.layerY];
10477
+
10478
+ let x = this.bb[0];
10479
+ let y = this.bb[1];
10480
+ let height = this.bb[2];
10481
+ let width = this.bb[3];
10482
+ if (this.selection[0] > x + 3 && this.selection[0] < x + width - 3 && (this.selection[1] >= y + height - 3 && this.selection[1] <= y + height + 3)) {
10483
+ this.dir = Direction.South;
10484
+ } else if (this.selection[0] > x + 3 && this.selection[0] < x + width - 3 && (this.selection[1] >= y - 3 && this.selection[1] <= y + 3)) {
10485
+ this.dir = Direction.North;
10486
+ } else if (this.selection[1] > y + 3 && this.selection[1] < y + height - 3 && (this.selection[0] >= x + width - 3 && this.selection[0] <= x + width + 3)) {
10487
+ this.dir = Direction.East;
10488
+ } else if (this.selection[1] > y + 3 && this.selection[1] < y + height - 3 && (this.selection[0] >= x - 3 && this.selection[0] <= x + 3)) {
10489
+ this.dir = Direction.West;
10490
+ } else if (this.selection[0] >= x - 3 && this.selection[0] <= x + 3 && this.selection[1] >= y - 3 && this.selection[1] <= y + 3) {
10491
+ this.dir = Direction.NorthWest;
10492
+ } else if (this.selection[0] >= x - 3 && this.selection[0] <= x + 3 && this.selection[1] >= y + height - 3 && this.selection[1] <= y + height + 3) {
10493
+ this.dir = Direction.SouthWest;
10494
+ } else if (this.selection[0] >= x + width - 3 && this.selection[0] <= x + width + 3 && this.selection[1] >= y - 3 && this.selection[1] <= y + 3) {
10495
+ this.dir = Direction.NorthEast;
10496
+ } else if (this.selection[0] >= x + width - 3 && this.selection[0] <= x + width + 3 && this.selection[1] >= y + height - 3 && this.selection[1] <= y + height + 3) {
10497
+ this.dir = Direction.SouthEast;
10498
+ } else if (this.selection[0] > x + 3 && this.selection[0] < x + width - 3 && this.selection[1] > y + 3 && this.selection[1] < y + height - 3) {
10499
+ this.dir = Direction.Move;
10500
+ } else {
10501
+ this.dir = null;
10502
+ this.updateRectangles(null, $e.layerX, $e.layerY, 0, 0);
10503
+ }
10504
+ });
10505
+
10506
+ document.addEventListener(
10507
+ 'mousemove', ($e) => {
10508
+ if (this.mouseDown) {
10509
+ this.drag = true;
10510
+ if (this.dir == Direction.North) {
10511
+ if ($e.layerY > this.bb[1]) {
10512
+ //pull down
10513
+ if ($e.layerY <= this.bb[1] + this.bb[2])//When we are above bottom line of rect
10514
+ this.updateRectangles(null, this.bb[0], $e.layerY, this.bb[3], this.bb[2] + this.bb[1] - $e.layerY);
10515
+ else//When we go below bottom line of rect
10516
+ this.updateRectangles(null, this.bb[0], this.bb[1] + this.bb[2], this.bb[3], $e.layerY - this.bb[1] - this.bb[2]);
10517
+ } else {
10518
+ // pull up
10519
+ this.updateRectangles(null, this.bb[0], $e.layerY, this.bb[3], this.bb[2] + this.bb[1] - $e.layerY);
10520
+ }
10521
+ } else if (this.dir == Direction.South) {
10522
+ if ($e.layerY > this.bb[1]) {
10523
+ //pull down
10524
+ this.updateRectangles(null, this.bb[0], this.bb[1], this.bb[3], $e.layerY - this.bb[1]);
10525
+ } else {
10526
+ // pull up
10527
+ this.updateRectangles(null, this.bb[0], $e.layerY, this.bb[3], this.bb[1] - $e.layerY);
10528
+ }
10529
+ //x,y,height,width
10530
+ } else if (this.dir == Direction.West) {
10531
+ if ($e.layerX > this.bb[0]) {//Move Right
10532
+ if ($e.layerX <= this.bb[0] + this.bb[3])// When we are to the left of rightmost border
10533
+ this.updateRectangles(null, $e.layerX, this.bb[1], this.bb[3] - $e.layerX + this.bb[0], this.bb[2]);
10534
+ else
10535
+ this.updateRectangles(null, this.bb[0] + this.bb[3], this.bb[1], $e.layerX - this.bb[0] - this.bb[3], this.bb[2]);
10536
+
10537
+ } else {// Move Left
10538
+ this.updateRectangles(null, $e.layerX, this.bb[1], this.bb[3] + this.bb[0] - $e.layerX, this.bb[2]);
10539
+ }
10540
+ } else if (this.dir == Direction.East) {
10541
+ if ($e.layerX > this.bb[0]) {//Move Left
10542
+ this.updateRectangles(null, this.bb[0], this.bb[1], $e.layerX - this.bb[0], this.bb[2]);
10543
+ } else {
10544
+ this.updateRectangles(null, $e.layerX, this.bb[1], this.bb[0] - $e.layerX, this.bb[2]);
10545
+ }
10546
+ }
10547
+ else if (this.dir == Direction.NorthEast) ;
10548
+ else if (this.dir == Direction.NorthWest) ;
10549
+ else if (this.dir == Direction.SouthEast) {
10550
+ //Done
10551
+ if ($e.layerX > this.bb[0] && $e.layerY > this.bb[1]) {
10552
+ //4
10553
+ this.updateRectangles(null, this.bb[0], this.bb[1], $e.layerX - this.bb[0], $e.layerY - this.bb[1]);
10554
+ } else if ($e.layerX > this.bb[0] && $e.layerY < this.bb[1]) {
10555
+ //1
10556
+ this.updateRectangles(null, this.bb[0], $e.layerY, $e.layerX - this.bb[0], this.bb[1] - $e.layerY);
10557
+ } else if ($e.layerX < this.bb[0] && $e.layerY < this.bb[1]) {
10558
+ //2
10559
+ this.updateRectangles(null, $e.layerX, $e.layerY, this.bb[0] - $e.layerX, this.bb[1] - $e.layerY);
10560
+ } else {
10561
+ //3
10562
+ this.updateRectangles(null, $e.layerX, this.bb[1], this.bb[0] - $e.layerX, $e.layerY - this.bb[1]);
10563
+ }
10564
+ }
10565
+ else if (this.dir == Direction.SouthWest) ;
10566
+ else if (this.dir == Direction.Move) {
10567
+ this.updateRectangles(null, this.bb[0] + $e.layerX - this.selection[0], this.bb[1] + $e.layerY - this.selection[1], this.bb[3], this.bb[2]);
10568
+ this.bb[0] = this.bb[0] + $e.layerX - this.selection[0];
10569
+ this.bb[1] = this.bb[1] + $e.layerY - this.selection[1];
10570
+ this.selection = [$e.layerX, $e.layerY];
10571
+ }
10572
+ else {
10573
+ let { __x, __y, __height, __width } = this.getRectCoordinates($e, this.selection);
10574
+ this.updateRectangles(null, __x, __y, __width, __height);
10575
+ }
10576
+ }
10577
+ });
10578
+
10579
+ document.addEventListener(
10580
+ 'mouseup', ($e) => {
10581
+ if (this.mouseDown) {
10582
+ if (this.drag) {
10583
+ console.log('Brush');
10584
+ let bb = this.rectSvg._groups[0][0].getBoundingClientRect();
10585
+ this.bb = [bb.x - 183, bb.y, bb.height, bb.width];
10586
+ document.dispatchEvent(new CustomEvent('brush', {
10587
+ 'detail': { selection: [[bb.x - 183, bb.y], [bb.x - 183 + bb.width, bb.y + bb.height]] },
10588
+ }));
10589
+ // Brush Update here
10590
+ } else {
10591
+ console.log('Click');
10592
+ this.updateRectangles('none');
10593
+ this.bb = [];
10594
+ this.removeRectangles();
10595
+ // Click Update here
10596
+ document.dispatchEvent(new CustomEvent('brush', {
10597
+ 'detail': { e: this.mouseDownEvent },
10598
+ }));
10599
+ }
10600
+ this.selection = [];
10601
+ this.dir = null;
10602
+ this.mouseDown = false;
10603
+ }
10604
+ });
10605
+ return 1;
10606
+ }
10607
+ removeRectangles() {
10608
+ this.rectSvg = null;
10609
+ d3.selectAll('.handle--selection').remove();
10610
+ d3.selectAll('.handle--n').remove();
10611
+ d3.selectAll('.handle--w').remove();
10612
+ d3.selectAll('.handle--e').remove();
10613
+ d3.selectAll('.handle--s').remove();
10614
+ d3.selectAll('.handle--nw').remove();
10615
+ d3.selectAll('.handle--ne').remove();
10616
+ d3.selectAll('.handle--sw').remove();
10617
+ d3.selectAll('.handle--se').remove();
10618
+ d3.selectAll('.handle--overlay').remove();
10619
+
10620
+ }
10621
+ appendRectangles(brushColor) {
10622
+ this.SVG
10623
+ .append('rect')
10624
+ .attr("class", "handle--overlay")
10625
+ .attr("x", "0")
10626
+ .attr("x", "0")
10627
+ .attr("height", this.SVG._groups[0][0].clientHeight)
10628
+ .attr("width", this.SVG._groups[0][0].clientWidth)
10629
+ .style('cursor', 'crosshair')
10630
+ .style("opacity", '0');
10631
+ this.rectSvg = this.SVG
10632
+ .append('rect')
10633
+ .attr("class", "handle--selection")
10634
+ .style("fill", brushColor)
10635
+ .style('cursor', 'move')
10636
+ .style("opacity", '0.3')
10637
+ .attr("display", "none");
10638
+ this.SVG
10639
+ .append('rect')
10640
+ .attr("class", "handle--n")
10641
+ .style('cursor', 'ns-resize')
10642
+ .attr("display", "none")
10643
+ .style("opacity", '0');
10644
+ this.SVG
10645
+ .append('rect')
10646
+ .attr("class", "handle--w")
10647
+ .style('cursor', 'ew-resize')
10648
+ .attr("display", "none")
10649
+ .style("opacity", '0');
10650
+ this.SVG
10651
+ .append('rect')
10652
+ .attr("class", "handle--e")
10653
+ .style('cursor', 'ew-resize')
10654
+ .attr("display", "none")
10655
+ .style("opacity", '0');
10656
+ this.SVG
10657
+ .append('rect')
10658
+ .attr("class", "handle--s")
10659
+ .style('cursor', 'ns-resize')
10660
+ .attr("display", "none")
10661
+ .style("opacity", '0');
10662
+ this.SVG
10663
+ .append('rect')
10664
+ .attr("class", "handle--nw")
10665
+ .style('cursor', 'nwse-resize')
10666
+ .attr("display", "none")
10667
+ .style("opacity", '0');
10668
+ this.SVG
10669
+ .append('rect')
10670
+ .attr("class", "handle--ne")
10671
+ .style('cursor', 'nesw-resize')
10672
+ .attr("display", "none")
10673
+ .style("opacity", '0');
10674
+ this.SVG
10675
+ .append('rect')
10676
+ .attr("class", "handle--sw")
10677
+ .style('cursor', 'nesw-resize')
10678
+ .attr("display", "none")
10679
+ .style("opacity", '0');
10680
+ this.SVG
10681
+ .append('rect')
10682
+ .attr("class", "handle--se")
10683
+ .style('cursor', 'nwse-resize')
10684
+ .attr("display", "none")
10685
+ .style("opacity", '0');
10686
+ }
10687
+ updateRectangles(display = null, __x = null, __y = null, __width = null, __height = null) {
10688
+ d3.selectAll('.handle--selection').attr("display", display).attr("x", __x)
10689
+ .attr("y", __y)
10690
+ .attr("height", __height)
10691
+ .attr("width", __width);
10692
+ d3.selectAll('.handle--n').attr("display", display).attr("x", __x ? __x - 3 : __x)
10693
+ .attr("y", __y ? __y - 3 : __y)
10694
+ .attr("height", __height == 0 || __height ? 6 : __height)
10695
+ .attr("width", __width == 0 || __width ? __width + 6 : __width);
10696
+ d3.selectAll('.handle--w').attr("display", display).attr("x", __x ? __x - 3 : __x)
10697
+ .attr("y", __y ? __y - 3 : __y)
10698
+ .attr("height", __height == 0 || __height ? __height + 6 : __height)
10699
+ .attr("width", __width == 0 || __width ? 6 : __width);
10700
+ d3.selectAll('.handle--e').attr("display", display).attr("x", __x ? __x + __width - 3 : __x)
10701
+ .attr("y", __y ? __y - 3 : __y)
10702
+ .attr("height", __height == 0 || __height ? __height + 6 : __height)
10703
+ .attr("width", __width == 0 || __width ? 6 : __width);
10704
+ d3.selectAll('.handle--s').attr("display", display).attr("x", __x ? __x - 3 : __x)
10705
+ .attr("y", __y ? __y + __height - 3 : __y)
10706
+ .attr("height", __height == 0 || __height ? 6 : __height)
10707
+ .attr("width", __width == 0 || __width ? __width + 6 : __width);
10708
+ d3.selectAll('.handle--nw').attr("display", display).attr("x", __x ? __x - 3 : __x)
10709
+ .attr("y", __y ? __y - 3 : __y)
10710
+ .attr("height", __height == 0 || __height ? 6 : __height)
10711
+ .attr("width", __width == 0 || __width ? 6 : __width);
10712
+ d3.selectAll('.handle--ne').attr("display", display).attr("x", __x ? __x + __width - 3 : __x)
10713
+ .attr("y", __y ? __y - 3 : __y)
10714
+ .attr("height", __height == 0 || __height ? 6 : __height)
10715
+ .attr("width", __width == 0 || __width ? 6 : __width);
10716
+ d3.selectAll('.handle--sw').attr("display", display).attr("x", __x ? __x - 3 : __x)
10717
+ .attr("y", __y ? __y + __height - 3 : __y)
10718
+ .attr("height", __height == 0 || __height ? 6 : __height)
10719
+ .attr("width", __width == 0 || __width ? 6 : __width);
10720
+ d3.selectAll('.handle--se').attr("display", display).attr("x", __x ? __x + __width - 3 : __x)
10721
+ .attr("y", __y ? __y + __height - 3 : __y)
10722
+ .attr("height", __height == 0 || __height ? 6 : __height)
10723
+ .attr("width", __width == 0 || __width ? 6 : __width);
10724
+ }
10725
+ getRectCoordinates($e, selection) {
10726
+ let __x, __y, __width, __height = null;
10727
+ if ($e.layerY - selection[1] < 0) {
10728
+ if ($e.layerX - selection[0] > 0) {
10729
+ // LB-RT x+y-
10730
+ __x = selection[0];
10731
+ __y = $e.layerY;
10732
+ __height = selection[1] - $e.layerY;
10733
+ __width = $e.layerX - selection[0];
10734
+ } else {
10735
+ // RB-LT x-y-
10736
+ __x = $e.layerX;
10737
+ __y = $e.layerY;
10738
+ __height = selection[1] - $e.layerY;
10739
+ __width = selection[0] - $e.layerX;
10740
+
10741
+ }
10742
+ } else {
10743
+ if ($e.layerX - selection[0] > 0) {
10744
+ // LT-BR x+y+
10745
+ __x = selection[0];
10746
+ __y = selection[1];
10747
+ __height = $e.layerY - selection[1];
10748
+ __width = $e.layerX - selection[0];
10749
+ } else {
10750
+ // RT-LB x-y+
10751
+ __x = $e.layerX;
10752
+ __y = selection[1];
10753
+ __height = $e.layerY - selection[1];
10754
+ __width = selection[0] - $e.layerX;
10755
+ }
10756
+ }
10757
+
10758
+ if (this.bounds) {
10759
+ // Bounded
10760
+ if ($e.layerY - selection[1] > 0) {
10761
+ if (__y + __height > this.bounds.top + this.bounds.height) {
10762
+ __height = this.bounds.top + this.bounds.height - selection[1];
10763
+ }
10764
+ } else {
10765
+ if (this.bounds.top + __height > selection[1]) {
10766
+ __y = this.bounds.top;
10767
+ __height = selection[1] - $e.layerY - (this.bounds.top + __height - selection[1]);
10768
+ }
10769
+ }
10770
+
10771
+ if ($e.layerX - selection[0] > 0) {
10772
+ if (__x + __width > this.bounds.left + this.bounds.width) {
10773
+ __width = this.bounds.left + this.bounds.width - selection[0];
10774
+ }
10775
+ } else {
10776
+ if (this.bounds.left + __width > selection[0]) {
10777
+ __x = this.bounds.left;
10778
+ __width = selection[0] - $e.layerX - (this.bounds.left + __width - selection[0]);
10779
+ }
10780
+ }
10781
+ }
10782
+ return { __x, __y, __height, __width };
10783
+ }
10784
+ }
10785
+
10498
10786
  class SVGInteractionHandler {
10499
10787
 
10500
10788
  constructor(svgRenderer) {
10501
10789
  this._renderer = svgRenderer;
10502
10790
  this._globalPredicates = {};
10503
10791
  }
10792
+ created = 0;
10504
10793
 
10505
10794
  processInteraction(i, scene) {
10506
- let listener = i.listener;
10507
- if (isMark(listener)) {
10508
- let selector = listener.classId ? "." + listener.classId : "#" + listener.id;
10509
- switch (i.eventType) {
10510
- case "hover":
10511
- d3__namespace.selectAll(selector).on("mouseover", i.getCallbackFunction(scene, this));
10512
- d3__namespace.selectAll(selector).on("mouseleave", i.getRestoreFunction(scene, this));
10513
- break;
10514
- case "click":
10515
- d3__namespace.selectAll(selector).on("mousedown", i.getCallbackFunction(scene, this));
10516
- break;
10795
+ if (!i.target || !i.targetEval || !i.targetEval['false']) return
10796
+ if (i.listener.type == ItemType.Scene) {
10797
+ const originalProperties = [];
10798
+ getPeers(i.target, scene).forEach(path => {
10799
+ const obj = {};
10800
+ Object.keys(i.targetEval['false']).forEach(prop => {
10801
+ obj[prop] = (path[prop]);
10802
+ });
10803
+ originalProperties.push(obj);
10804
+ });
10805
+ // if (i.event == 'click') {
10806
+ // this._processClick(i, scene, originalProperties);
10807
+ // }
10808
+ if (i.event == 'brush' || i.event == 'click') {
10809
+ if (this.created == 0) {
10810
+ // new Brush(this._renderer._svgId, '#9c3131', null).brush()
10811
+ this.created = new Brush(this._renderer._svgId, '#9c3131', i.hitObject._bounds).brush();
10812
+ document.addEventListener('brush', (e) => {
10813
+ this._processBrush1(i, scene, originalProperties, e.detail.selection ? { selection: e.detail.selection } : null);
10814
+ if (e.detail.selection == undefined) {
10815
+ this._processClick(i, scene, originalProperties, e.detail.e);
10816
+ }
10817
+ });
10818
+ }
10819
+ }
10820
+ }
10821
+ }
10822
+
10823
+
10824
+
10825
+ _processBrush1(i, scene, originalProperties, e) {
10826
+ let brushPredicateEvaluators = {};
10827
+ if (i.event == 'brush') {
10828
+ if (i.predicate.length <= 0) return;
10829
+ i.predicate.forEach(ele => {
10830
+ if (ele.type == 'range') {
10831
+ let rangeData = [];
10832
+ if (i.hitObject.type == 'axis') {
10833
+ i.hitObject._labels.children.forEach(_ => {
10834
+ rangeData.push({
10835
+ axisCoordinate: _[ele.channel], actualValue: _.text
10836
+ });
10837
+ });
10838
+ } else if (i.hitObject.type == 'collection') {
10839
+ i.hitObject.children.forEach(_ => {
10840
+ rangeData.push({
10841
+ axisCoordinate: _[ele.channel], actualValue: _.dataScope.getFieldValue(ele.field)
10842
+ });
10843
+ });
10844
+ }
10845
+ rangeData.sort((a, b) => a.axisCoordinate - b.axisCoordinate);
10846
+ brushPredicateEvaluators[ele.channel] = {
10847
+ _actualLabels: rangeData.map(e => e.actualValue),
10848
+ _axisCoordinates: rangeData.map(e => e.axisCoordinate)
10849
+ };
10850
+ rangeData = null;
10851
+ } else {
10852
+ // Brush should not have other predicates
10853
+ // Confirm with Leo
10854
+ throw new Error(`Event Type Brush should not have ${i.predicate.type} as Predicate Type`)
10855
+ }
10856
+ });
10857
+ }
10858
+ if (e && e.selection) {
10859
+ let _r = {
10860
+ 'x': [e.selection[0][0], e.selection[1][0]],
10861
+ 'y': [e.selection[0][1], e.selection[1][1]]
10862
+ };
10863
+ let _range = { 'x': null, 'y': null };
10864
+
10865
+ Object.entries(brushPredicateEvaluators).forEach(entry => {
10866
+ const [key, value] = entry;
10867
+ let val1 = value._actualLabels[d3__namespace.bisect(value._axisCoordinates, _r[key][0])];
10868
+ let val2 = value._actualLabels[d3__namespace.bisect(value._axisCoordinates, _r[key][1]) - 1];
10869
+ _range[key] = {
10870
+ _high: val1 >= val2 ? val1 : val2,
10871
+ _low: val1 < val2 ? val1 : val2
10872
+ };
10873
+ });
10874
+ let _x = i.predicate.filter(e => _range['x'] && e.channel == 'x')[0];
10875
+ let _y = i.predicate.filter(e => _range['y'] && e.channel == 'y')[0];
10876
+ let _1, _2 = false;
10877
+ getPeers(i.target, scene).forEach((path, _i) => {
10878
+ if (_x) {
10879
+ _1 = _range['x']['_high'] >= path.dataScope.getFieldValue(_x['field']) &&
10880
+ _range['x']['_low'] <= path.dataScope.getFieldValue(_x['field']);
10881
+ }
10882
+ if (_y) {
10883
+ _2 = _range['y']['_high'] >= path.dataScope.getFieldValue(_y['field']) &&
10884
+ _range['y']['_low'] <= path.dataScope.getFieldValue(_y['field']);
10885
+ }
10886
+ if ((_x == undefined && _2) || (_y == undefined && _1) || (_1 && _2)) {
10887
+ this.setTargetProperties(originalProperties[_i], path);
10888
+ } else {
10889
+ this.setTargetProperties(i.targetEval['false'], path);
10890
+ }
10891
+ });
10892
+ } else {
10893
+ getPeers(i.target, scene).forEach((path, _i) => {
10894
+ this.setTargetProperties(originalProperties[_i], path);
10895
+ });
10896
+ }
10897
+ this._renderer.render(scene, { visualOnly: true });
10898
+ }
10899
+
10900
+ _processClick(i, scene, originalProperties, $e) {
10901
+ i = scene._interactionsObj['click'];
10902
+ let multiSelectSet = new Set();
10903
+ if (i.predicate[0].type == 'point') {
10904
+ //continent done
10905
+ //country - can leverage multi select done
10906
+ if ($e.target.id.includes(i.target.type)) {
10907
+ const _ = getPeers(i.target, scene).filter(e => e.id == $e.target.id);
10908
+ if (_.length > 0) {
10909
+ getPeers(i.target, scene).forEach((path, _i) => {
10910
+ if (path.dataScope.getFieldValue(i.predicate[0].field) == _[0].dataScope.getFieldValue(i.predicate[0].field)) {
10911
+ this.setTargetProperties(originalProperties[_i], path);
10912
+ } else {
10913
+ this.setTargetProperties(i.targetEval['false'], path);
10914
+ }
10915
+ });
10916
+ }
10917
+ } else if (i.hitObject.type == 'legend' && i.hitObject.encoding.datatable._fieldSummaries[i.predicate[0].field].unique.includes($e.target.innerHTML)) {
10918
+ getPeers(i.target, scene).forEach((path, _i) => {
10919
+ if (path.dataScope.getFieldValue(i.predicate[0].field) == $e.target.innerHTML) {
10920
+ this.setTargetProperties(originalProperties[_i], path);
10921
+ } else {
10922
+ this.setTargetProperties(i.targetEval['false'], path);
10923
+ }
10924
+ });
10925
+ } else {
10926
+ getPeers(i.target, scene).forEach((path, _i) => {
10927
+ this.setTargetProperties(originalProperties[_i], path);
10928
+ });
10517
10929
  }
10518
- } else if (listener.type == ItemType.Scene) {
10519
- if (!i.targetDef || !i.targetDef.item) return;
10520
- if (!i.selectionDef.item) {
10521
- d3__namespace.select("#"+this._renderer._svgId).on("mousedown", i.getRestoreFunction(scene, this, true));
10930
+ } else if (i.predicate[0].type == 'list') {
10931
+ // countries done
10932
+ // continents
10933
+ if (i.predicate[0].multiByField) {
10934
+ // select Multiple fields by continents for instance
10935
+ if ($e.target.id.includes(i.target.type)) {
10936
+ const _ = getPeers(i.target, scene).filter(e => e.id == $e.target.id);
10937
+ if (_.length > 0) {
10938
+ multiSelectSet.add(_[0].dataScope.getFieldValue(i.predicate[0].field));
10939
+ getPeers(i.target, scene).forEach((path, _i) => {
10940
+ if (multiSelectSet.has(path.dataScope.getFieldValue(i.predicate[0].field))) {
10941
+ this.setTargetProperties(originalProperties[_i], path);
10942
+ } else {
10943
+ this.setTargetProperties(i.targetEval['false'], path);
10944
+ }
10945
+ });
10946
+ }
10947
+ } else {
10948
+ multiSelectSet.clear();
10949
+ getPeers(i.target, scene).forEach((path, _i) => {
10950
+ this.setTargetProperties(originalProperties[_i], path);
10951
+ });
10952
+ }
10953
+ } else {
10954
+ if ($e.target.id.includes(i.target.type)) {
10955
+ if (multiSelectSet.has($e.target.id)) {
10956
+ multiSelectSet.delete($e.target.id); // deselect
10957
+ } else {
10958
+ multiSelectSet.add($e.target.id);
10959
+ }
10960
+ getPeers(i.target, scene).forEach((path, _i) => {
10961
+ if (multiSelectSet.has(path.id)) {
10962
+ this.setTargetProperties(originalProperties[_i], path);
10963
+ } else {
10964
+ this.setTargetProperties(i.targetEval['false'], path);
10965
+ }
10966
+ });
10967
+ } else {
10968
+ multiSelectSet.clear();
10969
+ getPeers(i.target, scene).forEach((path, _i) => {
10970
+ this.setTargetProperties(originalProperties[_i], path);
10971
+ });
10972
+ }
10522
10973
  }
10523
10974
  }
10975
+ this._renderer.render(scene, { visualOnly: true });
10976
+ }
10977
+
10978
+ evaluatePredicate(i, path, _range) {
10979
+ if (i.predicate.type == 'range') {
10980
+ return path.dataScope.getFieldValue(i.predicate.field) <= _[0] && path.dataScope.getFieldValue(i.predicate.field) >= _[1]
10981
+ }
10982
+ }
10983
+
10984
+ setTargetProperties(obj, path) {
10985
+ Object.keys(obj).forEach(prop => {
10986
+ try {
10987
+ path[prop] = obj[prop];
10988
+ } catch (error) {
10989
+ console.log('Property not found');
10990
+ }
10991
+ });
10524
10992
  }
10525
10993
 
10526
10994
  _getSelection(e, selDef, listener, item) {
@@ -10531,7 +10999,7 @@
10531
10999
 
10532
11000
  let field = selDef.field ? selDef.field : atlas_rowId;
10533
11001
  if (selection.item) {
10534
- selection.predicate = {"field": field, "value": selection.item.dataScope.getFieldValue(field)};
11002
+ selection.predicate = { "field": field, "value": selection.item.dataScope.getFieldValue(field) };
10535
11003
  }
10536
11004
  return selection;
10537
11005
  }
@@ -10553,7 +11021,7 @@
10553
11021
  constructor(svgId) {
10554
11022
  this._svgId = svgId;
10555
11023
  this._compMap = {};
10556
- this._decoMap = {};
11024
+ this._decoMap = {};
10557
11025
  this._interactionHandler = new SVGInteractionHandler(this);
10558
11026
  }
10559
11027
 
@@ -24026,7 +24494,7 @@
24026
24494
  let parentMark = node2mark[node[nodeId]];
24027
24495
  let x, y;
24028
24496
  switch (this._direction) {
24029
- case Direction.Down:
24497
+ case Direction$1.Down:
24030
24498
  default:
24031
24499
  x = parentMark.left;
24032
24500
  y = parentMark.bottom;
@@ -24333,18 +24801,24 @@
24333
24801
 
24334
24802
  function canRepeat(compnt) {
24335
24803
  if (Array.isArray(compnt)) {
24336
- for (let c of compnt) {
24337
- if (!isMark(c) || c.dataScope)
24338
- return false;
24804
+ if (compnt.length === 1) {
24805
+ return itemIsRepeatable(compnt[0]);
24806
+ } else {
24807
+ for (let c of compnt) {
24808
+ if (!isMark(c) || c.dataScope)
24809
+ return false;
24810
+ }
24339
24811
  }
24340
24812
  return true;
24341
- } else if ((isMark(compnt) || compnt.type == ItemType.Glyph) && !compnt.dataScope) {
24342
- return true;
24343
- } else if (compnt.type == ItemType.Collection) {
24344
- //TODO: check if repeatable
24345
- return true;
24813
+ } else {
24814
+ return itemIsRepeatable(compnt);
24346
24815
  }
24347
- return false;
24816
+ // else if ((isMark(compnt) || compnt.type == ItemType.Glyph) && !compnt.dataScope) {
24817
+ // return true;
24818
+ // } else if (compnt.type == ItemType.Collection) {
24819
+ // return itemIsRepeatable(compnt);
24820
+ // }
24821
+ //return false;
24348
24822
  }
24349
24823
 
24350
24824
  function canDivide(compnt) {