maidr 1.0.0 → 1.0.2

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.
Files changed (204) hide show
  1. package/dist/maidr.js +281 -44
  2. package/dist/maidr.min.js +1 -1
  3. package/package.json +6 -2
  4. package/.Rbuildignore +0 -1
  5. package/.eslintignore +0 -3
  6. package/.eslintrc.json +0 -6
  7. package/.github/workflows/build.yml +0 -20
  8. package/.prettierignore +0 -3
  9. package/.prettierrc.json +0 -7
  10. package/.vscode/extensions.json +0 -25
  11. package/.vscode/settings.json +0 -30
  12. package/.vscode/tasks.json +0 -57
  13. package/CHANGELOG.md +0 -7
  14. package/CITATION.cff +0 -21
  15. package/CONTRIBUTING.md +0 -87
  16. package/dist/styles.css +0 -244
  17. package/dist/styles.min.css +0 -1
  18. package/docs/Audio.html +0 -1398
  19. package/docs/Constants.html +0 -256
  20. package/docs/Description.html +0 -582
  21. package/docs/Helper.html +0 -364
  22. package/docs/LogError.html +0 -905
  23. package/docs/Menu.html +0 -665
  24. package/docs/Position.html +0 -174
  25. package/docs/Resources.html +0 -338
  26. package/docs/Review.html +0 -333
  27. package/docs/Tracker.html +0 -965
  28. package/docs/audio.js.html +0 -635
  29. package/docs/constants.js.html +0 -1242
  30. package/docs/display.js.html +0 -1184
  31. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  32. package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
  33. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  34. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  35. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  36. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  37. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  38. package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
  39. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  40. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  41. package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
  42. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  43. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  44. package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  45. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  46. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  47. package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
  48. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  49. package/docs/fonts/OpenSans-Semibold-webfont.eot +0 -0
  50. package/docs/fonts/OpenSans-Semibold-webfont.svg +0 -1830
  51. package/docs/fonts/OpenSans-Semibold-webfont.ttf +0 -0
  52. package/docs/fonts/OpenSans-Semibold-webfont.woff +0 -0
  53. package/docs/fonts/OpenSans-SemiboldItalic-webfont.eot +0 -0
  54. package/docs/fonts/OpenSans-SemiboldItalic-webfont.svg +0 -1830
  55. package/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf +0 -0
  56. package/docs/fonts/OpenSans-SemiboldItalic-webfont.woff +0 -0
  57. package/docs/index.html +0 -66
  58. package/docs/scripts/linenumber.js +0 -25
  59. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  60. package/docs/scripts/prettify/lang-css.js +0 -2
  61. package/docs/scripts/prettify/prettify.js +0 -28
  62. package/docs/styles/jsdoc-default.css +0 -692
  63. package/docs/styles/prettify-jsdoc.css +0 -111
  64. package/docs/styles/prettify-tomorrow.css +0 -132
  65. package/examples/dev_charts/barplot.html +0 -1056
  66. package/examples/dev_charts/boxplot.html +0 -1856
  67. package/examples/dev_charts/boxplot_flipped.svg +0 -727
  68. package/examples/dev_charts/heatmap.html +0 -1217
  69. package/examples/dev_charts/scatterplot/displ.js +0 -18
  70. package/examples/dev_charts/scatterplot/histogram_for_residual.svg +0 -595
  71. package/examples/dev_charts/scatterplot/hwy.js +0 -15
  72. package/examples/dev_charts/scatterplot/layers/point_layer.json +0 -938
  73. package/examples/dev_charts/scatterplot/layers/smooth_layer.json +0 -322
  74. package/examples/dev_charts/scatterplot/point_layer.js +0 -938
  75. package/examples/dev_charts/scatterplot/prediction_array.js +0 -31
  76. package/examples/dev_charts/scatterplot/prediction_array.json +0 -31
  77. package/examples/dev_charts/scatterplot/residual_array.js +0 -29
  78. package/examples/dev_charts/scatterplot/residual_array.json +0 -29
  79. package/examples/dev_charts/scatterplot/scatterplot.svg +0 -1428
  80. package/examples/dev_charts/scatterplot/scatterplot_data.html +0 -2838
  81. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_point_only.svg +0 -1393
  82. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_bestfit.svg +0 -1424
  83. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_loess_curve.svg +0 -1402
  84. package/examples/dev_charts/scatterplot/smooth_layer.js +0 -322
  85. package/examples/dev_charts/scatterplot.html +0 -4560
  86. package/examples/dodged_bar/dodged_bar.png +0 -0
  87. package/examples/dodged_bar/dodged_bar.svg +0 -198
  88. package/examples/dodged_bar/schema.json +0 -41
  89. package/examples/histogram/histogram_tutorial.svg +0 -482
  90. package/examples/histogram/histogram_tutorial_raw_data.json +0 -362
  91. package/examples/histogram/histogram_user_study.svg +0 -578
  92. package/examples/histogram/histogram_user_study_raw_data.json +0 -362
  93. package/examples/lineplot/lineplot_sample.svg +0 -126
  94. package/examples/lineplot/lineplot_sample_raw_data.json +0 -1
  95. package/examples/lineplot/point+lineplot_sample.svg +0 -700
  96. package/examples/other/audio_oscillator_boxplot.js +0 -95
  97. package/examples/other/barplot_labels.svg +0 -314
  98. package/examples/other/barplot_user_study.svg +0 -313
  99. package/examples/other/boxplot.html +0 -927
  100. package/examples/other/boxplot_data_frame.html +0 -568
  101. package/examples/other/boxplot_label.svg +0 -751
  102. package/examples/other/braille-display_boxplot.js +0 -79
  103. package/examples/other/control_boxplot.js +0 -55
  104. package/examples/other/draft.js +0 -56
  105. package/examples/other/getData.html +0 -400
  106. package/examples/other/getData.js +0 -41
  107. package/examples/other/ggplot_to_svg.R +0 -371
  108. package/examples/other/heatmap.svg +0 -582
  109. package/examples/other/heatmap_label.svg +0 -608
  110. package/examples/other/multiple_barplot.html +0 -2250
  111. package/examples/other/new_scatterplot_user_study_point_layer.json +0 -122
  112. package/examples/other/py_binder_output.html +0 -1167
  113. package/examples/other/scatterplot_label.svg +0 -1429
  114. package/examples/other/seaborn_plot.py +0 -9
  115. package/examples/other/svglite_bar.svg +0 -136
  116. package/examples/other/tutorial_boxplot.svg +0 -727
  117. package/examples/other/tutorial_boxplot_data.json +0 -72
  118. package/examples/other/user_study_boxplot.svg +0 -676
  119. package/examples/stacked_bar/schema.json +0 -41
  120. package/examples/stacked_bar/stack_bar.png +0 -0
  121. package/examples/stacked_bar/stacked_bar.svg +0 -180
  122. package/examples/stacked_normalized_bar/stacked_normalized_bar.png +0 -0
  123. package/examples/stacked_normalized_bar/stacked_normalized_bar.svg +0 -189
  124. package/examples/static/barplot.svg +0 -263
  125. package/examples/static/barplot_diamonds_gridSVG.svg +0 -254
  126. package/examples/static/boxplot.svg +0 -424
  127. package/examples/static/heatmap.svg +0 -373
  128. package/examples/static/heatmap_penguins_table.html +0 -486
  129. package/examples/static/scatterplot.svg +0 -530
  130. package/examples/svglite/task_heatmap.html +0 -802
  131. package/examples/svglite/task_heatmap.svg +0 -111
  132. package/examples/svglite/tutorial_bar.svg +0 -136
  133. package/examples/svglite/tutorial_bar_plot.html +0 -504
  134. package/examples/svglite/tutorial_boxplot.html +0 -1850
  135. package/examples/svglite/tutorial_boxplot.svg +0 -727
  136. package/examples/svglite/tutorial_scatterplot.html +0 -3135
  137. package/examples/svglite/tutorial_scatterplot.svg +0 -311
  138. package/gulpfile.js +0 -49
  139. package/index.html +0 -40
  140. package/jsconfig.json +0 -10
  141. package/jsdoc.json +0 -19
  142. package/src/css/styles.css +0 -241
  143. package/src/js/__tests__/audio.test.js +0 -49
  144. package/src/js/__tests__/constants.test.js +0 -622
  145. package/src/js/audio.js +0 -575
  146. package/src/js/barplot.js +0 -254
  147. package/src/js/boxplot.js +0 -682
  148. package/src/js/constants.js +0 -1182
  149. package/src/js/controls.js +0 -3182
  150. package/src/js/display.js +0 -1124
  151. package/src/js/heatmap.js +0 -411
  152. package/src/js/histogram.js +0 -134
  153. package/src/js/init.js +0 -427
  154. package/src/js/lineplot.js +0 -219
  155. package/src/js/scatterplot.js +0 -619
  156. package/src/js/segmented.js +0 -268
  157. package/user_study_pilot/binder_test.html +0 -526
  158. package/user_study_pilot/data/barplot_user_study.svg +0 -492
  159. package/user_study_pilot/data/barplot_user_study_raw_data.json +0 -22
  160. package/user_study_pilot/data/boxplot_tutorial.json +0 -72
  161. package/user_study_pilot/data/boxplot_tutorial_horizontal.svg +0 -727
  162. package/user_study_pilot/data/boxplot_user_study.json +0 -52
  163. package/user_study_pilot/data/boxplot_user_study_vertical.svg +0 -675
  164. package/user_study_pilot/data/boxplot_user_study_vertical_horizontal.svg +0 -676
  165. package/user_study_pilot/data/heatmap_user_study.svg +0 -719
  166. package/user_study_pilot/data/heatmap_user_study_raw_data.json +0 -127
  167. package/user_study_pilot/data/new_barplot_user_study.svg +0 -269
  168. package/user_study_pilot/data/new_heatmap_user_study.svg +0 -367
  169. package/user_study_pilot/data/new_scatterplot_user_study.svg +0 -603
  170. package/user_study_pilot/data/new_scatterplot_user_study_point_layer.json +0 -122
  171. package/user_study_pilot/data/scatterplot_user_study (1).svg +0 -321
  172. package/user_study_pilot/data/scatterplot_user_study.svg +0 -603
  173. package/user_study_pilot/data/scatterplot_user_study_point_layer.json +0 -122
  174. package/user_study_pilot/data/scatterplot_user_study_smooth_layer.json +0 -322
  175. package/user_study_pilot/intro.html +0 -215
  176. package/user_study_pilot/jaws_settings/Chrome.JDF +0 -10
  177. package/user_study_pilot/jaws_settings/Firefox.JDF +0 -10
  178. package/user_study_pilot/jaws_settings/backup_utf8/Chrome.JDF +0 -10
  179. package/user_study_pilot/jaws_settings/backup_utf8/Firefox.JDF +0 -10
  180. package/user_study_pilot/jaws_settings/backup_utf8/msedge.JDF +0 -10
  181. package/user_study_pilot/jaws_settings/msedge.JDF +0 -10
  182. package/user_study_pilot/nvda_settings/chrome.dic +0 -10
  183. package/user_study_pilot/nvda_settings/default.dic +0 -10
  184. package/user_study_pilot/nvda_settings/firefox.dic +0 -10
  185. package/user_study_pilot/nvda_settings/msedge.dic +0 -10
  186. package/user_study_pilot/scatterplot.html +0 -4560
  187. package/user_study_pilot/seaborn_test.html +0 -1059
  188. package/user_study_pilot/svglite_test.html +0 -534
  189. package/user_study_pilot/task1_bar_plot.html +0 -1111
  190. package/user_study_pilot/task2_heatmap.html +0 -1661
  191. package/user_study_pilot/task3_boxplot_horizontal.html +0 -1690
  192. package/user_study_pilot/task3_boxplot_vertical.html +0 -1689
  193. package/user_study_pilot/task4_scatterplot.html +0 -2091
  194. package/user_study_pilot/tutorial1_bar_plot.html +0 -1159
  195. package/user_study_pilot/tutorial2_heatmap.html +0 -1276
  196. package/user_study_pilot/tutorial3_boxplot_horizontal.html +0 -1861
  197. package/user_study_pilot/tutorial3_boxplot_vertical.html +0 -1807
  198. package/user_study_pilot/tutorial4_scatterplot.html +0 -5893
  199. package/user_study_pilot/tutorial5_histogram.html +0 -1553
  200. package/user_study_pilot/tutorial6_lineplot.html +0 -1011
  201. package/user_study_pilot/tutorial7_stacked.html +0 -763
  202. package/user_study_pilot/tutorial8_stacked_normalized.html +0 -796
  203. package/user_study_pilot/tutorial9_dodged_bar.html +0 -831
  204. package/user_study_pilot/voiceover_settings/user_study_VoiceOver Archive.voprefs +0 -573
