maidr 1.3.0 → 1.3.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/README.md +170 -174
- package/dist/maidr.js +393 -507
- package/dist/maidr.min.js +1 -1
- package/package.json +1 -1
package/dist/maidr.js
CHANGED
|
@@ -74,13 +74,12 @@ class Constants {
|
|
|
74
74
|
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)
|
|
75
75
|
globalMinMax = true;
|
|
76
76
|
ariaMode = 'assertive'; // assertive (default) / polite
|
|
77
|
-
playLLMWaitingSound = true;
|
|
78
77
|
|
|
79
78
|
// LLM settings
|
|
80
|
-
LLMDebugMode = 0; // 0 = use real data, 1 = all fake, 2 = real data but no image
|
|
81
79
|
openAIAuthKey = null; // OpenAI authentication key, set in menu
|
|
82
80
|
geminiAuthKey = null; // Gemini authentication key, set in menu
|
|
83
81
|
LLMmaxResponseTokens = 1000; // max tokens to send to LLM, 20 for testing, 1000 ish for real
|
|
82
|
+
playLLMWaitingSound = true;
|
|
84
83
|
LLMDetail = 'high'; // low (default for testing, like 100 tokens) / high (default for real, like 1000 tokens)
|
|
85
84
|
LLMModel = 'openai'; // openai (default) / gemini
|
|
86
85
|
LLMSystemMessage =
|
|
@@ -301,7 +300,7 @@ class Menu {
|
|
|
301
300
|
<div class="modal-dialog" role="document" tabindex="0">
|
|
302
301
|
<div class="modal-content">
|
|
303
302
|
<div class="modal-header">
|
|
304
|
-
<
|
|
303
|
+
<h2 class="modal-title">Menu</h2>
|
|
305
304
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
306
305
|
<span aria-hidden="true">×</span>
|
|
307
306
|
</button>
|
|
@@ -428,7 +427,7 @@ class Menu {
|
|
|
428
427
|
</select>
|
|
429
428
|
<label for="skill_level">Level of skill in statistical charts</label>
|
|
430
429
|
</p>
|
|
431
|
-
<p id="skill_level_other_container" class="hidden"><input type="text" id="skill_level_other"> <label for="skill_level_other">
|
|
430
|
+
<p id="skill_level_other_container" class="hidden"><input type="text" placeholder="Very basic" id="skill_level_other"> <label for="skill_level_other">Describe your level of skill in statistical charts</label></p>
|
|
432
431
|
</div>
|
|
433
432
|
</div>
|
|
434
433
|
<div class="modal-footer">
|
|
@@ -595,7 +594,6 @@ class Menu {
|
|
|
595
594
|
*/
|
|
596
595
|
PopulateData() {
|
|
597
596
|
document.getElementById('vol').value = constants.vol;
|
|
598
|
-
//document.getElementById('show_rect').checked = constants.showRect;
|
|
599
597
|
document.getElementById('autoplay_rate').value = constants.autoPlayRate;
|
|
600
598
|
document.getElementById('braille_display_length').value =
|
|
601
599
|
constants.brailleDisplayLength;
|
|
@@ -619,7 +617,6 @@ class Menu {
|
|
|
619
617
|
}
|
|
620
618
|
document.getElementById('LLM_model').value = constants.LLMModel;
|
|
621
619
|
|
|
622
|
-
|
|
623
620
|
// aria mode
|
|
624
621
|
if (constants.ariaMode == 'assertive') {
|
|
625
622
|
document.getElementById('aria_mode_assertive').checked = true;
|
|
@@ -657,7 +654,6 @@ class Menu {
|
|
|
657
654
|
*/
|
|
658
655
|
SaveData() {
|
|
659
656
|
constants.vol = document.getElementById('vol').value;
|
|
660
|
-
//constants.showRect = document.getElementById('show_rect').checked;
|
|
661
657
|
constants.autoPlayRate = document.getElementById('autoplay_rate').value;
|
|
662
658
|
constants.brailleDisplayLength = document.getElementById(
|
|
663
659
|
'braille_display_length'
|
|
@@ -710,7 +706,6 @@ class Menu {
|
|
|
710
706
|
SaveDataToLocalStorage() {
|
|
711
707
|
let data = {};
|
|
712
708
|
data.vol = constants.vol;
|
|
713
|
-
//data.showRect = constants.showRect;
|
|
714
709
|
data.autoPlayRate = constants.autoPlayRate;
|
|
715
710
|
data.brailleDisplayLength = constants.brailleDisplayLength;
|
|
716
711
|
data.colorSelected = constants.colorSelected;
|
|
@@ -732,7 +727,6 @@ class Menu {
|
|
|
732
727
|
let data = JSON.parse(localStorage.getItem('settings_data'));
|
|
733
728
|
if (data) {
|
|
734
729
|
constants.vol = data.vol;
|
|
735
|
-
//constants.showRect = data.showRect;
|
|
736
730
|
constants.autoPlayRate = data.autoPlayRate;
|
|
737
731
|
constants.brailleDisplayLength = data.brailleDisplayLength;
|
|
738
732
|
constants.colorSelected = data.colorSelected;
|
|
@@ -773,7 +767,7 @@ class ChatLLM {
|
|
|
773
767
|
<div class="modal-dialog" role="document" tabindex="0">
|
|
774
768
|
<div class="modal-content">
|
|
775
769
|
<div class="modal-header">
|
|
776
|
-
<
|
|
770
|
+
<h2 id="chatLLM_title" class="modal-title">Ask a Question</h2>
|
|
777
771
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
778
772
|
<span aria-hidden="true">×</span>
|
|
779
773
|
</button>
|
|
@@ -833,7 +827,7 @@ class ChatLLM {
|
|
|
833
827
|
document,
|
|
834
828
|
'keyup',
|
|
835
829
|
function (e) {
|
|
836
|
-
if (e.key == '?') {
|
|
830
|
+
if (e.key == '?' && (e.ctrlKey || e.metaKey)) {
|
|
837
831
|
chatLLM.Toggle(true);
|
|
838
832
|
}
|
|
839
833
|
},
|
|
@@ -893,13 +887,7 @@ class ChatLLM {
|
|
|
893
887
|
chatLLM.WaitingSound(true);
|
|
894
888
|
}
|
|
895
889
|
|
|
896
|
-
if (constants.
|
|
897
|
-
// do the below with a 5 sec delay
|
|
898
|
-
setTimeout(function () {
|
|
899
|
-
chatLLM.ProcessLLMResponse(chatLLM.fakeLLMResponseData());
|
|
900
|
-
}, 5000);
|
|
901
|
-
return;
|
|
902
|
-
} else if (constants.LLMModel == 'gemini') {
|
|
890
|
+
if (constants.LLMModel == 'gemini') {
|
|
903
891
|
chatLLM.GeminiPrompt(text, img);
|
|
904
892
|
} else if (constants.LLMModel == 'openai') {
|
|
905
893
|
chatLLM.OpenAIPrompt(text, img);
|
|
@@ -1100,10 +1088,7 @@ class ChatLLM {
|
|
|
1100
1088
|
let i = this.requestJson.messages.length;
|
|
1101
1089
|
this.requestJson.messages[i] = {};
|
|
1102
1090
|
this.requestJson.messages[i].role = 'user';
|
|
1103
|
-
if (
|
|
1104
|
-
// backup message only, no image
|
|
1105
|
-
this.requestJson.messages[i].content = backupMessage;
|
|
1106
|
-
} else if (img) {
|
|
1091
|
+
if (img) {
|
|
1107
1092
|
// first message, include the img
|
|
1108
1093
|
this.requestJson.messages[i].content = [
|
|
1109
1094
|
{
|
|
@@ -1176,7 +1161,7 @@ class ChatLLM {
|
|
|
1176
1161
|
<div class="chatLLM_message ${
|
|
1177
1162
|
user == 'User' ? 'chatLLM_message_self' : 'chatLLM_message_other'
|
|
1178
1163
|
}">
|
|
1179
|
-
<
|
|
1164
|
+
<h3 class="chatLLM_message_user">${user}</h3>
|
|
1180
1165
|
<p class="chatLLM_message_text">${text}</p>
|
|
1181
1166
|
</div>
|
|
1182
1167
|
`;
|
|
@@ -1352,7 +1337,7 @@ class Description {
|
|
|
1352
1337
|
<div class="modal-dialog" role="document" tabindex="0">
|
|
1353
1338
|
<div class="modal-content">
|
|
1354
1339
|
<div class="modal-header">
|
|
1355
|
-
<
|
|
1340
|
+
<h2 id="desc_title" class="modal-title">Description</h2>
|
|
1356
1341
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
|
1357
1342
|
<span aria-hidden="true">×</span>
|
|
1358
1343
|
</button>
|
|
@@ -2144,7 +2129,7 @@ class Audio {
|
|
|
2144
2129
|
panning = 0;
|
|
2145
2130
|
}
|
|
2146
2131
|
} else if (constants.chartType == 'heat') {
|
|
2147
|
-
rawFreq = plot.
|
|
2132
|
+
rawFreq = plot.data[position.y][position.x];
|
|
2148
2133
|
rawPanning = position.x;
|
|
2149
2134
|
frequency = this.SlideBetween(
|
|
2150
2135
|
rawFreq,
|
|
@@ -2940,7 +2925,7 @@ class Display {
|
|
|
2940
2925
|
plot.fill +
|
|
2941
2926
|
' is ';
|
|
2942
2927
|
// if (constants.hasRect) {
|
|
2943
|
-
verboseText += plot.
|
|
2928
|
+
verboseText += plot.data[position.y][position.x];
|
|
2944
2929
|
// }
|
|
2945
2930
|
} else {
|
|
2946
2931
|
verboseText +=
|
|
@@ -2955,7 +2940,7 @@ class Display {
|
|
|
2955
2940
|
plot.fill +
|
|
2956
2941
|
' is ';
|
|
2957
2942
|
// if (constants.hasRect) {
|
|
2958
|
-
verboseText += plot.
|
|
2943
|
+
verboseText += plot.data[position.y][position.x];
|
|
2959
2944
|
// }
|
|
2960
2945
|
}
|
|
2961
2946
|
// terse and verbose alternate between columns and rows
|
|
@@ -2969,7 +2954,7 @@ class Display {
|
|
|
2969
2954
|
'<p>' +
|
|
2970
2955
|
plot.x_labels[position.x] +
|
|
2971
2956
|
', ' +
|
|
2972
|
-
plot.
|
|
2957
|
+
plot.data[position.y][position.x] +
|
|
2973
2958
|
'</p>\n';
|
|
2974
2959
|
} else {
|
|
2975
2960
|
// row navigation
|
|
@@ -2977,7 +2962,7 @@ class Display {
|
|
|
2977
2962
|
'<p>' +
|
|
2978
2963
|
plot.y_labels[position.y] +
|
|
2979
2964
|
', ' +
|
|
2980
|
-
plot.
|
|
2965
|
+
plot.data[position.y][position.x] +
|
|
2981
2966
|
'</p>\n';
|
|
2982
2967
|
}
|
|
2983
2968
|
} else if (constants.textMode == 'verbose') {
|
|
@@ -3154,11 +3139,11 @@ class Display {
|
|
|
3154
3139
|
} else if (constants.chartType == 'line') {
|
|
3155
3140
|
// line layer
|
|
3156
3141
|
verboseText +=
|
|
3157
|
-
plot.
|
|
3142
|
+
plot.plotLegend.x +
|
|
3158
3143
|
' is ' +
|
|
3159
3144
|
plot.pointValuesX[position.x] +
|
|
3160
3145
|
', ' +
|
|
3161
|
-
plot.
|
|
3146
|
+
plot.plotLegend.y +
|
|
3162
3147
|
' is ' +
|
|
3163
3148
|
plot.pointValuesY[position.x];
|
|
3164
3149
|
|
|
@@ -3831,6 +3816,8 @@ class BarChart {
|
|
|
3831
3816
|
let elements = null;
|
|
3832
3817
|
if ('selector' in singleMaidr) {
|
|
3833
3818
|
elements = document.querySelectorAll(singleMaidr.selector);
|
|
3819
|
+
} else if ('elements' in singleMaidr) {
|
|
3820
|
+
elements = singleMaidr.elements;
|
|
3834
3821
|
}
|
|
3835
3822
|
|
|
3836
3823
|
if (xlevel && data && elements) {
|
|
@@ -3867,15 +3854,6 @@ class BarChart {
|
|
|
3867
3854
|
logError.LogAbsentElement('elements');
|
|
3868
3855
|
}
|
|
3869
3856
|
|
|
3870
|
-
// bars. The actual bar elements in the SVG. Used to highlight visually
|
|
3871
|
-
// if ('elements' in singleMaidr) {
|
|
3872
|
-
// this.bars = singleMaidr.elements;
|
|
3873
|
-
// constants.hasRect = 1;
|
|
3874
|
-
// } else {
|
|
3875
|
-
// // this.bars = constants.chart.querySelectorAll('g[id^="geom_rect"] > rect'); // if we use plot.plotData.length instead of plot.bars.length, we don't have to include this
|
|
3876
|
-
// constants.hasRect = 0;
|
|
3877
|
-
// }
|
|
3878
|
-
|
|
3879
3857
|
// column labels, both legend and tick
|
|
3880
3858
|
this.columnLabels = [];
|
|
3881
3859
|
let legendX = '';
|
|
@@ -3951,10 +3929,8 @@ class BarChart {
|
|
|
3951
3929
|
|
|
3952
3930
|
if (Array.isArray(singleMaidr)) {
|
|
3953
3931
|
this.plotData = singleMaidr;
|
|
3954
|
-
} else {
|
|
3955
|
-
|
|
3956
|
-
this.plotData = singleMaidr.data;
|
|
3957
|
-
}
|
|
3932
|
+
} else if ('data' in singleMaidr) {
|
|
3933
|
+
this.plotData = singleMaidr.data;
|
|
3958
3934
|
}
|
|
3959
3935
|
|
|
3960
3936
|
// set the max and min values for the plot
|
|
@@ -4145,8 +4121,6 @@ class BoxPlot {
|
|
|
4145
4121
|
* @constructor
|
|
4146
4122
|
*/
|
|
4147
4123
|
constructor() {
|
|
4148
|
-
constants.plotOrientation = 'horz'; // default
|
|
4149
|
-
|
|
4150
4124
|
// the default sections for all boxplots
|
|
4151
4125
|
this.sections = [
|
|
4152
4126
|
'lower_outlier',
|
|
@@ -4158,6 +4132,8 @@ class BoxPlot {
|
|
|
4158
4132
|
'upper_outlier',
|
|
4159
4133
|
];
|
|
4160
4134
|
|
|
4135
|
+
// set orientation
|
|
4136
|
+
constants.plotOrientation = 'horz';
|
|
4161
4137
|
if ('axes' in singleMaidr) {
|
|
4162
4138
|
if ('x' in singleMaidr.axes) {
|
|
4163
4139
|
if ('level' in singleMaidr.axes.x) {
|
|
@@ -4238,7 +4214,11 @@ class BoxPlot {
|
|
|
4238
4214
|
|
|
4239
4215
|
// bounds data
|
|
4240
4216
|
if ('selector' in singleMaidr) {
|
|
4241
|
-
|
|
4217
|
+
let elements = document.querySelector(singleMaidr.selector);
|
|
4218
|
+
this.plotBounds = this.GetPlotBounds(elements);
|
|
4219
|
+
constants.hasRect = true;
|
|
4220
|
+
} else if ('elements' in singleMaidr) {
|
|
4221
|
+
this.plotBounds = this.GetPlotBounds(singleMaidr.elements);
|
|
4242
4222
|
constants.hasRect = true;
|
|
4243
4223
|
} else {
|
|
4244
4224
|
constants.hasRect = false;
|
|
@@ -4324,7 +4304,7 @@ class BoxPlot {
|
|
|
4324
4304
|
* Calculates the bounding boxes for all elements in the parent element, including outliers, whiskers, and range.
|
|
4325
4305
|
* @returns {Array} An array of bounding boxes for all elements.
|
|
4326
4306
|
*/
|
|
4327
|
-
GetPlotBounds() {
|
|
4307
|
+
GetPlotBounds(elements) {
|
|
4328
4308
|
// we fetch the elements in our parent,
|
|
4329
4309
|
// and similar to old GetData we run through and get bounding boxes (or blanks) for everything,
|
|
4330
4310
|
// and store in an identical structure
|
|
@@ -4332,7 +4312,6 @@ class BoxPlot {
|
|
|
4332
4312
|
let plotBounds = [];
|
|
4333
4313
|
let allWeNeed = this.GetAllSegmentTypes();
|
|
4334
4314
|
let re = /(?:\d+(?:\.\d*)?|\.\d+)/g;
|
|
4335
|
-
let elements = document.querySelector(singleMaidr.selector);
|
|
4336
4315
|
|
|
4337
4316
|
// get initial set of elements, a parent element for all outliers, whiskers, and range
|
|
4338
4317
|
let initialElemSet = [];
|
|
@@ -4903,100 +4882,36 @@ class HeatMap {
|
|
|
4903
4882
|
}
|
|
4904
4883
|
}
|
|
4905
4884
|
}
|
|
4906
|
-
let data = null;
|
|
4907
|
-
let dataLength = 0;
|
|
4908
4885
|
if ('data' in singleMaidr) {
|
|
4909
|
-
data = singleMaidr.data;
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4886
|
+
this.data = singleMaidr.data;
|
|
4887
|
+
this.num_rows = this.data.length;
|
|
4888
|
+
this.num_cols = this.data[0].length;
|
|
4889
|
+
} else {
|
|
4890
|
+
// critical error, no data
|
|
4891
|
+
console.error('No data found in singleMaidr object');
|
|
4913
4892
|
}
|
|
4914
|
-
let elements = null;
|
|
4915
4893
|
if ('selector' in singleMaidr) {
|
|
4916
|
-
elements = document.querySelectorAll(singleMaidr.selector);
|
|
4894
|
+
this.elements = document.querySelectorAll(singleMaidr.selector);
|
|
4895
|
+
constants.hasRect = 1;
|
|
4896
|
+
} else if ('elements' in singleMaidr) {
|
|
4897
|
+
this.elements = singleMaidr.elements;
|
|
4898
|
+
constants.hasRect = 1;
|
|
4899
|
+
} else {
|
|
4900
|
+
this.elements = null;
|
|
4901
|
+
constants.hasRect = 0;
|
|
4917
4902
|
}
|
|
4918
4903
|
|
|
4919
|
-
// if (xlevel && ylevel && data && elements) {
|
|
4920
|
-
// if (elements.length != dataLength) {
|
|
4921
|
-
// // I didn't throw an error but give a warning
|
|
4922
|
-
// constants.hasRect = 0;
|
|
4923
|
-
// logError.LogDifferentLengths('data', 'elements');
|
|
4924
|
-
// } else if (ylevel.length != data.length) {
|
|
4925
|
-
// constants.hasRect = 0;
|
|
4926
|
-
// logError.logDifferentLengths('y level', 'rows');
|
|
4927
|
-
// } else if (data[0].length != xlevel.length) {
|
|
4928
|
-
// constants.hasRect = 0;
|
|
4929
|
-
// logError.logDifferentLengths('x level', 'columns');
|
|
4930
|
-
// } else {
|
|
4931
|
-
// this.plots = elements;
|
|
4932
|
-
// constants.hasRect = 1;
|
|
4933
|
-
// }
|
|
4934
|
-
// } else if (ylevel && data && elements) {
|
|
4935
|
-
// if (dataLength != elements.length) {
|
|
4936
|
-
// constants.hasRect = 0;
|
|
4937
|
-
// logError.logDifferentLengths('data', 'elements');
|
|
4938
|
-
// } else if (ylevel.length != data.length) {
|
|
4939
|
-
// constants.hasRect = 0;
|
|
4940
|
-
// logError.logDifferentLengths('y level', 'rows');
|
|
4941
|
-
// } else {
|
|
4942
|
-
// this.plots = elements;
|
|
4943
|
-
// constants.hasRect = 1;
|
|
4944
|
-
// }
|
|
4945
|
-
// } else if (xlevel && data && elements) {
|
|
4946
|
-
// if (dataLength != elements.length) {
|
|
4947
|
-
// constants.hasRect = 0;
|
|
4948
|
-
// logError.logDifferentLengths('data', 'elements');
|
|
4949
|
-
// } else if (xlevel.length != data[0].length) {
|
|
4950
|
-
// constants.hasRect = 0;
|
|
4951
|
-
// logError.logDifferentLengths('x level', 'columns');
|
|
4952
|
-
// } else {
|
|
4953
|
-
// this.plots = elements;
|
|
4954
|
-
// constants.hasRect = 1;
|
|
4955
|
-
// }
|
|
4956
|
-
// }
|
|
4957
|
-
// else if (xlevel && ylevel && data) {
|
|
4958
|
-
// constants.hasRect = 0;
|
|
4959
|
-
// if (ylevel.length != data.length) {
|
|
4960
|
-
// logError.logDifferentLengths('y level', 'rows');
|
|
4961
|
-
// } else if (data[0].length != xlevel.length) {
|
|
4962
|
-
// logError.logDifferentLengths('x level', 'columns');
|
|
4963
|
-
// }
|
|
4964
|
-
// logError.LogAbsentElement('elements');
|
|
4965
|
-
// }
|
|
4966
|
-
// else if (data && elements) {
|
|
4967
|
-
// if (dataLength != elements.length) {
|
|
4968
|
-
// constants.hasRect = 0;
|
|
4969
|
-
// logError.logDifferentLengths('data', 'elements');
|
|
4970
|
-
// } else {
|
|
4971
|
-
// this.plots = elements;
|
|
4972
|
-
// constants.hasRect = 1;
|
|
4973
|
-
// }
|
|
4974
|
-
// } else if (data) {
|
|
4975
|
-
// constants.hasRect = 0;
|
|
4976
|
-
// if (!xlevel) logError.LogAbsentElement('x level');
|
|
4977
|
-
// if (!ylevel) logError.LogAbsentElement('y level');
|
|
4978
|
-
// if (!elements) logError.LogAbsentElement('elements');
|
|
4979
|
-
// }
|
|
4980
|
-
|
|
4981
|
-
this.plots = elements;
|
|
4982
|
-
constants.hasRect = 1;
|
|
4983
|
-
|
|
4984
4904
|
this.group_labels = this.getGroupLabels();
|
|
4985
|
-
// this.x_labels = this.getXLabels();
|
|
4986
|
-
// this.y_labels = this.getYLabels();
|
|
4987
4905
|
this.x_labels = xlevel;
|
|
4988
4906
|
this.y_labels = ylevel;
|
|
4989
4907
|
this.title = this.getTitle();
|
|
4990
4908
|
this.fill = this.getFill();
|
|
4991
4909
|
|
|
4992
|
-
|
|
4993
|
-
|
|
4910
|
+
if (constants.hasRect) {
|
|
4911
|
+
this.SetHeatmapRectData();
|
|
4912
|
+
}
|
|
4994
4913
|
|
|
4995
|
-
this.
|
|
4996
|
-
this.y_coord = this.plotData[1];
|
|
4997
|
-
this.values = this.plotData[2];
|
|
4998
|
-
this.num_rows = this.plotData[3];
|
|
4999
|
-
this.num_cols = this.plotData[4];
|
|
4914
|
+
this.updateConstants();
|
|
5000
4915
|
|
|
5001
4916
|
this.x_group_label = this.group_labels[0].trim();
|
|
5002
4917
|
this.y_group_label = this.group_labels[1].trim();
|
|
@@ -5007,113 +4922,77 @@ class HeatMap {
|
|
|
5007
4922
|
* If 'data' exists in singleMaidr, it returns the norms from the data. Otherwise, it calculates the norms from the unique x and y coordinates.
|
|
5008
4923
|
* @returns {Array} An array of heatmap data containing unique x and y coordinates, norms, number of rows, and number of columns.
|
|
5009
4924
|
*/
|
|
5010
|
-
|
|
4925
|
+
SetHeatmapRectData() {
|
|
4926
|
+
// We get a set of x and y coordinates from the heatmap squares,
|
|
4927
|
+
// which is different and only sometimes connected to the actual data
|
|
4928
|
+
// note, only runs if constants.hasRect is true
|
|
4929
|
+
|
|
5011
4930
|
// get the x_coord and y_coord to check if a square exists at the coordinates
|
|
5012
4931
|
let x_coord_check = [];
|
|
5013
4932
|
let y_coord_check = [];
|
|
5014
|
-
|
|
5015
4933
|
let unique_x_coord = [];
|
|
5016
4934
|
let unique_y_coord = [];
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
y_coord_check.push(parseFloat(this.plots[i].getAttribute('y')));
|
|
5036
|
-
}
|
|
4935
|
+
for (let i = 0; i < this.elements.length; i++) {
|
|
4936
|
+
if (this.elements[i]) {
|
|
4937
|
+
// heatmap SVG containing path element instead of rect
|
|
4938
|
+
if (this.elements[i] instanceof SVGPathElement) {
|
|
4939
|
+
// Assuming the path data is in the format "M x y L x y L x y L x y"
|
|
4940
|
+
const path_d = this.elements[i].getAttribute('d');
|
|
4941
|
+
const regex = /[ML]\s*(-?\d+(\.\d+)?)\s+(-?\d+(\.\d+)?)/g;
|
|
4942
|
+
const match = regex.exec(path_d);
|
|
4943
|
+
|
|
4944
|
+
const coords = [Number(match[1]), Number(match[3])];
|
|
4945
|
+
const x = coords[0];
|
|
4946
|
+
const y = coords[1];
|
|
4947
|
+
|
|
4948
|
+
x_coord_check.push(parseFloat(x));
|
|
4949
|
+
y_coord_check.push(parseFloat(y));
|
|
4950
|
+
} else {
|
|
4951
|
+
x_coord_check.push(parseFloat(this.elements[i].getAttribute('x')));
|
|
4952
|
+
y_coord_check.push(parseFloat(this.elements[i].getAttribute('y')));
|
|
5037
4953
|
}
|
|
5038
4954
|
}
|
|
5039
|
-
|
|
5040
|
-
// sort the squares to access from left to right, up to down
|
|
5041
|
-
x_coord_check.sort(function (a, b) {
|
|
5042
|
-
return a - b;
|
|
5043
|
-
}); // ascending
|
|
5044
|
-
y_coord_check.sort(function (a, b) {
|
|
5045
|
-
return a - b;
|
|
5046
|
-
});
|
|
5047
|
-
|
|
5048
|
-
let svgScaler = this.GetSVGScaler();
|
|
5049
|
-
// inverse scale if svg is scaled
|
|
5050
|
-
if (svgScaler[0] == -1) {
|
|
5051
|
-
x_coord_check = x_coord_check.reverse();
|
|
5052
|
-
}
|
|
5053
|
-
if (svgScaler[1] == -1) {
|
|
5054
|
-
y_coord_check = y_coord_check.reverse();
|
|
5055
|
-
}
|
|
5056
|
-
|
|
5057
|
-
// get unique elements from x_coord and y_coord
|
|
5058
|
-
unique_x_coord = [...new Set(x_coord_check)];
|
|
5059
|
-
unique_y_coord = [...new Set(y_coord_check)];
|
|
5060
4955
|
}
|
|
5061
4956
|
|
|
5062
|
-
//
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
} else {
|
|
5070
|
-
num_rows = unique_y_coord.length;
|
|
5071
|
-
num_cols = unique_x_coord.length;
|
|
5072
|
-
}
|
|
5073
|
-
num_squares = num_rows * num_cols;
|
|
5074
|
-
|
|
5075
|
-
let norms = [];
|
|
5076
|
-
if ('data' in singleMaidr) {
|
|
5077
|
-
norms = [...singleMaidr.data];
|
|
5078
|
-
} else {
|
|
5079
|
-
norms = Array(num_rows)
|
|
5080
|
-
.fill()
|
|
5081
|
-
.map(() => Array(num_cols).fill(0));
|
|
5082
|
-
let min_norm = 3 * Math.pow(255, 2);
|
|
5083
|
-
let max_norm = 0;
|
|
5084
|
-
|
|
5085
|
-
for (var i = 0; i < this.plots.length; i++) {
|
|
5086
|
-
var x_index = unique_x_coord.indexOf(x_coord_check[i]);
|
|
5087
|
-
var y_index = unique_y_coord.indexOf(y_coord_check[i]);
|
|
5088
|
-
let norm = this.getRGBNorm(i);
|
|
5089
|
-
norms[y_index][x_index] = norm;
|
|
4957
|
+
// sort the squares to access from left to right, up to down
|
|
4958
|
+
x_coord_check.sort(function (a, b) {
|
|
4959
|
+
return a - b;
|
|
4960
|
+
}); // ascending
|
|
4961
|
+
y_coord_check.sort(function (a, b) {
|
|
4962
|
+
return a - b;
|
|
4963
|
+
});
|
|
5090
4964
|
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
4965
|
+
let svgScaler = this.GetSVGScaler();
|
|
4966
|
+
// inverse scale if svg has a negative scale in the actual svg
|
|
4967
|
+
if (svgScaler[0] == -1) {
|
|
4968
|
+
x_coord_check = x_coord_check.reverse();
|
|
4969
|
+
}
|
|
4970
|
+
if (svgScaler[1] == -1) {
|
|
4971
|
+
y_coord_check = y_coord_check.reverse();
|
|
5094
4972
|
}
|
|
5095
4973
|
|
|
5096
|
-
|
|
4974
|
+
// get unique elements from x_coord and y_coord
|
|
4975
|
+
unique_x_coord = [...new Set(x_coord_check)];
|
|
4976
|
+
unique_y_coord = [...new Set(y_coord_check)];
|
|
5097
4977
|
|
|
5098
|
-
|
|
4978
|
+
this.x_coord = unique_x_coord;
|
|
4979
|
+
this.y_coord = unique_y_coord;
|
|
5099
4980
|
}
|
|
5100
4981
|
|
|
5101
4982
|
/**
|
|
5102
4983
|
* Updates the constants used in the heatmap.
|
|
4984
|
+
* minX: 0, always
|
|
4985
|
+
* maxX: the x length of the data array
|
|
4986
|
+
* minY: the minimum value of the data array
|
|
4987
|
+
* maxY: the maximum value of the data array
|
|
4988
|
+
* autoPlayRate: the rate at which the heatmap will autoplay, based on the number of columns
|
|
4989
|
+
*
|
|
5103
4990
|
*/
|
|
5104
4991
|
updateConstants() {
|
|
5105
4992
|
constants.minX = 0;
|
|
5106
|
-
constants.maxX = this.
|
|
5107
|
-
constants.minY = this.
|
|
5108
|
-
constants.maxY = this.
|
|
5109
|
-
for (let i = 0; i < this.plotData[2].length; i++) {
|
|
5110
|
-
for (let j = 0; j < this.plotData[2][i].length; j++) {
|
|
5111
|
-
if (this.plotData[2][i][j] < constants.minY)
|
|
5112
|
-
constants.minY = this.plotData[2][i][j];
|
|
5113
|
-
if (this.plotData[2][i][j] > constants.maxY)
|
|
5114
|
-
constants.maxY = this.plotData[2][i][j];
|
|
5115
|
-
}
|
|
5116
|
-
}
|
|
4993
|
+
constants.maxX = this.data[0].length - 1;
|
|
4994
|
+
constants.minY = Math.min(...this.data.map((row) => Math.min(...row)));
|
|
4995
|
+
constants.maxY = Math.max(...this.data.map((row) => Math.max(...row)));
|
|
5117
4996
|
constants.autoPlayRate = Math.min(
|
|
5118
4997
|
Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
|
|
5119
4998
|
constants.MAX_SPEED
|
|
@@ -5132,7 +5011,7 @@ class HeatMap {
|
|
|
5132
5011
|
}
|
|
5133
5012
|
|
|
5134
5013
|
/**
|
|
5135
|
-
* Returns an array of the X and Y scales of the first SVG element found in the
|
|
5014
|
+
* Returns an array of the X and Y scales of the first SVG element found in the elements array.
|
|
5136
5015
|
* @returns {Array<number>} An array containing the X and Y scales of the SVG element.
|
|
5137
5016
|
*/
|
|
5138
5017
|
GetSVGScaler() {
|
|
@@ -5142,7 +5021,7 @@ class HeatMap {
|
|
|
5142
5021
|
|
|
5143
5022
|
// but first, are we even in an svg that can be scaled?
|
|
5144
5023
|
let isSvg = false;
|
|
5145
|
-
let element = this.
|
|
5024
|
+
let element = this.elements[0]; // a random start, may as well be the first
|
|
5146
5025
|
while (element) {
|
|
5147
5026
|
if (element.tagName.toLowerCase() == 'body') {
|
|
5148
5027
|
break;
|
|
@@ -5154,7 +5033,7 @@ class HeatMap {
|
|
|
5154
5033
|
}
|
|
5155
5034
|
|
|
5156
5035
|
if (isSvg) {
|
|
5157
|
-
let element = this.
|
|
5036
|
+
let element = this.elements[0]; // a random start, may as well be the first
|
|
5158
5037
|
while (element) {
|
|
5159
5038
|
if (element.tagName.toLowerCase() == 'body') {
|
|
5160
5039
|
break;
|
|
@@ -5186,7 +5065,7 @@ class HeatMap {
|
|
|
5186
5065
|
* @returns {number} The sum of squared values of the RGB color.
|
|
5187
5066
|
*/
|
|
5188
5067
|
getRGBNorm(i) {
|
|
5189
|
-
let rgb_string = this.
|
|
5068
|
+
let rgb_string = this.elements[i].getAttribute('fill');
|
|
5190
5069
|
let rgb_array = rgb_string.slice(4, -1).split(',');
|
|
5191
5070
|
// just get the sum of squared value of rgb, similar without sqrt, save computation
|
|
5192
5071
|
return rgb_array
|
|
@@ -5344,10 +5223,10 @@ class HeatMapRect {
|
|
|
5344
5223
|
this.x = plot.x_coord[position.x];
|
|
5345
5224
|
this.y = plot.y_coord[position.y];
|
|
5346
5225
|
// find which square we're on by searching for the x and y coordinates
|
|
5347
|
-
for (let i = 0; i < plot.
|
|
5226
|
+
for (let i = 0; i < plot.elements.length; i++) {
|
|
5348
5227
|
if (
|
|
5349
|
-
plot.
|
|
5350
|
-
plot.
|
|
5228
|
+
plot.elements[i].getAttribute('x') == this.x &&
|
|
5229
|
+
plot.elements[i].getAttribute('y') == this.y
|
|
5351
5230
|
) {
|
|
5352
5231
|
this.squareIndex = i;
|
|
5353
5232
|
break;
|
|
@@ -5375,7 +5254,7 @@ class HeatMapRect {
|
|
|
5375
5254
|
rect.setAttribute('stroke', constants.colorSelected);
|
|
5376
5255
|
rect.setAttribute('stroke-width', this.rectStrokeWidth);
|
|
5377
5256
|
rect.setAttribute('fill', 'none');
|
|
5378
|
-
plot.
|
|
5257
|
+
plot.elements[this.squareIndex].parentNode.appendChild(rect);
|
|
5379
5258
|
//constants.chart.appendChild(rect);
|
|
5380
5259
|
}
|
|
5381
5260
|
}
|
|
@@ -5391,87 +5270,12 @@ class ScatterPlot {
|
|
|
5391
5270
|
*/
|
|
5392
5271
|
constructor() {
|
|
5393
5272
|
this.prefix = this.GetPrefix();
|
|
5394
|
-
// this.SetVisualHighlight();
|
|
5395
5273
|
this.SetScatterLayer();
|
|
5396
5274
|
this.SetLineLayer();
|
|
5397
5275
|
this.SetAxes();
|
|
5398
5276
|
this.svgScaler = this.GetSVGScaler();
|
|
5399
5277
|
}
|
|
5400
5278
|
|
|
5401
|
-
// SetVisualHighlight() {
|
|
5402
|
-
// let point_index = this.GetElementIndex('point');
|
|
5403
|
-
// let smooth_index = this.GetElementIndex('smooth');
|
|
5404
|
-
// if (point_index && smooth_index && elements < 2) {
|
|
5405
|
-
// logError.LogAbsentElement('point or/and smooth line elements');
|
|
5406
|
-
// }
|
|
5407
|
-
// if (point_index != -1) {
|
|
5408
|
-
// this.CheckData(point_index);
|
|
5409
|
-
// }
|
|
5410
|
-
|
|
5411
|
-
// if (smooth_index != -1) {
|
|
5412
|
-
// this.CheckData(smooth_index);
|
|
5413
|
-
// }
|
|
5414
|
-
// }
|
|
5415
|
-
|
|
5416
|
-
// CheckData(i) {
|
|
5417
|
-
// let elements = 'elements' in singleMaidr ? singleMaidr.elements : null;
|
|
5418
|
-
|
|
5419
|
-
// // elements does not exist at all
|
|
5420
|
-
// if (elements == null) {
|
|
5421
|
-
// logError.LogAbsentElement('elements');
|
|
5422
|
-
// if (i == 0) constants.hasRect = 0;
|
|
5423
|
-
// if (i == 1) constants.hasSmooth = 0;
|
|
5424
|
-
// return;
|
|
5425
|
-
// }
|
|
5426
|
-
|
|
5427
|
-
// // elements exists but is empty
|
|
5428
|
-
// if (elements.length == 0) {
|
|
5429
|
-
// logError.LogAbsentElement('elements');
|
|
5430
|
-
// if (i == 0) constants.hasRect = 0;
|
|
5431
|
-
// if (i == 1) constants.hasSmooth = 0;
|
|
5432
|
-
// return;
|
|
5433
|
-
// }
|
|
5434
|
-
|
|
5435
|
-
// // elements exists but is not an array
|
|
5436
|
-
// if (!Array.isArray(elements)) {
|
|
5437
|
-
// logError.LogNotArray('elements');
|
|
5438
|
-
// if (i == 0) constants.hasRect = 0;
|
|
5439
|
-
// if (i == 1) constants.hasSmooth = 0;
|
|
5440
|
-
// return;
|
|
5441
|
-
// }
|
|
5442
|
-
|
|
5443
|
-
// // elements.length is more than 2
|
|
5444
|
-
// if (elements.length > 2) {
|
|
5445
|
-
// logError.LogTooManyElements('elements', 2);
|
|
5446
|
-
// }
|
|
5447
|
-
|
|
5448
|
-
// if ('data' in singleMaidr) {
|
|
5449
|
-
// if (i == 0) {
|
|
5450
|
-
// // check point elements
|
|
5451
|
-
// if (
|
|
5452
|
-
// singleMaidr.data[i] == null ||
|
|
5453
|
-
// singleMaidr.data[i].length != singleMaidr.elements[i].length
|
|
5454
|
-
// ) {
|
|
5455
|
-
// constants.hasRect = 0;
|
|
5456
|
-
// logError.LogDifferentLengths('point data', 'point elements');
|
|
5457
|
-
// }
|
|
5458
|
-
// } else if (i == 1) {
|
|
5459
|
-
// // check smooth line elements
|
|
5460
|
-
// if (
|
|
5461
|
-
// singleMaidr.data[i] == null ||
|
|
5462
|
-
// (!Array.isArray(singleMaidr.data[i]) &&
|
|
5463
|
-
// singleMaidr.data[i].length != this.chartLineX.length)
|
|
5464
|
-
// ) {
|
|
5465
|
-
// constants.hasSmooth = 0;
|
|
5466
|
-
// logError.LogDifferentLengths(
|
|
5467
|
-
// 'smooth line data',
|
|
5468
|
-
// 'smooth line elements'
|
|
5469
|
-
// );
|
|
5470
|
-
// }
|
|
5471
|
-
// }
|
|
5472
|
-
// }
|
|
5473
|
-
// }
|
|
5474
|
-
|
|
5475
5279
|
/**
|
|
5476
5280
|
* Sets the x and y group labels and title for the scatterplot based on the data in singleMaidr.
|
|
5477
5281
|
*/
|
|
@@ -5517,28 +5321,34 @@ class ScatterPlot {
|
|
|
5517
5321
|
*/
|
|
5518
5322
|
SetScatterLayer() {
|
|
5519
5323
|
// initially set as smooth layer (layer 2), if possible
|
|
5520
|
-
let elIndex = this.GetElementIndex('point');
|
|
5324
|
+
let elIndex = this.GetElementIndex('point'); // check if we have it
|
|
5521
5325
|
if (elIndex != -1) {
|
|
5522
|
-
|
|
5523
|
-
|
|
5524
|
-
|
|
5326
|
+
if ('selector' in singleMaidr) {
|
|
5327
|
+
this.plotPoints = document.querySelectorAll(
|
|
5328
|
+
singleMaidr.selector[elIndex]
|
|
5329
|
+
);
|
|
5330
|
+
} else if ('elements' in singleMaidr) {
|
|
5331
|
+
this.plotPoints = singleMaidr.elements[elIndex];
|
|
5332
|
+
}
|
|
5525
5333
|
} else if (singleMaidr.type == 'point') {
|
|
5526
|
-
|
|
5334
|
+
if ('selector' in singleMaidr) {
|
|
5335
|
+
this.plotPoints = document.querySelectorAll(singleMaidr.selector);
|
|
5336
|
+
} else if ('elements' in singleMaidr) {
|
|
5337
|
+
this.plotPoints = singleMaidr.elements;
|
|
5338
|
+
}
|
|
5527
5339
|
}
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
let pointValues = this.GetPointValues();
|
|
5340
|
+
let svgPointCoords = this.GetSvgPointCoords();
|
|
5341
|
+
let pointValues = this.GetPointValues();
|
|
5531
5342
|
|
|
5532
|
-
|
|
5533
|
-
|
|
5343
|
+
this.chartPointsX = svgPointCoords[0]; // x coordinates of points
|
|
5344
|
+
this.chartPointsY = svgPointCoords[1]; // y coordinates of points
|
|
5534
5345
|
|
|
5535
|
-
|
|
5536
|
-
|
|
5346
|
+
this.x = pointValues[0]; // actual values of x
|
|
5347
|
+
this.y = pointValues[1]; // actual values of y
|
|
5537
5348
|
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
}
|
|
5349
|
+
// for sound weight use
|
|
5350
|
+
this.points_count = pointValues[2]; // number of each points
|
|
5351
|
+
this.max_count = pointValues[3];
|
|
5542
5352
|
}
|
|
5543
5353
|
|
|
5544
5354
|
/**
|
|
@@ -5546,28 +5356,34 @@ class ScatterPlot {
|
|
|
5546
5356
|
*/
|
|
5547
5357
|
SetLineLayer() {
|
|
5548
5358
|
// layer = 2, smooth layer (from singleMaidr types)
|
|
5549
|
-
let elIndex = this.GetElementIndex('smooth');
|
|
5359
|
+
let elIndex = this.GetElementIndex('smooth'); // check if we have it
|
|
5550
5360
|
if (elIndex != -1) {
|
|
5551
|
-
|
|
5552
|
-
|
|
5553
|
-
|
|
5361
|
+
if ('selector' in singleMaidr) {
|
|
5362
|
+
this.plotLine = document.querySelectorAll(
|
|
5363
|
+
singleMaidr.selector[elIndex]
|
|
5364
|
+
)[0];
|
|
5365
|
+
} else if ('elements' in singleMaidr) {
|
|
5366
|
+
this.plotLine = singleMaidr.elements[elIndex][0];
|
|
5367
|
+
}
|
|
5554
5368
|
} else if (singleMaidr.type == 'smooth') {
|
|
5555
|
-
|
|
5369
|
+
if ('selector' in singleMaidr) {
|
|
5370
|
+
this.plotLine = document.querySelectorAll(singleMaidr.selector);
|
|
5371
|
+
} else if ('elements' in singleMaidr) {
|
|
5372
|
+
this.plotLine = singleMaidr.elements;
|
|
5373
|
+
}
|
|
5556
5374
|
}
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
let smoothCurvePoints = this.GetSmoothCurvePoints();
|
|
5375
|
+
let svgLineCoords = this.GetSvgLineCoords();
|
|
5376
|
+
let smoothCurvePoints = this.GetSmoothCurvePoints();
|
|
5560
5377
|
|
|
5561
|
-
|
|
5562
|
-
|
|
5378
|
+
this.chartLineX = svgLineCoords[0]; // x coordinates of curve
|
|
5379
|
+
this.chartLineY = svgLineCoords[1]; // y coordinates of curve
|
|
5563
5380
|
|
|
5564
|
-
|
|
5565
|
-
|
|
5381
|
+
this.curveX = smoothCurvePoints[0]; // actual values of x
|
|
5382
|
+
this.curvePoints = smoothCurvePoints[1]; // actual values of y
|
|
5566
5383
|
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
}
|
|
5384
|
+
this.curveMinY = Math.min(...this.curvePoints);
|
|
5385
|
+
this.curveMaxY = Math.max(...this.curvePoints);
|
|
5386
|
+
this.gradient = this.GetGradient();
|
|
5571
5387
|
}
|
|
5572
5388
|
|
|
5573
5389
|
/**
|
|
@@ -5577,13 +5393,33 @@ class ScatterPlot {
|
|
|
5577
5393
|
GetSvgPointCoords() {
|
|
5578
5394
|
let points = new Map();
|
|
5579
5395
|
|
|
5580
|
-
|
|
5581
|
-
let
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
points.
|
|
5585
|
-
|
|
5586
|
-
|
|
5396
|
+
if (this.plotPoints) {
|
|
5397
|
+
for (let i = 0; i < this.plotPoints.length; i++) {
|
|
5398
|
+
let x = parseFloat(this.plotPoints[i].getAttribute(this.prefix + 'x')); // .toFixed(1);
|
|
5399
|
+
let y = parseFloat(this.plotPoints[i].getAttribute(this.prefix + 'y'));
|
|
5400
|
+
if (!points.has(x)) {
|
|
5401
|
+
points.set(x, new Set([y]));
|
|
5402
|
+
} else {
|
|
5403
|
+
points.get(x).add(y);
|
|
5404
|
+
}
|
|
5405
|
+
}
|
|
5406
|
+
} else {
|
|
5407
|
+
// pull from data instead
|
|
5408
|
+
let elIndex = this.GetElementIndex('point');
|
|
5409
|
+
for (let i = 0; i < singleMaidr.data[elIndex].length; i++) {
|
|
5410
|
+
let x;
|
|
5411
|
+
let y;
|
|
5412
|
+
if ('x' in singleMaidr.data[elIndex][i]) {
|
|
5413
|
+
x = singleMaidr.data[elIndex][i]['x'];
|
|
5414
|
+
}
|
|
5415
|
+
if ('y' in singleMaidr.data[elIndex][i]) {
|
|
5416
|
+
y = singleMaidr.data[elIndex][i]['y'];
|
|
5417
|
+
}
|
|
5418
|
+
if (!points.has(x)) {
|
|
5419
|
+
points.set(x, new Set([y]));
|
|
5420
|
+
} else {
|
|
5421
|
+
points.get(x).add(y);
|
|
5422
|
+
}
|
|
5587
5423
|
}
|
|
5588
5424
|
}
|
|
5589
5425
|
|
|
@@ -5649,38 +5485,40 @@ class ScatterPlot {
|
|
|
5649
5485
|
|
|
5650
5486
|
// but first, are we even in an svg that can be scaled?
|
|
5651
5487
|
let isSvg = false;
|
|
5652
|
-
|
|
5653
|
-
while (element) {
|
|
5654
|
-
if (element.tagName.toLowerCase() == 'body') {
|
|
5655
|
-
break;
|
|
5656
|
-
}
|
|
5657
|
-
if (element.tagName && element.tagName.toLowerCase() === 'svg') {
|
|
5658
|
-
isSvg = true;
|
|
5659
|
-
}
|
|
5660
|
-
element = element.parentNode;
|
|
5661
|
-
}
|
|
5662
|
-
|
|
5663
|
-
if (isSvg) {
|
|
5488
|
+
if (this.plotPoints) {
|
|
5664
5489
|
let element = this.plotPoints[0]; // a random start, may as well be the first
|
|
5665
5490
|
while (element) {
|
|
5666
5491
|
if (element.tagName.toLowerCase() == 'body') {
|
|
5667
5492
|
break;
|
|
5668
5493
|
}
|
|
5669
|
-
if (element.
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5494
|
+
if (element.tagName && element.tagName.toLowerCase() === 'svg') {
|
|
5495
|
+
isSvg = true;
|
|
5496
|
+
}
|
|
5497
|
+
element = element.parentNode;
|
|
5498
|
+
}
|
|
5499
|
+
|
|
5500
|
+
if (isSvg) {
|
|
5501
|
+
let element = this.plotPoints[0]; // a random start, may as well be the first
|
|
5502
|
+
while (element) {
|
|
5503
|
+
if (element.tagName.toLowerCase() == 'body') {
|
|
5504
|
+
break;
|
|
5505
|
+
}
|
|
5506
|
+
if (element.getAttribute('transform')) {
|
|
5507
|
+
let transform = element.getAttribute('transform');
|
|
5508
|
+
let match = transform.match(
|
|
5509
|
+
/scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/
|
|
5510
|
+
);
|
|
5511
|
+
if (match) {
|
|
5512
|
+
if (!isNaN(match[1])) {
|
|
5513
|
+
scaleX *= parseFloat(match[1]);
|
|
5514
|
+
}
|
|
5515
|
+
if (!isNaN(match[3])) {
|
|
5516
|
+
scaleY *= parseFloat(match[3]);
|
|
5517
|
+
}
|
|
5680
5518
|
}
|
|
5681
5519
|
}
|
|
5520
|
+
element = element.parentNode;
|
|
5682
5521
|
}
|
|
5683
|
-
element = element.parentNode;
|
|
5684
5522
|
}
|
|
5685
5523
|
}
|
|
5686
5524
|
|
|
@@ -5689,22 +5527,30 @@ class ScatterPlot {
|
|
|
5689
5527
|
|
|
5690
5528
|
/**
|
|
5691
5529
|
* Returns a prefix based on the element type.
|
|
5530
|
+
* This helps manipulate svg stuff, as the attribute info is slightly different depending on svg source
|
|
5692
5531
|
* @returns {string} The prefix.
|
|
5693
5532
|
*/
|
|
5694
5533
|
GetPrefix() {
|
|
5695
5534
|
let pointIndex = this.GetElementIndex('point');
|
|
5696
5535
|
|
|
5697
|
-
let element;
|
|
5536
|
+
let element = null;
|
|
5698
5537
|
if (pointIndex != -1) {
|
|
5699
|
-
|
|
5538
|
+
if ('selector' in singleMaidr) {
|
|
5539
|
+
element = document.querySelectorAll(
|
|
5540
|
+
singleMaidr.selector[pointIndex]
|
|
5541
|
+
)[0];
|
|
5542
|
+
} else if ('elements' in singleMaidr) {
|
|
5543
|
+
element = singleMaidr.elements[pointIndex][0];
|
|
5544
|
+
}
|
|
5700
5545
|
} else if (singleMaidr.type == 'point') {
|
|
5701
|
-
|
|
5546
|
+
if ('selector' in singleMaidr) {
|
|
5547
|
+
element = document.querySelectorAll(singleMaidr.selector)[0];
|
|
5548
|
+
} else if ('elements' in singleMaidr) {
|
|
5549
|
+
element = singleMaidr.elements[0];
|
|
5550
|
+
}
|
|
5702
5551
|
}
|
|
5703
5552
|
let prefix = '';
|
|
5704
|
-
if (
|
|
5705
|
-
'selector' in singleMaidr &&
|
|
5706
|
-
element.tagName.toLowerCase() === 'circle'
|
|
5707
|
-
) {
|
|
5553
|
+
if (element && element.tagName.toLowerCase() === 'circle') {
|
|
5708
5554
|
prefix = 'c';
|
|
5709
5555
|
}
|
|
5710
5556
|
return prefix;
|
|
@@ -5857,20 +5703,32 @@ class ScatterPlot {
|
|
|
5857
5703
|
* @returns {Array<Array<number>>} An array containing two arrays: the x-coordinates and y-coordinates.
|
|
5858
5704
|
*/
|
|
5859
5705
|
GetSvgLineCoords() {
|
|
5860
|
-
|
|
5861
|
-
let
|
|
5862
|
-
let coords = str.split(' ');
|
|
5863
|
-
|
|
5864
|
-
let X = [];
|
|
5865
|
-
let Y = [];
|
|
5706
|
+
let x_points = [];
|
|
5707
|
+
let y_points = [];
|
|
5866
5708
|
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5709
|
+
if (this.plotLine) {
|
|
5710
|
+
// extract all the y coordinates from the point attribute of polyline
|
|
5711
|
+
let str = this.plotLine.getAttribute('points');
|
|
5712
|
+
let coords = str.split(' ');
|
|
5713
|
+
for (let i = 0; i < coords.length; i++) {
|
|
5714
|
+
let coord = coords[i].split(',');
|
|
5715
|
+
x_points.push(parseFloat(coord[0]));
|
|
5716
|
+
y_points.push(parseFloat(coord[1]));
|
|
5717
|
+
}
|
|
5718
|
+
} else {
|
|
5719
|
+
// fetch from data instead
|
|
5720
|
+
let elIndex = this.GetElementIndex('point');
|
|
5721
|
+
for (let i = 0; i < singleMaidr.data[elIndex].length; i++) {
|
|
5722
|
+
if ('x' in singleMaidr.data[elIndex][i]) {
|
|
5723
|
+
x_points.push(singleMaidr.data[elIndex][i]['x']);
|
|
5724
|
+
}
|
|
5725
|
+
if ('y' in singleMaidr.data[elIndex][i]) {
|
|
5726
|
+
y_points.push(singleMaidr.data[elIndex][i]['y']);
|
|
5727
|
+
}
|
|
5728
|
+
}
|
|
5871
5729
|
}
|
|
5872
5730
|
|
|
5873
|
-
return [
|
|
5731
|
+
return [x, y];
|
|
5874
5732
|
}
|
|
5875
5733
|
|
|
5876
5734
|
/**
|
|
@@ -5932,6 +5790,24 @@ class ScatterPlot {
|
|
|
5932
5790
|
|
|
5933
5791
|
return gradients;
|
|
5934
5792
|
}
|
|
5793
|
+
|
|
5794
|
+
/**
|
|
5795
|
+
* Returns whether or not we have elements / selectors for the given type.
|
|
5796
|
+
* @param {string} type - The type of element to check for. eg, 'point' or 'smooth'.
|
|
5797
|
+
* @returns {boolean} - True if we have elements / selectors for the given type, false otherwise.
|
|
5798
|
+
* @function
|
|
5799
|
+
* @memberof scatterplot
|
|
5800
|
+
*/
|
|
5801
|
+
GetRectStatus(type) {
|
|
5802
|
+
let elIndex = this.GetElementIndex(type);
|
|
5803
|
+
if ('selector' in singleMaidr) {
|
|
5804
|
+
return singleMaidr.selector[elIndex] ? true : false;
|
|
5805
|
+
} else if ('elements' in singleMaidr) {
|
|
5806
|
+
return singleMaidr.elements[elIndex] ? true : false;
|
|
5807
|
+
} else {
|
|
5808
|
+
return false;
|
|
5809
|
+
}
|
|
5810
|
+
}
|
|
5935
5811
|
}
|
|
5936
5812
|
|
|
5937
5813
|
/**
|
|
@@ -5950,6 +5826,7 @@ class Layer0Point {
|
|
|
5950
5826
|
this.y = plot.chartPointsY[0];
|
|
5951
5827
|
this.strokeWidth = 1.35;
|
|
5952
5828
|
this.circleIndex = [];
|
|
5829
|
+
this.hasRect = plot.GetRectStatus('point');
|
|
5953
5830
|
}
|
|
5954
5831
|
|
|
5955
5832
|
/**
|
|
@@ -6049,6 +5926,7 @@ class Layer1Point {
|
|
|
6049
5926
|
this.x = plot.chartLineX[0];
|
|
6050
5927
|
this.y = plot.chartLineY[0];
|
|
6051
5928
|
this.strokeWidth = 1.35;
|
|
5929
|
+
this.hasRect = plot.GetRectStatus('point');
|
|
6052
5930
|
}
|
|
6053
5931
|
|
|
6054
5932
|
/**
|
|
@@ -6139,6 +6017,8 @@ class Histogram {
|
|
|
6139
6017
|
this.bars = null;
|
|
6140
6018
|
if ('selector' in singleMaidr) {
|
|
6141
6019
|
this.bars = document.querySelectorAll(singleMaidr.selector);
|
|
6020
|
+
} else if ('elements' in singleMaidr) {
|
|
6021
|
+
this.bars = singleMaidr.elements;
|
|
6142
6022
|
}
|
|
6143
6023
|
|
|
6144
6024
|
// labels (optional)
|
|
@@ -6252,9 +6132,31 @@ class Histogram {
|
|
|
6252
6132
|
if (this.bars) {
|
|
6253
6133
|
this.activeElement = this.bars[position.x];
|
|
6254
6134
|
if (this.activeElement) {
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6135
|
+
// Case where fill is a direct attribute
|
|
6136
|
+
if (this.activeElement.hasAttribute('fill')) {
|
|
6137
|
+
this.activeElementColor = this.activeElement.getAttribute('fill');
|
|
6138
|
+
// Get new color to highlight and replace fill value
|
|
6139
|
+
this.activeElement.setAttribute(
|
|
6140
|
+
'fill',
|
|
6141
|
+
constants.GetBetterColor(this.activeElementColor)
|
|
6142
|
+
);
|
|
6143
|
+
// Case where fill is within the style attribute
|
|
6144
|
+
} else if (
|
|
6145
|
+
this.activeElement.hasAttribute('style') &&
|
|
6146
|
+
this.activeElement.getAttribute('style').indexOf('fill') !== -1
|
|
6147
|
+
) {
|
|
6148
|
+
let styleString = this.activeElement.getAttribute('style');
|
|
6149
|
+
// Extract all style attributes and values
|
|
6150
|
+
let styleArray = constants.GetStyleArrayFromString(styleString);
|
|
6151
|
+
this.activeElementColor = styleArray[styleArray.indexOf('fill') + 1];
|
|
6152
|
+
// Get new color to highlight and replace fill value in style array
|
|
6153
|
+
styleArray[styleArray.indexOf('fill') + 1] = constants.GetBetterColor(
|
|
6154
|
+
this.activeElementColor
|
|
6155
|
+
);
|
|
6156
|
+
// Recreate style string and set style attribute
|
|
6157
|
+
styleString = constants.GetStyleStringFromArray(styleArray);
|
|
6158
|
+
this.activeElement.setAttribute('style', styleString);
|
|
6159
|
+
}
|
|
6258
6160
|
}
|
|
6259
6161
|
}
|
|
6260
6162
|
}
|
|
@@ -6270,8 +6172,21 @@ class Histogram {
|
|
|
6270
6172
|
UnSelectPrevious() {
|
|
6271
6173
|
if (this.activeElement) {
|
|
6272
6174
|
// set fill attribute to the original color
|
|
6273
|
-
this.activeElement.
|
|
6274
|
-
|
|
6175
|
+
if (this.activeElement.hasAttribute('fill')) {
|
|
6176
|
+
this.activeElement.setAttribute('fill', this.activeElementColor);
|
|
6177
|
+
this.activeElement = null;
|
|
6178
|
+
} else if (
|
|
6179
|
+
this.activeElement.hasAttribute('style') &&
|
|
6180
|
+
this.activeElement.getAttribute('style').indexOf('fill') !== -1
|
|
6181
|
+
) {
|
|
6182
|
+
let styleString = this.activeElement.getAttribute('style');
|
|
6183
|
+
let styleArray = constants.GetStyleArrayFromString(styleString);
|
|
6184
|
+
styleArray[styleArray.indexOf('fill') + 1] = this.activeElementColor;
|
|
6185
|
+
// Recreate style string and set style attribute
|
|
6186
|
+
styleString = constants.GetStyleStringFromArray(styleArray);
|
|
6187
|
+
this.activeElement.setAttribute('style', styleString);
|
|
6188
|
+
this.activeElement = null;
|
|
6189
|
+
}
|
|
6275
6190
|
}
|
|
6276
6191
|
}
|
|
6277
6192
|
}
|
|
@@ -6288,57 +6203,7 @@ class LinePlot {
|
|
|
6288
6203
|
constructor() {
|
|
6289
6204
|
this.SetLineLayer();
|
|
6290
6205
|
this.SetAxes();
|
|
6291
|
-
|
|
6292
|
-
let legendX = '';
|
|
6293
|
-
let legendY = '';
|
|
6294
|
-
if ('axes' in singleMaidr) {
|
|
6295
|
-
// legend labels
|
|
6296
|
-
if (singleMaidr.axes.x) {
|
|
6297
|
-
if (singleMaidr.axes.x.label) {
|
|
6298
|
-
if (legendX == '') {
|
|
6299
|
-
legendX = singleMaidr.axes.x.label;
|
|
6300
|
-
}
|
|
6301
|
-
}
|
|
6302
|
-
}
|
|
6303
|
-
if (singleMaidr.axes.y) {
|
|
6304
|
-
if (singleMaidr.axes.y.label) {
|
|
6305
|
-
if (legendY == '') {
|
|
6306
|
-
legendY = singleMaidr.axes.y.label;
|
|
6307
|
-
}
|
|
6308
|
-
}
|
|
6309
|
-
}
|
|
6310
|
-
}
|
|
6311
|
-
|
|
6312
|
-
this.plotLegend = {
|
|
6313
|
-
x: legendX,
|
|
6314
|
-
y: legendY,
|
|
6315
|
-
};
|
|
6316
|
-
|
|
6317
|
-
// title
|
|
6318
|
-
this.title = '';
|
|
6319
|
-
if ('labels' in singleMaidr) {
|
|
6320
|
-
if ('title' in singleMaidr.labels) {
|
|
6321
|
-
this.title = singleMaidr.labels.title;
|
|
6322
|
-
}
|
|
6323
|
-
}
|
|
6324
|
-
if (this.title == '') {
|
|
6325
|
-
if ('title' in singleMaidr) {
|
|
6326
|
-
this.title = singleMaidr.title;
|
|
6327
|
-
}
|
|
6328
|
-
}
|
|
6329
|
-
|
|
6330
|
-
// subtitle
|
|
6331
|
-
if ('labels' in singleMaidr) {
|
|
6332
|
-
if ('subtitle' in singleMaidr.labels) {
|
|
6333
|
-
this.subtitle = singleMaidr.labels.subtitle;
|
|
6334
|
-
}
|
|
6335
|
-
}
|
|
6336
|
-
// caption
|
|
6337
|
-
if ('labels' in singleMaidr) {
|
|
6338
|
-
if ('caption' in singleMaidr.labels) {
|
|
6339
|
-
this.caption = singleMaidr.labels.caption;
|
|
6340
|
-
}
|
|
6341
|
-
}
|
|
6206
|
+
this.UpdateConstants();
|
|
6342
6207
|
}
|
|
6343
6208
|
|
|
6344
6209
|
/**
|
|
@@ -6348,12 +6213,13 @@ class LinePlot {
|
|
|
6348
6213
|
let elements;
|
|
6349
6214
|
if ('selector' in singleMaidr) {
|
|
6350
6215
|
elements = document.querySelectorAll(singleMaidr.selector);
|
|
6216
|
+
} else if ('elements' in singleMaidr) {
|
|
6217
|
+
elements = singleMaidr.elements;
|
|
6351
6218
|
}
|
|
6352
6219
|
|
|
6353
|
-
|
|
6354
|
-
|
|
6220
|
+
if (elements) {
|
|
6221
|
+
this.plotLine = elements[elements.length - 1];
|
|
6355
6222
|
|
|
6356
|
-
if (typeof this.plotLine !== 'undefined') {
|
|
6357
6223
|
let pointCoords = this.GetPointCoords();
|
|
6358
6224
|
let pointValues = this.GetPoints();
|
|
6359
6225
|
|
|
@@ -6365,35 +6231,33 @@ class LinePlot {
|
|
|
6365
6231
|
|
|
6366
6232
|
this.curveMinY = Math.min(...this.pointValuesY);
|
|
6367
6233
|
this.curveMaxY = Math.max(...this.pointValuesY);
|
|
6368
|
-
constants.minX = 0;
|
|
6369
|
-
constants.maxX = this.pointValuesX.length - 1;
|
|
6370
|
-
constants.minY = this.curveMinY;
|
|
6371
|
-
constants.maxY = this.curveMaxY;
|
|
6372
|
-
|
|
6373
|
-
constants.autoPlayRate = Math.min(
|
|
6374
|
-
Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
|
|
6375
|
-
constants.MAX_SPEED
|
|
6376
|
-
);
|
|
6377
|
-
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
6378
|
-
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
6379
|
-
constants.MIN_SPEED = constants.autoPlayRate;
|
|
6380
|
-
}
|
|
6381
|
-
|
|
6382
|
-
// this.gradient = this.GetGradient();
|
|
6383
6234
|
}
|
|
6384
6235
|
}
|
|
6385
6236
|
|
|
6386
6237
|
/**
|
|
6387
|
-
*
|
|
6238
|
+
* Updates the constants for the line plot.
|
|
6239
|
+
* This includes the minimum and maximum x and y values, the autoplay rate, and the default speed.
|
|
6388
6240
|
*/
|
|
6389
|
-
|
|
6241
|
+
UpdateConstants() {
|
|
6390
6242
|
constants.minX = 0;
|
|
6391
|
-
constants.maxX =
|
|
6392
|
-
constants.minY =
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
constants.AUTOPLAY_DURATION / (constants.maxX + 1)
|
|
6243
|
+
constants.maxX = singleMaidr.data.length - 1;
|
|
6244
|
+
constants.minY = singleMaidr.data.reduce(
|
|
6245
|
+
(min, item) => (item.y < min ? item.y : min),
|
|
6246
|
+
singleMaidr.data[0].y
|
|
6396
6247
|
);
|
|
6248
|
+
constants.maxY = singleMaidr.data.reduce(
|
|
6249
|
+
(max, item) => (item.y > max ? item.y : max),
|
|
6250
|
+
singleMaidr.data[0].y
|
|
6251
|
+
);
|
|
6252
|
+
|
|
6253
|
+
constants.autoPlayRate = Math.min(
|
|
6254
|
+
Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
|
|
6255
|
+
constants.MAX_SPEED
|
|
6256
|
+
);
|
|
6257
|
+
constants.DEFAULT_SPEED = constants.autoPlayRate;
|
|
6258
|
+
if (constants.autoPlayRate < constants.MIN_SPEED) {
|
|
6259
|
+
constants.MIN_SPEED = constants.autoPlayRate;
|
|
6260
|
+
}
|
|
6397
6261
|
}
|
|
6398
6262
|
|
|
6399
6263
|
/**
|
|
@@ -6449,46 +6313,60 @@ class LinePlot {
|
|
|
6449
6313
|
}
|
|
6450
6314
|
}
|
|
6451
6315
|
|
|
6452
|
-
// GetGradient() {
|
|
6453
|
-
// let gradients = [];
|
|
6454
|
-
|
|
6455
|
-
// for (let i = 0; i < this.pointValuesY.length - 1; i++) {
|
|
6456
|
-
// let abs_grad = Math.abs(
|
|
6457
|
-
// (this.pointValuesY[i + 1] - this.pointValuesY[i]) /
|
|
6458
|
-
// (this.pointValuesX[i + 1] - this.pointValuesX[i])
|
|
6459
|
-
// ).toFixed(3);
|
|
6460
|
-
// gradients.push(abs_grad);
|
|
6461
|
-
// }
|
|
6462
|
-
|
|
6463
|
-
// gradients.push('end');
|
|
6464
|
-
|
|
6465
|
-
// return gradients;
|
|
6466
|
-
// }
|
|
6467
|
-
|
|
6468
6316
|
/**
|
|
6469
6317
|
* Sets the x and y group labels and title for the line plot based on the axes and title properties of the singleMaidr object.
|
|
6470
6318
|
*/
|
|
6471
6319
|
SetAxes() {
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
this.title = '';
|
|
6320
|
+
let legendX = '';
|
|
6321
|
+
let legendY = '';
|
|
6475
6322
|
if ('axes' in singleMaidr) {
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6323
|
+
// legend labels
|
|
6324
|
+
if (singleMaidr.axes.x) {
|
|
6325
|
+
if (singleMaidr.axes.x.label) {
|
|
6326
|
+
if (legendX == '') {
|
|
6327
|
+
legendX = singleMaidr.axes.x.label;
|
|
6328
|
+
}
|
|
6479
6329
|
}
|
|
6480
6330
|
}
|
|
6481
|
-
if (
|
|
6482
|
-
if (
|
|
6483
|
-
|
|
6331
|
+
if (singleMaidr.axes.y) {
|
|
6332
|
+
if (singleMaidr.axes.y.label) {
|
|
6333
|
+
if (legendY == '') {
|
|
6334
|
+
legendY = singleMaidr.axes.y.label;
|
|
6335
|
+
}
|
|
6484
6336
|
}
|
|
6485
6337
|
}
|
|
6486
6338
|
}
|
|
6487
|
-
|
|
6488
|
-
|
|
6339
|
+
|
|
6340
|
+
this.plotLegend = {
|
|
6341
|
+
x: legendX,
|
|
6342
|
+
y: legendY,
|
|
6343
|
+
};
|
|
6344
|
+
|
|
6345
|
+
// title
|
|
6346
|
+
this.title = '';
|
|
6347
|
+
if ('labels' in singleMaidr) {
|
|
6348
|
+
if ('title' in singleMaidr.labels) {
|
|
6349
|
+
this.title = singleMaidr.labels.title;
|
|
6350
|
+
}
|
|
6351
|
+
}
|
|
6352
|
+
if (this.title == '') {
|
|
6353
|
+
if ('title' in singleMaidr) {
|
|
6489
6354
|
this.title = singleMaidr.title;
|
|
6490
6355
|
}
|
|
6491
6356
|
}
|
|
6357
|
+
|
|
6358
|
+
// subtitle
|
|
6359
|
+
if ('labels' in singleMaidr) {
|
|
6360
|
+
if ('subtitle' in singleMaidr.labels) {
|
|
6361
|
+
this.subtitle = singleMaidr.labels.subtitle;
|
|
6362
|
+
}
|
|
6363
|
+
}
|
|
6364
|
+
// caption
|
|
6365
|
+
if ('labels' in singleMaidr) {
|
|
6366
|
+
if ('caption' in singleMaidr.labels) {
|
|
6367
|
+
this.caption = singleMaidr.labels.caption;
|
|
6368
|
+
}
|
|
6369
|
+
}
|
|
6492
6370
|
}
|
|
6493
6371
|
|
|
6494
6372
|
/**
|
|
@@ -6579,7 +6457,6 @@ class Segmented {
|
|
|
6579
6457
|
*/
|
|
6580
6458
|
constructor() {
|
|
6581
6459
|
// initialize variables level, data, and elements
|
|
6582
|
-
let level = null;
|
|
6583
6460
|
let fill = null;
|
|
6584
6461
|
let data = null;
|
|
6585
6462
|
let elements = null;
|
|
@@ -6587,17 +6464,17 @@ class Segmented {
|
|
|
6587
6464
|
//axes.x.level
|
|
6588
6465
|
if ('x' in singleMaidr.axes) {
|
|
6589
6466
|
if ('level' in singleMaidr.axes.x) {
|
|
6590
|
-
level = singleMaidr.axes.x.level;
|
|
6467
|
+
this.level = singleMaidr.axes.x.level;
|
|
6591
6468
|
}
|
|
6592
6469
|
} else if ('y' in singleMaidr.axes) {
|
|
6593
6470
|
if ('level' in singleMaidr.axes.y) {
|
|
6594
|
-
level = singleMaidr.axes.y.level;
|
|
6471
|
+
this.level = singleMaidr.axes.y.level;
|
|
6595
6472
|
}
|
|
6596
6473
|
}
|
|
6597
6474
|
// axes.fill
|
|
6598
6475
|
if ('fill' in singleMaidr.axes) {
|
|
6599
6476
|
if ('level' in singleMaidr.axes.fill) {
|
|
6600
|
-
fill = singleMaidr.axes.fill.level;
|
|
6477
|
+
this.fill = singleMaidr.axes.fill.level;
|
|
6601
6478
|
}
|
|
6602
6479
|
}
|
|
6603
6480
|
}
|
|
@@ -6606,6 +6483,8 @@ class Segmented {
|
|
|
6606
6483
|
}
|
|
6607
6484
|
if ('selector' in singleMaidr) {
|
|
6608
6485
|
elements = document.querySelectorAll(singleMaidr.selector);
|
|
6486
|
+
} else if ('elements' in singleMaidr) {
|
|
6487
|
+
elements = singleMaidr.elements;
|
|
6609
6488
|
}
|
|
6610
6489
|
|
|
6611
6490
|
// gracefull failure: must have level + fill + data, elements optional
|
|
@@ -6613,9 +6492,10 @@ class Segmented {
|
|
|
6613
6492
|
logError.LogAbsentElement('elements');
|
|
6614
6493
|
constants.hasRect = 0;
|
|
6615
6494
|
}
|
|
6616
|
-
if (
|
|
6617
|
-
this.
|
|
6618
|
-
|
|
6495
|
+
if (data) {
|
|
6496
|
+
if (this.fill) {
|
|
6497
|
+
this.fill = this.fill.reverse(); // typically fill is in reverse order
|
|
6498
|
+
}
|
|
6619
6499
|
let dataAndELements = this.ParseData(data, elements);
|
|
6620
6500
|
this.plotData = dataAndELements[0];
|
|
6621
6501
|
this.elements = dataAndELements[1];
|
|
@@ -6703,7 +6583,12 @@ class Segmented {
|
|
|
6703
6583
|
let plotData = [];
|
|
6704
6584
|
let plotElements = [];
|
|
6705
6585
|
|
|
6706
|
-
if
|
|
6586
|
+
// override and kill elements if not same length as data
|
|
6587
|
+
if (elements) {
|
|
6588
|
+
if (elements.length != data.length) {
|
|
6589
|
+
plotElements = null;
|
|
6590
|
+
}
|
|
6591
|
+
} else {
|
|
6707
6592
|
plotElements = null;
|
|
6708
6593
|
}
|
|
6709
6594
|
|
|
@@ -6733,7 +6618,9 @@ class Segmented {
|
|
|
6733
6618
|
// set actual values
|
|
6734
6619
|
if (data[k].x == this.level[i] && data[k].fill == this.fill[j]) {
|
|
6735
6620
|
plotData[i][j] = data[k].y;
|
|
6736
|
-
|
|
6621
|
+
if (elements) {
|
|
6622
|
+
plotElements[i][j] = elements[k];
|
|
6623
|
+
}
|
|
6737
6624
|
break;
|
|
6738
6625
|
}
|
|
6739
6626
|
}
|
|
@@ -6784,6 +6671,7 @@ class Segmented {
|
|
|
6784
6671
|
if (constants.sonifMode == 'on') {
|
|
6785
6672
|
// we play a run of tones
|
|
6786
6673
|
position.z = 0;
|
|
6674
|
+
constants.KillSepPlay();
|
|
6787
6675
|
constants.sepPlayId = setInterval(
|
|
6788
6676
|
function () {
|
|
6789
6677
|
// play this tone
|
|
@@ -7428,10 +7316,8 @@ class Control {
|
|
|
7428
7316
|
window.position = new Position(-1, plot.plotData.length);
|
|
7429
7317
|
}
|
|
7430
7318
|
let rect;
|
|
7431
|
-
constants.hasRect
|
|
7432
|
-
if ('selector' in singleMaidr) {
|
|
7319
|
+
if (constants.hasRect) {
|
|
7433
7320
|
rect = new BoxplotRect();
|
|
7434
|
-
constants.hasRect = true;
|
|
7435
7321
|
}
|
|
7436
7322
|
let lastPlayed = '';
|
|
7437
7323
|
|
|
@@ -8380,7 +8266,7 @@ class Control {
|
|
|
8380
8266
|
return new Promise((resolve) => setTimeout(resolve, time));
|
|
8381
8267
|
}
|
|
8382
8268
|
|
|
8383
|
-
// helper functions
|
|
8269
|
+
// heat helper functions
|
|
8384
8270
|
function lockPosition() {
|
|
8385
8271
|
// lock to min / max postions
|
|
8386
8272
|
let didLockHappen = false;
|
|
@@ -8783,7 +8669,7 @@ class Control {
|
|
|
8783
8669
|
if (constants.showDisplay) {
|
|
8784
8670
|
display.displayValues();
|
|
8785
8671
|
}
|
|
8786
|
-
if (
|
|
8672
|
+
if (layer0Point.hasRect) {
|
|
8787
8673
|
layer0Point.UpdatePointDisplay();
|
|
8788
8674
|
}
|
|
8789
8675
|
if (constants.sonifMode != 'off') {
|
|
@@ -8796,9 +8682,9 @@ class Control {
|
|
|
8796
8682
|
display.displayValues();
|
|
8797
8683
|
}
|
|
8798
8684
|
if (constants.showRect) {
|
|
8799
|
-
if (constants.chartType == 'point') {
|
|
8685
|
+
if (constants.chartType == 'point' && layer0Point.hasRect) {
|
|
8800
8686
|
layer0Point.UpdatePointDisplay();
|
|
8801
|
-
} else {
|
|
8687
|
+
} else if (constants.chartType == 'smooth' && layer1Point.hasRect) {
|
|
8802
8688
|
layer1Point.UpdatePointDisplay();
|
|
8803
8689
|
}
|
|
8804
8690
|
}
|
|
@@ -8813,7 +8699,7 @@ class Control {
|
|
|
8813
8699
|
if (constants.showDisplayInBraille) {
|
|
8814
8700
|
display.displayValues();
|
|
8815
8701
|
}
|
|
8816
|
-
if (
|
|
8702
|
+
if (layer1Point.hasRect) {
|
|
8817
8703
|
layer1Point.UpdatePointDisplay();
|
|
8818
8704
|
}
|
|
8819
8705
|
if (constants.sonifMode != 'off') {
|