maidr 1.0.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.
Files changed (206) hide show
  1. package/.Rbuildignore +1 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.json +6 -0
  4. package/.github/workflows/build.yml +20 -0
  5. package/.prettierignore +3 -0
  6. package/.prettierrc.json +7 -0
  7. package/.vscode/extensions.json +25 -0
  8. package/.vscode/settings.json +30 -0
  9. package/.vscode/tasks.json +57 -0
  10. package/CHANGELOG.md +7 -0
  11. package/CITATION.cff +21 -0
  12. package/CONTRIBUTING.md +87 -0
  13. package/LICENSE.md +595 -0
  14. package/README.md +341 -0
  15. package/dist/maidr.js +8851 -0
  16. package/dist/maidr.min.js +1 -0
  17. package/dist/styles.css +244 -0
  18. package/dist/styles.min.css +1 -0
  19. package/docs/Audio.html +1398 -0
  20. package/docs/Constants.html +256 -0
  21. package/docs/Description.html +582 -0
  22. package/docs/Helper.html +364 -0
  23. package/docs/LogError.html +905 -0
  24. package/docs/Menu.html +665 -0
  25. package/docs/Position.html +174 -0
  26. package/docs/Resources.html +338 -0
  27. package/docs/Review.html +333 -0
  28. package/docs/Tracker.html +965 -0
  29. package/docs/audio.js.html +635 -0
  30. package/docs/constants.js.html +1242 -0
  31. package/docs/display.js.html +1184 -0
  32. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  33. package/docs/fonts/OpenSans-Bold-webfont.svg +1830 -0
  34. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  35. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  36. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +1830 -0
  37. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  38. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  39. package/docs/fonts/OpenSans-Italic-webfont.svg +1830 -0
  40. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  41. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  42. package/docs/fonts/OpenSans-Light-webfont.svg +1831 -0
  43. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  44. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  45. package/docs/fonts/OpenSans-LightItalic-webfont.svg +1835 -0
  46. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  47. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  48. package/docs/fonts/OpenSans-Regular-webfont.svg +1831 -0
  49. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  50. package/docs/fonts/OpenSans-Semibold-webfont.eot +0 -0
  51. package/docs/fonts/OpenSans-Semibold-webfont.svg +1830 -0
  52. package/docs/fonts/OpenSans-Semibold-webfont.ttf +0 -0
  53. package/docs/fonts/OpenSans-Semibold-webfont.woff +0 -0
  54. package/docs/fonts/OpenSans-SemiboldItalic-webfont.eot +0 -0
  55. package/docs/fonts/OpenSans-SemiboldItalic-webfont.svg +1830 -0
  56. package/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf +0 -0
  57. package/docs/fonts/OpenSans-SemiboldItalic-webfont.woff +0 -0
  58. package/docs/index.html +66 -0
  59. package/docs/scripts/linenumber.js +25 -0
  60. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  61. package/docs/scripts/prettify/lang-css.js +2 -0
  62. package/docs/scripts/prettify/prettify.js +28 -0
  63. package/docs/styles/jsdoc-default.css +692 -0
  64. package/docs/styles/prettify-jsdoc.css +111 -0
  65. package/docs/styles/prettify-tomorrow.css +132 -0
  66. package/examples/dev_charts/barplot.html +1056 -0
  67. package/examples/dev_charts/boxplot.html +1856 -0
  68. package/examples/dev_charts/boxplot_flipped.svg +727 -0
  69. package/examples/dev_charts/heatmap.html +1217 -0
  70. package/examples/dev_charts/scatterplot/displ.js +18 -0
  71. package/examples/dev_charts/scatterplot/histogram_for_residual.svg +595 -0
  72. package/examples/dev_charts/scatterplot/hwy.js +15 -0
  73. package/examples/dev_charts/scatterplot/layers/point_layer.json +938 -0
  74. package/examples/dev_charts/scatterplot/layers/smooth_layer.json +322 -0
  75. package/examples/dev_charts/scatterplot/point_layer.js +938 -0
  76. package/examples/dev_charts/scatterplot/prediction_array.js +31 -0
  77. package/examples/dev_charts/scatterplot/prediction_array.json +31 -0
  78. package/examples/dev_charts/scatterplot/residual_array.js +29 -0
  79. package/examples/dev_charts/scatterplot/residual_array.json +29 -0
  80. package/examples/dev_charts/scatterplot/scatterplot.svg +1428 -0
  81. package/examples/dev_charts/scatterplot/scatterplot_data.html +2838 -0
  82. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_point_only.svg +1393 -0
  83. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_bestfit.svg +1424 -0
  84. package/examples/dev_charts/scatterplot/scatterplot_no_jitter_with_loess_curve.svg +1402 -0
  85. package/examples/dev_charts/scatterplot/smooth_layer.js +322 -0
  86. package/examples/dev_charts/scatterplot.html +4560 -0
  87. package/examples/dodged_bar/dodged_bar.png +0 -0
  88. package/examples/dodged_bar/dodged_bar.svg +198 -0
  89. package/examples/dodged_bar/schema.json +41 -0
  90. package/examples/histogram/histogram_tutorial.svg +482 -0
  91. package/examples/histogram/histogram_tutorial_raw_data.json +362 -0
  92. package/examples/histogram/histogram_user_study.svg +578 -0
  93. package/examples/histogram/histogram_user_study_raw_data.json +362 -0
  94. package/examples/lineplot/lineplot_sample.svg +126 -0
  95. package/examples/lineplot/lineplot_sample_raw_data.json +1 -0
  96. package/examples/lineplot/point+lineplot_sample.svg +700 -0
  97. package/examples/other/audio_oscillator_boxplot.js +95 -0
  98. package/examples/other/barplot_labels.svg +314 -0
  99. package/examples/other/barplot_user_study.svg +313 -0
  100. package/examples/other/boxplot.html +927 -0
  101. package/examples/other/boxplot_data_frame.html +568 -0
  102. package/examples/other/boxplot_label.svg +751 -0
  103. package/examples/other/braille-display_boxplot.js +79 -0
  104. package/examples/other/control_boxplot.js +55 -0
  105. package/examples/other/draft.js +56 -0
  106. package/examples/other/getData.html +400 -0
  107. package/examples/other/getData.js +41 -0
  108. package/examples/other/ggplot_to_svg.R +371 -0
  109. package/examples/other/heatmap.svg +582 -0
  110. package/examples/other/heatmap_label.svg +608 -0
  111. package/examples/other/multiple_barplot.html +2250 -0
  112. package/examples/other/new_scatterplot_user_study_point_layer.json +122 -0
  113. package/examples/other/py_binder_output.html +1167 -0
  114. package/examples/other/scatterplot_label.svg +1429 -0
  115. package/examples/other/seaborn_plot.py +9 -0
  116. package/examples/other/svglite_bar.svg +136 -0
  117. package/examples/other/tutorial_boxplot.svg +727 -0
  118. package/examples/other/tutorial_boxplot_data.json +72 -0
  119. package/examples/other/user_study_boxplot.svg +676 -0
  120. package/examples/stacked_bar/schema.json +41 -0
  121. package/examples/stacked_bar/stack_bar.png +0 -0
  122. package/examples/stacked_bar/stacked_bar.svg +180 -0
  123. package/examples/stacked_normalized_bar/stacked_normalized_bar.png +0 -0
  124. package/examples/stacked_normalized_bar/stacked_normalized_bar.svg +189 -0
  125. package/examples/static/barplot.svg +263 -0
  126. package/examples/static/barplot_diamonds_gridSVG.svg +254 -0
  127. package/examples/static/boxplot.svg +424 -0
  128. package/examples/static/heatmap.svg +373 -0
  129. package/examples/static/heatmap_penguins_table.html +486 -0
  130. package/examples/static/scatterplot.svg +530 -0
  131. package/examples/svglite/task_heatmap.html +802 -0
  132. package/examples/svglite/task_heatmap.svg +111 -0
  133. package/examples/svglite/tutorial_bar.svg +136 -0
  134. package/examples/svglite/tutorial_bar_plot.html +504 -0
  135. package/examples/svglite/tutorial_boxplot.html +1850 -0
  136. package/examples/svglite/tutorial_boxplot.svg +727 -0
  137. package/examples/svglite/tutorial_scatterplot.html +3135 -0
  138. package/examples/svglite/tutorial_scatterplot.svg +311 -0
  139. package/gulpfile.js +49 -0
  140. package/index.html +40 -0
  141. package/jsconfig.json +10 -0
  142. package/jsdoc.json +19 -0
  143. package/package.json +47 -0
  144. package/src/css/styles.css +241 -0
  145. package/src/js/__tests__/audio.test.js +49 -0
  146. package/src/js/__tests__/constants.test.js +622 -0
  147. package/src/js/audio.js +575 -0
  148. package/src/js/barplot.js +254 -0
  149. package/src/js/boxplot.js +682 -0
  150. package/src/js/constants.js +1182 -0
  151. package/src/js/controls.js +3182 -0
  152. package/src/js/display.js +1124 -0
  153. package/src/js/heatmap.js +411 -0
  154. package/src/js/histogram.js +134 -0
  155. package/src/js/init.js +427 -0
  156. package/src/js/lineplot.js +219 -0
  157. package/src/js/scatterplot.js +619 -0
  158. package/src/js/segmented.js +268 -0
  159. package/user_study_pilot/binder_test.html +526 -0
  160. package/user_study_pilot/data/barplot_user_study.svg +492 -0
  161. package/user_study_pilot/data/barplot_user_study_raw_data.json +22 -0
  162. package/user_study_pilot/data/boxplot_tutorial.json +72 -0
  163. package/user_study_pilot/data/boxplot_tutorial_horizontal.svg +727 -0
  164. package/user_study_pilot/data/boxplot_user_study.json +52 -0
  165. package/user_study_pilot/data/boxplot_user_study_vertical.svg +675 -0
  166. package/user_study_pilot/data/boxplot_user_study_vertical_horizontal.svg +676 -0
  167. package/user_study_pilot/data/heatmap_user_study.svg +719 -0
  168. package/user_study_pilot/data/heatmap_user_study_raw_data.json +127 -0
  169. package/user_study_pilot/data/new_barplot_user_study.svg +269 -0
  170. package/user_study_pilot/data/new_heatmap_user_study.svg +367 -0
  171. package/user_study_pilot/data/new_scatterplot_user_study.svg +603 -0
  172. package/user_study_pilot/data/new_scatterplot_user_study_point_layer.json +122 -0
  173. package/user_study_pilot/data/scatterplot_user_study (1).svg +321 -0
  174. package/user_study_pilot/data/scatterplot_user_study.svg +603 -0
  175. package/user_study_pilot/data/scatterplot_user_study_point_layer.json +122 -0
  176. package/user_study_pilot/data/scatterplot_user_study_smooth_layer.json +322 -0
  177. package/user_study_pilot/intro.html +215 -0
  178. package/user_study_pilot/jaws_settings/Chrome.JDF +10 -0
  179. package/user_study_pilot/jaws_settings/Firefox.JDF +10 -0
  180. package/user_study_pilot/jaws_settings/backup_utf8/Chrome.JDF +10 -0
  181. package/user_study_pilot/jaws_settings/backup_utf8/Firefox.JDF +10 -0
  182. package/user_study_pilot/jaws_settings/backup_utf8/msedge.JDF +10 -0
  183. package/user_study_pilot/jaws_settings/msedge.JDF +10 -0
  184. package/user_study_pilot/nvda_settings/chrome.dic +10 -0
  185. package/user_study_pilot/nvda_settings/default.dic +10 -0
  186. package/user_study_pilot/nvda_settings/firefox.dic +10 -0
  187. package/user_study_pilot/nvda_settings/msedge.dic +10 -0
  188. package/user_study_pilot/scatterplot.html +4560 -0
  189. package/user_study_pilot/seaborn_test.html +1059 -0
  190. package/user_study_pilot/svglite_test.html +534 -0
  191. package/user_study_pilot/task1_bar_plot.html +1111 -0
  192. package/user_study_pilot/task2_heatmap.html +1661 -0
  193. package/user_study_pilot/task3_boxplot_horizontal.html +1690 -0
  194. package/user_study_pilot/task3_boxplot_vertical.html +1689 -0
  195. package/user_study_pilot/task4_scatterplot.html +2091 -0
  196. package/user_study_pilot/tutorial1_bar_plot.html +1159 -0
  197. package/user_study_pilot/tutorial2_heatmap.html +1276 -0
  198. package/user_study_pilot/tutorial3_boxplot_horizontal.html +1861 -0
  199. package/user_study_pilot/tutorial3_boxplot_vertical.html +1807 -0
  200. package/user_study_pilot/tutorial4_scatterplot.html +5893 -0
  201. package/user_study_pilot/tutorial5_histogram.html +1553 -0
  202. package/user_study_pilot/tutorial6_lineplot.html +1011 -0
  203. package/user_study_pilot/tutorial7_stacked.html +763 -0
  204. package/user_study_pilot/tutorial8_stacked_normalized.html +796 -0
  205. package/user_study_pilot/tutorial9_dodged_bar.html +831 -0
  206. package/user_study_pilot/voiceover_settings/user_study_VoiceOver Archive.voprefs +573 -0
