maidr 2.27.1 → 2.28.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/maidr.js +286 -98
- package/dist/maidr.min.js +1 -1
- package/dist/maidr_style.css +84 -0
- package/dist/maidr_style.min.css +1 -1
- package/package.json +1 -1
package/dist/maidr.js
CHANGED
|
@@ -7722,12 +7722,8 @@ class Layer0Point {
|
|
|
7722
7722
|
* @async
|
|
7723
7723
|
*/
|
|
7724
7724
|
async ClearPoints() {
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
let points = document.getElementsByClassName('highlight_point');
|
|
7728
|
-
for (let i = 0; i < points.length; i++) {
|
|
7729
|
-
document.getElementsByClassName('highlight_point')[i].remove();
|
|
7730
|
-
}
|
|
7725
|
+
// kill all .highlight_point
|
|
7726
|
+
document.querySelectorAll('.highlight_point').forEach((e) => e.remove());
|
|
7731
7727
|
}
|
|
7732
7728
|
|
|
7733
7729
|
/**
|
|
@@ -7803,12 +7799,8 @@ class Layer1Point {
|
|
|
7803
7799
|
* @async
|
|
7804
7800
|
*/
|
|
7805
7801
|
async ClearPoints() {
|
|
7806
|
-
|
|
7807
|
-
|
|
7808
|
-
document.getElementsByClassName('highlight_point')[i].remove();
|
|
7809
|
-
}
|
|
7810
|
-
if (document.getElementById('highlight_point'))
|
|
7811
|
-
document.getElementById('highlight_point').remove();
|
|
7802
|
+
// kill all .highlight_point
|
|
7803
|
+
document.querySelectorAll('.highlight_point').forEach((e) => e.remove());
|
|
7812
7804
|
}
|
|
7813
7805
|
|
|
7814
7806
|
/**
|
|
@@ -8817,95 +8809,97 @@ class Control {
|
|
|
8817
8809
|
SetPrefixControls() {
|
|
8818
8810
|
// prefix events, l + x, where x is a key for the title, axis, etc
|
|
8819
8811
|
// we listen for a moment when l is hit for a key to follow
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
|
|
8833
|
-
|
|
8834
|
-
pressedTimeout = setTimeout(function () {
|
|
8835
|
-
control.pressedL = false;
|
|
8836
|
-
}, constants.keypressInterval);
|
|
8837
|
-
}
|
|
8838
|
-
|
|
8839
|
-
// Prefix mode stuff: L is enabled, look for these keys
|
|
8840
|
-
if (control.pressedL) {
|
|
8841
|
-
if (e.key == 'x') {
|
|
8842
|
-
// X: x label
|
|
8843
|
-
let xlabel = '';
|
|
8844
|
-
if (singleMaidr.type == 'bar' || singleMaidr.type == 'line') {
|
|
8845
|
-
xlabel = plot.plotLegend.x;
|
|
8846
|
-
} else if (singleMaidr.type == 'hist') {
|
|
8847
|
-
xlabel = plot.legendX;
|
|
8848
|
-
} else if (
|
|
8849
|
-
singleMaidr.type == 'heat' ||
|
|
8850
|
-
singleMaidr.type == 'box' ||
|
|
8851
|
-
singleMaidr.type == 'point' ||
|
|
8852
|
-
singleMaidr.type.includes('point')
|
|
8853
|
-
) {
|
|
8854
|
-
xlabel = plot.x_group_label;
|
|
8855
|
-
} else if (
|
|
8856
|
-
singleMaidr.type == 'stacked_bar' ||
|
|
8857
|
-
singleMaidr.type == 'stacked_normalized_bar' ||
|
|
8858
|
-
singleMaidr.type == 'dodged_bar'
|
|
8859
|
-
) {
|
|
8860
|
-
xlabel = plot.plotLegend.x;
|
|
8812
|
+
for (let i = 0; i < this.allControlElements.length; i++) {
|
|
8813
|
+
constants.events.push([
|
|
8814
|
+
this.allControlElements[i],
|
|
8815
|
+
'keydown',
|
|
8816
|
+
function (e) {
|
|
8817
|
+
// init
|
|
8818
|
+
let pressedTimeout = null;
|
|
8819
|
+
|
|
8820
|
+
// enable / disable prefix mode
|
|
8821
|
+
if (e.key == 'l') {
|
|
8822
|
+
control.pressedL = true;
|
|
8823
|
+
if (pressedTimeout != null) {
|
|
8824
|
+
clearTimeout(pressedTimeout);
|
|
8825
|
+
pressedTimeout = null;
|
|
8861
8826
|
}
|
|
8862
|
-
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
|
|
8867
|
-
|
|
8868
|
-
|
|
8869
|
-
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
singleMaidr.type == '
|
|
8873
|
-
|
|
8874
|
-
singleMaidr.type == '
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8827
|
+
pressedTimeout = setTimeout(function () {
|
|
8828
|
+
control.pressedL = false;
|
|
8829
|
+
}, constants.keypressInterval);
|
|
8830
|
+
}
|
|
8831
|
+
|
|
8832
|
+
// Prefix mode stuff: L is enabled, look for these keys
|
|
8833
|
+
if (control.pressedL) {
|
|
8834
|
+
if (e.key == 'x') {
|
|
8835
|
+
// X: x label
|
|
8836
|
+
let xlabel = '';
|
|
8837
|
+
if (singleMaidr.type == 'bar' || singleMaidr.type == 'line') {
|
|
8838
|
+
xlabel = plot.plotLegend.x;
|
|
8839
|
+
} else if (singleMaidr.type == 'hist') {
|
|
8840
|
+
xlabel = plot.legendX;
|
|
8841
|
+
} else if (
|
|
8842
|
+
singleMaidr.type == 'heat' ||
|
|
8843
|
+
singleMaidr.type == 'box' ||
|
|
8844
|
+
singleMaidr.type == 'point' ||
|
|
8845
|
+
singleMaidr.type.includes('point')
|
|
8846
|
+
) {
|
|
8847
|
+
xlabel = plot.x_group_label;
|
|
8848
|
+
} else if (
|
|
8849
|
+
singleMaidr.type == 'stacked_bar' ||
|
|
8850
|
+
singleMaidr.type == 'stacked_normalized_bar' ||
|
|
8851
|
+
singleMaidr.type == 'dodged_bar'
|
|
8852
|
+
) {
|
|
8853
|
+
xlabel = plot.plotLegend.x;
|
|
8854
|
+
}
|
|
8855
|
+
display.displayInfo('x label', xlabel);
|
|
8856
|
+
control.pressedL = false;
|
|
8857
|
+
} else if (e.key == 'y') {
|
|
8858
|
+
// Y: y label
|
|
8859
|
+
let ylabel = '';
|
|
8860
|
+
if (singleMaidr.type == 'bar' || singleMaidr.type == 'line') {
|
|
8861
|
+
ylabel = plot.plotLegend.y;
|
|
8862
|
+
} else if (singleMaidr.type == 'hist') {
|
|
8863
|
+
ylabel = plot.legendY;
|
|
8864
|
+
} else if (
|
|
8865
|
+
singleMaidr.type == 'heat' ||
|
|
8866
|
+
singleMaidr.type == 'box' ||
|
|
8867
|
+
singleMaidr.type == 'point' ||
|
|
8868
|
+
singleMaidr.type == 'line' ||
|
|
8869
|
+
singleMaidr.type.includes('point')
|
|
8870
|
+
) {
|
|
8871
|
+
ylabel = plot.y_group_label;
|
|
8872
|
+
} else if (
|
|
8873
|
+
singleMaidr.type == 'stacked_bar' ||
|
|
8874
|
+
singleMaidr.type == 'stacked_normalized_bar' ||
|
|
8875
|
+
singleMaidr.type == 'dodged_bar'
|
|
8876
|
+
) {
|
|
8877
|
+
ylabel = plot.plotLegend.y;
|
|
8878
|
+
}
|
|
8879
|
+
display.displayInfo('y label', ylabel);
|
|
8880
|
+
control.pressedL = false;
|
|
8881
|
+
} else if (e.key == 't') {
|
|
8882
|
+
// T: title
|
|
8883
|
+
display.displayInfo('title', plot.title);
|
|
8884
|
+
control.pressedL = false;
|
|
8885
|
+
} else if (e.key == 's') {
|
|
8886
|
+
// subtitle
|
|
8887
|
+
display.displayInfo('subtitle', plot.subtitle);
|
|
8888
|
+
control.pressedL = false;
|
|
8889
|
+
} else if (e.key == 'c') {
|
|
8890
|
+
// caption
|
|
8891
|
+
display.displayInfo('caption', plot.caption);
|
|
8892
|
+
control.pressedL = false;
|
|
8893
|
+
} else if (e.key == 'f') {
|
|
8894
|
+
display.displayInfo('fill', plot.fill);
|
|
8895
|
+
control.pressedL = false;
|
|
8896
|
+
} else if (e.key != 'l') {
|
|
8897
|
+
control.pressedL = false;
|
|
8885
8898
|
}
|
|
8886
|
-
display.displayInfo('y label', ylabel);
|
|
8887
|
-
control.pressedL = false;
|
|
8888
|
-
} else if (e.key == 't') {
|
|
8889
|
-
// T: title
|
|
8890
|
-
display.displayInfo('title', plot.title);
|
|
8891
|
-
control.pressedL = false;
|
|
8892
|
-
} else if (e.key == 's') {
|
|
8893
|
-
// subtitle
|
|
8894
|
-
display.displayInfo('subtitle', plot.subtitle);
|
|
8895
|
-
control.pressedL = false;
|
|
8896
|
-
} else if (e.key == 'c') {
|
|
8897
|
-
// caption
|
|
8898
|
-
display.displayInfo('caption', plot.caption);
|
|
8899
|
-
control.pressedL = false;
|
|
8900
|
-
} else if (e.key == 'f') {
|
|
8901
|
-
display.displayInfo('fill', plot.fill);
|
|
8902
|
-
control.pressedL = false;
|
|
8903
|
-
} else if (e.key != 'l') {
|
|
8904
|
-
control.pressedL = false;
|
|
8905
8899
|
}
|
|
8906
|
-
}
|
|
8907
|
-
|
|
8908
|
-
|
|
8900
|
+
},
|
|
8901
|
+
]);
|
|
8902
|
+
}
|
|
8909
8903
|
}
|
|
8910
8904
|
|
|
8911
8905
|
/**
|
|
@@ -11914,6 +11908,199 @@ class Control {
|
|
|
11914
11908
|
}
|
|
11915
11909
|
}
|
|
11916
11910
|
|
|
11911
|
+
class Goto {
|
|
11912
|
+
//locations = ['Max Value', 'Min Value', 'Mean', 'Median'];
|
|
11913
|
+
static options = ['Max Value', 'Min Value'];
|
|
11914
|
+
|
|
11915
|
+
constructor() {
|
|
11916
|
+
this.menuOpen = false;
|
|
11917
|
+
this.initMenu();
|
|
11918
|
+
this.attachEventListeners();
|
|
11919
|
+
}
|
|
11920
|
+
|
|
11921
|
+
initMenu() {
|
|
11922
|
+
this.menu = document.createElement('div');
|
|
11923
|
+
this.menu.id = 'goto-menu';
|
|
11924
|
+
this.menu.style.display = 'none';
|
|
11925
|
+
this.menu.innerHTML = `
|
|
11926
|
+
<div class="menu-container">
|
|
11927
|
+
<input
|
|
11928
|
+
type="text"
|
|
11929
|
+
id="menu-search"
|
|
11930
|
+
placeholder="Search locations..."
|
|
11931
|
+
aria-label="Search locations to go to"
|
|
11932
|
+
/>
|
|
11933
|
+
<ul id="menu-items">
|
|
11934
|
+
${Goto.options
|
|
11935
|
+
.map((option) => `<li><button>${option}</button></li>`)
|
|
11936
|
+
.join('')}
|
|
11937
|
+
</ul>
|
|
11938
|
+
</div>
|
|
11939
|
+
`;
|
|
11940
|
+
|
|
11941
|
+
this.menuSearch = this.menu.querySelector('#menu-search');
|
|
11942
|
+
this.menuItems = Array.from(
|
|
11943
|
+
this.menu.querySelectorAll('#menu-items button')
|
|
11944
|
+
);
|
|
11945
|
+
|
|
11946
|
+
constants.gotoMenu = this.menu;
|
|
11947
|
+
document.body.appendChild(this.menu);
|
|
11948
|
+
}
|
|
11949
|
+
|
|
11950
|
+
openMenu() {
|
|
11951
|
+
this.whereWasMyFocus = document.activeElement;
|
|
11952
|
+
constants.tabMovement = 0; // to prevent maidr from being destroyed as we leave the chart
|
|
11953
|
+
|
|
11954
|
+
this.menuOpen = true;
|
|
11955
|
+
this.menu.style.display = 'block';
|
|
11956
|
+
this.menuSearch.focus();
|
|
11957
|
+
}
|
|
11958
|
+
|
|
11959
|
+
closeMenu() {
|
|
11960
|
+
this.menuOpen = false;
|
|
11961
|
+
this.menu.style.display = 'none';
|
|
11962
|
+
this.whereWasMyFocus.focus();
|
|
11963
|
+
this.whereWasMyFocus = null;
|
|
11964
|
+
}
|
|
11965
|
+
|
|
11966
|
+
filterItems(query) {
|
|
11967
|
+
const lowerCaseQuery = query.toLowerCase();
|
|
11968
|
+
this.menuItems.forEach((item) => {
|
|
11969
|
+
if (item.textContent.toLowerCase().includes(lowerCaseQuery)) {
|
|
11970
|
+
item.parentElement.style.display = 'block';
|
|
11971
|
+
} else {
|
|
11972
|
+
item.parentElement.style.display = 'none';
|
|
11973
|
+
}
|
|
11974
|
+
});
|
|
11975
|
+
}
|
|
11976
|
+
|
|
11977
|
+
attachEventListeners() {
|
|
11978
|
+
this.menuSearch.addEventListener('input', (event) =>
|
|
11979
|
+
this.filterItems(event.target.value)
|
|
11980
|
+
);
|
|
11981
|
+
|
|
11982
|
+
// Open the modal when the user presses 'g'
|
|
11983
|
+
constants.events.push([
|
|
11984
|
+
[constants.chart, constants.brailleInput],
|
|
11985
|
+
'keyup',
|
|
11986
|
+
function (event) {
|
|
11987
|
+
if (event.key === 'g' && !goto.popupOpen) {
|
|
11988
|
+
goto.openMenu();
|
|
11989
|
+
}
|
|
11990
|
+
},
|
|
11991
|
+
]);
|
|
11992
|
+
// arrow keys to navigate the list, escape to close
|
|
11993
|
+
constants.events.push([
|
|
11994
|
+
constants.gotoMenu,
|
|
11995
|
+
'keydown',
|
|
11996
|
+
function (event) {
|
|
11997
|
+
if (goto.menuOpen) {
|
|
11998
|
+
const focusableElements = [
|
|
11999
|
+
goto.menuSearch,
|
|
12000
|
+
...goto.menuItems.filter(
|
|
12001
|
+
(item) => item.parentElement.style.display !== 'none'
|
|
12002
|
+
),
|
|
12003
|
+
];
|
|
12004
|
+
const currentIndex = focusableElements.indexOf(
|
|
12005
|
+
document.activeElement
|
|
12006
|
+
);
|
|
12007
|
+
|
|
12008
|
+
if (event.key === 'ArrowDown') {
|
|
12009
|
+
event.preventDefault();
|
|
12010
|
+
const nextIndex = (currentIndex + 1) % focusableElements.length;
|
|
12011
|
+
focusableElements[nextIndex]?.focus();
|
|
12012
|
+
} else if (event.key === 'ArrowUp') {
|
|
12013
|
+
event.preventDefault();
|
|
12014
|
+
const prevIndex =
|
|
12015
|
+
(currentIndex - 1 + focusableElements.length) %
|
|
12016
|
+
focusableElements.length;
|
|
12017
|
+
focusableElements[prevIndex]?.focus();
|
|
12018
|
+
} else {
|
|
12019
|
+
if (event.key === 'Escape') {
|
|
12020
|
+
goto.closeMenu();
|
|
12021
|
+
}
|
|
12022
|
+
}
|
|
12023
|
+
}
|
|
12024
|
+
},
|
|
12025
|
+
]);
|
|
12026
|
+
// enter to select, which we register as a click event so it works with screen readers
|
|
12027
|
+
constants.events.push([
|
|
12028
|
+
constants.gotoMenu,
|
|
12029
|
+
'click',
|
|
12030
|
+
function (event) {
|
|
12031
|
+
if (event.target.tagName === 'BUTTON') {
|
|
12032
|
+
let loc = event.target.textContent;
|
|
12033
|
+
goto.closeMenu();
|
|
12034
|
+
goto.goToLocation(loc);
|
|
12035
|
+
}
|
|
12036
|
+
},
|
|
12037
|
+
]);
|
|
12038
|
+
}
|
|
12039
|
+
|
|
12040
|
+
goToLocation(loc) {
|
|
12041
|
+
console.log(`Navigating to: ${loc}`);
|
|
12042
|
+
// Replace this with your actual navigation logic
|
|
12043
|
+
|
|
12044
|
+
if (loc == 'Max Value') {
|
|
12045
|
+
if (constants.chartType == 'bar' || constants.chartType == 'hist') {
|
|
12046
|
+
// get the max value of this array and return the index
|
|
12047
|
+
let max = Math.max(...plot.plotData);
|
|
12048
|
+
let index = plot.plotData.indexOf(max);
|
|
12049
|
+
position.x = index;
|
|
12050
|
+
control.UpdateAll();
|
|
12051
|
+
} else if (constants.chartType == 'line') {
|
|
12052
|
+
let max = Math.max(...plot.pointValuesY);
|
|
12053
|
+
let index = plot.pointValuesY.indexOf(max);
|
|
12054
|
+
position.x = index;
|
|
12055
|
+
control.UpdateAll();
|
|
12056
|
+
} else if (constants.chartType == 'point') {
|
|
12057
|
+
let max = Math.max(...plot.curvePoints);
|
|
12058
|
+
let index = plot.curvePoints.indexOf(max);
|
|
12059
|
+
position.x = index;
|
|
12060
|
+
control.UpdateAll();
|
|
12061
|
+
} else if (constants.chartType == 'heat') {
|
|
12062
|
+
// here we have a 2d array to search, and we need both y (parent) and x (child) indexes
|
|
12063
|
+
let max = Math.max(...plot.data.flat());
|
|
12064
|
+
let index = plot.data.flat().indexOf(max);
|
|
12065
|
+
let y = Math.floor(index / plot.data[0].length);
|
|
12066
|
+
let x = index % plot.data[0].length;
|
|
12067
|
+
position.x = x;
|
|
12068
|
+
position.y = y;
|
|
12069
|
+
control.UpdateAll();
|
|
12070
|
+
}
|
|
12071
|
+
} else if (loc == 'Min Value') {
|
|
12072
|
+
if (constants.chartType == 'bar' || constants.chartType == 'hist') {
|
|
12073
|
+
// get the min value of this array and return the index
|
|
12074
|
+
let min = Math.min(...plot.plotData);
|
|
12075
|
+
let index = plot.plotData.indexOf(min);
|
|
12076
|
+
position.x = index;
|
|
12077
|
+
control.UpdateAll();
|
|
12078
|
+
} else if (constants.chartType == 'line') {
|
|
12079
|
+
let min = Math.min(...plot.pointValuesY);
|
|
12080
|
+
let index = plot.pointValuesY.indexOf(min);
|
|
12081
|
+
position.x = index;
|
|
12082
|
+
control.UpdateAll();
|
|
12083
|
+
} else if (constants.chartType == 'point') {
|
|
12084
|
+
let min = Math.min(...plot.curvePoints);
|
|
12085
|
+
let index = plot.curvePoints.indexOf(min);
|
|
12086
|
+
position.x = index;
|
|
12087
|
+
control.UpdateAll();
|
|
12088
|
+
} else if (constants.chartType == 'heat') {
|
|
12089
|
+
// here we have a 2d array to search, and we need both y (parent) and x (child) indexes
|
|
12090
|
+
let min = Math.min(...plot.data.flat());
|
|
12091
|
+
let index = plot.data.flat().indexOf(min);
|
|
12092
|
+
let y = Math.floor(index / plot.data[0].length);
|
|
12093
|
+
let x = index % plot.data[0].length;
|
|
12094
|
+
position.x = x;
|
|
12095
|
+
position.y = y;
|
|
12096
|
+
control.UpdateAll();
|
|
12097
|
+
}
|
|
12098
|
+
} else if (loc == 'Mean') {
|
|
12099
|
+
} else if (loc == 'Median') {
|
|
12100
|
+
}
|
|
12101
|
+
}
|
|
12102
|
+
}
|
|
12103
|
+
|
|
11917
12104
|
// events and init functions
|
|
11918
12105
|
// we do some setup, but most of the work is done when user focuses on an element matching an id from maidr user data
|
|
11919
12106
|
document.addEventListener('DOMContentLoaded', function (e) {
|
|
@@ -11981,6 +12168,7 @@ function InitMaidr(thisMaidr) {
|
|
|
11981
12168
|
window.control = new Control(); // this inits the actual chart object and Position
|
|
11982
12169
|
window.review = new Review();
|
|
11983
12170
|
window.display = new Display();
|
|
12171
|
+
window.goto = new Goto();
|
|
11984
12172
|
window.audio = new Audio();
|
|
11985
12173
|
|
|
11986
12174
|
// blur destruction events
|