maidr 2.17.3 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/maidr.js +88 -84
- package/dist/maidr.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
<img src="
|
|
3
|
+
<img src="assets/logo.svg" width="350px" alt="A stylized MAIDR logo, with curved characters for M A, a hand pointing for an I, the D character, and R represented in braille."/>
|
|
4
4
|
|
|
5
5
|
<hr style="color:transparent" />
|
|
6
6
|
<br />
|
package/dist/maidr.js
CHANGED
|
@@ -129,6 +129,7 @@ class Constants {
|
|
|
129
129
|
* @default 'verbose'
|
|
130
130
|
*/
|
|
131
131
|
textMode = 'verbose';
|
|
132
|
+
|
|
132
133
|
/**
|
|
133
134
|
* The current braille mode. Can be 'off' or 'on'.
|
|
134
135
|
* @type {("off"|"on")}
|
|
@@ -296,7 +297,7 @@ class Constants {
|
|
|
296
297
|
* @default 5000
|
|
297
298
|
* @memberof AudioProperties
|
|
298
299
|
*/
|
|
299
|
-
AUTOPLAY_DURATION =
|
|
300
|
+
AUTOPLAY_DURATION = 2000; // 5s
|
|
300
301
|
|
|
301
302
|
// user settings
|
|
302
303
|
/**
|
|
@@ -438,7 +439,7 @@ class Constants {
|
|
|
438
439
|
'colorSelected',
|
|
439
440
|
'MIN_FREQUENCY',
|
|
440
441
|
'MAX_FREQUENCY',
|
|
441
|
-
'
|
|
442
|
+
'AUTOPLAY_DURATION',
|
|
442
443
|
'ariaMode',
|
|
443
444
|
'openAIAuthKey',
|
|
444
445
|
'geminiAuthKey',
|
|
@@ -605,10 +606,13 @@ class Constants {
|
|
|
605
606
|
* @memberof PlatformControls
|
|
606
607
|
*/
|
|
607
608
|
end = this.isMac ? 'fn + Right arrow' : 'End';
|
|
609
|
+
/**
|
|
610
|
+
* The interval we wait for an L + X prefix event
|
|
611
|
+
*/
|
|
612
|
+
keypressInterval = 2000; // ms or 2s
|
|
608
613
|
|
|
609
614
|
// internal controls
|
|
610
615
|
// todo: are these even used? Sean doesn't think so (May 2024)
|
|
611
|
-
keypressInterval = 2000; // ms or 2s
|
|
612
616
|
tabMovement = null;
|
|
613
617
|
|
|
614
618
|
// debug stuff
|
|
@@ -944,7 +948,11 @@ class Menu {
|
|
|
944
948
|
<td>Auto-play speed down</td>
|
|
945
949
|
<td>Comma (,)</td>
|
|
946
950
|
</tr>
|
|
947
|
-
|
|
951
|
+
<tr>
|
|
952
|
+
<td>Auto-play speed reset</td>
|
|
953
|
+
<td>Slash (/)</td>
|
|
954
|
+
</tr>
|
|
955
|
+
<tr>
|
|
948
956
|
<td>Check label for the title of current plot</td>
|
|
949
957
|
<td>l t</td>
|
|
950
958
|
</tr>
|
|
@@ -987,16 +995,11 @@ class Menu {
|
|
|
987
995
|
<h5 class="modal-title">Settings</h5>
|
|
988
996
|
<p><input type="range" id="vol" name="vol" min="0" max="1" step=".05"><label for="vol">Volume</label></p>
|
|
989
997
|
<!-- <p><input type="checkbox" id="show_rect" name="show_rect"><label for="show_rect">Show Outline</label></p> //-->
|
|
990
|
-
<p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>
|
|
991
|
-
<p><input type="number" min="${
|
|
992
|
-
constants.MIN_SPEED
|
|
993
|
-
}" max="500" step="${
|
|
994
|
-
constants.INTERVAL
|
|
995
|
-
}" id="autoplay_rate" name="autoplay_rate"><label for="autoplay_rate">Autoplay Rate</label></p>
|
|
996
998
|
<p><input type="color" id="color_selected" name="color_selected"><label for="color_selected">Outline Color</label></p>
|
|
999
|
+
<p><input type="number" min="4" max="2000" step="1" id="braille_display_length" name="braille_display_length"><label for="braille_display_length">Braille Display Size</label></p>
|
|
997
1000
|
<p><input type="number" min="10" max="2000" step="10" id="min_freq" name="min_freq"><label for="min_freq">Min Frequency (Hz)</label></p>
|
|
998
1001
|
<p><input type="number" min="20" max="2010" step="10" id="max_freq" name="max_freq"><label for="max_freq">Max Frequency (Hz)</label></p>
|
|
999
|
-
<p><input type="number" min="500" max="
|
|
1002
|
+
<p> <p><input type="number" min="500" max="500000" step="500" id="AUTOPLAY_DURATION">Autoplay Duration (ms)</label></p>
|
|
1000
1003
|
<div><fieldset>
|
|
1001
1004
|
<legend>Aria Mode</legend>
|
|
1002
1005
|
<p><input type="radio" id="aria_mode_assertive" name="aria_mode" value="assertive" ${
|
|
@@ -1262,14 +1265,13 @@ class Menu {
|
|
|
1262
1265
|
*/
|
|
1263
1266
|
PopulateData() {
|
|
1264
1267
|
document.getElementById('vol').value = constants.vol;
|
|
1265
|
-
document.getElementById('autoplay_rate').value = constants.autoPlayRate;
|
|
1266
1268
|
document.getElementById('braille_display_length').value =
|
|
1267
1269
|
constants.brailleDisplayLength;
|
|
1268
1270
|
document.getElementById('color_selected').value = constants.colorSelected;
|
|
1269
1271
|
document.getElementById('min_freq').value = constants.MIN_FREQUENCY;
|
|
1270
1272
|
document.getElementById('max_freq').value = constants.MAX_FREQUENCY;
|
|
1271
|
-
document.getElementById('
|
|
1272
|
-
constants.
|
|
1273
|
+
document.getElementById('AUTOPLAY_DURATION').value =
|
|
1274
|
+
constants.AUTOPLAY_DURATION;
|
|
1273
1275
|
if (typeof constants.openAIAuthKey == 'string') {
|
|
1274
1276
|
document.getElementById('openai_auth_key').value =
|
|
1275
1277
|
constants.openAIAuthKey;
|
|
@@ -1355,15 +1357,14 @@ class Menu {
|
|
|
1355
1357
|
let shouldReset = this.ShouldLLMReset();
|
|
1356
1358
|
|
|
1357
1359
|
constants.vol = document.getElementById('vol').value;
|
|
1358
|
-
constants.autoPlayRate = document.getElementById('autoplay_rate').value;
|
|
1359
1360
|
constants.brailleDisplayLength = document.getElementById(
|
|
1360
1361
|
'braille_display_length'
|
|
1361
1362
|
).value;
|
|
1362
1363
|
constants.colorSelected = document.getElementById('color_selected').value;
|
|
1363
1364
|
constants.MIN_FREQUENCY = document.getElementById('min_freq').value;
|
|
1364
1365
|
constants.MAX_FREQUENCY = document.getElementById('max_freq').value;
|
|
1365
|
-
constants.
|
|
1366
|
-
document.getElementById('
|
|
1366
|
+
constants.AUTOPLAY_DURATION =
|
|
1367
|
+
document.getElementById('AUTOPLAY_DURATION').value;
|
|
1367
1368
|
|
|
1368
1369
|
constants.openAIAuthKey = document.getElementById('openai_auth_key').value;
|
|
1369
1370
|
constants.geminiAuthKey = document.getElementById('gemini_auth_key').value;
|
|
@@ -1517,7 +1518,8 @@ class Menu {
|
|
|
1517
1518
|
if (data) {
|
|
1518
1519
|
for (let i = 0; i < constants.userSettingsKeys.length; i++) {
|
|
1519
1520
|
constants[constants.userSettingsKeys[i]] =
|
|
1520
|
-
data[constants.userSettingsKeys[i]]
|
|
1521
|
+
data[constants.userSettingsKeys[i]] ||
|
|
1522
|
+
constants[constants.userSettingsKeys[i]];
|
|
1521
1523
|
}
|
|
1522
1524
|
}
|
|
1523
1525
|
this.PopulateData();
|
|
@@ -2846,9 +2848,6 @@ class Tracker {
|
|
|
2846
2848
|
if (!this.isUndefinedOrNull(constants.vol)) {
|
|
2847
2849
|
eventToLog.volume = Object.assign(constants.vol);
|
|
2848
2850
|
}
|
|
2849
|
-
if (!this.isUndefinedOrNull(constants.autoPlayRate)) {
|
|
2850
|
-
eventToLog.autoplay_rate = Object.assign(constants.autoPlayRate);
|
|
2851
|
-
}
|
|
2852
2851
|
if (!this.isUndefinedOrNull(constants.colorSelected)) {
|
|
2853
2852
|
eventToLog.color = Object.assign(constants.colorSelected);
|
|
2854
2853
|
}
|
|
@@ -2860,6 +2859,9 @@ class Tracker {
|
|
|
2860
2859
|
if (!this.isUndefinedOrNull(constants.duration)) {
|
|
2861
2860
|
eventToLog.tone_duration = Object.assign(constants.duration);
|
|
2862
2861
|
}
|
|
2862
|
+
if (!this.isUndefinedOrNull(constants.AUTOPLAY_DURATION)) {
|
|
2863
|
+
eventToLog.AUTOPLAY_DURATION = Object.assign(constants.AUTOPLAY_DURATION);
|
|
2864
|
+
}
|
|
2863
2865
|
if (!this.isUndefinedOrNull(constants.autoPlayOutlierRate)) {
|
|
2864
2866
|
eventToLog.autoplay_outlier_rate = Object.assign(
|
|
2865
2867
|
constants.autoPlayOutlierRate
|
|
@@ -3967,10 +3969,6 @@ class Display {
|
|
|
3967
3969
|
let targetLabel = this.boxplotGridPlaceholders[sectionPos];
|
|
3968
3970
|
let haveTargetLabel = false;
|
|
3969
3971
|
let adjustedPos = 0;
|
|
3970
|
-
// bookmark: shiny issue: this is being called twice??
|
|
3971
|
-
// and the issue happens on 2nd call, sometimes it skips like 75% or whatever
|
|
3972
|
-
//
|
|
3973
|
-
// on first call, we might call it multiple as we're setting up, I care but let's check that later
|
|
3974
3972
|
|
|
3975
3973
|
if (constants.brailleData) {
|
|
3976
3974
|
for (let i = 0; i < constants.brailleData.length; i++) {
|
|
@@ -4673,6 +4671,10 @@ class Display {
|
|
|
4673
4671
|
|
|
4674
4672
|
// Step 2: normalize and allocate remaining characters and add to our main braille array
|
|
4675
4673
|
let charsAvailable = constants.brailleDisplayLength - numAllocatedChars;
|
|
4674
|
+
// Bug happened here: if our numAllocatedChars is bigger than brailleDisplayLength, it cuts off chars
|
|
4675
|
+
// temp fix: just let it overflow by setting charsAvailable to positive if it's below 0. Or maybe 5 to still give us some play
|
|
4676
|
+
// todo: real solution should probably be to kill outliers that are too close together
|
|
4677
|
+
if (charsAvailable < 5) charsAvailable = 5;
|
|
4676
4678
|
let allocateCharacters = this.AllocateCharacters(lenData, charsAvailable);
|
|
4677
4679
|
// apply allocation
|
|
4678
4680
|
let brailleData = lenData;
|
|
@@ -5086,9 +5088,8 @@ class BarChart {
|
|
|
5086
5088
|
}
|
|
5087
5089
|
}
|
|
5088
5090
|
constants.maxX = this.columnLabels.length;
|
|
5089
|
-
constants.autoPlayRate = Math.
|
|
5090
|
-
|
|
5091
|
-
constants.MAX_SPEED
|
|
5091
|
+
constants.autoPlayRate = Math.ceil(
|
|
5092
|
+
constants.AUTOPLAY_DURATION / this.plotData.length
|
|
5092
5093
|
);
|
|
5093
5094
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
5094
5095
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -5419,10 +5420,7 @@ class BoxPlot {
|
|
|
5419
5420
|
constants.minY = 0;
|
|
5420
5421
|
constants.maxY = this.plotData.length - 1;
|
|
5421
5422
|
}
|
|
5422
|
-
constants.autoPlayRate = Math.
|
|
5423
|
-
Math.ceil(constants.AUTOPLAY_DURATION / this.plotData.length),
|
|
5424
|
-
constants.MAX_SPEED
|
|
5425
|
-
);
|
|
5423
|
+
constants.autoPlayRate = Math.ceil(constants.AUTOPLAY_DURATION / 7);
|
|
5426
5424
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
5427
5425
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
5428
5426
|
constants.MIN_SPEED = constants.autoPlayRate;
|
|
@@ -6123,9 +6121,8 @@ class HeatMap {
|
|
|
6123
6121
|
constants.maxX = this.data[0].length - 1;
|
|
6124
6122
|
constants.minY = Math.min(...this.data.map((row) => Math.min(...row)));
|
|
6125
6123
|
constants.maxY = Math.max(...this.data.map((row) => Math.max(...row)));
|
|
6126
|
-
constants.autoPlayRate = Math.
|
|
6127
|
-
|
|
6128
|
-
constants.MAX_SPEED
|
|
6124
|
+
constants.autoPlayRate = Math.ceil(
|
|
6125
|
+
constants.AUTOPLAY_DURATION / (constants.maxX + 1)
|
|
6129
6126
|
);
|
|
6130
6127
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
6131
6128
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -6797,9 +6794,8 @@ class ScatterPlot {
|
|
|
6797
6794
|
constants.minY = Math.min(...yValues);
|
|
6798
6795
|
constants.maxY = Math.max(...yValues);
|
|
6799
6796
|
|
|
6800
|
-
constants.autoPlayRate = Math.
|
|
6801
|
-
|
|
6802
|
-
constants.MAX_SPEED
|
|
6797
|
+
constants.autoPlayRate = Math.ceil(
|
|
6798
|
+
constants.AUTOPLAY_DURATION / (constants.maxX + 1)
|
|
6803
6799
|
);
|
|
6804
6800
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
6805
6801
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -7349,9 +7345,8 @@ class Histogram {
|
|
|
7349
7345
|
}
|
|
7350
7346
|
}
|
|
7351
7347
|
}
|
|
7352
|
-
constants.autoPlayRate = Math.
|
|
7353
|
-
|
|
7354
|
-
constants.MAX_SPEED
|
|
7348
|
+
constants.autoPlayRate = Math.ceil(
|
|
7349
|
+
constants.AUTOPLAY_DURATION / this.plotData.length
|
|
7355
7350
|
);
|
|
7356
7351
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
7357
7352
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -7372,13 +7367,13 @@ class Histogram {
|
|
|
7372
7367
|
this.activeElementColor = this.activeElement.getAttribute('fill');
|
|
7373
7368
|
// Get new color to highlight and replace fill value
|
|
7374
7369
|
this.activeElement.setAttribute(
|
|
7375
|
-
|
|
7376
|
-
|
|
7370
|
+
'fill',
|
|
7371
|
+
constants.GetBetterColor(this.activeElementColor)
|
|
7377
7372
|
);
|
|
7378
7373
|
// Case where fill is within the style attribute
|
|
7379
7374
|
} else if (
|
|
7380
|
-
|
|
7381
|
-
|
|
7375
|
+
this.activeElement.hasAttribute('style') &&
|
|
7376
|
+
this.activeElement.getAttribute('style').indexOf('fill') !== -1
|
|
7382
7377
|
) {
|
|
7383
7378
|
let styleString = this.activeElement.getAttribute('style');
|
|
7384
7379
|
// Extract all style attributes and values
|
|
@@ -7386,7 +7381,7 @@ class Histogram {
|
|
|
7386
7381
|
this.activeElementColor = styleArray[styleArray.indexOf('fill') + 1];
|
|
7387
7382
|
// Get new color to highlight and replace fill value in style array
|
|
7388
7383
|
styleArray[styleArray.indexOf('fill') + 1] = constants.GetBetterColor(
|
|
7389
|
-
|
|
7384
|
+
this.activeElementColor
|
|
7390
7385
|
);
|
|
7391
7386
|
// Recreate style string and set style attribute
|
|
7392
7387
|
styleString = constants.GetStyleStringFromArray(styleArray);
|
|
@@ -7411,8 +7406,8 @@ class Histogram {
|
|
|
7411
7406
|
this.activeElement.setAttribute('fill', this.activeElementColor);
|
|
7412
7407
|
this.activeElement = null;
|
|
7413
7408
|
} else if (
|
|
7414
|
-
|
|
7415
|
-
|
|
7409
|
+
this.activeElement.hasAttribute('style') &&
|
|
7410
|
+
this.activeElement.getAttribute('style').indexOf('fill') !== -1
|
|
7416
7411
|
) {
|
|
7417
7412
|
let styleString = this.activeElement.getAttribute('style');
|
|
7418
7413
|
let styleArray = constants.GetStyleArrayFromString(styleString);
|
|
@@ -7487,9 +7482,8 @@ class LinePlot {
|
|
|
7487
7482
|
singleMaidr.data[0].y
|
|
7488
7483
|
);
|
|
7489
7484
|
|
|
7490
|
-
constants.autoPlayRate = Math.
|
|
7491
|
-
|
|
7492
|
-
constants.MAX_SPEED
|
|
7485
|
+
constants.autoPlayRate = Math.ceil(
|
|
7486
|
+
constants.AUTOPLAY_DURATION / (constants.maxX + 1)
|
|
7493
7487
|
);
|
|
7494
7488
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
7495
7489
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -7991,9 +7985,8 @@ class Segmented {
|
|
|
7991
7985
|
}
|
|
7992
7986
|
}
|
|
7993
7987
|
constants.maxX = this.level.length;
|
|
7994
|
-
constants.autoPlayRate = Math.
|
|
7995
|
-
|
|
7996
|
-
constants.MAX_SPEED
|
|
7988
|
+
constants.autoPlayRate = Math.ceil(
|
|
7989
|
+
constants.AUTOPLAY_DURATION / this.plotData.length
|
|
7997
7990
|
);
|
|
7998
7991
|
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
7999
7992
|
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
@@ -11201,41 +11194,52 @@ function InitMaidr(thisMaidr) {
|
|
|
11201
11194
|
// actually do eventlisteners for all events
|
|
11202
11195
|
this.SetEvents();
|
|
11203
11196
|
|
|
11197
|
+
// Set img role for chart
|
|
11198
|
+
constants.chart.setAttribute('role', 'img');
|
|
11199
|
+
|
|
11204
11200
|
// once everything is set up, announce the chart name (or title as a backup) to the user
|
|
11205
|
-
setTimeout(function () {
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
)
|
|
11212
|
-
|
|
11213
|
-
|
|
11201
|
+
// setTimeout(function () {
|
|
11202
|
+
if ('name' in singleMaidr) {
|
|
11203
|
+
// Add the aria-label and title attributes to the chart
|
|
11204
|
+
constants.chart.setAttribute('aria-label', announceText);
|
|
11205
|
+
constants.chart.setAttribute('title', announceText);
|
|
11206
|
+
|
|
11207
|
+
// display.announceText(singleMaidr.name);
|
|
11208
|
+
} else if (
|
|
11209
|
+
'title' in singleMaidr ||
|
|
11210
|
+
('labels' in singleMaidr && 'title' in singleMaidr.labels)
|
|
11211
|
+
) {
|
|
11212
|
+
let title =
|
|
11213
|
+
'title' in singleMaidr ? singleMaidr.title : singleMaidr.labels.title;
|
|
11214
11214
|
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11215
|
+
// Determine whether type is multiple or single. If multiple, put commas and "and" in between. If single, just put the type.
|
|
11216
|
+
let plotTypeString = Array.isArray(singleMaidr.type)
|
|
11217
|
+
? singleMaidr.type.slice(0, -1).join(', ') +
|
|
11218
|
+
' and ' +
|
|
11219
|
+
singleMaidr.type.slice(-1)
|
|
11220
|
+
: singleMaidr.type;
|
|
11221
11221
|
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11222
|
+
// Prepare the instruction text for multi-layered plot
|
|
11223
|
+
let multiLayerInstruction =
|
|
11224
|
+
'This is a multi-layered plot. Use PageUp and PageDown to switch between layers.';
|
|
11225
11225
|
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11226
|
+
// Check if plotTypeString has multiple types
|
|
11227
|
+
let isMultiLayered =
|
|
11228
|
+
Array.isArray(singleMaidr.type) && singleMaidr.type.length > 1;
|
|
11229
11229
|
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11230
|
+
// Construct the final announceText string
|
|
11231
|
+
let announceText = `${plotTypeString} plot of ${title}: Use Arrows to navigate data points. ${
|
|
11232
|
+
isMultiLayered ? multiLayerInstruction : ' '
|
|
11233
|
+
}Toggle B for Braille, T for Text, S for Sonification, and R for Review mode. Use H for Help.`;
|
|
11234
11234
|
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11235
|
+
// Add the aria-label and title attributes to the chart
|
|
11236
|
+
constants.chart.setAttribute('aria-label', announceText);
|
|
11237
|
+
constants.chart.setAttribute('title', announceText);
|
|
11238
|
+
|
|
11239
|
+
// Display the announcement text
|
|
11240
|
+
// display.announceText(announceText);
|
|
11241
|
+
}
|
|
11242
|
+
// }, 100);
|
|
11239
11243
|
}
|
|
11240
11244
|
}
|
|
11241
11245
|
|
|
@@ -11514,7 +11518,7 @@ function CreateChartComponents() {
|
|
|
11514
11518
|
constants.review_id_container +
|
|
11515
11519
|
'" class="hidden sr-only sr-only-focusable"><input id="' +
|
|
11516
11520
|
constants.review_id +
|
|
11517
|
-
'" type="text" size="50" /></div>'
|
|
11521
|
+
'" type="text" size="50" autocomplete="off" /></div>'
|
|
11518
11522
|
);
|
|
11519
11523
|
|
|
11520
11524
|
// some tweaks
|