@decidables/discountable-elements 0.5.0 → 0.6.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/CHANGELOG.md +17 -0
- package/lib/discountableElements.esm.js +308 -188
- package/lib/discountableElements.esm.js.map +1 -1
- package/lib/discountableElements.esm.min.js +75 -55
- package/lib/discountableElements.esm.min.js.map +1 -1
- package/lib/discountableElements.umd.js +308 -188
- package/lib/discountableElements.umd.js.map +1 -1
- package/lib/discountableElements.umd.min.js +76 -56
- package/lib/discountableElements.umd.min.js.map +1 -1
- package/package.json +4 -4
- package/src/colors.yml +2 -2
- package/src/components/htd-curves.js +398 -267
|
@@ -13065,54 +13065,90 @@
|
|
|
13065
13065
|
/* shape-rendering: crispEdges; */
|
|
13066
13066
|
}
|
|
13067
13067
|
|
|
13068
|
-
.
|
|
13069
|
-
|
|
13070
|
-
stroke: var(---color-element-emphasis);
|
|
13071
|
-
stroke-width: 2;
|
|
13068
|
+
.option .interactive {
|
|
13069
|
+
filter: url("#shadow-2");
|
|
13072
13070
|
}
|
|
13073
13071
|
|
|
13074
|
-
.
|
|
13075
|
-
|
|
13076
|
-
|
|
13077
|
-
filter: url("#shadow-2");
|
|
13078
|
-
outline: none;
|
|
13072
|
+
.option .interactive:hover {
|
|
13073
|
+
filter: url("#shadow-4");
|
|
13079
13074
|
}
|
|
13080
13075
|
|
|
13081
|
-
.
|
|
13076
|
+
.option .body.interactive:has(~ .point:hover) {
|
|
13082
13077
|
filter: url("#shadow-4");
|
|
13083
13078
|
}
|
|
13084
13079
|
|
|
13085
|
-
.
|
|
13080
|
+
.option .interactive:active {
|
|
13086
13081
|
filter: url("#shadow-8");
|
|
13087
13082
|
}
|
|
13088
13083
|
|
|
13089
|
-
|
|
13084
|
+
.option .body.interactive:has(~ .point:active) {
|
|
13090
13085
|
filter: url("#shadow-8");
|
|
13091
13086
|
}
|
|
13092
13087
|
|
|
13093
|
-
.
|
|
13094
|
-
|
|
13095
|
-
stroke: var(---color-element-emphasis);
|
|
13096
|
-
stroke-width: 2;
|
|
13088
|
+
:host(.keyboard) .option .interactive:focus-within {
|
|
13089
|
+
filter: url("#shadow-8");
|
|
13097
13090
|
}
|
|
13098
13091
|
|
|
13099
|
-
.
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13092
|
+
:host(.keyboard) .option .body.interactive:has(~ .point:focus-within) {
|
|
13093
|
+
filter: url("#shadow-8");
|
|
13094
|
+
}
|
|
13095
|
+
|
|
13096
|
+
.gradient.sooner stop {
|
|
13097
|
+
stop-color: var(---color-sooner);
|
|
13098
|
+
}
|
|
13099
|
+
|
|
13100
|
+
.gradient.later stop {
|
|
13101
|
+
stop-color: var(---color-later);
|
|
13102
|
+
}
|
|
13103
|
+
|
|
13104
|
+
.stop-0,
|
|
13105
|
+
.stop-before {
|
|
13106
|
+
stop-opacity: 0;
|
|
13107
|
+
}
|
|
13108
|
+
|
|
13109
|
+
.stop-after,
|
|
13110
|
+
.stop-100 {
|
|
13111
|
+
stop-opacity: 1;
|
|
13112
|
+
}
|
|
13113
|
+
|
|
13114
|
+
.fill {
|
|
13115
|
+
fill: var(---color-element-enabled);
|
|
13116
|
+
fill-opacity: 0.5;
|
|
13117
|
+
stroke: none;
|
|
13118
|
+
}
|
|
13119
|
+
|
|
13120
|
+
.interactive .fill {
|
|
13121
|
+
cursor: move;
|
|
13122
|
+
|
|
13103
13123
|
outline: none;
|
|
13104
13124
|
}
|
|
13105
13125
|
|
|
13106
|
-
.
|
|
13107
|
-
|
|
13126
|
+
.sooner .fill {
|
|
13127
|
+
fill: var(---color-sooner);
|
|
13108
13128
|
}
|
|
13109
13129
|
|
|
13110
|
-
.
|
|
13111
|
-
|
|
13130
|
+
.later .fill {
|
|
13131
|
+
fill: var(---color-later);
|
|
13112
13132
|
}
|
|
13113
13133
|
|
|
13114
|
-
|
|
13115
|
-
|
|
13134
|
+
.trial.sooner .fill {
|
|
13135
|
+
fill: url("#sooner-gradient");
|
|
13136
|
+
}
|
|
13137
|
+
|
|
13138
|
+
.trial.later .fill {
|
|
13139
|
+
fill: url("#later-gradient");
|
|
13140
|
+
}
|
|
13141
|
+
|
|
13142
|
+
.bar {
|
|
13143
|
+
fill: none;
|
|
13144
|
+
stroke: var(---color-element-emphasis);
|
|
13145
|
+
stroke-width: 2;
|
|
13146
|
+
}
|
|
13147
|
+
|
|
13148
|
+
.interactive .bar {
|
|
13149
|
+
cursor: ew-resize;
|
|
13150
|
+
|
|
13151
|
+
outline: none;
|
|
13116
13152
|
}
|
|
13117
13153
|
|
|
13118
13154
|
.point .mark {
|
|
@@ -13130,38 +13166,22 @@
|
|
|
13130
13166
|
fill: var(---color-text-inverse);
|
|
13131
13167
|
}
|
|
13132
13168
|
|
|
13133
|
-
.point.
|
|
13169
|
+
.point.interact {
|
|
13134
13170
|
cursor: ns-resize;
|
|
13135
13171
|
|
|
13136
|
-
filter: url("#shadow-2");
|
|
13137
13172
|
outline: none;
|
|
13138
|
-
|
|
13139
|
-
/* HACK: This gets Safari to correctly apply the filter! */
|
|
13140
|
-
/* https://github.com/emilbjorklund/svg-weirdness/issues/27 */
|
|
13141
|
-
stroke: #000000;
|
|
13142
|
-
stroke-opacity: 0;
|
|
13143
|
-
stroke-width: 0;
|
|
13144
13173
|
}
|
|
13145
13174
|
|
|
13146
|
-
.
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
|
|
13150
|
-
stroke: #ff0000;
|
|
13151
|
-
}
|
|
13152
|
-
|
|
13153
|
-
.point.interactive:active {
|
|
13154
|
-
filter: url("#shadow-8");
|
|
13155
|
-
|
|
13156
|
-
/* HACK: This gets Safari to correctly apply the filter! */
|
|
13157
|
-
stroke: #00ff00;
|
|
13175
|
+
.curve {
|
|
13176
|
+
fill: none;
|
|
13177
|
+
stroke: var(---color-element-emphasis);
|
|
13178
|
+
stroke-width: 2;
|
|
13158
13179
|
}
|
|
13159
13180
|
|
|
13160
|
-
|
|
13161
|
-
|
|
13181
|
+
.curve.interactive {
|
|
13182
|
+
cursor: nwse-resize;
|
|
13162
13183
|
|
|
13163
|
-
|
|
13164
|
-
stroke: #0000ff;
|
|
13184
|
+
outline: none;
|
|
13165
13185
|
}
|
|
13166
13186
|
|
|
13167
13187
|
/* Make larger targets for touch users */
|
|
@@ -13238,6 +13258,18 @@
|
|
|
13238
13258
|
// ENTER
|
|
13239
13259
|
const svgEnter = svgUpdate.enter().append('svg').classed('main', true);
|
|
13240
13260
|
svgEnter.html(DiscountableElement.svgDefs);
|
|
13261
|
+
// Gradients for fill animations
|
|
13262
|
+
const svgDefs = svgEnter.append('defs');
|
|
13263
|
+
const soonerGradient = svgDefs.append('linearGradient').classed('gradient sooner', true).attr('id', 'sooner-gradient');
|
|
13264
|
+
soonerGradient.append('stop').classed('stop-0', true).attr('offset', '0');
|
|
13265
|
+
soonerGradient.append('stop').classed('stop-before animation', true).attr('offset', '1');
|
|
13266
|
+
soonerGradient.append('stop').classed('stop-after animation', true).attr('offset', '1');
|
|
13267
|
+
soonerGradient.append('stop').classed('stop-100', true).attr('offset', '1');
|
|
13268
|
+
const laterGradient = svgDefs.append('linearGradient').classed('gradient later', true).attr('id', 'later-gradient');
|
|
13269
|
+
laterGradient.append('stop').classed('stop-0', true).attr('offset', '0');
|
|
13270
|
+
laterGradient.append('stop').classed('stop-before animation', true).attr('offset', '1');
|
|
13271
|
+
laterGradient.append('stop').classed('stop-after animation', true).attr('offset', '1');
|
|
13272
|
+
laterGradient.append('stop').classed('stop-100', true).attr('offset', '1');
|
|
13241
13273
|
// MERGE
|
|
13242
13274
|
const svgMerge = svgEnter.merge(svgUpdate).attr('viewBox', `0 0 ${elementWidth} ${elementHeight}`);
|
|
13243
13275
|
|
|
@@ -13314,42 +13346,39 @@
|
|
|
13314
13346
|
return datum.name;
|
|
13315
13347
|
});
|
|
13316
13348
|
// ENTER
|
|
13317
|
-
const optionEnter = optionUpdate.enter().append('g').
|
|
13318
|
-
|
|
13319
|
-
|
|
13320
|
-
|
|
13321
|
-
|
|
13322
|
-
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
});
|
|
13327
|
-
return line(curve);
|
|
13328
|
-
}).attr('stroke-dasharray', (datum, index, nodes) => {
|
|
13349
|
+
const optionEnter = optionUpdate.enter().append('g').attr('class', datum => {
|
|
13350
|
+
const labelClass = datum.label === 's' ? 'sooner' : datum.label === 'l' ? 'later' : '';
|
|
13351
|
+
const trialClass = datum.trial ? 'trial' : '';
|
|
13352
|
+
return `option ${labelClass} ${trialClass}`;
|
|
13353
|
+
});
|
|
13354
|
+
// Body (Fill, Bar, Point)
|
|
13355
|
+
const bodyEnter = optionEnter.append('g').classed('body', true);
|
|
13356
|
+
// Fill
|
|
13357
|
+
const fillEnter = bodyEnter.append('g').classed('fill', true).attr('clip-path', 'url(#clip-htd-curves)').each(datum => {
|
|
13329
13358
|
if (datum.trial) {
|
|
13330
|
-
|
|
13331
|
-
return `0,${length}`;
|
|
13359
|
+
svgMerge.selectAll('.gradient .animation').attr('offset', 1);
|
|
13332
13360
|
}
|
|
13333
|
-
return 'none';
|
|
13334
13361
|
});
|
|
13335
|
-
|
|
13362
|
+
fillEnter.append('path').classed('region', true).attr('d', datum => {
|
|
13336
13363
|
const curve = range$1(xScale(datum.d), xScale(0), -1).map(range => {
|
|
13337
13364
|
return {
|
|
13338
13365
|
d: xScale.invert(range),
|
|
13339
13366
|
v: HTDMath.adk2v(datum.a, datum.d - xScale.invert(range), this.k)
|
|
13340
13367
|
};
|
|
13341
13368
|
});
|
|
13342
|
-
return line(curve
|
|
13343
|
-
|
|
13344
|
-
|
|
13345
|
-
|
|
13346
|
-
|
|
13347
|
-
|
|
13348
|
-
|
|
13369
|
+
return line([...curve, {
|
|
13370
|
+
d: 0,
|
|
13371
|
+
v: 0
|
|
13372
|
+
}, {
|
|
13373
|
+
d: datum.d,
|
|
13374
|
+
v: 0
|
|
13375
|
+
}]);
|
|
13349
13376
|
});
|
|
13350
13377
|
// Bar
|
|
13351
|
-
const barEnter =
|
|
13352
|
-
barEnter.append('line').classed('line', true)
|
|
13378
|
+
const barEnter = bodyEnter.append('g').classed('bar', true);
|
|
13379
|
+
barEnter.append('line').classed('line', true);
|
|
13380
|
+
barEnter.append('line').classed('line touch', true);
|
|
13381
|
+
barEnter.selectAll('.line').attr('x1', datum => {
|
|
13353
13382
|
return xScale(datum.d);
|
|
13354
13383
|
}).attr('x2', datum => {
|
|
13355
13384
|
return xScale(datum.d);
|
|
@@ -13362,12 +13391,21 @@
|
|
|
13362
13391
|
}
|
|
13363
13392
|
return 'none';
|
|
13364
13393
|
});
|
|
13365
|
-
|
|
13366
|
-
|
|
13367
|
-
|
|
13368
|
-
|
|
13369
|
-
|
|
13370
|
-
|
|
13394
|
+
// Point
|
|
13395
|
+
const pointEnter = bodyEnter.append('g').classed('point', true);
|
|
13396
|
+
pointEnter.append('circle').classed('mark touch', true);
|
|
13397
|
+
// Curve
|
|
13398
|
+
const curveEnter = optionEnter.append('g').classed('curve', true).attr('clip-path', 'url(#clip-htd-curves)');
|
|
13399
|
+
curveEnter.append('path').classed('path', true);
|
|
13400
|
+
curveEnter.append('path').classed('path touch', true);
|
|
13401
|
+
curveEnter.selectAll('.path').attr('d', datum => {
|
|
13402
|
+
const curve = range$1(xScale(datum.d), xScale(0), -1).map(range => {
|
|
13403
|
+
return {
|
|
13404
|
+
d: xScale.invert(range),
|
|
13405
|
+
v: HTDMath.adk2v(datum.a, datum.d - xScale.invert(range), this.k)
|
|
13406
|
+
};
|
|
13407
|
+
});
|
|
13408
|
+
return line(curve);
|
|
13371
13409
|
}).attr('stroke-dasharray', (datum, index, nodes) => {
|
|
13372
13410
|
if (datum.trial) {
|
|
13373
13411
|
const length = nodes[index].getTotalLength();
|
|
@@ -13375,8 +13413,11 @@
|
|
|
13375
13413
|
}
|
|
13376
13414
|
return 'none';
|
|
13377
13415
|
});
|
|
13378
|
-
// Point
|
|
13379
|
-
const
|
|
13416
|
+
// Point (again)
|
|
13417
|
+
const topPointEnter = optionEnter.append('g').classed('point top-point', true);
|
|
13418
|
+
topPointEnter.append('circle').classed('mark touch', true);
|
|
13419
|
+
topPointEnter.append('text').classed('label', true);
|
|
13420
|
+
optionEnter.selectAll('.point').attr('transform', datum => {
|
|
13380
13421
|
return `translate(${xScale(datum.d)}, ${yScale(datum.a)})`;
|
|
13381
13422
|
}).attr('opacity', datum => {
|
|
13382
13423
|
if (datum.trial) {
|
|
@@ -13384,33 +13425,37 @@
|
|
|
13384
13425
|
}
|
|
13385
13426
|
return 1;
|
|
13386
13427
|
});
|
|
13387
|
-
|
|
13388
|
-
pointEnter.append('text').classed('label', true);
|
|
13428
|
+
|
|
13389
13429
|
// MERGE
|
|
13390
13430
|
const optionMerge = optionEnter.merge(optionUpdate);
|
|
13391
13431
|
|
|
13392
13432
|
// Interactive options
|
|
13393
|
-
//
|
|
13394
|
-
optionMerge.filter((datum, index, nodes) => {
|
|
13395
|
-
return this.interactive && !select(nodes[index]).select('.
|
|
13396
|
-
}).select('.
|
|
13433
|
+
// Body (Fill, Bar, Point)
|
|
13434
|
+
const bodyMergeInteractive = optionMerge.filter((datum, index, nodes) => {
|
|
13435
|
+
return this.interactive && !datum.trial && !select(nodes[index]).select('.body').classed('interactive');
|
|
13436
|
+
}).select('.body');
|
|
13437
|
+
bodyMergeInteractive.classed('interactive', true);
|
|
13438
|
+
// Fill
|
|
13439
|
+
bodyMergeInteractive.select('.fill').attr('tabindex', 0)
|
|
13397
13440
|
// Drag interaction
|
|
13398
|
-
.call(drag().subject(event => {
|
|
13441
|
+
.call(drag().subject((event, datum) => {
|
|
13399
13442
|
return {
|
|
13400
|
-
x:
|
|
13401
|
-
y:
|
|
13443
|
+
x: xScale(datum.d),
|
|
13444
|
+
y: yScale(datum.a)
|
|
13402
13445
|
};
|
|
13403
13446
|
}).on('start', event => {
|
|
13404
13447
|
const element = event.currentTarget;
|
|
13405
13448
|
select(element).classed('dragging', true);
|
|
13406
13449
|
}).on('drag', (event, datum) => {
|
|
13407
13450
|
this.drag = true;
|
|
13408
|
-
const
|
|
13409
|
-
const
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13451
|
+
const d = xScale.invert(event.x);
|
|
13452
|
+
const a = yScale.invert(event.y);
|
|
13453
|
+
datum.d = d < this.scale.time.min ? this.scale.time.min : d > this.scale.time.max ? this.scale.time.max : this.scale.time.round(d);
|
|
13454
|
+
datum.a = a < this.scale.value.min ? this.scale.value.min : a > this.scale.value.max ? this.scale.value.max : this.scale.value.round(a);
|
|
13455
|
+
if (datum.name === 'default') {
|
|
13456
|
+
this.d = datum.d;
|
|
13457
|
+
this.a = datum.a;
|
|
13458
|
+
}
|
|
13414
13459
|
this.alignState();
|
|
13415
13460
|
this.requestUpdate();
|
|
13416
13461
|
this.dispatchEvent(new CustomEvent('htd-curves-change', {
|
|
@@ -13429,24 +13474,33 @@
|
|
|
13429
13474
|
}))
|
|
13430
13475
|
// Keyboard interaction
|
|
13431
13476
|
.on('keydown', (event, datum) => {
|
|
13432
|
-
if (['ArrowUp', 'ArrowDown', '
|
|
13433
|
-
let
|
|
13434
|
-
|
|
13435
|
-
} = this;
|
|
13477
|
+
if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
|
|
13478
|
+
let keyA = datum.a;
|
|
13479
|
+
let keyD = datum.d;
|
|
13436
13480
|
switch (event.key) {
|
|
13437
13481
|
case 'ArrowUp':
|
|
13438
|
-
|
|
13439
|
-
k *= event.shiftKey ? 0.95 : 0.85;
|
|
13482
|
+
keyA += event.shiftKey ? 1 : 5;
|
|
13440
13483
|
break;
|
|
13441
13484
|
case 'ArrowDown':
|
|
13485
|
+
keyA -= event.shiftKey ? 1 : 5;
|
|
13486
|
+
break;
|
|
13442
13487
|
case 'ArrowRight':
|
|
13443
|
-
|
|
13488
|
+
keyD += event.shiftKey ? 1 : 5;
|
|
13489
|
+
break;
|
|
13490
|
+
case 'ArrowLeft':
|
|
13491
|
+
keyD -= event.shiftKey ? 1 : 5;
|
|
13444
13492
|
break;
|
|
13445
13493
|
// no-op
|
|
13446
13494
|
}
|
|
13447
|
-
|
|
13448
|
-
|
|
13449
|
-
|
|
13495
|
+
keyD = keyD < this.scale.time.min ? this.scale.time.min : keyD > this.scale.time.max ? this.scale.time.max : keyD;
|
|
13496
|
+
keyA = keyA < this.scale.value.min ? this.scale.value.min : keyA > this.scale.value.max ? this.scale.value.max : keyA;
|
|
13497
|
+
if (keyD !== datum.d || keyA !== datum.a) {
|
|
13498
|
+
datum.d = keyD;
|
|
13499
|
+
datum.a = keyA;
|
|
13500
|
+
if (datum.name === 'default') {
|
|
13501
|
+
this.d = datum.d;
|
|
13502
|
+
this.a = datum.a;
|
|
13503
|
+
}
|
|
13450
13504
|
this.alignState();
|
|
13451
13505
|
this.requestUpdate();
|
|
13452
13506
|
this.dispatchEvent(new CustomEvent('htd-curves-change', {
|
|
@@ -13464,9 +13518,7 @@
|
|
|
13464
13518
|
}
|
|
13465
13519
|
});
|
|
13466
13520
|
// Bar
|
|
13467
|
-
|
|
13468
|
-
return this.interactive && !datum.trial && !select(nodes[index]).select('.bar').classed('interactive');
|
|
13469
|
-
}).select('.bar').classed('interactive', true).attr('tabindex', 0)
|
|
13521
|
+
bodyMergeInteractive.select('.bar')
|
|
13470
13522
|
// Drag interaction
|
|
13471
13523
|
.call(drag().subject((event, datum) => {
|
|
13472
13524
|
return {
|
|
@@ -13536,8 +13588,8 @@
|
|
|
13536
13588
|
});
|
|
13537
13589
|
// Point
|
|
13538
13590
|
optionMerge.filter((datum, index, nodes) => {
|
|
13539
|
-
return this.interactive && !datum.trial && !select(nodes[index]).select('.point').classed('
|
|
13540
|
-
}).select('.point').classed('
|
|
13591
|
+
return this.interactive && !datum.trial && !select(nodes[index]).select('.top-point').classed('interact');
|
|
13592
|
+
}).select('.top-point').classed('interact', true)
|
|
13541
13593
|
// Drag interaction
|
|
13542
13594
|
.call(drag().subject((event, datum) => {
|
|
13543
13595
|
return {
|
|
@@ -13605,26 +13657,125 @@
|
|
|
13605
13657
|
event.preventDefault();
|
|
13606
13658
|
}
|
|
13607
13659
|
});
|
|
13660
|
+
// Curve
|
|
13661
|
+
optionMerge.filter((datum, index, nodes) => {
|
|
13662
|
+
return this.interactive && !select(nodes[index]).select('.curve').classed('interactive');
|
|
13663
|
+
}).select('.curve').classed('interactive', true).attr('tabindex', 0)
|
|
13664
|
+
// Drag interaction
|
|
13665
|
+
.call(drag().subject(event => {
|
|
13666
|
+
return {
|
|
13667
|
+
x: event.x,
|
|
13668
|
+
y: event.y
|
|
13669
|
+
};
|
|
13670
|
+
}).on('start', event => {
|
|
13671
|
+
const element = event.currentTarget;
|
|
13672
|
+
select(element).classed('dragging', true);
|
|
13673
|
+
}).on('drag', (event, datum) => {
|
|
13674
|
+
this.drag = true;
|
|
13675
|
+
const dragD = datum.d - xScale.invert(event.x);
|
|
13676
|
+
const d = dragD < 0 ? 0 : dragD > datum.d ? datum.d : dragD;
|
|
13677
|
+
const dragV = yScale.invert(event.y);
|
|
13678
|
+
const v = dragV <= 0 ? 0.001 : dragV > datum.a ? datum.a : dragV;
|
|
13679
|
+
const k = HTDMath.adv2k(datum.a, d, v);
|
|
13680
|
+
this.k = k < HTDMath.k.MIN ? HTDMath.k.MIN : k > HTDMath.k.MAX ? HTDMath.k.MAX : k;
|
|
13681
|
+
this.alignState();
|
|
13682
|
+
this.requestUpdate();
|
|
13683
|
+
this.dispatchEvent(new CustomEvent('htd-curves-change', {
|
|
13684
|
+
detail: {
|
|
13685
|
+
name: datum.name,
|
|
13686
|
+
a: datum.a,
|
|
13687
|
+
d: datum.d,
|
|
13688
|
+
k: this.k,
|
|
13689
|
+
label: datum.label
|
|
13690
|
+
},
|
|
13691
|
+
bubbles: true
|
|
13692
|
+
}));
|
|
13693
|
+
}).on('end', event => {
|
|
13694
|
+
const element = event.currentTarget;
|
|
13695
|
+
select(element).classed('dragging', false);
|
|
13696
|
+
}))
|
|
13697
|
+
// Keyboard interaction
|
|
13698
|
+
.on('keydown', (event, datum) => {
|
|
13699
|
+
if (['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft'].includes(event.key)) {
|
|
13700
|
+
let {
|
|
13701
|
+
k
|
|
13702
|
+
} = this;
|
|
13703
|
+
switch (event.key) {
|
|
13704
|
+
case 'ArrowUp':
|
|
13705
|
+
case 'ArrowLeft':
|
|
13706
|
+
k *= event.shiftKey ? 0.95 : 0.85;
|
|
13707
|
+
break;
|
|
13708
|
+
case 'ArrowDown':
|
|
13709
|
+
case 'ArrowRight':
|
|
13710
|
+
k *= event.shiftKey ? 1 / 0.95 : 1 / 0.85;
|
|
13711
|
+
break;
|
|
13712
|
+
// no-op
|
|
13713
|
+
}
|
|
13714
|
+
k = k < HTDMath.k.MIN ? HTDMath.k.MIN : k > HTDMath.k.MAX ? HTDMath.k.MAX : k;
|
|
13715
|
+
if (k !== this.k) {
|
|
13716
|
+
this.k = k;
|
|
13717
|
+
this.alignState();
|
|
13718
|
+
this.requestUpdate();
|
|
13719
|
+
this.dispatchEvent(new CustomEvent('htd-curves-change', {
|
|
13720
|
+
detail: {
|
|
13721
|
+
name: datum.name,
|
|
13722
|
+
a: datum.a,
|
|
13723
|
+
d: datum.d,
|
|
13724
|
+
k: this.k,
|
|
13725
|
+
label: datum.label
|
|
13726
|
+
},
|
|
13727
|
+
bubbles: true
|
|
13728
|
+
}));
|
|
13729
|
+
}
|
|
13730
|
+
event.preventDefault();
|
|
13731
|
+
}
|
|
13732
|
+
});
|
|
13608
13733
|
|
|
13609
13734
|
// Non-interactive options
|
|
13735
|
+
// Body (Fill, Bar, Point)
|
|
13736
|
+
const bodyMergeNoninteractive = optionMerge.filter((datum, index, nodes) => {
|
|
13737
|
+
return (!this.interactive || datum.trial) && select(nodes[index]).select('.body').classed('interactive');
|
|
13738
|
+
});
|
|
13739
|
+
bodyMergeNoninteractive.classed('interactive', false);
|
|
13740
|
+
// Fill
|
|
13741
|
+
bodyMergeNoninteractive.select('.fill').attr('tabindex', null).on('drag', null).on('keydown', null);
|
|
13742
|
+
// Bar
|
|
13743
|
+
bodyMergeNoninteractive.select('.bar').on('drag', null).on('keydown', null);
|
|
13744
|
+
// Point
|
|
13745
|
+
optionMerge.filter((datum, index, nodes) => {
|
|
13746
|
+
return (!this.interactive || datum.trial) && select(nodes[index]).select('.top-point').classed('interact');
|
|
13747
|
+
}).select('.top-point').classed('interact', false).on('drag', null).on('keydown', null);
|
|
13610
13748
|
// Curve
|
|
13611
13749
|
optionMerge.filter((datum, index, nodes) => {
|
|
13612
13750
|
return !this.interactive && select(nodes[index]).select('.curve').classed('interactive');
|
|
13613
13751
|
}).select('.curve').classed('interactive', false).attr('tabindex', null).on('drag', null).on('keydown', null);
|
|
13614
|
-
// Bar
|
|
13615
|
-
optionMerge.filter((datum, index, nodes) => {
|
|
13616
|
-
return (!this.interactive || datum.trial) && select(nodes[index]).select('.bar').classed('interactive');
|
|
13617
|
-
}).select('.bar').classed('interactive', false).attr('tabindex', null).on('drag', null).on('keydown', null);
|
|
13618
|
-
// Point
|
|
13619
|
-
optionMerge.filter((datum, index, nodes) => {
|
|
13620
|
-
return (!this.interactive || datum.trial) && select(nodes[index]).select('.point').classed('interactive');
|
|
13621
|
-
}).select('.point').classed('interactive', false).attr('tabindex', null).on('drag', null).on('keydown', null);
|
|
13622
13752
|
|
|
13623
13753
|
// Trial Animation
|
|
13754
|
+
// Fill
|
|
13755
|
+
optionMerge.filter(datum => {
|
|
13756
|
+
return datum.new;
|
|
13757
|
+
}).each(() => {
|
|
13758
|
+
svgMerge.selectAll('.gradient .animation').transition().duration(transitionDuration).delay(transitionDuration + transitionDuration / 10).ease(linear$1).attrTween('offset', () => {
|
|
13759
|
+
return interpolate$1(1, 0);
|
|
13760
|
+
});
|
|
13761
|
+
});
|
|
13762
|
+
// Bar
|
|
13763
|
+
optionMerge.filter(datum => {
|
|
13764
|
+
return datum.new;
|
|
13765
|
+
}).selectAll('.bar .line').transition().duration(transitionDuration).ease(linear$1).attrTween('stroke-dasharray', (datum, index, nodes) => {
|
|
13766
|
+
const length = nodes[index].getTotalLength();
|
|
13767
|
+
return interpolate$1(`0,${length}`, `${length},${length}`);
|
|
13768
|
+
});
|
|
13769
|
+
// Point
|
|
13770
|
+
optionMerge.filter(datum => {
|
|
13771
|
+
return datum.new;
|
|
13772
|
+
}).selectAll('.point').transition().duration(transitionDuration / 10).delay(transitionDuration).ease(linear$1).attrTween('opacity', () => {
|
|
13773
|
+
return interpolate$1(0, 1);
|
|
13774
|
+
});
|
|
13624
13775
|
// Curve
|
|
13625
13776
|
optionMerge.filter(datum => {
|
|
13626
13777
|
return datum.new;
|
|
13627
|
-
}).
|
|
13778
|
+
}).selectAll('.curve .path').transition().duration(transitionDuration).delay(transitionDuration + transitionDuration / 10).ease(linear$1).attrTween('stroke-dasharray', (datum, index, nodes) => {
|
|
13628
13779
|
const length = nodes[index].getTotalLength();
|
|
13629
13780
|
return interpolate$1(`0,${length}`, `${length},${0}`);
|
|
13630
13781
|
}).on('end', datum => {
|
|
@@ -13641,50 +13792,16 @@
|
|
|
13641
13792
|
bubbles: true
|
|
13642
13793
|
}));
|
|
13643
13794
|
});
|
|
13644
|
-
optionMerge.filter(datum => {
|
|
13645
|
-
return datum.new;
|
|
13646
|
-
}).select('.curve .path.touch').transition().duration(transitionDuration).delay(transitionDuration + transitionDuration / 10).ease(linear$1).attrTween('stroke-dasharray', (datum, index, nodes) => {
|
|
13647
|
-
const length = nodes[index].getTotalLength();
|
|
13648
|
-
return interpolate$1(`0,${length}`, `${length},${0}`);
|
|
13649
|
-
});
|
|
13650
|
-
// Bar
|
|
13651
|
-
optionMerge.filter(datum => {
|
|
13652
|
-
return datum.new;
|
|
13653
|
-
}).select('.bar .line').transition().duration(transitionDuration).ease(linear$1).attrTween('stroke-dasharray', (datum, index, nodes) => {
|
|
13654
|
-
const length = nodes[index].getTotalLength();
|
|
13655
|
-
return interpolate$1(`0,${length}`, `${length},${length}`);
|
|
13656
|
-
});
|
|
13657
|
-
optionMerge.filter(datum => {
|
|
13658
|
-
return datum.new;
|
|
13659
|
-
}).select('.bar .line.touch').transition().duration(transitionDuration).ease(linear$1).attrTween('stroke-dasharray', (datum, index, nodes) => {
|
|
13660
|
-
const length = nodes[index].getTotalLength();
|
|
13661
|
-
return interpolate$1(`0,${length}`, `${length},${length}`);
|
|
13662
|
-
});
|
|
13663
|
-
// Point
|
|
13664
|
-
optionMerge.filter(datum => {
|
|
13665
|
-
return datum.new;
|
|
13666
|
-
}).select('.point').transition().duration(transitionDuration / 10).delay(transitionDuration).ease(linear$1).attrTween('opacity', () => {
|
|
13667
|
-
return interpolate$1(0, 1);
|
|
13668
|
-
});
|
|
13669
13795
|
|
|
13670
13796
|
// All options
|
|
13671
|
-
|
|
13672
|
-
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
return
|
|
13676
|
-
|
|
13677
|
-
|
|
13678
|
-
|
|
13679
|
-
return {
|
|
13680
|
-
d: xScale.invert(range),
|
|
13681
|
-
v: HTDMath.adk2v(element.a, element.d - xScale.invert(range), this.k)
|
|
13682
|
-
};
|
|
13683
|
-
});
|
|
13684
|
-
return line(curve);
|
|
13685
|
-
};
|
|
13686
|
-
});
|
|
13687
|
-
optionUpdate.select('.curve .path.touch').transition().duration(this.drag ? 0 : this.firstUpdate ? transitionDuration * 2 : transitionDuration).ease(cubicOut).attrTween('d', (datum, index, elements) => {
|
|
13797
|
+
optionMerge.filter(datum => {
|
|
13798
|
+
return datum.label === 's';
|
|
13799
|
+
}).raise();
|
|
13800
|
+
optionMerge.filter(datum => {
|
|
13801
|
+
return datum.label === 'l';
|
|
13802
|
+
}).lower();
|
|
13803
|
+
// Fill
|
|
13804
|
+
optionUpdate.select('.fill .region').transition().duration(this.drag ? 0 : this.firstUpdate ? transitionDuration * 2 : transitionDuration).ease(cubicOut).attrTween('d', (datum, index, elements) => {
|
|
13688
13805
|
const element = elements[index];
|
|
13689
13806
|
const interpolateA = interpolate$1(element.a !== undefined ? element.a : datum.a, datum.a);
|
|
13690
13807
|
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
@@ -13697,10 +13814,17 @@
|
|
|
13697
13814
|
v: HTDMath.adk2v(element.a, element.d - xScale.invert(range), this.k)
|
|
13698
13815
|
};
|
|
13699
13816
|
});
|
|
13700
|
-
return line(curve
|
|
13817
|
+
return line([...curve, {
|
|
13818
|
+
d: 0,
|
|
13819
|
+
v: 0
|
|
13820
|
+
}, {
|
|
13821
|
+
d: element.d,
|
|
13822
|
+
v: 0
|
|
13823
|
+
}]);
|
|
13701
13824
|
};
|
|
13702
13825
|
});
|
|
13703
|
-
|
|
13826
|
+
// Bar
|
|
13827
|
+
optionUpdate.selectAll('.bar .line').transition().duration(this.drag ? 0 : this.firstUpdate ? transitionDuration * 2 : transitionDuration).ease(cubicOut).attrTween('x1', (datum, index, elements) => {
|
|
13704
13828
|
const element = elements[index];
|
|
13705
13829
|
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
13706
13830
|
return time => {
|
|
@@ -13722,41 +13846,37 @@
|
|
|
13722
13846
|
return `${yScale(element.a)}`;
|
|
13723
13847
|
};
|
|
13724
13848
|
});
|
|
13725
|
-
|
|
13726
|
-
|
|
13727
|
-
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
13728
|
-
return time => {
|
|
13729
|
-
element.d = interpolateD(time);
|
|
13730
|
-
return `${xScale(element.d)}`;
|
|
13731
|
-
};
|
|
13732
|
-
}).attrTween('x2', (datum, index, elements) => {
|
|
13849
|
+
// Point
|
|
13850
|
+
optionUpdate.selectAll('.point').transition().duration(this.drag ? 0 : this.firstUpdate ? transitionDuration * 2 : transitionDuration).ease(cubicOut).attrTween('transform', (datum, index, elements) => {
|
|
13733
13851
|
const element = elements[index];
|
|
13734
13852
|
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
13735
|
-
return time => {
|
|
13736
|
-
element.d = interpolateD(time);
|
|
13737
|
-
return `${xScale(element.d)}`;
|
|
13738
|
-
};
|
|
13739
|
-
}).attrTween('y2', (datum, index, elements) => {
|
|
13740
|
-
const element = elements[index];
|
|
13741
13853
|
const interpolateA = interpolate$1(element.a !== undefined ? element.a : datum.a, datum.a);
|
|
13742
13854
|
return time => {
|
|
13855
|
+
element.d = interpolateD(time);
|
|
13743
13856
|
element.a = interpolateA(time);
|
|
13744
|
-
return
|
|
13857
|
+
return `translate(${xScale(element.d)}, ${yScale(element.a)})`;
|
|
13745
13858
|
};
|
|
13746
13859
|
});
|
|
13747
|
-
|
|
13860
|
+
optionMerge.select('.point .label').text(datum => {
|
|
13861
|
+
return datum.label;
|
|
13862
|
+
});
|
|
13863
|
+
// Curve
|
|
13864
|
+
optionUpdate.selectAll('.curve .path').transition().duration(this.drag ? 0 : this.firstUpdate ? transitionDuration * 2 : transitionDuration).ease(cubicOut).attrTween('d', (datum, index, elements) => {
|
|
13748
13865
|
const element = elements[index];
|
|
13749
|
-
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
13750
13866
|
const interpolateA = interpolate$1(element.a !== undefined ? element.a : datum.a, datum.a);
|
|
13867
|
+
const interpolateD = interpolate$1(element.d !== undefined ? element.d : datum.d, datum.d);
|
|
13751
13868
|
return time => {
|
|
13752
|
-
element.d = interpolateD(time);
|
|
13753
13869
|
element.a = interpolateA(time);
|
|
13754
|
-
|
|
13870
|
+
element.d = interpolateD(time);
|
|
13871
|
+
const curve = range$1(xScale(element.d), xScale(0), -1).map(range => {
|
|
13872
|
+
return {
|
|
13873
|
+
d: xScale.invert(range),
|
|
13874
|
+
v: HTDMath.adk2v(element.a, element.d - xScale.invert(range), this.k)
|
|
13875
|
+
};
|
|
13876
|
+
});
|
|
13877
|
+
return line(curve);
|
|
13755
13878
|
};
|
|
13756
13879
|
});
|
|
13757
|
-
optionMerge.select('.point .label').text(datum => {
|
|
13758
|
-
return datum.label;
|
|
13759
|
-
});
|
|
13760
13880
|
// EXIT
|
|
13761
13881
|
// NOTE: Could add a transition here
|
|
13762
13882
|
optionUpdate.exit().remove();
|