@decidables/detectable-elements 0.2.16 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decidables/detectable-elements",
3
- "version": "0.2.16",
3
+ "version": "0.3.1",
4
4
  "description": "detectable-elements: Web Components for visualizing Signal Detection Theory",
5
5
  "keywords": [
6
6
  "web component",
@@ -50,14 +50,14 @@
50
50
  "build": "gulp build"
51
51
  },
52
52
  "devDependencies": {
53
- "gulp": "^5.0.0"
53
+ "gulp": "^5.0.1"
54
54
  },
55
55
  "dependencies": {
56
- "@decidables/decidables-elements": "^0.4.9",
57
- "@decidables/detectable-math": "^0.1.13",
56
+ "@decidables/decidables-elements": "^0.5.1",
57
+ "@decidables/detectable-math": "^0.2.1",
58
58
  "d3": "^7.9.0",
59
59
  "jstat": "^1.9.6",
60
- "lit": "^3.2.1"
60
+ "lit": "^3.3.1"
61
61
  },
62
- "gitHead": "00eb1274a09e86f55fff70b01b446f6729e608f3"
62
+ "gitHead": "f4acb671770a55a5c6d0f87ae8a7bad7fb981c67"
63
63
  }
@@ -49,6 +49,7 @@ export default class DetectableControl extends DetectableElement {
49
49
  type: Boolean,
50
50
  reflect: true,
51
51
  },
