maidr 2.4.0 → 2.5.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/README.md +59 -8
- package/dist/maidr.js +102 -55
- package/dist/maidr.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,11 +13,15 @@ maidr (pronounced as 'mader') is a system for non-visual access and control of s
|
|
|
13
13
|
## Table of Contents
|
|
14
14
|
|
|
15
15
|
1. [Usage](#usage)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
1. [Controls](#controls)
|
|
17
|
+
1. [Braille Generation](#braille-generation)
|
|
18
|
+
1. [API](#api)
|
|
19
|
+
1. [Binders](#binders)
|
|
20
|
+
1. [Papers](#papers)
|
|
21
|
+
1. [License](#license)
|
|
22
|
+
1. [Contact](#contact)
|
|
23
|
+
1. [Acknowledgments](#acknowledgments)
|
|
24
|
+
|
|
21
25
|
|
|
22
26
|
## Usage
|
|
23
27
|
|
|
@@ -47,7 +51,7 @@ To use maidr, follow these steps:
|
|
|
47
51
|
</html>
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
3. Add your data: Include your data as a json schema directly in the HTML file. There should be a single `maidr` object with the following properties, or an array of objects if multiple
|
|
54
|
+
3. Add your data: Include your data as a json schema directly in the HTML file. There should be a single `maidr` object with the following properties, or an array of objects if multiple plots exist on the page. Your json schema may look like so: (values for demonstration purposes)
|
|
51
55
|
|
|
52
56
|
```javascript
|
|
53
57
|
// a single plot
|
|
@@ -74,7 +78,7 @@ To use maidr, follow these steps:
|
|
|
74
78
|
data: ...
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
// or, multiple
|
|
81
|
+
// or, multiple plots
|
|
78
82
|
let maidr = [
|
|
79
83
|
{
|
|
80
84
|
type: 'box',
|
|
@@ -220,7 +224,7 @@ For more information and examples, refer to the example HTML files provided in t
|
|
|
220
224
|
|
|
221
225
|
## Controls
|
|
222
226
|
|
|
223
|
-
To interact with the
|
|
227
|
+
To interact with the plots using maidr, follow these steps:
|
|
224
228
|
|
|
225
229
|
1. Press the **Tab** key to focus on the SVG element.
|
|
226
230
|
2. Use the **arrow keys** to move around the plot.
|
|
@@ -355,6 +359,53 @@ In the braille representation of segmented bar plots, braille depends on where y
|
|
|
355
359
|
|
|
356
360
|
In the Braille representation of a lineplot, braille is nearly identical to the above barplot: data values are encoded as Braille characters based on their relative magnitude within the plot. Low values are denoted by Braille characters that have dots only along the bottom, while high values are indicated by characters that have dots higher up.
|
|
357
361
|
|
|
362
|
+
## API
|
|
363
|
+
|
|
364
|
+
maidr is available via a restful API. Learn more about the usage at [maidr-api](https://github.com/xability/maidr-api) repo.
|
|
365
|
+
|
|
366
|
+
## Binders
|
|
367
|
+
|
|
368
|
+
We currently provide the following binders, all of which can be found at each separate repo:
|
|
369
|
+
|
|
370
|
+
- [x] Python binder for matplotlib and seaborn: [py_maidr](https://github.com/xability/py_maidr).
|
|
371
|
+
|
|
372
|
+
- [ ] R binder for ggplot2: [r_maidr](https://github.com/xability/r_maidr).
|
|
373
|
+
|
|
374
|
+
## Papers
|
|
375
|
+
|
|
376
|
+
To learn more about the theoretical background and user study results, we recommend you read and cite the following papers.
|
|
377
|
+
|
|
378
|
+
1. [MAIDR: Making Statistical Visualizations Accessible with Multimodal Data Representation](https://arxiv.org/abs/2403.00717):
|
|
379
|
+
|
|
380
|
+
```tex
|
|
381
|
+
@inproceedings{seoMAIDR2024,
|
|
382
|
+
title = {{{MAIDR}}: Making Statistical Visualizations Accessible with Multimodal Data Representation},
|
|
383
|
+
booktitle = {Proceedings of the {{SIGCHI Conference}} on {{Human Factors}} in {{Computing Systems}}},
|
|
384
|
+
author = {Seo, JooYoung and Xia, Yilin and Lee, Bongshin and McCurry, Sean and Yam, Yu Jun},
|
|
385
|
+
year = {2024},
|
|
386
|
+
doi = {10.1145/3613904.3642730}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
1. [Born Accessible Data Science and Visualization Courses: Challenges of Developing Curriculum to be Taught by Blind Instructors to Blind Students](https://arxiv.org/abs/2403.02568v1):
|
|
391
|
+
|
|
392
|
+
```tex
|
|
393
|
+
@misc{seoBornAccessibleData2024,
|
|
394
|
+
title = {Born {{Accessible Data Science}} and {{Visualization Courses}}: {{Challenges}} of {{Developing Curriculum}} to Be {{Taught}} by {{Blind Instructors}} to {{Blind Students}}},
|
|
395
|
+
shorttitle = {Born {{Accessible Data Science}} and {{Visualization Courses}}},
|
|
396
|
+
author = {Seo, JooYoung and O'Modhrain, Sile and Xia, Yilin and Kamath, Sanchita and Lee, Bongshin and Coughlan, James M.},
|
|
397
|
+
year = {2024},
|
|
398
|
+
month = mar,
|
|
399
|
+
number = {arXiv:2403.02568},
|
|
400
|
+
eprint = {2403.02568},
|
|
401
|
+
primaryclass = {cs},
|
|
402
|
+
publisher = {{arXiv}},
|
|
403
|
+
urldate = {2024-03-08},
|
|
404
|
+
archiveprefix = {arxiv},
|
|
405
|
+
keywords = {Computer Science - Human-Computer Interaction}
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
358
409
|
## License
|
|
359
410
|
|
|
360
411
|
This project is licensed under the GPL 3 License.
|
package/dist/maidr.js
CHANGED
|
@@ -86,6 +86,7 @@ class Constants {
|
|
|
86
86
|
'You are a helpful assistant describing the chart to a blind person. ';
|
|
87
87
|
skillLevel = 'basic'; // basic / intermediate / expert
|
|
88
88
|
skillLevelOther = ''; // custom skill level
|
|
89
|
+
autoInitLLM = true; // auto initialize LLM on page load
|
|
89
90
|
|
|
90
91
|
// user controls (not exposed to menu, with shortcuts usually)
|
|
91
92
|
showDisplay = 1; // true / false
|
|
@@ -429,6 +430,9 @@ class Menu {
|
|
|
429
430
|
<span id="gemini_multi_container" class="hidden"><input type="checkbox" id="gemini_multi" name="gemini_multi" aria-label="Use Gemini in Multi modal mode"></span>
|
|
430
431
|
<input type="password" id="gemini_auth_key"><button aria-label="Delete Gemini key" title="Delete Gemini key" id="delete_gemini_key" class="invis_button">×</button><label for="gemini_auth_key">Gemini Authentication Key</label>
|
|
431
432
|
</p>
|
|
433
|
+
<p><input type="checkbox" ${
|
|
434
|
+
constants.autoInitLLM ? 'checked' : ''
|
|
435
|
+
} id="init_llm_on_load" name="init_llm_on_load"><label for="init_llm_on_load">Start first LLM chat chart load</label></p>
|
|
432
436
|
<p>
|
|
433
437
|
<select id="skill_level">
|
|
434
438
|
<option value="basic">Basic</option>
|
|
@@ -740,7 +744,7 @@ class Menu {
|
|
|
740
744
|
* Saves the data from the HTML elements into the constants object.
|
|
741
745
|
*/
|
|
742
746
|
SaveData() {
|
|
743
|
-
this.
|
|
747
|
+
let shouldReset = this.ShouldLLMReset();
|
|
744
748
|
|
|
745
749
|
constants.vol = document.getElementById('vol').value;
|
|
746
750
|
constants.autoPlayRate = document.getElementById('autoplay_rate').value;
|
|
@@ -760,9 +764,9 @@ class Menu {
|
|
|
760
764
|
document.getElementById('skill_level_other').value;
|
|
761
765
|
constants.LLMModel = document.getElementById('LLM_model').value;
|
|
762
766
|
constants.LLMPreferences = document.getElementById('LLM_preferences').value;
|
|
763
|
-
|
|
764
767
|
constants.LLMOpenAiMulti = document.getElementById('openai_multi').checked;
|
|
765
768
|
constants.LLMGeminiMulti = document.getElementById('gemini_multi').checked;
|
|
769
|
+
constants.autoInitLLM = document.getElementById('init_llm_on_load').checked;
|
|
766
770
|
|
|
767
771
|
// aria
|
|
768
772
|
if (document.getElementById('aria_mode_assertive').checked) {
|
|
@@ -773,6 +777,12 @@ class Menu {
|
|
|
773
777
|
|
|
774
778
|
this.SaveDataToLocalStorage();
|
|
775
779
|
this.UpdateHtml();
|
|
780
|
+
|
|
781
|
+
if (shouldReset) {
|
|
782
|
+
if (chatLLM) {
|
|
783
|
+
chatLLM.ResetLLM();
|
|
784
|
+
}
|
|
785
|
+
}
|
|
776
786
|
}
|
|
777
787
|
|
|
778
788
|
/**
|
|
@@ -789,6 +799,8 @@ class Menu {
|
|
|
789
799
|
document
|
|
790
800
|
.getElementById(constants.announcement_container_id)
|
|
791
801
|
.setAttribute('aria-live', constants.ariaMode);
|
|
802
|
+
|
|
803
|
+
document.getElementById('init_llm_on_load').checked = constants.autoInitLLM;
|
|
792
804
|
}
|
|
793
805
|
|
|
794
806
|
/**
|
|
@@ -797,6 +809,10 @@ class Menu {
|
|
|
797
809
|
NotifyOfLLMReset() {
|
|
798
810
|
let html =
|
|
799
811
|
'<p id="LLM_reset_notification">Note: Changes in LLM settings will reset any existing conversation.</p>';
|
|
812
|
+
|
|
813
|
+
if (document.getElementById('LLM_reset_notification')) {
|
|
814
|
+
document.getElementById('LLM_reset_notification').remove();
|
|
815
|
+
}
|
|
800
816
|
document
|
|
801
817
|
.getElementById('save_and_close_menu')
|
|
802
818
|
.insertAdjacentHTML('beforebegin', html);
|
|
@@ -813,7 +829,7 @@ class Menu {
|
|
|
813
829
|
* Handles changes to the LLM model and multi-modal settings.
|
|
814
830
|
* We reset if we change the LLM model, multi settings, or skill level.
|
|
815
831
|
*/
|
|
816
|
-
|
|
832
|
+
ShouldLLMReset() {
|
|
817
833
|
let shouldReset = false;
|
|
818
834
|
if (
|
|
819
835
|
!shouldReset &&
|
|
@@ -837,11 +853,7 @@ class Menu {
|
|
|
837
853
|
shouldReset = true;
|
|
838
854
|
}
|
|
839
855
|
|
|
840
|
-
|
|
841
|
-
if (chatLLM) {
|
|
842
|
-
chatLLM.ResetChatHistory();
|
|
843
|
-
}
|
|
844
|
-
}
|
|
856
|
+
return shouldReset;
|
|
845
857
|
}
|
|
846
858
|
|
|
847
859
|
/**
|
|
@@ -868,6 +880,7 @@ class Menu {
|
|
|
868
880
|
data.LLMPreferences = constants.LLMPreferences;
|
|
869
881
|
data.LLMOpenAiMulti = constants.LLMOpenAiMulti;
|
|
870
882
|
data.LLMGeminiMulti = constants.LLMGeminiMulti;
|
|
883
|
+
data.autoInitLLM = constants.autoInitLLM;
|
|
871
884
|
localStorage.setItem('settings_data', JSON.stringify(data));
|
|
872
885
|
}
|
|
873
886
|
/**
|
|
@@ -892,6 +905,7 @@ class Menu {
|
|
|
892
905
|
constants.LLMPreferences = data.LLMPreferences;
|
|
893
906
|
constants.LLMOpenAiMulti = data.LLMOpenAiMulti;
|
|
894
907
|
constants.LLMGeminiMulti = data.LLMGeminiMulti;
|
|
908
|
+
constants.autoInitLLM = data.autoInitLLM;
|
|
895
909
|
}
|
|
896
910
|
this.PopulateData();
|
|
897
911
|
this.UpdateHtml();
|
|
@@ -907,8 +921,12 @@ class ChatLLM {
|
|
|
907
921
|
constructor() {
|
|
908
922
|
this.firstTime = true;
|
|
909
923
|
this.firstMulti = true;
|
|
924
|
+
this.shown = false;
|
|
910
925
|
this.CreateComponent();
|
|
911
926
|
this.SetEvents();
|
|
927
|
+
if (constants.autoInitLLM) {
|
|
928
|
+
this.InitChatMessage();
|
|
929
|
+
}
|
|
912
930
|
}
|
|
913
931
|
|
|
914
932
|
/**
|
|
@@ -1073,10 +1091,18 @@ class ChatLLM {
|
|
|
1073
1091
|
document.getElementById('reset_chatLLM'),
|
|
1074
1092
|
'click',
|
|
1075
1093
|
function (e) {
|
|
1076
|
-
chatLLM.
|
|
1094
|
+
chatLLM.ResetLLM();
|
|
1077
1095
|
},
|
|
1078
1096
|
]);
|
|
1079
1097
|
|
|
1098
|
+
// bookmark:
|
|
1099
|
+
//
|
|
1100
|
+
// have LLM run on init (#425)
|
|
1101
|
+
// quiet first, but if they open window, it does the beep and aria live alert
|
|
1102
|
+
// make toggle in settings to yes / no auto initiate LLM (or wait for window to open)
|
|
1103
|
+
// as part of this, fix reset so it loads the LLM again without refreshing the window,
|
|
1104
|
+
// left undone from the other request
|
|
1105
|
+
|
|
1080
1106
|
// copy to clipboard
|
|
1081
1107
|
constants.events.push([
|
|
1082
1108
|
document.getElementById('chatLLM_copy_all'),
|
|
@@ -1123,7 +1149,7 @@ class ChatLLM {
|
|
|
1123
1149
|
async Submit(text, firsttime = false) {
|
|
1124
1150
|
// start waiting sound
|
|
1125
1151
|
if (constants.playLLMWaitingSound) {
|
|
1126
|
-
|
|
1152
|
+
this.WaitingSound(true);
|
|
1127
1153
|
}
|
|
1128
1154
|
|
|
1129
1155
|
let img = null;
|
|
@@ -1169,7 +1195,7 @@ class ChatLLM {
|
|
|
1169
1195
|
let delay = 1000;
|
|
1170
1196
|
let freq = 440; // a440 babee
|
|
1171
1197
|
constants.waitingInterval = setInterval(function () {
|
|
1172
|
-
if (audio) {
|
|
1198
|
+
if (audio && chatLLM.shown) {
|
|
1173
1199
|
audio.playOscillator(freq, 0.2, 0);
|
|
1174
1200
|
}
|
|
1175
1201
|
}, delay);
|
|
@@ -1181,6 +1207,15 @@ class ChatLLM {
|
|
|
1181
1207
|
}
|
|
1182
1208
|
}
|
|
1183
1209
|
|
|
1210
|
+
InitChatMessage() {
|
|
1211
|
+
// get name from resource
|
|
1212
|
+
let LLMName = resources.GetString(constants.LLMModel);
|
|
1213
|
+
this.firstTime = false;
|
|
1214
|
+
this.DisplayChatMessage(LLMName, resources.GetString('processing'), true);
|
|
1215
|
+
let defaultPrompt = this.GetDefaultPrompt();
|
|
1216
|
+
this.Submit(defaultPrompt, true);
|
|
1217
|
+
}
|
|
1218
|
+
|
|
1184
1219
|
/**
|
|
1185
1220
|
* Processes the response from the LLM and displays it to the user.
|
|
1186
1221
|
* @function
|
|
@@ -1392,9 +1427,9 @@ class ChatLLM {
|
|
|
1392
1427
|
};
|
|
1393
1428
|
|
|
1394
1429
|
// Generate the content
|
|
1395
|
-
|
|
1430
|
+
console.log('LLM request: ', prompt, image);
|
|
1396
1431
|
const result = await model.generateContent([prompt, image]);
|
|
1397
|
-
|
|
1432
|
+
console.log(result.response.text());
|
|
1398
1433
|
|
|
1399
1434
|
// Process the response
|
|
1400
1435
|
chatLLM.ProcessLLMResponse(result.response, 'gemini');
|
|
@@ -1457,7 +1492,7 @@ class ChatLLM {
|
|
|
1457
1492
|
/**
|
|
1458
1493
|
* Resets the chat history window
|
|
1459
1494
|
*/
|
|
1460
|
-
|
|
1495
|
+
ResetLLM() {
|
|
1461
1496
|
// clear the main chat history
|
|
1462
1497
|
document.getElementById('chatLLM_chat_history').innerHTML = '';
|
|
1463
1498
|
// unhide the more button
|
|
@@ -1469,6 +1504,11 @@ class ChatLLM {
|
|
|
1469
1504
|
// reset the data
|
|
1470
1505
|
this.requestJson = null;
|
|
1471
1506
|
this.firstTime = true;
|
|
1507
|
+
|
|
1508
|
+
// and start over, if enabled
|
|
1509
|
+
if (constants.autoInitLLM) {
|
|
1510
|
+
chatLLM.InitChatMessage();
|
|
1511
|
+
}
|
|
1472
1512
|
}
|
|
1473
1513
|
|
|
1474
1514
|
/**
|
|
@@ -1502,6 +1542,7 @@ class ChatLLM {
|
|
|
1502
1542
|
onoff = false;
|
|
1503
1543
|
}
|
|
1504
1544
|
}
|
|
1545
|
+
chatLLM.shown = onoff;
|
|
1505
1546
|
if (onoff) {
|
|
1506
1547
|
// open
|
|
1507
1548
|
this.whereWasMyFocus = document.activeElement;
|
|
@@ -1511,20 +1552,6 @@ class ChatLLM {
|
|
|
1511
1552
|
.getElementById('chatLLM_modal_backdrop')
|
|
1512
1553
|
.classList.remove('hidden');
|
|
1513
1554
|
document.querySelector('#chatLLM .close').focus();
|
|
1514
|
-
|
|
1515
|
-
// first time, send default query
|
|
1516
|
-
if (this.firstTime) {
|
|
1517
|
-
// get name from resource
|
|
1518
|
-
let LLMName = resources.GetString(constants.LLMModel);
|
|
1519
|
-
this.firstTime = false;
|
|
1520
|
-
this.DisplayChatMessage(
|
|
1521
|
-
LLMName,
|
|
1522
|
-
resources.GetString('processing'),
|
|
1523
|
-
true
|
|
1524
|
-
);
|
|
1525
|
-
let defaultPrompt = this.GetDefaultPrompt();
|
|
1526
|
-
this.Submit(defaultPrompt, true);
|
|
1527
|
-
}
|
|
1528
1555
|
} else {
|
|
1529
1556
|
// close
|
|
1530
1557
|
document.getElementById('chatLLM').classList.add('hidden');
|
|
@@ -6631,19 +6658,21 @@ class LinePlot {
|
|
|
6631
6658
|
|
|
6632
6659
|
if (elements) {
|
|
6633
6660
|
this.plotLine = elements[elements.length - 1];
|
|
6661
|
+
} else {
|
|
6662
|
+
constants.hasRect = 0;
|
|
6663
|
+
}
|
|
6634
6664
|
|
|
6635
|
-
|
|
6636
|
-
|
|
6665
|
+
let pointCoords = this.GetPointCoords();
|
|
6666
|
+
let pointValues = this.GetPoints();
|
|
6637
6667
|
|
|
6638
|
-
|
|
6639
|
-
|
|
6668
|
+
this.chartLineX = pointCoords[0]; // x coordinates of curve
|
|
6669
|
+
this.chartLineY = pointCoords[1]; // y coordinates of curve
|
|
6640
6670
|
|
|
6641
|
-
|
|
6642
|
-
|
|
6671
|
+
this.pointValuesX = pointValues[0]; // actual values of x
|
|
6672
|
+
this.pointValuesY = pointValues[1]; // actual values of y
|
|
6643
6673
|
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
}
|
|
6674
|
+
this.curveMinY = Math.min(...this.pointValuesY);
|
|
6675
|
+
this.curveMaxY = Math.max(...this.pointValuesY);
|
|
6647
6676
|
}
|
|
6648
6677
|
|
|
6649
6678
|
/**
|
|
@@ -6678,27 +6707,47 @@ class LinePlot {
|
|
|
6678
6707
|
*/
|
|
6679
6708
|
GetPointCoords() {
|
|
6680
6709
|
let svgLineCoords = [[], []];
|
|
6681
|
-
// lineplot SVG containing path element instead of polyline
|
|
6682
|
-
if (this.plotLine instanceof SVGPathElement) {
|
|
6683
|
-
// Assuming the path data is in the format "M x y L x y L x y L x y"
|
|
6684
|
-
const pathD = this.plotLine.getAttribute('d');
|
|
6685
|
-
const regex = /[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;
|
|
6686
6710
|
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6711
|
+
if (this.plotLine) {
|
|
6712
|
+
// lineplot SVG containing path element instead of polyline
|
|
6713
|
+
if (this.plotLine instanceof SVGPathElement) {
|
|
6714
|
+
// Assuming the path data is in the format "M x y L x y L x y L x y"
|
|
6715
|
+
const pathD = this.plotLine.getAttribute('d');
|
|
6716
|
+
const regex = /[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;
|
|
6717
|
+
|
|
6718
|
+
let match;
|
|
6719
|
+
while ((match = regex.exec(pathD)) !== null) {
|
|
6720
|
+
svgLineCoords[0].push(match[1]); // x coordinate
|
|
6721
|
+
svgLineCoords[1].push(match[3]); // y coordinate
|
|
6722
|
+
}
|
|
6723
|
+
} else {
|
|
6724
|
+
let points = this.plotLine.getAttribute('points').split(' ');
|
|
6725
|
+
for (let i = 0; i < points.length; i++) {
|
|
6726
|
+
if (points[i] !== '') {
|
|
6727
|
+
let point = points[i].split(',');
|
|
6728
|
+
svgLineCoords[0].push(point[0]);
|
|
6729
|
+
svgLineCoords[1].push(point[1]);
|
|
6730
|
+
}
|
|
6731
|
+
}
|
|
6691
6732
|
}
|
|
6692
6733
|
} else {
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6734
|
+
// fetch from data instead
|
|
6735
|
+
let x_points = [];
|
|
6736
|
+
let y_points = [];
|
|
6737
|
+
|
|
6738
|
+
let data;
|
|
6739
|
+
if ('data' in singleMaidr) {
|
|
6740
|
+
data = singleMaidr.data;
|
|
6741
|
+
}
|
|
6742
|
+
if (typeof data !== 'undefined') {
|
|
6743
|
+
for (let i = 0; i < data.length; i++) {
|
|
6744
|
+
x_points.push(data[i].x);
|
|
6745
|
+
y_points.push(data[i].y);
|
|
6699
6746
|
}
|
|
6700
6747
|
}
|
|
6748
|
+
return [x_points, y_points];
|
|
6701
6749
|
}
|
|
6750
|
+
|
|
6702
6751
|
return svgLineCoords;
|
|
6703
6752
|
}
|
|
6704
6753
|
|
|
@@ -6720,8 +6769,6 @@ class LinePlot {
|
|
|
6720
6769
|
y_points.push(data[i].y);
|
|
6721
6770
|
}
|
|
6722
6771
|
return [x_points, y_points];
|
|
6723
|
-
} else {
|
|
6724
|
-
return;
|
|
6725
6772
|
}
|
|
6726
6773
|
}
|
|
6727
6774
|
|
|
@@ -10220,7 +10267,7 @@ class Control {
|
|
|
10220
10267
|
if (constants.showDisplay) {
|
|
10221
10268
|
display.displayValues();
|
|
10222
10269
|
}
|
|
10223
|
-
if (constants.showRect) {
|
|
10270
|
+
if (constants.showRect && constants.hasRect) {
|
|
10224
10271
|
point.UpdatePointDisplay();
|
|
10225
10272
|
}
|
|
10226
10273
|
if (constants.sonifMode != 'off') {
|