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.
- package/dist/maidr.js +281 -44
- package/dist/maidr.min.js +1 -1
- package/package.json +6 -2
- package/.Rbuildignore +0 -1
- package/.eslintignore +0 -3
- package/.eslintrc.json +0 -6
- package/.github/workflows/build.yml +0 -20
- package/.prettierignore +0 -3
- package/.prettierrc.json +0 -7
- package/.vscode/extensions.json +0 -25
- package/.vscode/settings.json +0 -30
- package/.vscode/tasks.json +0 -57
- package/CHANGELOG.md +0 -7
- package/CITATION.cff +0 -21
- package/CONTRIBUTING.md +0 -87
- package/dist/styles.css +0 -244
- package/dist/styles.min.css +0 -1
- package/docs/Audio.html +0 -1398
- package/docs/Constants.html +0 -256
- package/docs/Description.html +0 -582
- package/docs/Helper.html +0 -364
- package/docs/LogError.html +0 -905
- package/docs/Menu.html +0 -665
- package/docs/Position.html +0 -174
- package/docs/Resources.html +0 -338
- package/docs/Review.html +0 -333
- package/docs/Tracker.html +0 -965
- package/docs/audio.js.html +0 -635
- package/docs/constants.js.html +0 -1242
- package/docs/display.js.html +0 -1184
- package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
- package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
- package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
- package/docs/fonts/OpenSans-Semibold-webfont.eot +0 -0
- package/docs/fonts/OpenSans-Semibold-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-Semibold-webfont.ttf +0 -0
- package/docs/fonts/OpenSans-Semibold-webfont.woff +0 -0
- package/docs/fonts/OpenSans-SemiboldItalic-webfont.eot +0 -0
- package/docs/fonts/OpenSans-SemiboldItalic-webfont.svg +0 -1830
- package/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf +0 -0
- package/docs/fonts/OpenSans-SemiboldItalic-webfont.woff +0 -0
- package/docs/index.html +0 -66
- package/docs/scripts/linenumber.js +0 -25
- package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
- package/docs/scripts/prettify/lang-css.js +0 -2
- package/docs/scripts/prettify/prettify.js +0 -28
- package/docs/styles/jsdoc-default.css +0 -692
- package/docs/styles/prettify-jsdoc.css +0 -111
- package/docs/styles/prettify-tomorrow.css +0 -132
- package/examples/dev_charts/barplot.html +0 -1056
- package/examples/dev_charts/boxplot.html +0 -1856
- package/examples/dev_charts/boxplot_flipped.svg +0 -727
- package/examples/dev_charts/heatmap.html +0 -1217
- package/examples/dev_charts/scatterplot/displ.js +0 -18
- package/examples/dev_charts/scatterplot/histogram_for_residual.svg +0 -595
- package/examples/dev_charts/scatterplot/hwy.js +0 -15
- package/examples/dev_charts/scatterplot/layers/point_layer.json +0 -938
- package/examples/dev_charts/scatterplot/layers/smooth_layer.json +0 -322
- package/examples/dev_charts/scatterplot/point_layer.js +0 -938
- package/examples/dev_charts/scatterplot/prediction_array.js +0 -31
- package/examples/dev_charts/scatterplot/prediction_array.json +0 -31
- package/examples/dev_charts/scatterplot/residual_array.js +0 -29
- package/examples/dev_charts/scatterplot/residual_array.json +0 -29
- package/examples/dev_charts/scatterplot/scatterplot.svg +0 -1428
- package/examples/dev_charts/scatterplot/scatterplot_data.html +0 -2838
- package/examples/dev_charts/scatterplot/scatterplot_no_jitter_point_only.svg +0 -1393
- package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_bestfit.svg +0 -1424
- package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_loess_curve.svg +0 -1402
- package/examples/dev_charts/scatterplot/smooth_layer.js +0 -322
- package/examples/dev_charts/scatterplot.html +0 -4560
- package/examples/dodged_bar/dodged_bar.png +0 -0
- package/examples/dodged_bar/dodged_bar.svg +0 -198
- package/examples/dodged_bar/schema.json +0 -41
- package/examples/histogram/histogram_tutorial.svg +0 -482
- package/examples/histogram/histogram_tutorial_raw_data.json +0 -362
- package/examples/histogram/histogram_user_study.svg +0 -578
- package/examples/histogram/histogram_user_study_raw_data.json +0 -362
- package/examples/lineplot/lineplot_sample.svg +0 -126
- package/examples/lineplot/lineplot_sample_raw_data.json +0 -1
- package/examples/lineplot/point+lineplot_sample.svg +0 -700
- package/examples/other/audio_oscillator_boxplot.js +0 -95
- package/examples/other/barplot_labels.svg +0 -314
- package/examples/other/barplot_user_study.svg +0 -313
- package/examples/other/boxplot.html +0 -927
- package/examples/other/boxplot_data_frame.html +0 -568
- package/examples/other/boxplot_label.svg +0 -751
- package/examples/other/braille-display_boxplot.js +0 -79
- package/examples/other/control_boxplot.js +0 -55
- package/examples/other/draft.js +0 -56
- package/examples/other/getData.html +0 -400
- package/examples/other/getData.js +0 -41
- package/examples/other/ggplot_to_svg.R +0 -371
- package/examples/other/heatmap.svg +0 -582
- package/examples/other/heatmap_label.svg +0 -608
- package/examples/other/multiple_barplot.html +0 -2250
- package/examples/other/new_scatterplot_user_study_point_layer.json +0 -122
- package/examples/other/py_binder_output.html +0 -1167
- package/examples/other/scatterplot_label.svg +0 -1429
- package/examples/other/seaborn_plot.py +0 -9
- package/examples/other/svglite_bar.svg +0 -136
- package/examples/other/tutorial_boxplot.svg +0 -727
- package/examples/other/tutorial_boxplot_data.json +0 -72
- package/examples/other/user_study_boxplot.svg +0 -676
- package/examples/stacked_bar/schema.json +0 -41
- package/examples/stacked_bar/stack_bar.png +0 -0
- package/examples/stacked_bar/stacked_bar.svg +0 -180
- package/examples/stacked_normalized_bar/stacked_normalized_bar.png +0 -0
- package/examples/stacked_normalized_bar/stacked_normalized_bar.svg +0 -189
- package/examples/static/barplot.svg +0 -263
- package/examples/static/barplot_diamonds_gridSVG.svg +0 -254
- package/examples/static/boxplot.svg +0 -424
- package/examples/static/heatmap.svg +0 -373
- package/examples/static/heatmap_penguins_table.html +0 -486
- package/examples/static/scatterplot.svg +0 -530
- package/examples/svglite/task_heatmap.html +0 -802
- package/examples/svglite/task_heatmap.svg +0 -111
- package/examples/svglite/tutorial_bar.svg +0 -136
- package/examples/svglite/tutorial_bar_plot.html +0 -504
- package/examples/svglite/tutorial_boxplot.html +0 -1850
- package/examples/svglite/tutorial_boxplot.svg +0 -727
- package/examples/svglite/tutorial_scatterplot.html +0 -3135
- package/examples/svglite/tutorial_scatterplot.svg +0 -311
- package/gulpfile.js +0 -49
- package/index.html +0 -40
- package/jsconfig.json +0 -10
- package/jsdoc.json +0 -19
- package/src/css/styles.css +0 -241
- package/src/js/__tests__/audio.test.js +0 -49
- package/src/js/__tests__/constants.test.js +0 -622
- package/src/js/audio.js +0 -575
- package/src/js/barplot.js +0 -254
- package/src/js/boxplot.js +0 -682
- package/src/js/constants.js +0 -1182
- package/src/js/controls.js +0 -3182
- package/src/js/display.js +0 -1124
- package/src/js/heatmap.js +0 -411
- package/src/js/histogram.js +0 -134
- package/src/js/init.js +0 -427
- package/src/js/lineplot.js +0 -219
- package/src/js/scatterplot.js +0 -619
- package/src/js/segmented.js +0 -268
- package/user_study_pilot/binder_test.html +0 -526
- package/user_study_pilot/data/barplot_user_study.svg +0 -492
- package/user_study_pilot/data/barplot_user_study_raw_data.json +0 -22
- package/user_study_pilot/data/boxplot_tutorial.json +0 -72
- package/user_study_pilot/data/boxplot_tutorial_horizontal.svg +0 -727
- package/user_study_pilot/data/boxplot_user_study.json +0 -52
- package/user_study_pilot/data/boxplot_user_study_vertical.svg +0 -675
- package/user_study_pilot/data/boxplot_user_study_vertical_horizontal.svg +0 -676
- package/user_study_pilot/data/heatmap_user_study.svg +0 -719
- package/user_study_pilot/data/heatmap_user_study_raw_data.json +0 -127
- package/user_study_pilot/data/new_barplot_user_study.svg +0 -269
- package/user_study_pilot/data/new_heatmap_user_study.svg +0 -367
- package/user_study_pilot/data/new_scatterplot_user_study.svg +0 -603
- package/user_study_pilot/data/new_scatterplot_user_study_point_layer.json +0 -122
- package/user_study_pilot/data/scatterplot_user_study (1).svg +0 -321
- package/user_study_pilot/data/scatterplot_user_study.svg +0 -603
- package/user_study_pilot/data/scatterplot_user_study_point_layer.json +0 -122
- package/user_study_pilot/data/scatterplot_user_study_smooth_layer.json +0 -322
- package/user_study_pilot/intro.html +0 -215
- package/user_study_pilot/jaws_settings/Chrome.JDF +0 -10
- package/user_study_pilot/jaws_settings/Firefox.JDF +0 -10
- package/user_study_pilot/jaws_settings/backup_utf8/Chrome.JDF +0 -10
- package/user_study_pilot/jaws_settings/backup_utf8/Firefox.JDF +0 -10
- package/user_study_pilot/jaws_settings/backup_utf8/msedge.JDF +0 -10
- package/user_study_pilot/jaws_settings/msedge.JDF +0 -10
- package/user_study_pilot/nvda_settings/chrome.dic +0 -10
- package/user_study_pilot/nvda_settings/default.dic +0 -10
- package/user_study_pilot/nvda_settings/firefox.dic +0 -10
- package/user_study_pilot/nvda_settings/msedge.dic +0 -10
- package/user_study_pilot/scatterplot.html +0 -4560
- package/user_study_pilot/seaborn_test.html +0 -1059
- package/user_study_pilot/svglite_test.html +0 -534
- package/user_study_pilot/task1_bar_plot.html +0 -1111
- package/user_study_pilot/task2_heatmap.html +0 -1661
- package/user_study_pilot/task3_boxplot_horizontal.html +0 -1690
- package/user_study_pilot/task3_boxplot_vertical.html +0 -1689
- package/user_study_pilot/task4_scatterplot.html +0 -2091
- package/user_study_pilot/tutorial1_bar_plot.html +0 -1159
- package/user_study_pilot/tutorial2_heatmap.html +0 -1276
- package/user_study_pilot/tutorial3_boxplot_horizontal.html +0 -1861
- package/user_study_pilot/tutorial3_boxplot_vertical.html +0 -1807
- package/user_study_pilot/tutorial4_scatterplot.html +0 -5893
- package/user_study_pilot/tutorial5_histogram.html +0 -1553
- package/user_study_pilot/tutorial6_lineplot.html +0 -1011
- package/user_study_pilot/tutorial7_stacked.html +0 -763
- package/user_study_pilot/tutorial8_stacked_normalized.html +0 -796
- package/user_study_pilot/tutorial9_dodged_bar.html +0 -831
- 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 =
|
|
67
|
-
colorUnselected = '#595959'; //
|
|
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
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
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 (
|
|
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.
|
|
2906
|
-
|
|
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
|
-
|
|
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.
|
|
4754
|
-
|
|
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
|
-
|
|
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
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
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
|
-
|
|
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
|
|
5235
|
-
this.activeElement.style.fill =
|
|
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
|
-
|
|
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
|