52
+
52
53
  run: {
53
54
  attribute: 'run',
54
55
  type: Boolean,
@@ -84,6 +85,7 @@ export default class DetectableControl extends DetectableElement {
84
85
  this.colors = ['none', 'accuracy', 'stimulus', 'response', 'outcome', 'all'];
85
86
  this.color = undefined;
86
87
  this.zRoc = undefined;
88
+
87
89
  this.run = false;
88
90
  this.pause = false;
89
91
  this.reset = false;
@@ -218,19 +220,19 @@ export default class DetectableControl extends DetectableElement {
218
220
  render() {
219
221
  return html`
220
222
  <div class="holder">
221
- ${this.trials
223
+ ${this.trials != null
222
224
  ? html`<decidables-slider min="1" max="100" step="1" .value=${this.trials} @change=${this.setTrials.bind(this)} @input=${this.setTrials.bind(this)}>Trials</decidables-slider>`
223
225
  : html``}
224
- ${this.duration
226
+ ${this.duration != null
225
227
  ? html`<decidables-slider min="10" max="2000" step="10" .value=${this.duration} @change=${this.setDuration.bind(this)} @input=${this.setDuration.bind(this)}>Duration</decidables-slider>`
226
228
  : html``}
227
- ${this.coherence
229
+ ${this.coherence != null
228
230
  ? html`<decidables-slider min="0" max="1" step=".01" .value=${this.coherence} @change=${this.setCoherence.bind(this)} @input=${this.setCoherence.bind(this)}>Coherence</decidables-slider>`
229
231
  : html``}
230
- ${this.payoff
232
+ ${this.payoff != null
231
233
  ? html`<decidables-slider class="payoff" min="0" max="100" step="1" .value=${this.payoff} @change=${this.setPayoff.bind(this)} @input=${this.setPayoff.bind(this)}>Payoff</decidables-slider>`
232
234
  : html``}
233
- ${this.color !== undefined
235
+ ${this.color != null
234
236
  ? html`
235
237
  <decidables-toggle @change=${this.chooseColor.bind(this)}>
236
238
  <span slot="label">Emphasis</span>
@@ -243,7 +245,7 @@ export default class DetectableControl extends DetectableElement {
243
245
  </decidables-toggle>
244
246
  `
245
247
  : html``}
246
- ${this.zRoc !== undefined
248
+ ${this.zRoc != null
247
249
  ? html`
248
250
  <decidables-switch ?checked=${this.zRoc} @change=${this.flipZRoc.bind(this)}>
249
251
  <span class="math-var">z</span>ROC
@@ -227,6 +227,30 @@ export default class DetectableResponse extends DetectableElement {
227
227
  this.e = 0;
228
228
  }
229
229
 
230
+ keydown(event) {
231
+ if (this.state === 'waiting') {
232
+ if (event.key === 'ArrowUp') {
233
+ this.responded('present');
234
+ event.preventDefault();
235
+ } else if (event.key === 'ArrowDown') {
236
+ this.responded('absent');
237
+ event.preventDefault();
238
+ }
239
+ }
240
+ }
241
+
242
+ connectedCallback() {
243
+ super.connectedCallback();
244
+
245
+ window.addEventListener('keydown', this.keydown.bind(this));
246
+ }
247
+
248
+ disconnectedCallback() {
249
+ window.removeEventListener('keydown', this.keydown.bind(this));
250
+
251
+ super.disconnectedCallback();
252
+ }
253
+
230
254
  static get styles() {
231
255
  return [
232
256
  super.styles,
@@ -1,7 +1,8 @@
1
1
 
2
- export {default as RDKTask} from './rdk-task';
3
- export {default as ROCSpace} from './roc-space';
4
2
  export {default as DetectableControl} from './detectable-control';
5
- export {default as SDTModel} from './sdt-model';
6
3
  export {default as DetectableResponse} from './detectable-response';
7
4
  export {default as DetectableTable} from './detectable-table';
5
+ export {default as RDKTask} from './rdk-task';
6
+ export {default as ROCSpace} from './roc-space';
7
+ export {default as SDTModel} from './sdt-model';
8
+ export {default as SDTParameters} from './sdt-parameters';
@@ -104,7 +104,7 @@ export default class ROCSpace extends DecidablesMixinResizeable(DetectableElemen
104
104
  this.far = 0.25;
105
105
  this.hr = 0.75;
106
106
 
107
- this.s = 1;
107
+ this.s = SDTMath.s.DEFAULT;
108
108
 
109
109
  this.label = '';
110
110
 
@@ -261,15 +261,6 @@ export default class ROCSpace extends DecidablesMixinResizeable(DetectableElemen
261
261
  stroke-width: 0;
262
262
  }
263
263
 
264
- /* Make a larger target for touch users */
265
- @media (pointer: coarse) {
266
- .point.interactive .circle {
267
- stroke: #000000;
268
- stroke-opacity: 0;
269
- stroke-width: 12px;
270
- }
271
- }
272
-
273
264
  .point.interactive:hover {
274
265
  filter: url("#shadow-4");
275
266
 
@@ -353,6 +344,19 @@ export default class ROCSpace extends DecidablesMixinResizeable(DetectableElemen
353
344
 
354
345
  fill: var(---color-text-inverse);
355
346
  }
347
+
348
+ /* Make a larger target for touch users */
349
+ .interactive .touch {
350
+ stroke: #000000;
351
+ stroke-opacity: 0;
352
+ }
353
+
354
+ @media (pointer: coarse) {
355
+ .interactive .touch {
356
+ stroke-linecap: round;
357
+ stroke-width: 12;
358
+ }
359
+ }
356
360
  `,
357
361
  ];
358
362
  }
@@ -1012,7 +1016,7 @@ export default class ROCSpace extends DecidablesMixinResizeable(DetectableElemen
1012
1016
  const pointEnter = pointUpdate.enter().append('g')
1013
1017
  .classed('point', true);
1014
1018
  pointEnter.append('circle')
1015
- .classed('circle', true);
1019
+ .classed('circle touch', true);
1016
1020
  pointEnter.append('text')
1017
1021
  .classed('label', true);
1018
1022
  // MERGE
@@ -109,8 +109,8 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
109
109
  super();
110
110
 
111
111
  // Attributes
112
- this.colors = ['outcome', 'response', 'stimulus', 'none']; // Allowable values of 'color'
113
- this.color = 'outcome'; // How to color distributions and trials
112
+ this.colors = ['all', 'outcome', 'response', 'stimulus', 'none']; // Allowable values of 'color'
113
+ this.color = 'all'; // How to color distributions and trials
114
114
  this.distributions = false; // Show distributions?
115
115
  this.threshold = false; // Show threshold?
116
116
  this.unequal = false; // Allow unequal variance?
@@ -119,9 +119,9 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
119
119
  this.variance = false; // Show variance?
120
120
  this.histogram = false; // Show histogram?
121
121
 
122
- this.d = 1; // Sensitivity
123
- this.c = 0; // Bias
124
- this.s = 1; // Variance
122
+ this.d = SDTMath.d.DEFAULT; // Sensitivity
123
+ this.c = SDTMath.c.DEFAULT; // Bias
124
+ this.s = SDTMath.s.DEFAULT; // Variance
125
125
 
126
126
  // Properties
127
127
  this.binWidth = 0.25; // Histogram bin width in units of evidence
@@ -399,15 +399,6 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
399
399
  r: 6px;
400
400
  }
401
401
 
402
- /* Make a larger target for touch users */
403
- @media (pointer: coarse) {
404
- .threshold.interactive .handle {
405
- stroke: #000000;
406
- stroke-opacity: 0;
407
- stroke-width: 12px;
408
- }
409
- }
410
-
411
402
  .measure-d .line,
412
403
  .measure-d .cap-left,
413
404
  .measure-d .cap-right {
@@ -450,6 +441,19 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
450
441
  text-anchor: middle;
451
442
  fill: currentColor;
452
443
  }
444
+
445
+ /* Make a larger target for touch users */
446
+ .interactive .touch {
447
+ stroke: #000000;
448
+ stroke-opacity: 0;
449
+ }
450
+
451
+ @media (pointer: coarse) {
452
+ .interactive .touch {
453
+ stroke-linecap: round;
454
+ stroke-width: 12;
455
+ }
456
+ }
453
457
  `,
454
458
  ];
455
459
  }
@@ -544,14 +548,13 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
544
548
  })
545
549
  .on('drag', (event) => {
546
550
  this.drag = true;
547
- let l = xScale.invert(event.x);
548
- // Clamp lambda to stay visible
549
- l = (l < xScale.domain()[0])
550
- ? xScale.domain()[0]
551
- : (l > xScale.domain()[1])
552
- ? xScale.domain()[1]
553
- : l;
554
- this.c = SDTMath.l2C(l, this.s);
551
+ const l = xScale.invert(event.x);
552
+ const c = SDTMath.l2C(l, this.s);
553
+ this.c = (c < SDTMath.c.MIN)
554
+ ? SDTMath.c.MIN
555
+ : (c > SDTMath.c.MAX)
556
+ ? SDTMath.c.MAX
557
+ : c;
555
558
  this.alignState();
556
559
  this.sendEvent();
557
560
  })
@@ -571,14 +574,13 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
571
574
  })
572
575
  .on('drag', (event) => {
573
576
  this.drag = true;
574
- let muN = xScale.invert(event.x);
575
- // Clamp Noise Curve to stay visible
576
- muN = (muN < xScale.domain()[0])
577
- ? xScale.domain()[0]
578
- : (muN > xScale.domain()[1])
579
- ? xScale.domain()[1]
580
- : muN;
581
- this.d = SDTMath.muN2D(muN, this.s);
577
+ const muN = xScale.invert(event.x);
578
+ const d = SDTMath.muN2D(muN, this.s);
579
+ this.d = (d < SDTMath.d.MIN)
580
+ ? SDTMath.d.MIN
581
+ : (d > SDTMath.d.MAX)
582
+ ? SDTMath.d.MAX
583
+ : d;
582
584
  this.alignState();
583
585
  this.sendEvent();
584
586
  })
@@ -605,22 +607,10 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
605
607
  let muS = this.muS; /* eslint-disable-line prefer-destructuring */
606
608
  if (this.interactive) {
607
609
  muS = xScale.invert(event.x);
608
- // Clamp Signal Curve to stay visible
609
- muS = (muS < xScale.domain()[0])
610
- ? xScale.domain()[0]
611
- : (muS > xScale.domain()[1])
612
- ? xScale.domain()[1]
613
- : muS;
614
610
  }
615
611
  let hS = this.hS; /* eslint-disable-line prefer-destructuring */
616
612
  if (this.unequal) {
617
613
  hS = yScale.invert(event.y);
618
- // Clamp Signal Curve to stay visible
619
- hS = (hS < 0.01)
620
- ? 0.01
621
- : (hS > yScale.domain()[0])
622
- ? yScale.domain()[0]
623
- : hS;
624
614
  }
625
615
  if (this.interactive && this.unequal) {
626
616
  // Use shift key as modifier for single dimension
@@ -633,10 +623,25 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
633
623
  }
634
624
  }
635
625
  if (this.unequal) {
636
- this.s = SDTMath.h2S(hS);
637
- this.c = SDTMath.l2C(this.l, this.s);
626
+ const s = SDTMath.h2S(hS);
627
+ this.s = (s < SDTMath.s.MIN)
628
+ ? SDTMath.s.MIN
629
+ : (s > SDTMath.s.MAX)
630
+ ? SDTMath.s.MAX
631
+ : s;
632
+ const c = SDTMath.l2C(this.l, this.s);
633
+ this.c = (c < SDTMath.c.MIN)
634
+ ? SDTMath.c.MIN
635
+ : (c > SDTMath.c.MAX)
636
+ ? SDTMath.c.MAX
637
+ : c;
638
638
  }
639
- this.d = SDTMath.muS2D(muS, this.s);
639
+ const d = SDTMath.muS2D(muS, this.s);
640
+ this.d = (d < SDTMath.d.MIN)
641
+ ? SDTMath.d.MIN
642
+ : (d > SDTMath.d.MAX)
643
+ ? SDTMath.d.MAX
644
+ : d;
640
645
  this.alignState();
641
646
  this.sendEvent();
642
647
  })