package/dist/maidr.js CHANGED
@@ -1,5 +1,12 @@
1
+ /**
2
+ * A class representing constants used throughout the application.
3
+ */
1
4
  class Constants {
2
5
  // element ids
6
+ /**
7
+ * The ID of the chart container element.
8
+ * @type {string}
9
+ */
3
10
  chart_container_id = 'chart-container';
4
11
  main_container_id = 'maidr-container';
5
12
  //chart_container_class = 'chart-container'; // remove later
@@ -19,6 +26,10 @@ class Constants {
19
26
  postLoadEvents = [];
20
27
 
21
28
  // default constructor for all charts
29
+ /**
30
+ * Creates a new instance of the Constants class.
31
+ * @constructor
32
+ */
22
33
  constructor() {}
23
34
 
24
35
  // BTS modes initial values
@@ -63,8 +74,8 @@ class Constants {
63
74
  duration = 0.3;
64
75
  outlierDuration = 0.06;
65
76
  autoPlayOutlierRate = 50; // ms per tone
66
- autoPlayPointsRate = 30;
67
- colorUnselected = '#595959'; // we don't use this yet, but remember: don't rely on color! also do a shape or pattern fill
77
+ autoPlayPointsRate = 50; // time between tones in a run
78
+ colorUnselected = '#595959'; // deprecated, todo: find all instances replace with storing old color method
68
79
  isTracking = 1; // 0 / 1, is tracking on or off
69
80
  visualBraille = false; // do we want to represent braille based on what's visually there or actually there. Like if we have 2 outliers with the same position, do we show 1 (visualBraille true) or 2 (false)
70
81
  globalMinMax = true;
@@ -129,8 +140,29 @@ class Constants {
129
140
  let b = 255 - rgb[2];
130
141
  return 'rgb(' + r + ',' + g + ',' + b + ')';
131
142
  }
143
+ GetBetterColor(oldColor) {
144
+ // get a highly contrasting color against the current
145
+ // method: choose an inverted color, but if it's just a shade of gray, default to this.colorSelected
146
+ let newColor = this.ColorInvert(oldColor);
147
+ let rgb = newColor.replace(/[^\d,]/g, '').split(',');
148
+ if (
149
+ rgb[1] < rgb[0] + 10 &&
150
+ rgb[1] > rgb[0] - 10 &&
151
+ rgb[2] < rgb[0] + 10 &&
152
+ rgb[2] > rgb[0] - 10 &&
153
+ (rgb[0] > 86 || rgb[0] < 169)
154
+ ) {
155
+ // too gray and too close to center gray, use default
156
+ newColor = this.colorSelected;
157
+ }
158
+
159
+ return newColor;
160
+ }
132
161
  }
133
162
 
163
+ /**
164
+ * Resources class contains properties and methods related to language, knowledge level, and strings.
165
+ */
134
166
  class Resources {
135
167
  constructor() {}
136
168
 
@@ -163,11 +195,19 @@ class Resources {
163
195
  },
164
196
  };
165
197
 
198
+ /**
199
+ * Returns a string based on the provided ID, language, and knowledge level.
200
+ * @param {string} id - The ID of the string to retrieve.
201
+ * @returns {string} The string corresponding to the provided ID, language, and knowledge level.
202
+ */
166
203
  GetString(id) {
167
204
  return this.strings[this.language][this.knowledgeLevel][id];
168
205
  }
169
206
  }
170
207
 
208
+ /**
209
+ * Represents a menu object with various settings and keyboard shortcuts.
210
+ */
171
211
  class Menu {
172
212
  whereWasMyFocus = null;
173
213
 
@@ -276,6 +316,9 @@ class Menu {
276
316
  <div id="menu_modal_backdrop" class="modal-backdrop hidden"></div>
277
317
  `;
278
318
 
319
+ /**
320
+ * Creates a menu element and sets up event listeners for opening and closing the menu.
321
+ */
279
322
  CreateMenu() {
280
323
  // menu element creation
281
324
  document
@@ -325,6 +368,13 @@ class Menu {
325
368
  ]);
326
369
  }
327
370
 
371
+ /**
372
+ * Destroys the menu element and its backdrop.
373
+ * @function
374
+ * @name Destroy
375
+ * @memberof module:constants
376
+ * @returns {void}
377
+ */
328
378
  Destroy() {
329
379
  // menu element destruction
330
380
  let menu = document.getElementById('menu');
@@ -337,6 +387,10 @@ class Menu {
337
387
  }
338
388
  }
339
389
 
390
+ /**
391
+ * Toggles the menu on and off.
392
+ * @param {boolean} [onoff=false] - Whether to turn the menu on or off. Defaults to false.
393
+ */
340
394
  Toggle(onoff = false) {
341
395
  if (typeof onoff == 'undefined') {
342
396
  if (document.getElementById('menu').classList.contains('hidden')) {
@@ -362,6 +416,9 @@ class Menu {
362
416
  }
363
417
  }
364
418
 
419
+ /**
420
+ * Populates the data in the HTML elements with the values from the constants object.
421
+ */
365
422
  PopulateData() {
366
423
  document.getElementById('vol').value = constants.vol;
367
424
  //document.getElementById('show_rect').checked = constants.showRect;
@@ -375,6 +432,9 @@ class Menu {
375
432
  constants.keypressInterval;
376
433
  }
377
434
 
435
+ /**
436
+ * Saves the data from the HTML elements into the constants object.
437
+ */
378
438
  SaveData() {
379
439
  constants.vol = document.getElementById('vol').value;
380
440
  //constants.showRect = document.getElementById('show_rect').checked;
@@ -389,6 +449,12 @@ class Menu {
389
449
  document.getElementById('keypress_interval').value;
390
450
  }
391
451
 
452
+ /**
453
+ * Saves all data in this.SaveData() to local storage.
454
+ * @function
455
+ * @memberof constants
456
+ * @returns {void}
457
+ */
392
458
  SaveDataToLocalStorage() {
393
459
  // save all data in this.SaveData() to local storage
394
460
  let data = {};
@@ -402,6 +468,9 @@ class Menu {
402
468
  data.keypressInterval = constants.keypressInterval;
403
469
  localStorage.setItem('settings_data', JSON.stringify(data));
404
470
  }
471
+ /**
472
+ * Loads data from local storage and updates the constants object with the retrieved values.
473
+ */
405
474
  LoadDataFromLocalStorage() {
406
475
  let data = JSON.parse(localStorage.getItem('settings_data'));
407
476
  if (data) {
@@ -417,6 +486,10 @@ class Menu {
417
486
  }
418
487
  }
419
488
 
489
+ /**
490
+ * Creates an html modal containing summary info of the active chart.
491
+ * @class
492
+ */
420
493
  class Description {
421
494
  // This class creates an html modal containing summary info of the active chart
422
495
  // Trigger popup with 'D' key
@@ -429,6 +502,9 @@ class Description {
429
502
  //this.CreateComponent(); // disabled as we're in development and have switched priorities
430
503
  }
431
504
 
505
+ /**
506
+ * Creates a modal component containing description summary stuff.
507
+ */
432
508
  CreateComponent() {
433
509
  // modal containing description summary stuff
434
510
  let html = `
@@ -496,6 +572,9 @@ class Description {
496
572
  ]);
497
573
  }
498
574
 
575
+ /**
576
+ * Removes the description element and backdrop from the DOM.
577
+ */
499
578
  Destroy() {
500
579
  // description element destruction
501
580
  let description = document.getElementById('menu');
@@ -508,6 +587,10 @@ class Description {
508
587
  }
509
588
  }
510
589
 
590
+ /**
591
+ * Toggles the visibility of the description element.
592
+ * @param {boolean} [onoff=false] - Whether to turn the description element on or off.
593
+ */
511
594
  Toggle(onoff = false) {
512
595
  if (typeof onoff == 'undefined') {
513
596
  if (document.getElementById('description').classList.contains('hidden')) {
@@ -533,6 +616,9 @@ class Description {
533
616
  }
534
617
  }
535
618
 
619
+ /**
620
+ * Populates the data for the chart and table based on the chart type and plot data.
621
+ */
536
622
  PopulateData() {
537
623
  let descHtml = '';
538
624
 
@@ -663,6 +749,10 @@ class Description {
663
749
  }
664
750
  }
665
751
 
752
+ /**
753
+ * Represents a position in 3D space.
754
+ * @class
755
+ */
666
756
  class Position {
667
757
  constructor(x, y, z = -1) {
668
758
  this.x = x;
@@ -672,7 +762,16 @@ class Position {
672
762
  }
673
763
 
674
764
  // HELPER FUNCTIONS
765
+ /**
766
+ * A helper class with static methods.
767
+ */
675
768
  class Helper {
769
+ /**
770
+ * Checks if an object is present in an array.
771
+ * @param {Object} obj - The object to search for.
772
+ * @param {Array} arr - The array to search in.
773
+ * @returns {boolean} - True if the object is present in the array, false otherwise.
774
+ */
676
775
  static containsObject(obj, arr) {
677
776
  for (let i = 0; i < arr.length; i++) {
678
777
  if (arr[i] === obj) return true;
@@ -681,11 +780,18 @@ class Helper {
681
780
  }
682
781
  }
683
782
 
783
+ /**
784
+ * A class representing a Tracker.
785
+ * @class
786
+ */
684
787
  class Tracker {
685
788
  constructor() {
686
789
  this.DataSetup();
687
790
  }
688
791
 
792
+ /**
793
+ * Sets up the tracker data by checking if previous data exists and creating new data if it doesn't.
794
+ */
689
795
  DataSetup() {
690
796
  let prevData = this.GetTrackerData();
691
797
  if (prevData) {
@@ -702,6 +808,9 @@ class Tracker {
702
808
  }
703
809
  }
704
810
 
811
+ /**
812
+ * Downloads the tracker data as a JSON file.
813
+ */
705
814
  DownloadTrackerData() {
706
815
  let link = document.createElement('a');
707
816
  let data = this.GetTrackerData();
@@ -711,15 +820,26 @@ class Tracker {
711
820
  link.click();
712
821
  }
713
822
 
823
+ /**
824
+ * Saves the tracker data to local storage.
825
+ * @param {Object} data - The data to be saved.
826
+ */
714
827
  SaveTrackerData(data) {
715
828
  localStorage.setItem(constants.project_id, JSON.stringify(data));
716
829
  }
717
830
 
831
+ /**
832
+ * Retrieves tracker data from local storage.
833
+ * @returns {Object} The tracker data.
834
+ */
718
835
  GetTrackerData() {
719
836
  let data = JSON.parse(localStorage.getItem(constants.project_id));
720
837
  return data;
721
838
  }
722
839
 
840
+ /**
841
+ * Removes the project_id from localStorage, clears the tracking data, and sets up new data.
842
+ */
723
843
  Delete() {
724
844
  localStorage.removeItem(constants.project_id);
725
845
  this.data = null;
@@ -731,6 +851,10 @@ class Tracker {
731
851
  this.DataSetup();
732
852
  }
733
853
 
854
+ /**
855
+ * Logs an event with various properties to the tracker data.
856
+ * @param {Event} e - The event to log.
857
+ */
734
858
  LogEvent(e) {
735
859
  let eventToLog = {};
736
860
 
@@ -950,6 +1074,11 @@ class Tracker {
950
1074
  this.SaveTrackerData(data);
951
1075
  }
952
1076
 
1077
+ /**
1078
+ * Checks if the given item is undefined or null.
1079
+ * @param {*} item - The item to check.
1080
+ * @returns {boolean} - Returns true if the item is undefined or null, else false.
1081
+ */
953
1082
  isUndefinedOrNull(item) {
954
1083
  try {
955
1084
  return item === undefined || item === null;
@@ -959,9 +1088,17 @@ class Tracker {
959
1088
  }
960
1089
  }
961
1090
 
1091
+ /**
1092
+ * Represents a Review object.
1093
+ * @class
1094
+ */
962
1095
  class Review {
963
1096
  constructor() {}
964
1097
 
1098
+ /**
1099
+ * Toggles the review mode on or off.
1100
+ * @param {boolean} [onoff=true] - Whether to turn review mode on or off. Default is true.
1101
+ */
965
1102
  ToggleReviewMode(onoff = true) {
966
1103
  // true means on or show
967
1104
  if (onoff) {
@@ -984,17 +1121,33 @@ class Review {
984
1121
  }
985
1122
  }
986
1123
 
1124
+ /**
1125
+ * Represents a class for logging errors.
1126
+ */
987
1127
  class LogError {
988
1128
  constructor() {}
989
1129
 
1130
+ /**
1131
+ * Logs the absent element and turns off visual highlighting.
1132
+ * @param {string} a - The absent element to log.
1133
+ */
990
1134
  LogAbsentElement(a) {
991
1135
  console.log(a, 'not found. Visual highlighting is turned off.');
992
1136
  }
993
1137
 
1138
+ /**
1139
+ * Logs a critical element and indicates that MAIDR is unable to run.
1140
+ * @param {string} a - The critical element to log.
1141
+ */
994
1142
  LogCriticalElement(a) {
995
1143
  consolelog(a, 'is critical. MAIDR unable to run');
996
1144
  }
997
1145
 
1146
+ /**
1147
+ * Logs a message indicating that two values do not have the same length.
1148
+ * @param {*} a - The first value to compare.
1149
+ * @param {*} b - The second value to compare.
1150
+ */
998
1151
  LogDifferentLengths(a, b) {
999
1152
  console.log(
1000
1153
  a,
@@ -1004,6 +1157,11 @@ class LogError {
1004
1157
  );
1005
1158
  }
1006
1159
 
1160
+ /**
1161
+ * Logs a message indicating that too many elements were found and only the first n elements will be highlighted.
1162
+ * @param {string} a - The type of element being highlighted.
1163
+ * @param {number} b - The maximum number of elements to highlight.
1164
+ */
1007
1165
  LogTooManyElements(a, b) {
1008
1166
  console.log(
1009
1167
  'Too many',
@@ -1014,15 +1172,23 @@ class LogError {
1014
1172
  );
1015
1173
  }
1016
1174
 
1175
+ /**
1176
+ * Logs a message indicating that the provided parameter is not an array.
1177
+ * @param {*} a - The parameter that is not an array.
1178
+ */
1017
1179
  LogNotArray(a) {
1018
1180
  console.log(a, 'is not an array. Visual highlighting is turned off.');
1019
1181
  }
1020
1182
  }
1021
-
1022
- // Audio class
1023
- // Sets up audio stuff (compressor, gain),
1024
- // sets up an oscillator that has good falloff (no clipping sounds) and can be instanced to be played anytime and can handle overlaps,
1025
- // sets up an actual playTone function that plays tones based on current chart position
1183
+
1184
+ /**
1185
+ * Audio class
1186
+ * Sets up audio stuff (compressor, gain),
1187
+ * sets up an oscillator that has good falloff (no clipping sounds) and can be instanced to be played anytime and can handle overlaps,
1188
+ * sets up an actual playTone function that plays tones based on current chart position
1189
+ *
1190
+ * @class
1191
+ */
1026
1192
  class Audio {
1027
1193
  constructor() {
1028
1194
  this.AudioContext = window['AudioContext'] || window['webkitAudioContext'];
@@ -1030,6 +1196,10 @@ class Audio {
1030
1196
  this.compressor = this.compressorSetup(this.audioContext);
1031
1197
  }
1032
1198
 
1199
+ /**
1200
+ * Sets up a dynamics compressor for better audio quality.
1201
+ * @returns {DynamicsCompressorNode} The created compressor.
1202
+ */
1033
1203
  compressorSetup() {
1034
1204
  let compressor = this.audioContext.createDynamicsCompressor(); // create compressor for better audio quality
1035
1205
 
@@ -1047,6 +1217,9 @@ class Audio {
1047
1217
  }
1048
1218
 
1049
1219
  // an oscillator is created and destroyed after some falloff
1220
+ /**
1221
+ * Plays a tone based on the current chart type and position.
1222
+ */
1050
1223
  playTone() {
1051
1224
  let currentDuration = constants.duration;
1052
1225
  let volume = constants.vol;
@@ -1339,6 +1512,14 @@ class Audio {
1339
1512
  }
1340
1513
  }
1341
1514
 
1515
+ /**
1516
+ * Plays an oscillator with the given frequency, duration, panning, volume, and wave type.
1517
+ * @param {number} frequency - The frequency of the oscillator.
1518
+ * @param {number} currentDuration - The duration of the oscillator in seconds.
1519
+ * @param {number} panning - The panning value of the oscillator.
1520
+ * @param {number} [currentVol=1] - The volume of the oscillator.
1521
+ * @param {string} [wave='sine'] - The wave type of the oscillator.
1522
+ */
1342
1523
  playOscillator(
1343
1524
  frequency,
1344
1525
  currentDuration,
@@ -1406,6 +1587,14 @@ class Audio {
1406
1587
  }, currentDuration * 1e3 * 2);
1407
1588
  }
1408
1589
 
1590
+ /**
1591
+ * Plays a smooth sound with the given frequency array, duration, panning array, volume, and wave type.
1592
+ * @param {number[]} freqArr - The array of frequencies to play.
1593
+ * @param {number} currentDuration - The duration of the sound in seconds.
1594
+ * @param {number[]} panningArr - The array of panning values.
1595
+ * @param {number} currentVol - The volume of the sound.
1596
+ * @param {string} wave - The type of wave to use for the oscillator.
1597
+ */
1409
1598
  playSmooth(
1410
1599
  freqArr = [600, 500, 400, 300],
1411
1600
  currentDuration = 2,
@@ -1466,6 +1655,9 @@ class Audio {
1466
1655
  }, currentDuration * 1e3 * 2);
1467
1656
  }
1468
1657
 
1658
+ /**
1659
+ * Plays a null frequency sound.
1660
+ */
1469
1661
  PlayNull() {
1470
1662
  let frequency = constants.NULL_FREQUENCY;
1471
1663
  let duration = constants.duration;
@@ -1490,6 +1682,12 @@ class Audio {
1490
1682
  );
1491
1683
  }
1492
1684
 
1685
+ /**
1686
+ * Plays a pleasant end chime.
1687
+ * @function
1688
+ * @memberof audio
1689
+ * @returns {void}
1690
+ */
1493
1691
  playEnd() {
1494
1692
  // play a pleasent end chime. We'll use terminal chime from VSCode
1495
1693
  if (constants.canPlayEndChime) {
@@ -1519,6 +1717,13 @@ class Audio {
1519
1717
  }
1520
1718
  }
1521
1719
 
1720
+ /**
1721
+ * Stops the smooth gain and cancels any scheduled values.
1722
+ * @function
1723
+ * @memberof Audio
1724
+ * @instance
1725
+ * @returns {void}
1726
+ */
1522
1727
  KillSmooth() {
1523
1728
  if (constants.smoothId) {
1524
1729
  this.smoothGain.gain.cancelScheduledValues(0);
@@ -1533,6 +1738,15 @@ class Audio {
1533
1738
  }
1534
1739
  }
1535
1740
 
1741
+ /**
1742
+ * Goes between min and max proportional to how val goes between a and b.
1743
+ * @param {number} val - The value to slide between a and b.
1744
+ * @param {number} a - The start value of the slide.
1745
+ * @param {number} b - The end value of the slide.
1746
+ * @param {number} min - The minimum value of the slide.
1747
+ * @param {number} max - The maximum value of the slide.
1748
+ * @returns {number} The new value between min and max.
1749
+ */
1536
1750
  SlideBetween(val, a, b, min, max) {
1537
1751
  // helper function that goes between min and max proportional to how val goes between a and b
1538
1752
  let newVal = ((val - a) / (b - a)) * (max - min) + min;
@@ -1542,7 +1756,7 @@ class Audio {
1542
1756
  return newVal;
1543
1757
  }
1544
1758
  }
1545
-
1759
+
1546
1760
  class Display {
1547
1761
  constructor() {
1548
1762
  this.infoDiv = constants.infoDiv;
@@ -1658,7 +1872,12 @@ class Display {
1658
1872
  }
1659
1873
 
1660
1874
  toggleSonificationMode() {
1661
- if (singleMaidr.type == 'point' || singleMaidr.type.includes('point')) {
1875
+ if (
1876
+ constants.chartType == 'point' ||
1877
+ constants.chartType == 'stacked_bar' ||
1878
+ constants.chartType == 'stacked_normalized_bar' ||
1879
+ constants.chartType == 'dodged_bar'
1880
+ ) {
1662
1881
  if (constants.sonifMode == 'off') {
1663
1882
  constants.sonifMode = 'on';
1664
1883
  this.announceText(resources.GetString('son_sep'));
@@ -2662,7 +2881,7 @@ class Display {
2662
2881
  return allocation;
2663
2882
  }
2664
2883
  }
2665
-
2884
+
2666
2885
  class BarChart {
2667
2886
  constructor() {
2668
2887
  // initialize variables xlevel, data, and elements
@@ -2902,20 +3121,22 @@ class BarChart {
2902
3121
  if (this.bars) {
2903
3122
  this.activeElement = this.bars[position.x];
2904
3123
  if (this.activeElement) {
2905
- this.activeElementColor = this.activeElement.style.fill;
2906
- this.activeElement.style.fill = constants.colorSelected;
3124
+ this.activeElementColor = this.activeElement.getAttribute('fill');
3125
+ let newColor = constants.GetBetterColor(this.activeElementColor);
3126
+ this.activeElement.setAttribute('fill', newColor);
2907
3127
  }
2908
3128
  }
2909
3129
  }
2910
3130
 
2911
3131
  UnSelectPrevious() {
2912
3132
  if (this.activeElement) {
2913
- this.activeElement.style.fill = this.activeElementColor;
3133
+ // set fill attribute to the original color
3134
+ this.activeElement.setAttribute('fill', this.activeElementColor);
2914
3135
  this.activeElement = null;
2915
3136
  }
2916
3137
  }
2917
3138
  }
2918
-
3139
+
2919
3140
  //
2920
3141
  // BoxPlot class.
2921
3142
  // This initializes and contains the JSON data model for this chart
@@ -3598,7 +3819,7 @@ class BoxplotRect {
3598
3819
  constants.chart.appendChild(rect);
3599
3820
  }
3600
3821
  }
3601
-
3822
+
3602
3823
  class HeatMap {
3603
3824
  constructor() {
3604
3825
  // initialize variables xlevel, data, and elements
@@ -4010,7 +4231,7 @@ class HeatMapRect {
4010
4231
  //constants.chart.appendChild(rect);
4011
4232
  }
4012
4233
  }
4013
-
4234
+
4014
4235
  document.addEventListener('DOMContentLoaded', function (e) {
4015
4236
  // we wrap in DOMContentLoaded to make sure everything has loaded before we run anything
4016
4237
  });
@@ -4630,7 +4851,7 @@ class Layer1Point {
4630
4851
  this.PrintPoints();
4631
4852
  }
4632
4853
  }
4633
-
4854
+
4634
4855
  class Histogram {
4635
4856
  constructor() {
4636
4857
  // initialize main data: data, elements
@@ -4750,20 +4971,22 @@ class Histogram {
4750
4971
  if (this.bars) {
4751
4972
  this.activeElement = this.bars[position.x];
4752
4973
  if (this.activeElement) {
4753
- this.activeElementColor = this.activeElement.style.fill;
4754
- this.activeElement.style.fill = constants.colorSelected;
4974
+ this.activeElementColor = this.activeElement.getAttribute('fill');
4975
+ let newColor = constants.GetBetterColor(this.activeElementColor);
4976
+ this.activeElement.setAttribute('fill', newColor);
4755
4977
  }
4756
4978
  }
4757
4979
  }
4758
4980
 
4759
4981
  UnSelectPrevious() {
4760
4982
  if (this.activeElement) {
4761
- this.activeElement.style.fill = this.activeElementColor;
4983
+ // set fill attribute to the original color
4984
+ this.activeElement.setAttribute('fill', this.activeElementColor);
4762
4985
  this.activeElement = null;
4763
4986
  }
4764
4987
  }
4765
4988
  }
4766
-
4989
+
4767
4990
  class LinePlot {
4768
4991
  constructor() {
4769
4992
  this.SetLineLayer();
@@ -4983,7 +5206,7 @@ class Point {
4983
5206
  this.PrintPoints();
4984
5207
  }
4985
5208
  }
4986
-
5209
+
4987
5210
  class Segmented {
4988
5211
  constructor() {
4989
5212
  // initialize variables level, data, and elements
@@ -5177,24 +5400,32 @@ class Segmented {
5177
5400
 
5178
5401
  PlayTones() {
5179
5402
  if (Array.isArray(this.plotData[position.x][position.y])) {
5180
- // we play a run of tones
5181
- position.z = 0;
5182
- constants.sepPlayId = setInterval(
5183
- function () {
5184
- // play this tone
5403
+ if (constants.sonifMode == 'on') {
5404
+ // we play a run of tones
5405
+ position.z = 0;
5406
+ constants.sepPlayId = setInterval(
5407
+ function () {
5408
+ // play this tone
5409
+ audio.playTone();
5410
+
5411
+ // and then set up for the next one
5412
+ position.z += 1;
5413
+
5414
+ // and kill if we're done
5415
+ if (position.z + 1 > plot.plotData[position.x][position.y].length) {
5416
+ constants.KillSepPlay();
5417
+ position.z = -1;
5418
+ }
5419
+ },
5420
+ constants.sonifMode == 'on' ? constants.autoPlayPointsRate : 0
5421
+ );
5422
+ } else {
5423
+ // sonifMode == 'same', so we play all at once
5424
+ for (let i = 0; i < this.plotData[position.x][position.y].length; i++) {
5425
+ position.z = i;
5185
5426
  audio.playTone();
5186
-
5187
- // and then set up for the next one
5188
- position.z += 1;
5189
-
5190
- // and kill if we're done
5191
- if (position.z + 1 > plot.plotData[position.x][position.y].length) {
5192
- constants.KillSepPlay();
5193
- position.z = -1;
5194
- }
5195
- },
5196
- constants.sonifMode == 'on' ? constants.autoPlayPointsRate : 0
5197
- );
5427
+ }
5428
+ }
5198
5429
  } else {
5199
5430
  audio.playTone();
5200
5431
  }
@@ -5231,8 +5462,8 @@ class Segmented {
5231
5462
  this.activeElement = this.elements[position.x][position.y];
5232
5463
  if (this.activeElement) {
5233
5464
  this.activeElementColor = this.activeElement.style.fill;
5234
- let invertedColor = constants.ColorInvert(this.activeElementColor);
5235
- this.activeElement.style.fill = invertedColor;
5465
+ let newColor = constants.GetBetterColor(this.activeElementColor);
5466
+ this.activeElement.style.fill = newColor;
5236
5467
  }
5237
5468
  }
5238
5469
  }
@@ -5244,7 +5475,7 @@ class Segmented {
5244
5475
  }
5245
5476
  }
5246
5477
  }
5247
-
5478
+
5248
5479
  class Control {
5249
5480
  constructor() {
5250
5481
  this.SetControls();
@@ -8427,7 +8658,7 @@ class Control {
8427
8658
  // now we get next / prev based on chartIndex. If DNE, return null
8428
8659
  }
8429
8660
  }
8430
-
8661
+
8431
8662
  // events and init functions
8432
8663
  // we do some setup, but most of the work is done when user focuses on an element matching an id from maidr user data
8433
8664
  document.addEventListener('DOMContentLoaded', function (e) {
@@ -8604,7 +8835,13 @@ function FocusBeforeOrAfter() {
8604
8835
  function DestroyMaidr() {
8605
8836
  // chart cleanup
8606
8837
  if (constants.chartType == 'bar' || constants.chartType == 'hist') {
8607
- plot.DeselectAll();
8838
+ // deselect, if possible
8839
+ if (typeof plot.DeselectAll === 'function') {
8840
+ plot.DeselectAll();
8841
+ }
8842
+ if (typeof plot.UnSelectPrevious === 'function') {
8843
+ plot.UnSelectPrevious();
8844
+ }
8608
8845
  }
8609
8846
 
8610
8847
  // remove events