maidr 2.27.1 → 2.28.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/dist/maidr.js +273 -98
- package/dist/maidr.min.js +1 -1
- package/dist/maidr_style.css +31 -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,186 @@ class Control {
|
|
|
11914
11908
|
}
|
|
11915
11909
|
}
|
|
11916
11910
|
|
|
11911
|
+
class Goto {
|
|
11912
|
+
//locations = ['Max Value', 'Min Value', 'Mean', 'Median'];
|
|
11913
|
+
locations = ['Max Value', 'Min Value'];
|
|
11914
|
+
|
|
11915
|
+
constructor() {
|
|
11916
|
+
this.popupOpen = false;
|
|
11917
|
+
this.popupIndex = 0;
|
|
11918
|
+
this.attachBootstrapModal();
|
|
11919
|
+
this.attachEventListeners();
|
|
11920
|
+
}
|
|
11921
|
+
|
|
11922
|
+
attachBootstrapModal() {
|
|
11923
|
+
// Create modal container
|
|
11924
|
+
const modalHtml = `
|
|
11925
|
+
<div class="modal fade hidden" id="goto-modal" tabindex="-1" aria-labelledby="navigationModalLabel">
|
|
11926
|
+
<div class="modal-dialog modal-dialog-centered">
|
|
11927
|
+
<div class="modal-content">
|
|
11928
|
+
<div class="modal-header">
|
|
11929
|
+
<h5 class="modal-title" id="navigationModalLabel">Navigate to Location</h5>
|
|
11930
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
11931
|
+
<span aria-hidden="true">×</span>
|
|
11932
|
+
</button>
|
|
11933
|
+
</div>
|
|
11934
|
+
<div class="modal-body">
|
|
11935
|
+
<ul class="list-group" id="goto-list">
|
|
11936
|
+
${this.locations
|
|
11937
|
+
.map(
|
|
11938
|
+
(location, index) => `
|
|
11939
|
+
<li class="list-group-item ${index === 0 ? 'active' : ''}">
|
|
11940
|
+
<button type="button" class="btn btn-link">
|
|
11941
|
+
${location}
|
|
11942
|
+
</button>
|
|
11943
|
+
</li>`
|
|
11944
|
+
)
|
|
11945
|
+
.join('')}
|
|
11946
|
+
</ul>
|
|
11947
|
+
</div>
|
|
11948
|
+
</div>
|
|
11949
|
+
</div>
|
|
11950
|
+
</div>
|
|
11951
|
+
<div id="goto_modal_backdrop" class="modal-backdrop hidden"></div>
|
|
11952
|
+
`;
|
|
11953
|
+
|
|
11954
|
+
document.body.insertAdjacentHTML('beforeend', modalHtml);
|
|
11955
|
+
|
|
11956
|
+
constants.gotoModal = document.getElementById('goto-modal');
|
|
11957
|
+
}
|
|
11958
|
+
|
|
11959
|
+
openPopup() {
|
|
11960
|
+
this.popupOpen = true;
|
|
11961
|
+
this.popupIndex = 0;
|
|
11962
|
+
constants.tabMovement = 0;
|
|
11963
|
+
|
|
11964
|
+
this.whereWasMyFocus = document.activeElement;
|
|
11965
|
+
document.getElementById('goto-modal').classList.remove('hidden');
|
|
11966
|
+
document.getElementById('goto_modal_backdrop').classList.remove('hidden');
|
|
11967
|
+
document.querySelector('#goto-modal .close').focus();
|
|
11968
|
+
this.updateSelection(this.popupIndex);
|
|
11969
|
+
}
|
|
11970
|
+
|
|
11971
|
+
closePopup() {
|
|
11972
|
+
this.popupOpen = false;
|
|
11973
|
+
// close
|
|
11974
|
+
document.getElementById('goto-modal').classList.add('hidden');
|
|
11975
|
+
document.getElementById('goto_modal_backdrop').classList.add('hidden');
|
|
11976
|
+
this.whereWasMyFocus.focus();
|
|
11977
|
+
this.whereWasMyFocus = null;
|
|
11978
|
+
}
|
|
11979
|
+
|
|
11980
|
+
updateSelection(index) {
|
|
11981
|
+
const items = document.querySelectorAll('#goto-list button');
|
|
11982
|
+
Array.from(items).forEach((item, idx) => {
|
|
11983
|
+
item.classList.toggle('active', idx === index);
|
|
11984
|
+
});
|
|
11985
|
+
}
|
|
11986
|
+
|
|
11987
|
+
attachEventListeners() {
|
|
11988
|
+
// Open the modal when the user presses 'g'
|
|
11989
|
+
constants.events.push([
|
|
11990
|
+
[constants.chart, constants.brailleInput],
|
|
11991
|
+
'keydown',
|
|
11992
|
+
function (event) {
|
|
11993
|
+
if (event.key === 'g' && !goto.popupOpen) {
|
|
11994
|
+
goto.openPopup();
|
|
11995
|
+
}
|
|
11996
|
+
},
|
|
11997
|
+
]);
|
|
11998
|
+
// arrow keys to navigate the list, enter to select, escape to close
|
|
11999
|
+
constants.events.push([
|
|
12000
|
+
constants.gotoModal,
|
|
12001
|
+
'keydown',
|
|
12002
|
+
function (event) {
|
|
12003
|
+
if (goto.popupOpen) {
|
|
12004
|
+
if (event.key === 'ArrowDown') {
|
|
12005
|
+
event.preventDefault();
|
|
12006
|
+
goto.popupIndex = (goto.popupIndex + 1) % goto.locations.length;
|
|
12007
|
+
goto.updateSelection(goto.popupIndex);
|
|
12008
|
+
} else if (event.key === 'ArrowUp') {
|
|
12009
|
+
event.preventDefault();
|
|
12010
|
+
goto.popupIndex =
|
|
12011
|
+
(goto.popupIndex - 1 + goto.locations.length) %
|
|
12012
|
+
goto.locations.length;
|
|
12013
|
+
goto.updateSelection(goto.popupIndex);
|
|
12014
|
+
} else if (event.key === 'Enter') {
|
|
12015
|
+
event.preventDefault();
|
|
12016
|
+
const selectedLocation = goto.locations[goto.popupIndex];
|
|
12017
|
+
goto.closePopup();
|
|
12018
|
+
goto.goToLocation(selectedLocation);
|
|
12019
|
+
} else if (event.key === 'Escape') {
|
|
12020
|
+
goto.closePopup();
|
|
12021
|
+
}
|
|
12022
|
+
}
|
|
12023
|
+
},
|
|
12024
|
+
]);
|
|
12025
|
+
}
|
|
12026
|
+
|
|
12027
|
+
goToLocation(loc) {
|
|
12028
|
+
console.log(`Navigating to: ${loc}`);
|
|
12029
|
+
// Replace this with your actual navigation logic
|
|
12030
|
+
|
|
12031
|
+
if (loc == 'Max Value') {
|
|
12032
|
+
if (constants.chartType == 'bar' || constants.chartType == 'hist') {
|
|
12033
|
+
// get the max value of this array and return the index
|
|
12034
|
+
let max = Math.max(...plot.plotData);
|
|
12035
|
+
let index = plot.plotData.indexOf(max);
|
|
12036
|
+
position.x = index;
|
|
12037
|
+
control.UpdateAll();
|
|
12038
|
+
} else if (constants.chartType == 'line') {
|
|
12039
|
+
let max = Math.max(...plot.pointValuesY);
|
|
12040
|
+
let index = plot.pointValuesY.indexOf(max);
|
|
12041
|
+
position.x = index;
|
|
12042
|
+
control.UpdateAll();
|
|
12043
|
+
} else if (constants.chartType == 'point') {
|
|
12044
|
+
let max = Math.max(...plot.curvePoints);
|
|
12045
|
+
let index = plot.curvePoints.indexOf(max);
|
|
12046
|
+
position.x = index;
|
|
12047
|
+
control.UpdateAll();
|
|
12048
|
+
} else if (constants.chartType == 'heat') {
|
|
12049
|
+
// here we have a 2d array to search, and we need both y (parent) and x (child) indexes
|
|
12050
|
+
let max = Math.max(...plot.data.flat());
|
|
12051
|
+
let index = plot.data.flat().indexOf(max);
|
|
12052
|
+
let y = Math.floor(index / plot.data[0].length);
|
|
12053
|
+
let x = index % plot.data[0].length;
|
|
12054
|
+
position.x = x;
|
|
12055
|
+
position.y = y;
|
|
12056
|
+
control.UpdateAll();
|
|
12057
|
+
}
|
|
12058
|
+
} else if (loc == 'Min Value') {
|
|
12059
|
+
if (constants.chartType == 'bar' || constants.chartType == 'hist') {
|
|
12060
|
+
// get the min value of this array and return the index
|
|
12061
|
+
let min = Math.min(...plot.plotData);
|
|
12062
|
+
let index = plot.plotData.indexOf(min);
|
|
12063
|
+
position.x = index;
|
|
12064
|
+
control.UpdateAll();
|
|
12065
|
+
} else if (constants.chartType == 'line') {
|
|
12066
|
+
let min = Math.min(...plot.pointValuesY);
|
|
12067
|
+
let index = plot.pointValuesY.indexOf(min);
|
|
12068
|
+
position.x = index;
|
|
12069
|
+
control.UpdateAll();
|
|
12070
|
+
} else if (constants.chartType == 'point') {
|
|
12071
|
+
let min = Math.min(...plot.curvePoints);
|
|
12072
|
+
let index = plot.curvePoints.indexOf(min);
|
|
12073
|
+
position.x = index;
|
|
12074
|
+
control.UpdateAll();
|
|
12075
|
+
} else if (constants.chartType == 'heat') {
|
|
12076
|
+
// here we have a 2d array to search, and we need both y (parent) and x (child) indexes
|
|
12077
|
+
let min = Math.min(...plot.data.flat());
|
|
12078
|
+
let index = plot.data.flat().indexOf(min);
|
|
12079
|
+
let y = Math.floor(index / plot.data[0].length);
|
|
12080
|
+
let x = index % plot.data[0].length;
|
|
12081
|
+
position.x = x;
|
|
12082
|
+
position.y = y;
|
|
12083
|
+
control.UpdateAll();
|
|
12084
|
+
}
|
|
12085
|
+
} else if (loc == 'Mean') {
|
|
12086
|
+
} else if (loc == 'Median') {
|
|
12087
|
+
}
|
|
12088
|
+
}
|
|
12089
|
+
}
|
|
12090
|
+
|
|
11917
12091
|
// events and init functions
|
|
11918
12092
|
// 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
12093
|
document.addEventListener('DOMContentLoaded', function (e) {
|
|
@@ -11981,6 +12155,7 @@ function InitMaidr(thisMaidr) {
|
|
|
11981
12155
|
window.control = new Control(); // this inits the actual chart object and Position
|
|
11982
12156
|
window.review = new Review();
|
|
11983
12157
|
window.display = new Display();
|
|
12158
|
+
window.goto = new Goto();
|
|
11984
12159
|
window.audio = new Audio();
|
|
11985
12160
|
|
|
11986
12161
|
// blur destruction events
|