@@ -818,17 +823,14 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
818
823
  break;
819
824
  default:
820
825
  }
821
- // Clamp C to visible extent
822
- muN = (muN < xScale.domain()[0])
823
- ? xScale.domain()[0]
824
- : (muN > xScale.domain()[1])
825
- ? xScale.domain()[1]
826
- : muN;
827
- if (muN !== this.muN) {
828
- this.d = SDTMath.muN2D(muN, this.s);
829
- this.alignState();
830
- this.sendEvent();
831
- }
826
+ const d = SDTMath.muN2D(muN, this.s);
827
+ this.d = (d < SDTMath.d.MIN)
828
+ ? SDTMath.d.MIN
829
+ : (d > SDTMath.d.MAX)
830
+ ? SDTMath.d.MAX
831
+ : d;
832
+ this.alignState();
833
+ this.sendEvent();
832
834
  event.preventDefault();
833
835
  }
834
836
  }
@@ -1013,17 +1015,14 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1013
1015
  break;
1014
1016
  default:
1015
1017
  }
1016
- // Clamp C to visible extent
1017
- muS = (muS < xScale.domain()[0])
1018
- ? xScale.domain()[0]
1019
- : (muS > xScale.domain()[1])
1020
- ? xScale.domain()[1]
1021
- : muS;
1022
- if (muS !== this.muS) {
1023
- this.d = SDTMath.muS2D(muS, this.s);
1024
- this.alignState();
1025
- this.sendEvent();
1026
- }
1018
+ const d = SDTMath.muS2D(muS, this.s);
1019
+ this.d = (d < SDTMath.d.MIN)
1020
+ ? SDTMath.d.MIN
1021
+ : (d > SDTMath.d.MAX)
1022
+ ? SDTMath.d.MAX
1023
+ : d;
1024
+ this.alignState();
1025
+ this.sendEvent();
1027
1026
  event.preventDefault();