@@ -0,0 +1,411 @@
1
+ class HeatMap {
2
+ constructor() {
3
+ // initialize variables xlevel, data, and elements
4
+ let xlevel = null;
5
+ let ylevel = null;
6
+ if ('axes' in singleMaidr) {
7
+ if (singleMaidr.axes.x) {
8
+ if (singleMaidr.axes.x.level) {
9
+ xlevel = singleMaidr.axes.x.level;
10
+ }
11
+ }
12
+ if (singleMaidr.axes.y) {
13
+ if (singleMaidr.axes.y.level) {
14
+ ylevel = singleMaidr.axes.y.level;
15
+ }
16
+ }
17
+ }
18
+ let data = null;
19
+ let dataLength = 0;
20
+ if ('data' in singleMaidr) {
21
+ data = singleMaidr.data;
22
+ for (let i = 0; i < data.length; i++) {
23
+ dataLength += data[i].length;
24
+ }
25
+ }
26
+ let elements = null;
27
+ if ('elements' in singleMaidr) {
28
+ elements = singleMaidr.elements;
29
+ }
30
+
31
+ // if (xlevel && ylevel && data && elements) {
32
+ // if (elements.length != dataLength) {
33
+ // // I didn't throw an error but give a warning
34
+ // constants.hasRect = 0;
35
+ // logError.LogDifferentLengths('data', 'elements');
36
+ // } else if (ylevel.length != data.length) {
37
+ // constants.hasRect = 0;
38
+ // logError.logDifferentLengths('y level', 'rows');
39
+ // } else if (data[0].length != xlevel.length) {
40
+ // constants.hasRect = 0;
41
+ // logError.logDifferentLengths('x level', 'columns');
42
+ // } else {
43
+ // this.plots = elements;
44
+ // constants.hasRect = 1;
45
+ // }
46
+ // } else if (ylevel && data && elements) {
47
+ // if (dataLength != elements.length) {
48
+ // constants.hasRect = 0;
49
+ // logError.logDifferentLengths('data', 'elements');
50
+ // } else if (ylevel.length != data.length) {
51
+ // constants.hasRect = 0;
52
+ // logError.logDifferentLengths('y level', 'rows');
53
+ // } else {
54
+ // this.plots = elements;
55
+ // constants.hasRect = 1;
56
+ // }
57
+ // } else if (xlevel && data && elements) {
58
+ // if (dataLength != elements.length) {
59
+ // constants.hasRect = 0;
60
+ // logError.logDifferentLengths('data', 'elements');
61
+ // } else if (xlevel.length != data[0].length) {
62
+ // constants.hasRect = 0;
63
+ // logError.logDifferentLengths('x level', 'columns');
64
+ // } else {
65
+ // this.plots = elements;
66
+ // constants.hasRect = 1;
67
+ // }
68
+ // }
69
+ // else if (xlevel && ylevel && data) {
70
+ // constants.hasRect = 0;
71
+ // if (ylevel.length != data.length) {
72
+ // logError.logDifferentLengths('y level', 'rows');
73
+ // } else if (data[0].length != xlevel.length) {
74
+ // logError.logDifferentLengths('x level', 'columns');
75
+ // }
76
+ // logError.LogAbsentElement('elements');
77
+ // }
78
+ // else if (data && elements) {
79
+ // if (dataLength != elements.length) {
80
+ // constants.hasRect = 0;
81
+ // logError.logDifferentLengths('data', 'elements');
82
+ // } else {
83
+ // this.plots = elements;
84
+ // constants.hasRect = 1;
85
+ // }
86
+ // } else if (data) {
87
+ // constants.hasRect = 0;
88
+ // if (!xlevel) logError.LogAbsentElement('x level');
89
+ // if (!ylevel) logError.LogAbsentElement('y level');
90
+ // if (!elements) logError.LogAbsentElement('elements');
91
+ // }
92
+
93
+ this.plots = maidr.elements;
94
+ constants.hasRect = 1;
95
+
96
+ this.group_labels = this.getGroupLabels();
97
+ // this.x_labels = this.getXLabels();
98
+ // this.y_labels = this.getYLabels();
99
+ this.x_labels = xlevel;
100
+ this.y_labels = ylevel;
101
+ this.title = this.getTitle();
102
+ this.fill = this.getFill();
103
+
104
+ this.plotData = this.getHeatMapData();
105
+ this.updateConstants();
106
+
107
+ this.x_coord = this.plotData[0];
108
+ this.y_coord = this.plotData[1];
109
+ this.values = this.plotData[2];
110
+ this.num_rows = this.plotData[3];
111
+ this.num_cols = this.plotData[4];
112
+
113
+ this.x_group_label = this.group_labels[0].trim();
114
+ this.y_group_label = this.group_labels[1].trim();
115
+ }
116
+
117
+ getHeatMapData() {
118
+ // get the x_coord and y_coord to check if a square exists at the coordinates
119
+ let x_coord_check = [];
120
+ let y_coord_check = [];
121
+
122
+ let unique_x_coord = [];
123
+ let unique_y_coord = [];
124
+ if (constants.hasRect) {
125
+ for (let i = 0; i < this.plots.length; i++) {
126
+ if (this.plots[i]) {
127
+ x_coord_check.push(parseFloat(this.plots[i].getAttribute('x')));
128
+ y_coord_check.push(parseFloat(this.plots[i].getAttribute('y')));
129
+ }
130
+ }
131
+
132
+ // sort the squares to access from left to right, up to down
133
+ x_coord_check.sort(function (a, b) {
134
+ return a - b;
135
+ }); // ascending
136
+ y_coord_check.sort(function (a, b) {
137
+ return a - b;
138
+ });
139
+
140
+ let svgScaler = this.GetSVGScaler();
141
+ // inverse scale if svg is scaled
142
+ if (svgScaler[0] == -1) {
143
+ x_coord_check = x_coord_check.reverse();
144
+ }
145
+ if (svgScaler[1] == -1) {
146
+ y_coord_check = y_coord_check.reverse();
147
+ }
148
+
149
+ // get unique elements from x_coord and y_coord
150
+ unique_x_coord = [...new Set(x_coord_check)];
151
+ unique_y_coord = [...new Set(y_coord_check)];
152
+ }
153
+
154
+ // get num of rows, num of cols, and total numbers of squares
155
+ let num_rows = 0;
156
+ let num_cols = 0;
157
+ let num_squares = 0;
158
+ if ('data' in singleMaidr) {
159
+ num_rows = singleMaidr.data.length;
160
+ num_cols = singleMaidr.data[0].length;
161
+ } else {
162
+ num_rows = unique_y_coord.length;
163
+ num_cols = unique_x_coord.length;
164
+ }
165
+ num_squares = num_rows * num_cols;
166
+
167
+ let norms = [];
168
+ if ('data' in singleMaidr) {
169
+ norms = [...singleMaidr.data];
170
+ } else {
171
+ norms = Array(num_rows)
172
+ .fill()
173
+ .map(() => Array(num_cols).fill(0));
174
+ let min_norm = 3 * Math.pow(255, 2);
175
+ let max_norm = 0;
176
+
177
+ for (var i = 0; i < this.plots.length; i++) {
178
+ var x_index = unique_x_coord.indexOf(x_coord_check[i]);
179
+ var y_index = unique_y_coord.indexOf(y_coord_check[i]);
180
+ let norm = this.getRGBNorm(i);
181
+ norms[y_index][x_index] = norm;
182
+
183
+ if (norm < min_norm) min_norm = norm;
184
+ if (norm > max_norm) max_norm = norm;
185
+ }
186
+ }
187
+
188
+ let plotData = [unique_x_coord, unique_y_coord, norms, num_rows, num_cols];
189
+
190
+ return plotData;
191
+ }
192
+
193
+ updateConstants() {
194
+ constants.minX = 0;
195
+ constants.maxX = this.plotData[4];
196
+ constants.minY = this.plotData[2][0][0]; // initial val
197
+ constants.maxY = this.plotData[2][0][0]; // initial val
198
+ for (let i = 0; i < this.plotData[2].length; i++) {
199
+ for (let j = 0; j < this.plotData[2][i].length; j++) {
200
+ if (this.plotData[2][i][j] < constants.minY)
201
+ constants.minY = this.plotData[2][i][j];
202
+ if (this.plotData[2][i][j] > constants.maxY)
203
+ constants.maxY = this.plotData[2][i][j];
204
+ }
205
+ }
206
+ constants.autoPlayRate = Math.min(
207
+ Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
208
+ constants.MAX_SPEED
209
+ );
210
+ constants.DEFAULT_SPEED = constants.autoPlayRate;
211
+ if (constants.autoPlayRate < constants.MIN_SPEED) {
212
+ constants.MIN_SPEED = constants.autoPlayRate;
213
+ }
214
+ }
215
+
216
+ PlayTones() {
217
+ audio.playTone();
218
+ }
219
+
220
+ GetSVGScaler() {
221
+ let scaleX = 1;
222
+ let scaleY = 1;
223
+ // start with some square (first), look all the way up the parents to the svg, and record any scales along the way
224
+
225
+ // but first, are we even in an svg that can be scaled?
226
+ let isSvg = false;
227
+ let element = this.plots[0]; // a random start, may as well be the first
228
+ while (element) {
229
+ if (element.tagName.toLowerCase() == 'body') {
230
+ break;
231
+ }
232
+ if (element.tagName && element.tagName.toLowerCase() === 'svg') {
233
+ isSvg = true;
234
+ }
235
+ element = element.parentNode;
236
+ }
237
+
238
+ if (isSvg) {
239
+ let element = this.plots[0]; // a random start, may as well be the first
240
+ while (element) {
241
+ if (element.tagName.toLowerCase() == 'body') {
242
+ break;
243
+ }
244
+ if (element.getAttribute('transform')) {
245
+ let transform = element.getAttribute('transform');
246
+ let match = transform.match(
247
+ /scale\((-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)\)/
248
+ );
249
+ if (match) {
250
+ if (!isNaN(match[1])) {
251
+ scaleX *= parseFloat(match[1]);
252
+ }
253
+ if (!isNaN(match[3])) {
254
+ scaleY *= parseFloat(match[3]);
255
+ }
256
+ }
257
+ }
258
+ element = element.parentNode;
259
+ }
260
+ }
261
+
262
+ return [scaleX, scaleY];
263
+ }
264
+
265
+ getRGBNorm(i) {
266
+ let rgb_string = this.plots[i].getAttribute('fill');
267
+ let rgb_array = rgb_string.slice(4, -1).split(',');
268
+ // just get the sum of squared value of rgb, similar without sqrt, save computation
269
+ return rgb_array
270
+ .map(function (x) {
271
+ return Math.pow(x, 2);
272
+ })
273
+ .reduce(function (a, b) {
274
+ return a + b;
275
+ });
276
+ }
277
+
278
+ getGroupLabels() {
279
+ let labels_nodelist;
280
+ let legendX = '';
281
+ let legendY = '';
282
+
283
+ if ('labels' in singleMaidr) {
284
+ if ('x' in singleMaidr.labels) {
285
+ legendX = singleMaidr.labels.x;
286
+ }
287
+ if ('y' in singleMaidr.labels) {
288
+ legendY = singleMaidr.labels.y;
289
+ }
290
+ }
291
+ if ('axes' in singleMaidr) {
292
+ if ('x' in singleMaidr.axes) {
293
+ if ('label' in singleMaidr.axes.x) {
294
+ if (legendX == '') {
295
+ legendX = singleMaidr.axes.x.label;
296
+ }
297
+ }
298
+ }
299
+ if ('y' in singleMaidr.axes) {
300
+ if ('label' in singleMaidr.axes.y) {
301
+ if (legendY == '') {
302
+ legendY = singleMaidr.axes.y.label;
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+ labels_nodelist = [legendX, legendY];
309
+
310
+ return labels_nodelist;
311
+ }
312
+
313
+ getXLabels() {
314
+ if ('axes' in singleMaidr) {
315
+ if ('x' in singleMaidr.axes) {
316
+ if ('level' in singleMaidr.axes.x) {
317
+ return singleMaidr.axes.x.level;
318
+ }
319
+ }
320
+ }
321
+ }
322
+
323
+ getYLabels() {
324
+ if ('axes' in singleMaidr) {
325
+ if ('y' in singleMaidr.axes) {
326
+ if ('level' in singleMaidr.axes.y) {
327
+ return singleMaidr.axes.y.level;
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ getTitle() {
334
+ if ('title' in singleMaidr) {
335
+ return singleMaidr.title;
336
+ } else if ('labels' in singleMaidr) {
337
+ if ('title' in singleMaidr.labels) {
338
+ return singleMaidr.labels.title;
339
+ }
340
+ }
341
+ }
342
+
343
+ getSubtitle() {
344
+ if ('labels' in singleMaidr) {
345
+ if ('subtitle' in singleMaidr.labels) {
346
+ return singleMaidr.labels.subtitle;
347
+ }
348
+ }
349
+ }
350
+
351
+ getCaption() {
352
+ if ('labels' in singleMaidr) {
353
+ if ('caption' in singleMaidr.labels) {
354
+ return singleMaidr.labels.caption;
355
+ }
356
+ }
357
+ }
358
+
359
+ getFill() {
360
+ if ('labels' in singleMaidr) {
361
+ if ('fill' in singleMaidr.labels) {
362
+ return singleMaidr.labels.fill;
363
+ }
364
+ }
365
+ }
366
+ }
367
+
368
+ class HeatMapRect {
369
+ constructor() {
370
+ if (constants.hasRect) {
371
+ this.x = plot.x_coord[0];
372
+ this.y = plot.y_coord[0];
373
+ this.squareIndex = 0;
374
+ this.rectStrokeWidth = 4; // px
375
+ this.height = Math.abs(plot.y_coord[1] - plot.y_coord[0]);
376
+ }
377
+ }
378
+
379
+ UpdateRect() {
380
+ this.x = plot.x_coord[position.x];
381
+ this.y = plot.y_coord[position.y];
382
+ // find which square we're on by searching for the x and y coordinates
383
+ for (let i = 0; i < plot.plots.length; i++) {
384
+ if (
385
+ plot.plots[i].getAttribute('x') == this.x &&
386
+ plot.plots[i].getAttribute('y') == this.y
387
+ ) {
388
+ this.squareIndex = i;
389
+ break;
390
+ }
391
+ }
392
+ }
393
+
394
+ UpdateRectDisplay() {
395
+ this.UpdateRect();
396
+ if (document.getElementById('highlight_rect'))
397
+ document.getElementById('highlight_rect').remove(); // destroy and recreate
398
+ const svgns = 'http://www.w3.org/2000/svg';
399
+ var rect = document.createElementNS(svgns, 'rect');
400
+ rect.setAttribute('id', 'highlight_rect');
401
+ rect.setAttribute('x', this.x);
402
+ rect.setAttribute('y', this.y);
403
+ rect.setAttribute('width', this.height);
404
+ rect.setAttribute('height', this.height);
405
+ rect.setAttribute('stroke', constants.colorSelected);
406
+ rect.setAttribute('stroke-width', this.rectStrokeWidth);
407
+ rect.setAttribute('fill', 'none');
408
+ plot.plots[this.squareIndex].parentNode.appendChild(rect);
409
+ //constants.chart.appendChild(rect);
410
+ }
411
+ }
@@ -0,0 +1,134 @@
1
+ class Histogram {
2
+ constructor() {
3
+ // initialize main data: data, elements
4
+
5
+ // data (required)
6
+ if ('data' in singleMaidr) {
7
+ this.plotData = singleMaidr.data;
8
+ } else {
9
+ console.log('Error: no data found');
10
+ return;
11
+ }
12
+ // elements (optional)
13
+ this.bars = null;
14
+ if ('elements' in singleMaidr) {
15
+ this.bars = singleMaidr.elements;
16
+ }
17
+
18
+ // labels (optional)
19
+ this.legendX = null;
20
+ this.legendY = null;
21
+ if ('labels' in singleMaidr) {
22
+ if ('x' in singleMaidr.labels) {
23
+ this.legendX = singleMaidr.labels.x;
24
+ }
25
+ if ('y' in singleMaidr.labels) {
26
+ this.legendY = singleMaidr.labels.y;
27
+ }
28
+ }
29
+ if ('axes' in singleMaidr) {
30
+ if ('x' in singleMaidr.axes) {
31
+ if ('label' in singleMaidr.axes.x) {
32
+ if (!this.legendX) {
33
+ this.legendX = singleMaidr.axes.x.label;
34
+ }
35
+ }
36
+ }
37
+ if ('y' in singleMaidr.axes) {
38
+ if ('label' in singleMaidr.axes.y) {
39
+ if (!this.legendY) {
40
+ this.legendY = singleMaidr.axes.y.label;
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ // tick labels: todo, not sure if they'll exist or not
47
+
48
+ // title (optional)
49
+ this.title = '';
50
+ if ('labels' in singleMaidr) {
51
+ if ('title' in singleMaidr.labels) {
52
+ this.title = singleMaidr.labels.title;
53
+ }
54
+ }
55
+ if (this.title == '') {
56
+ if ('title' in singleMaidr) {
57
+ this.title = singleMaidr.title;
58
+ }
59
+ }
60
+
61
+ // title (optional)
62
+ if ('labels' in singleMaidr) {
63
+ if ('subtitle' in singleMaidr.labels) {
64
+ this.subtitle = singleMaidr.labels.subtitle;
65
+ }
66
+ }
67
+ // title (optional)
68
+ if ('labels' in singleMaidr) {
69
+ if ('caption' in singleMaidr.labels) {
70
+ this.caption = singleMaidr.labels.caption;
71
+ }
72
+ }
73
+
74
+ this.SetMaxMin();
75
+
76
+ this.autoplay = null;
77
+ }
78
+
79
+ PlayTones() {
80
+ audio.playTone();
81
+ }
82
+
83
+ SetMaxMin() {
84
+ for (let i = 0; i < this.plotData.length; i++) {
85
+ if (i == 0) {
86
+ constants.maxY = this.plotData[i].y;
87
+ constants.minY = this.plotData[i].y;
88
+ constants.maxX = this.plotData[i].xmax;
89
+ constants.minX = this.plotData[i].xmin;
90
+ } else {
91
+ if (this.plotData[i].y > constants.maxY) {
92
+ constants.maxY = this.plotData[i].y;
93
+ }
94
+ if (this.plotData[i].y < constants.minY) {
95
+ constants.minY = this.plotData[i].y;
96
+ }
97
+ if (this.plotData[i].xmax > constants.maxX) {
98
+ constants.maxX = this.plotData[i].xmax;
99
+ }
100
+ if (this.plotData[i].xmin < constants.minX) {
101
+ constants.minX = this.plotData[i].xmin;
102
+ }
103
+ }
104
+ }
105
+ constants.autoPlayRate = Math.min(
106
+ Math.ceil(constants.AUTOPLAY_DURATION / (constants.maxX + 1)),
107
+ constants.MAX_SPEED
108
+ );
109
+ constants.DEFAULT_SPEED = constants.autoPlayRate;
110
+ if (constants.autoPlayRate < constants.MIN_SPEED) {
111
+ constants.MIN_SPEED = constants.autoPlayRate;
112
+ }
113
+ }
114
+
115
+ Select() {
116
+ this.UnSelectPrevious();
117
+ if (this.bars) {
118
+ this.activeElement = this.bars[position.x];
119
+ if (this.activeElement) {
120
+ this.activeElementColor = this.activeElement.getAttribute('fill');
121
+ let newColor = constants.GetBetterColor(this.activeElementColor);
122
+ this.activeElement.setAttribute('fill', newColor);
123
+ }
124
+ }
125
+ }
126
+
127
+ UnSelectPrevious() {
128
+ if (this.activeElement) {
129
+ // set fill attribute to the original color
130
+ this.activeElement.setAttribute('fill', this.activeElementColor);
131
+ this.activeElement = null;
132
+ }
133
+ }
134
+ }