1028
1027
  }
1029
1028
  }
@@ -1041,19 +1040,17 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1041
1040
  break;
1042
1041
  default:
1043
1042
  }
1044
- // Clamp s so distribution stays visible
1045
- hS = (hS < 0.01)
1046
- ? 0.01
1047
- : (hS > yScale.domain()[0])
1048
- ? yScale.domain()[0]
1049
- : hS;
1050
- if (hS !== this.hS) {
1051
- this.s = SDTMath.h2S(hS);
1052
- this.d = SDTMath.muN2D(this.muN, this.s);
1053
- this.c = SDTMath.l2C(this.l, this.s);
1054
- this.alignState();
1055
- this.sendEvent();
1056
- }
1043
+ hS = (hS < 0) ? 0 : hS;
1044
+ const s = SDTMath.h2S(hS);
1045
+ this.s = (s < SDTMath.s.MIN)
1046
+ ? SDTMath.s.MIN
1047
+ : (s > SDTMath.s.MAX)
1048
+ ? SDTMath.s.MAX
1049
+ : s;
1050
+ this.d = SDTMath.muN2D(this.muN, this.s);
1051
+ this.c = SDTMath.l2C(this.l, this.s);
1052
+ this.alignState();
1053
+ this.sendEvent();
1057
1054
  event.preventDefault();
1058
1055
  }
1059
1056
  }
@@ -1424,8 +1421,10 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1424
1421
  .classed('threshold', true);
1425
1422
  thresholdEnter.append('line')
1426
1423
  .classed('line', true);
1424
+ thresholdEnter.append('line')
1425
+ .classed('line touch', true);
1427
1426
  thresholdEnter.append('circle')
1428
- .classed('handle', true);
1427
+ .classed('handle touch', true);
1429
1428
  // MERGE
1430
1429
  const thresholdMerge = thresholdEnter.merge(thresholdUpdate)
1431
1430
  .attr('tabindex', this.interactive ? 0 : null)
@@ -1449,17 +1448,14 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1449
1448
  break;
1450
1449
  default:
1451
1450
  }
1452
- // Clamp C to visible extent
1453
- l = (l < xScale.domain()[0])
1454
- ? xScale.domain()[0]
1455
- : (l > xScale.domain()[1])
1456
- ? xScale.domain()[1]
1457
- : l;
1458
- if (l !== this.l) {
1459
- this.c = SDTMath.l2C(l, this.s);
1460
- this.alignState();
1461
- this.sendEvent();
1462
- }
1451
+ const c = SDTMath.l2C(l, this.s);
1452
+ this.c = (c < SDTMath.c.MIN)
1453
+ ? SDTMath.c.MIN
1454
+ : (c > SDTMath.c.MAX)
1455
+ ? SDTMath.c.MAX
1456
+ : c;
1457
+ this.alignState();
1458
+ this.sendEvent();
1463
1459
  event.preventDefault();
1464
1460
  }
1465
1461
  });
@@ -1476,6 +1472,13 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1476
1472
  .attr('y1', yScale(0))
1477
1473
  .attr('x2', xScale(this.l))
1478
1474
  .attr('y2', yScale(0.54));
1475
+ thresholdMerge.select('.line.touch').transition()
1476
+ .duration(this.drag ? 0 : transitionDuration)
1477
+ .ease(d3.easeCubicOut)
1478
+ .attr('x1', xScale(this.l))
1479
+ .attr('y1', yScale(0))
1480
+ .attr('x2', xScale(this.l))
1481
+ .attr('y2', yScale(0.54));
1479
1482
  thresholdMerge.select('.handle').transition()
1480
1483
  .duration(this.drag ? 0 : transitionDuration)
1481
1484
  .ease(d3.easeCubicOut)
@@ -1571,7 +1574,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1571
1574
  : this.getComputedStyleValue('---color-far')
1572
1575
  : (this.color === 'response')
1573
1576
  ? this.getComputedStyleValue(`---color-${datum.response}`)
1574
- : (this.color === 'outcome')
1577
+ : (this.color === 'outcome') || (this.color === 'all')
1575
1578
  ? this.getComputedStyleValue(`---color-${datum.outcome}`)
1576
1579
  : this.getComputedStyleValue('---color-acc'),
1577
1580
  );
@@ -1587,7 +1590,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1587
1590
  : this.getComputedStyleValue('---color-far-light')
1588
1591
  : (this.color === 'response')
1589
1592
  ? this.getComputedStyleValue(`---color-${datum.response}-light`)
1590
- : (this.color === 'outcome')
1593
+ : (this.color === 'outcome') || (this.color === 'all')
1591
1594
  ? this.getComputedStyleValue(`---color-${datum.outcome}-light`)
1592
1595
  : this.getComputedStyleValue('---color-acc-light'),
1593
1596
  );
@@ -1661,7 +1664,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1661
1664
  : this.getComputedStyleValue('---color-far')
1662
1665
  : (this.color === 'response')
1663
1666
  ? this.getComputedStyleValue(`---color-${datum.response}`)
1664
- : (this.color === 'outcome')
1667
+ : (this.color === 'outcome') || (this.color === 'all')
1665
1668
  ? this.getComputedStyleValue(`---color-${datum.outcome}`)
1666
1669
  : this.getComputedStyleValue('---color-acc'),
1667
1670
  );
@@ -1676,7 +1679,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1676
1679
  : this.getComputedStyleValue('---color-far-light')
1677
1680
  : (this.color === 'response')
1678
1681
  ? this.getComputedStyleValue(`---color-${datum.response}-light`)
1679
- : (this.color === 'outcome')
1682
+ : (this.color === 'outcome') || (this.color === 'all')
1680
1683
  ? this.getComputedStyleValue(`---color-${datum.outcome}-light`)
1681
1684
  : this.getComputedStyleValue('---color-acc-light'),
1682
1685
  );
@@ -1700,7 +1703,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1700
1703
  : this.getComputedStyleValue('---color-far')
1701
1704
  : (this.color === 'response')
1702
1705
  ? this.getComputedStyleValue(`---color-${datum.response}`)
1703
- : (this.color === 'outcome')
1706
+ : (this.color === 'outcome') || (this.color === 'all')
1704
1707
  ? this.getComputedStyleValue(`---color-${datum.outcome}`)
1705
1708
  : this.getComputedStyleValue('---color-acc');
1706
1709
  })
@@ -1711,7 +1714,7 @@ export default class SDTModel extends DecidablesMixinResizeable(DetectableElemen
1711
1714
  : this.getComputedStyleValue('---color-far-light')
1712
1715
  : (this.color === 'response')
1713
1716
  ? this.getComputedStyleValue(`---color-${datum.response}-light`)
1714
- : (this.color === 'outcome')
1717
+ : (this.color === 'outcome') || (this.color === 'all')
1715
1718
  ? this.getComputedStyleValue(`---color-${datum.outcome}-light`)
1716
1719
  : this.getComputedStyleValue('---color-acc-light');
1717
1720
  });
@@ -0,0 +1,163 @@
1
+
2
+ import {html, css} from 'lit';
3
+
4
+ import '@decidables/decidables-elements/slider';
5
+ import SDTMath from '@decidables/detectable-math';
6
+
7
+ import DetectableElement from '../detectable-element';
8
+
9
+ /*
10
+ SDTParameters element
11
+ <sdt-paramters>
12
+
13
+ Attributes:
14
+
15
+ */
16
+ export default class SDTParameters extends DetectableElement {
17
+ static get properties() {
18
+ return {
19
+ d: {
20
+ attribute: 'd',
21
+ type: Number,
22
+ reflect: true,
23
+ },
24
+ c: {
25
+ attribute: 'c',
26
+ type: Number,
27
+ reflect: true,
28
+ },
29
+ s: {
30
+ attribute: 's',
31
+ type: Number,
32
+ reflect: true,
33
+ },
34
+ };
35
+ }
36
+
37
+ constructor() {
38
+ super();
39
+
40
+ // Attributes
41
+ this.d = undefined;
42
+ this.c = undefined;
43
+ this.s = undefined;
44
+ }
45
+
46
+ setSensitivity(e) {
47
+ this.d = +e.target.value;
48
+ this.dispatchEvent(new CustomEvent('sdt-parameters-d', {
49
+ detail: {
50
+ d: this.d,
51
+ },
52
+ bubbles: true,
53
+ }));
54
+ }
55
+
56
+ setBias(e) {
57
+ this.c = +e.target.value;
58
+ this.dispatchEvent(new CustomEvent('sdt-parameters-c', {
59
+ detail: {
60
+ c: this.c,
61
+ },
62
+ bubbles: true,
63
+ }));
64
+ }
65
+
66
+ setVariance(e) {
67
+ this.s = +e.target.value;
68
+ this.dispatchEvent(new CustomEvent('sdt-parameters-s', {
69
+ detail: {
70
+ s: this.s,
71
+ },
72
+ bubbles: true,
73
+ }));
74
+ }
75
+
76
+ static get styles() {
77
+ return [
78
+ super.styles,
79
+ css`
80
+ :host {
81
+ display: inline-block;
82
+ }
83
+
84
+ .holder {
85
+ display: flex;
86
+
87
+ flex-direction: row;
88
+
89
+ align-items: stretch;
90
+ justify-content: center;
91
+ }
92
+
93
+ decidables-slider {
94
+ line-height: 1;
95
+ text-align: center;
96
+ }
97
+
98
+ decidables-slider div {
99
+ margin-bottom: 0.25rem;
100
+ }
101
+
102
+ .d {
103
+ --decidables-slider-background-color: var(---color-d-light);
104
+ --decidables-slider-color: var(---color-d);
105
+ }
106
+
107
+ .c {
108
+ --decidables-slider-background-color: var(---color-c-light);
109
+ --decidables-slider-color: var(---color-c);
110
+ }
111
+
112
+ .s {
113
+ --decidables-slider-background-color: var(---color-s-light);
114
+ --decidables-slider-color: var(---color-s);
115
+ }
116
+ `,
117
+ ];
118
+ }
119
+
120
+ render() {
121
+ return html`
122
+ <div class="holder">
123
+ ${this.d != null
124
+ ? html`<decidables-slider class="d"
125
+ ?disabled=${!this.interactive}
126
+ scale
127
+ min=${SDTMath.d.MIN}
128
+ max=${SDTMath.d.MAX}
129
+ step=${SDTMath.d.STEP}
130
+ .value=${+this.d.toFixed(2)}
131
+ @change=${this.setSensitivity.bind(this)}
132
+ @input=${this.setSensitivity.bind(this)}
133
+ ><div>Sensitivity<br><span class="math-var">d′</span></div></decidables-slider>`
134
+ : html``}
135
+ ${this.c != null
136
+ ? html`<decidables-slider class="c"
137
+ ?disabled=${!this.interactive}
138
+ scale
139
+ min=${SDTMath.c.MIN}
140
+ max=${SDTMath.c.MAX}
141
+ step=${SDTMath.c.STEP}
142
+ .value=${+this.c.toFixed(2)}
143
+ @change=${this.setBias.bind(this)}
144
+ @input=${this.setBias.bind(this)}
145
+ ><div>Bias<br><span class="math-var">c</span></div></decidables-slider>`
146
+ : html``}
147
+ ${this.s != null
148
+ ? html`<decidables-slider class="s"
149
+ ?disabled=${!this.interactive}
150
+ scale
151
+ min=${SDTMath.s.MIN}
152
+ max=${SDTMath.s.MAX}
153
+ step=${SDTMath.s.STEP}
154
+ .value=${+this.s.toFixed(2)}
155
+ @change=${this.setVariance.bind(this)}
156
+ @input=${this.setVariance.bind(this)}
157
+ ><div>Variance<br><span class="math-var">σ</span></div></decidables-slider>`
158
+ : html``}
159
+ </div>`;
160
+ }
161
+ }
162
+
163
+ customElements.define('sdt-parameters', SDTParameters);