diff --git a/keyboard_svg.js b/keyboard_svg.js
index 6a23cfb..bc69158 100644
--- a/keyboard_svg.js
+++ b/keyboard_svg.js
@@ -1,13 +1,12 @@
-
const params = new Proxy(new URLSearchParams(window.location.search), {
- get: (searchParams, prop) => searchParams.get(prop),
+ get: (searchParams, prop) => searchParams.get(prop),
});
var url_layout = params.layout;
var swidth = 1000;
var sheight = 180;
const w = 38;
-const inv_w = 1.0 / 38
+const inv_w = 1.0 / 38;
const nb_row = 3;
const nb_columns = 12;
const gap = 8;
@@ -26,247 +25,273 @@ var sh_scroll_amount = 0;
var trigram_scroll_amount = 0;
var green = 128;
var mode = params.mode;
-if (!mode){ mode = "ergo" }
+if (!mode) {
+ mode = "ergo";
+}
var thumb = params.thumb;
-if (!thumb){ thumb = "l" }
+if (!thumb) {
+ thumb = "l";
+}
var lang = "english";
var needs_update = true;
-function scroll(event){
- event.preventDefault();
- //
- const svgRect = el.getBoundingClientRect();
- const mouseX = event.clientX - svgRect.left;
- const mouseY = event.clientY - svgRect.top;
- if (mouseX > 570 && mouseX < 770 && mouseY > 345){
- hw_scroll_amount += Math.sign(event.deltaY);
- if (hw_scroll_amount < 0){hw_scroll_amount = 0;}
- } else if (mouseX > 200 && mouseX < 430 && mouseY > 345){
- sh_scroll_amount += Math.sign(event.deltaY);
- if (sh_scroll_amount < 0){sh_scroll_amount = 0;}
- } else if (mouseX > 780 && mouseX < 970 && mouseY > 345){
- trigram_scroll_amount += Math.sign(event.deltaY);
- if (trigram_scroll_amount < 0){trigram_scroll_amount = 0;}
- } else {
- scroll_amount += Math.sign(event.deltaY);
- if (scroll_amount < 0){scroll_amount = 0;}
- if (scroll_amount > 50){scroll_amount = 50;}
- }
- generatePlots();
+function scroll(event) {
+ event.preventDefault();
+ const svgRect = el.getBoundingClientRect();
+ const mouseX = event.clientX - svgRect.left;
+ const mouseY = event.clientY - svgRect.top;
+ if (mouseX > 570 && mouseX < 770 && mouseY > 345) {
+ hw_scroll_amount += Math.sign(event.deltaY);
+ if (hw_scroll_amount < 0) {
+ hw_scroll_amount = 0;
+ }
+ } else if (mouseX > 200 && mouseX < 430 && mouseY > 345) {
+ sh_scroll_amount += Math.sign(event.deltaY);
+ if (sh_scroll_amount < 0) {
+ sh_scroll_amount = 0;
+ }
+ } else if (mouseX > 780 && mouseX < 970 && mouseY > 345) {
+ trigram_scroll_amount += Math.sign(event.deltaY);
+ if (trigram_scroll_amount < 0) {
+ trigram_scroll_amount = 0;
+ }
+ } else {
+ scroll_amount += Math.sign(event.deltaY);
+ if (scroll_amount < 0) {
+ scroll_amount = 0;
+ }
+ if (scroll_amount > 50) {
+ scroll_amount = 50;
+ }
+ }
+ generatePlots();
}
-var svg = d3.select("#svglayout").append("svg").attr("xmlns","http://www.w3.org/2000/svg").attr("width", swidth).attr("height", sheight);
+var svg = d3
+ .select("#svglayout")
+ .append("svg")
+ .attr("xmlns", "http://www.w3.org/2000/svg")
+ .attr("width", swidth)
+ .attr("height", sheight);
-var stats = d3.select("#svgstats").append("svg").attr("width", swidth).attr("height", 600)
+var stats = d3
+ .select("#svgstats")
+ .append("svg")
+ .attr("width", swidth)
+ .attr("height", 600);
const el = document.querySelector("#svgstats");
el.onwheel = scroll;
-const word_list_url = 'words-'+lang+'.json';
-const dictionary_url = 'dictionary.json';
-const effort_url = 'bigram_effort.json';
+const word_list_url = `words-${lang}.json`;
+const dictionary_url = "dictionary.json";
+const effort_url = "bigram_effort.json";
let words = {};
let dictionary = [];
var dictionaryloaded = false;
var effortloaded = false;
let bigram_effort = {};
-function fetchData(){
- fetch(word_list_url)
- .then(response => response.json())
- .then(data => {
- words = data; // Assign data to the global variable
- console.log("fetchData");
- dataloaded = true;
- needs_update = true;
- })
- .catch(error => console.error('Error loading JSON file:', error));
+function fetchData() {
+ fetch(word_list_url)
+ .then((response) => response.json())
+ .then((data) => {
+ words = data; // (cyanophage) Assign data to the global variable
+ console.log("fetchData");
+ dataloaded = true;
+ needs_update = true;
+ })
+ .catch((error) => console.error("Error loading JSON file:", error));
}
-function fetchDictionary(){
- fetch(dictionary_url)
- .then(response => response.json())
- .then(data => {
- if (data["dictionary"]){
- dictionary = data["dictionary"]; // Assign data to the global variable
- } else {
- console.log("something went wrong with loading the dictionary");
- }
- console.log("fetchDictionary");
- dictionaryloaded = true;
- needs_update = true;
- })
- .catch(error => console.error('Error loading dictionary JSON file:', error));
+
+function fetchDictionary() {
+ fetch(dictionary_url)
+ .then((response) => response.json())
+ .then((data) => {
+ if (data.dictionary) {
+ dictionary = data.dictionary; // (cyanophage) Assign data to the global variable
+ } else {
+ console.log("something went wrong with loading the dictionary");
+ }
+ console.log("fetchDictionary");
+ dictionaryloaded = true;
+ needs_update = true;
+ })
+ .catch((error) =>
+ console.error("Error loading dictionary JSON file:", error),
+ );
}
async function loadAllData() {
- try {
- const [wordsData, dictionaryData, effortData] = await Promise.all([
- fetch(word_list_url).then(response => response.json()),
- fetch(dictionary_url).then(response => response.json()),
- fetch(effort_url).then(response => response.json())
- ]);
-
- // Assign the data to the global variables
- words = wordsData;
- dictionary = dictionaryData.dictionary || [];
- bigram_effort = effortData;
-
- console.log("All data loaded successfully!");
-
- dataloaded = true;
- dictionaryloaded = true;
- effortloaded = true;
- setMode();
- generateCoords();
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
-
- } catch (error) {
- console.error('Error loading data:', error);
- }
+ try {
+ const [wordsData, dictionaryData, effortData] = await Promise.all([
+ fetch(word_list_url).then((response) => response.json()),
+ fetch(dictionary_url).then((response) => response.json()),
+ fetch(effort_url).then((response) => response.json()),
+ ]);
+
+ // (cyanophage) Assign the data to the global variables
+ words = wordsData;
+ dictionary = dictionaryData.dictionary || [];
+ bigram_effort = effortData;
+
+ console.log("All data loaded successfully!");
+
+ dataloaded = true;
+ dictionaryloaded = true;
+ effortloaded = true;
+ setMode();
+ generateCoords();
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
+ } catch (error) {
+ console.error("Error loading data:", error);
+ }
}
function selectLanguage(lan, event) {
- lang = lan
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("lan",lang)
- history.replaceState(null, null, "?"+queryParams.toString());
-
- var word_list = 'words-'+lan+'.json';
- console.log("============ "+lan.toUpperCase()+" ============")
- fetch(word_list)
- .then(response => response.json())
- .then(data => {
- if (event && event.ctrlKey){
- console.log("adding "+lan+" to words")
- for (let word in data) {
- if (words[word]){
- words[word] += data[word]
- } else {
- words[word] = data[word]
- }
- }
- document.getElementById("langDropDown").innerHTML += ("+"+lan.charAt(0).toUpperCase() + lan.substr(1).toLowerCase());
- } else {
- words = data; // Assign data to the global variable
- document.getElementById("langDropDown").innerHTML = lan.charAt(0).toUpperCase() + lan.substr(1).toLowerCase();
- }
- needs_update = true;
- console.log("fetchData");
- dataloaded = true;
- updateRcData(lan);
- setMode();
- getDictionaryFromWords();
- dictionaryloaded = true;
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
- })
- .catch(error => console.error('Error loading JSON file:', error));
+ lang = lan;
+ var queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("lan", lang);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
+
+ var word_list = `words-${lan}.json`;
+ console.log(`============ ${lan.toUpperCase()} ============`);
+ fetch(word_list)
+ .then((response) => response.json())
+ .then((data) => {
+ if (event?.ctrlKey) {
+ console.log(`adding ${lan} to words`);
+ for (const word in data) {
+ if (words[word]) {
+ words[word] += data[word];
+ } else {
+ words[word] = data[word];
+ }
+ }
+ document.getElementById("langDropDown").innerHTML +=
+ `+${lan.charAt(0).toUpperCase()}${lan.substr(1).toLowerCase()}`;
+ } else {
+ words = data; // (cyanophage) Assign data to the global variable
+ document.getElementById("langDropDown").innerHTML =
+ lan.charAt(0).toUpperCase() + lan.substr(1).toLowerCase();
+ }
+ needs_update = true;
+ console.log("fetchData");
+ dataloaded = true;
+ updateRcData(lan);
+ setMode();
+ getDictionaryFromWords();
+ dictionaryloaded = true;
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
+ })
+ .catch((error) => console.error("Error loading JSON file:", error));
}
makeDraggable(svg.node());
// col 0 1 2 3 4 5 6 7 8 9 10 11
var fingerAssignment = [
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10]
- ]
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+];
// var hand = [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2]
// char, row, col, freq, y, x, width, keyname
var rcdata = [
- ["q", 0, 1, 0.06607202, 0, 0, 1, 0],
- ["w", 0, 2, 2.775025, 0, 0, 1, 1],
- ["e", 0, 3, 11.870939, 0, 0, 1, 2],
- ["r", 0, 4, 4.988437, 0, 0, 1, 3],
- ["t", 0, 5, 9.547406, 0, 0, 1, 4],
- ["y", 0, 6, 1.7949564, 0, 0, 1, 5],
- ["u", 0, 7, 2.7419887, 0, 0, 1, 6],
- ["i", 0, 8, 6.177734, 0, 0, 1, 7],
- ["o", 0, 9, 7.6643543, 0, 0, 1, 8],
- ["p", 0, 10, 1.4425724, 0, 0, 1, 9],
- ["-", 0, 11, 0.2753001, 0, 0, 1, 10],
- ["a", 1, 1, 7.466138, 0, 0, 1, 11],
- ["s", 1, 2, 5.5720735, 0, 0, 1, 12],
- ["d", 1, 3, 4.2616453, 0, 0, 1, 13],
- ["f", 1, 4, 2.0482326, 0, 0, 1, 14],
- ["g", 1, 5, 2.2244246, 0, 0, 1, 15],
- ["h", 1, 6, 6.519106, 0, 0, 1, 16],
- ["j", 1, 7, 0.06607202, 0, 0, 1, 17],
- ["k", 1, 8, 1.0571523, 0, 0, 1, 18],
- ["l", 1, 9, 4.6030173, 0, 0, 1, 19],
- [";", 1, 10, 0.4184561, 0, 0, 1, 20],
- ["'", 1, 11, 0.3523841, 0, 0, 1, 21],
- ["z", 2, 1, 0.04404801, 0, 0, 1, 22],
- ["x", 2, 2, 0.07708402, 0, 0, 1, 23],
- ["c", 2, 3, 1.8830525, 0, 0, 1, 24],
- ["v", 2, 4, 0.7488162, 0, 0, 1, 25],
- ["b", 2, 5, 1.5526924, 0, 0, 1, 26],
- ["n", 2, 6, 6.1446977, 0, 0, 1, 27],
- ["m", 2, 7, 1.5857284, 0, 0, 1, 28],
- [",", 2, 8, 1.9601365, 0, 0, 1, 29],
- [".", 2, 9, 0.48452812, 0, 0, 1, 30],
- ["/", 2, 10, 0.14315604, 0, 0, 1, 31],
- ["\\", 2, 0, 0, 0, 0, 1, 32],
- ["^", 3, 4, 0, 0, 0, 1, 33],
- ["tab", 0, 0, 0, 0, 0, 1, 34],
- ["$", 1, 0, 0, 0, 0, 1, 35],
- ["enter", 2, 11, 0, 0, 0, 1, 36],
- ["mod", 3, 5, 0, 0, 0, 1, 37],
- ["back", 3, 6, 0, 0, 0, 1, 38],
- ["space", 3, 7, 0, 0, 0, 1, 39],
-]
-const rcdata_len = rcdata.length // Compute once
+ ["q", 0, 1, 0.06607202, 0, 0, 1, 0],
+ ["w", 0, 2, 2.775025, 0, 0, 1, 1],
+ ["e", 0, 3, 11.870939, 0, 0, 1, 2],
+ ["r", 0, 4, 4.988437, 0, 0, 1, 3],
+ ["t", 0, 5, 9.547406, 0, 0, 1, 4],
+ ["y", 0, 6, 1.7949564, 0, 0, 1, 5],
+ ["u", 0, 7, 2.7419887, 0, 0, 1, 6],
+ ["i", 0, 8, 6.177734, 0, 0, 1, 7],
+ ["o", 0, 9, 7.6643543, 0, 0, 1, 8],
+ ["p", 0, 10, 1.4425724, 0, 0, 1, 9],
+ ["-", 0, 11, 0.2753001, 0, 0, 1, 10],
+ ["a", 1, 1, 7.466138, 0, 0, 1, 11],
+ ["s", 1, 2, 5.5720735, 0, 0, 1, 12],
+ ["d", 1, 3, 4.2616453, 0, 0, 1, 13],
+ ["f", 1, 4, 2.0482326, 0, 0, 1, 14],
+ ["g", 1, 5, 2.2244246, 0, 0, 1, 15],
+ ["h", 1, 6, 6.519106, 0, 0, 1, 16],
+ ["j", 1, 7, 0.06607202, 0, 0, 1, 17],
+ ["k", 1, 8, 1.0571523, 0, 0, 1, 18],
+ ["l", 1, 9, 4.6030173, 0, 0, 1, 19],
+ [";", 1, 10, 0.4184561, 0, 0, 1, 20],
+ ["'", 1, 11, 0.3523841, 0, 0, 1, 21],
+ ["z", 2, 1, 0.04404801, 0, 0, 1, 22],
+ ["x", 2, 2, 0.07708402, 0, 0, 1, 23],
+ ["c", 2, 3, 1.8830525, 0, 0, 1, 24],
+ ["v", 2, 4, 0.7488162, 0, 0, 1, 25],
+ ["b", 2, 5, 1.5526924, 0, 0, 1, 26],
+ ["n", 2, 6, 6.1446977, 0, 0, 1, 27],
+ ["m", 2, 7, 1.5857284, 0, 0, 1, 28],
+ [",", 2, 8, 1.9601365, 0, 0, 1, 29],
+ [".", 2, 9, 0.48452812, 0, 0, 1, 30],
+ ["/", 2, 10, 0.14315604, 0, 0, 1, 31],
+ ["\\", 2, 0, 0, 0, 0, 1, 32],
+ ["^", 3, 4, 0, 0, 0, 1, 33],
+ ["tab", 0, 0, 0, 0, 0, 1, 34],
+ ["$", 1, 0, 0, 0, 0, 1, 35],
+ ["enter", 2, 11, 0, 0, 0, 1, 36],
+ ["mod", 3, 5, 0, 0, 0, 1, 37],
+ ["back", 3, 6, 0, 0, 0, 1, 38],
+ ["space", 3, 7, 0, 0, 0, 1, 39],
+];
+const rcdata_len = rcdata.length;
var effort = [
- [
- 5, // column 0 tab
- 3, // column 1 q
- 2, // column 2 w
- 1, // column 3 e
- 2, // column 4 r
- 7, // column 5 t
- 7, // column 6 y
- 2, // column 7 u
- 1, // column 8 i
- 2, // column 9 o
- 3, // column 10 p
- 5, // column 11 -
- ],
- [
- 5, // column 0 ctrl
- 1, // column 1 a
- 0, // column 2 s
- 0, // column 3 d
- 0, // column 4 f
- 5, // column 5 g
- 5, // column 6 h
- 0, // column 7 j
- 0, // column 8 k
- 0, // column 9 l
- 1, // column 10 ;
- 5, // column 11 '
- ],
- [
- 7, // column 0
- 3, // column 1 z
- 2, // column 2 x
- 2, // column 3 c
- 1, // column 4 v
- 8, // column 5 b
- 8, // column 6 n
- 1, // column 7 m
- 2, // column 8 ,
- 2, // column 9 .
- 3, // column 10 /
- 7, // column 11 enter
- ],
+ [
+ 5, // column 0 tab
+ 3, // column 1 q
+ 2, // column 2 w
+ 1, // column 3 e
+ 2, // column 4 r
+ 7, // column 5 t
+ 7, // column 6 y
+ 2, // column 7 u
+ 1, // column 8 i
+ 2, // column 9 o
+ 3, // column 10 p
+ 5, // column 11 -
+ ],
+ [
+ 5, // column 0 ctrl
+ 1, // column 1 a
+ 0, // column 2 s
+ 0, // column 3 d
+ 0, // column 4 f
+ 5, // column 5 g
+ 5, // column 6 h
+ 0, // column 7 j
+ 0, // column 8 k
+ 0, // column 9 l
+ 1, // column 10 ;
+ 5, // column 11 '
+ ],
+ [
+ 7, // column 0
+ 3, // column 1 z
+ 2, // column 2 x
+ 2, // column 3 c
+ 1, // column 4 v
+ 8, // column 5 b
+ 8, // column 6 n
+ 1, // column 7 m
+ 2, // column 8 ,
+ 2, // column 9 .
+ 3, // column 10 /
+ 7, // column 11 enter
+ ],
];
// var bigram_effort = {
@@ -285,801 +310,1064 @@ var effort = [
// 2 \ z x c v b n m , . /
function openPopup() {
- for (let row = 0; row < nb_row; row++){
- for (let col = 0; col < nb_columns; col++){
- var name = "textInput-" + row + "-" + col
- document.getElementById(name).value = effort[row][col];
- }
- }
- document.getElementById('popup').style.display = 'flex';
+ for (let row = 0; row < nb_row; row++) {
+ for (let col = 0; col < nb_columns; col++) {
+ const name = `textInput-${row}-${col}`;
+ document.getElementById(name).value = effort[row][col];
+ }
+ }
+ document.getElementById("popup").style.display = "flex";
}
function openImportPopup() {
- document.getElementById('importPopup').style.display = 'flex';
+ document.getElementById("importPopup").style.display = "flex";
}
function openCorpusPopup() {
- document.getElementById('corpusPopup').style.display = 'flex';
+ document.getElementById("corpusPopup").style.display = "flex";
}
function deepCopy(arr) {
- return arr.map(item => Array.isArray(item) ? deepCopy(item) : item);
+ return arr.map((item) => (Array.isArray(item) ? deepCopy(item) : item));
}
-function strCount(str,char) {
- for(var count=-1,index=-2; index != -1; count++,index=str.indexOf(char,index+1) );
- return count
+function strCount(str, char) {
+ return str.split(char).length - 1;
}
function closeImportPopup() {
- var importString = document.getElementById('importText').value;
- importString = importString.replace(/\s+/g, '');
- if (importString.length == 0) {
- document.getElementById('importPopup').style.display = 'none';
- return
- }
- if (importString.length == 30){ // probably cmini
- if (strCount(importString,"-")==0 && strCount(importString,"'")==0){
- importString = importString.slice(0, 10) + "-" + importString.slice(10,20) + "'" + importString.slice(20) + "\\^";
- } else if (strCount(importString,"-")==0 && strCount(importString,";")==0 ) {
- importString = importString.slice(0, 10) + "-" + importString.slice(10,20) + ";" + importString.slice(20) + "\\^";
- } else if (strCount(importString,"'")==0 && strCount(importString,";")==0 ) {
- importString = importString.slice(0, 10) + ";" + importString.slice(10,20) + "'" + importString.slice(20) + "\\^";
- } else if (strCount(importString,"'")==0 && strCount(importString,"/")==0 ) {
- importString = importString.slice(0, 10) + "/" + importString.slice(10,20) + "'" + importString.slice(20) + "\\^";
- } else if (strCount(importString,";")==0 && strCount(importString,"/")==0 ) {
- importString = importString.slice(0, 10) + "/" + importString.slice(10,20) + ";" + importString.slice(20) + "\\^";
- } else if (strCount(importString,";")==0 && strCount(importString,"'")==0 ) {
- importString = importString.slice(0, 10) + ";" + importString.slice(10,20) + "'" + importString.slice(20) + "\\^";
- } else if (strCount(importString,"/")==0 && strCount(importString,"-")==0 ) {
- importString = importString.slice(0, 10) + "/" + importString.slice(10,20) + "-" + importString.slice(20) + "\\^";
- } else {
- importString = importString.slice(0, 10) + "+" + importString.slice(10,20) + "*" + importString.slice(20) + "\\^";
- }
- }
- const letters = importString.toUpperCase().match(/[A-Z\.\,\/\-\'\;]/g) || [];
- // Count occurrences of each letter
- const letterCount = {};
- letters.forEach(letter => {
- letterCount[letter] = (letterCount[letter] || 0) + 1;
- });
- const allLetters = Array.from({length: 26}, (_, i) => String.fromCharCode(65 + i)).concat(['.', ',',';','/','-','\'']);
- const missing = allLetters.filter(letter => !letterCount[letter]);
- const duplicates = Object.keys(letterCount).filter(letter => letterCount[letter] > 1);
- var message = ""
- if (missing.length > 0){
- message = message + "These letters are missing: "+missing.join(" ")+"\n"
- }
- if (duplicates.length > 0){
- message = message + "These letters are duplicated: "+duplicates.join(" ")+"\n"
- }
- if (message.length > 0){
- document.getElementById('importMessage').innerText = message
- return
- } else {
- if ((mode == "iso" || mode == "ansi") && importString.length >= 33) {
- document.getElementById('importMessage').innerText = "You can't have layouts with thumb letters on ISO/ANSI"
- } else if (importString.length <= 35) {
- needs_update = true;
- importLayout(importString);
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- history.replaceState(null, null, "?"+queryParams.toString());
- generateCoords();
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
- document.getElementById('importPopup').style.display = 'none';
- } else {
- document.getElementById('importMessage').innerText = "Input string contains too many characters"
- console.log("input string is length "+ importString.length + " " + importString);
- return
- }
- }
-
- needs_update = true;
+ var importString = document.getElementById("importText").value;
+ importString = importString.replace(/\s+/g, "");
+ if (importString.length === 0) {
+ document.getElementById("importPopup").style.display = "none";
+ return;
+ }
+ if (importString.length === 30) {
+ // (cyanophage) probably cmini
+ if (
+ strCount(importString, "-") === 0 &&
+ strCount(importString, "'") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ "-" +
+ importString.slice(10, 20) +
+ "'" +
+ importString.slice(20) +
+ "\\^";
+ } else if (
+ strCount(importString, "-") === 0 &&
+ strCount(importString, ";") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ "-" +
+ importString.slice(10, 20) +
+ ";" +
+ importString.slice(20) +
+ "\\^";
+ } else if (
+ strCount(importString, "'") === 0 &&
+ strCount(importString, ";") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ ";" +
+ importString.slice(10, 20) +
+ "'" +
+ importString.slice(20) +
+ "\\^";
+ } else if (
+ strCount(importString, "'") === 0 &&
+ strCount(importString, "/") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ "/" +
+ importString.slice(10, 20) +
+ "'" +
+ importString.slice(20) +
+ "\\^";
+ } else if (
+ strCount(importString, ";") === 0 &&
+ strCount(importString, "/") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ "/" +
+ importString.slice(10, 20) +
+ ";" +
+ importString.slice(20) +
+ "\\^";
+ } else if (
+ strCount(importString, "/") === 0 &&
+ strCount(importString, "-") === 0
+ ) {
+ importString =
+ importString.slice(0, 10) +
+ "/" +
+ importString.slice(10, 20) +
+ "-" +
+ importString.slice(20) +
+ "\\^";
+ } else {
+ importString =
+ importString.slice(0, 10) +
+ "+" +
+ importString.slice(10, 20) +
+ "*" +
+ importString.slice(20) +
+ "\\^";
+ }
+ }
+ const letters = importString.toUpperCase().match(/[A-Z.,/\-';]/g) || [];
+ // (cyanophage) Count occurrences of each letter
+ const letterCount = {};
+ letters.forEach((letter) => {
+ letterCount[letter] = (letterCount[letter] || 0) + 1;
+ });
+ const allLetters = Array.from({ length: 26 }, (_, i) =>
+ String.fromCharCode(65 + i),
+ ).concat([".", ",", ";", "/", "-", "'"]);
+ const missing = allLetters.filter((letter) => !letterCount[letter]);
+ const duplicates = Object.keys(letterCount).filter(
+ (letter) => letterCount[letter] > 1,
+ );
+ var message = "";
+ if (missing.length > 0) {
+ message = `${message}These letters are duplicated: ${duplicates.join(" ")}\n`;
+ }
+ if (duplicates.length > 0) {
+ message = `${message}These letters are duplicated: ${duplicates.join(" ")}\n`;
+ }
+ if (message.length > 0) {
+ document.getElementById("importMessage").innerText = message;
+ return;
+ } else {
+ if ((mode === "iso" || mode === "ansi") && importString.length >= 33) {
+ document.getElementById("importMessage").innerText =
+ "You can't have layouts with thumb letters on ISO/ANSI";
+ } else if (importString.length <= 35) {
+ needs_update = true;
+ importLayout(importString);
+ const queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
+ generateCoords();
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
+ document.getElementById("importPopup").style.display = "none";
+ } else {
+ document.getElementById("importMessage").innerText =
+ "Input string contains too many characters";
+ console.log(
+ `input string is length ${importString.length} ${importString}`,
+ );
+ return;
+ }
+ }
+
+ needs_update = true;
}
function closeCorpusPopup() {
- var massive_string = document.getElementById('corpusText').value;
- massive_string = massive_string.toLowerCase().replace(/\s+/g, ' ');
- words = {};
- if (massive_string.length == 0) {
- document.getElementById('corpusPopup').style.display = 'none';
- return;
- }
- if (massive_string.length < 1000) {
- document.getElementById('corpusMessage').innerText = "Input text not large enough";
- return;
- }
- list = massive_string.split(" ")
- var regex = /\d/;
- list.forEach(element => {
- // i don't know what to do with these at the moment. just replacing them for now
- element = element.replace("ä","a")
- element = element.replace("å","a")
- element = element.replace("á","a")
- element = element.replace("à","a")
- element = element.replace("â","a")
- element = element.replace("ö","o")
- element = element.replace("ó","o")
- element = element.replace("í","i")
- element = element.replace("ü","u")
- element = element.replace("é","e")
- element = element.replace("è","e")
- element = element.replace("ç","c")
- element = element.replace("æ","ae")
- element = element.replace("ß","ss")
- element = element.replace("ğ","g")
- if (regex.test(element)){
-
- } else {
- if (words[element]) {
- words[element] += 1
- } else {
- words[element] = 1
- }
- }
- });
- dictionary = [];
- count = 0;
- for(var word in words) {
- dictionary.push(word)
- count += 1
- }
- // console.log(count);
-
- document.getElementById('corpusPopup').style.display = 'none';
- needs_update = true;
- measureWords();
- measureDictionary();
- generatePlots();
+ var massive_string = document.getElementById("corpusText").value;
+ massive_string = massive_string.toLowerCase().replace(/\s+/g, " ");
+ words = {};
+ if (massive_string.length === 0) {
+ document.getElementById("corpusPopup").style.display = "none";
+ return;
+ }
+ if (massive_string.length < 1000) {
+ document.getElementById("corpusMessage").innerText =
+ "Input text not large enough";
+ return;
+ }
+ list = massive_string.split(" ");
+ var regex = /\d/;
+ list.forEach((element) => {
+ // (cyanophage) i don't know what to do with these at the moment. just replacing them for now
+ element = element.replace("ä", "a");
+ element = element.replace("å", "a");
+ element = element.replace("á", "a");
+ element = element.replace("à", "a");
+ element = element.replace("â", "a");
+ element = element.replace("ö", "o");
+ element = element.replace("ó", "o");
+ element = element.replace("í", "i");
+ element = element.replace("ü", "u");
+ element = element.replace("é", "e");
+ element = element.replace("è", "e");
+ element = element.replace("ç", "c");
+ element = element.replace("æ", "ae");
+ element = element.replace("ß", "ss");
+ element = element.replace("ğ", "g");
+ if (regex.test(element)) {
+ } else {
+ if (words[element]) {
+ words[element] += 1;
+ } else {
+ words[element] = 1;
+ }
+ }
+ });
+ dictionary = [];
+ count = 0;
+ for (var word in words) {
+ dictionary.push(word);
+ count += 1;
+ }
+ // console.log(count);
+
+ document.getElementById("corpusPopup").style.display = "none";
+ needs_update = true;
+ measureWords();
+ measureDictionary();
+ generatePlots();
}
function closePopup() {
- for (let row = 0; row < nb_row; row++){
- for (let col = 0; col < nb_columns; col++){
- var name = "textInput-" + row + "-" + col
- effort[row][col] = document.getElementById(name).value;
- }
- }
- document.getElementById('popup').style.display = 'none';
- needs_update = true;
- measureWords();
- generateLayout();
+ for (let row = 0; row < nb_row; row++) {
+ for (let col = 0; col < nb_columns; col++) {
+ const name = `textInput-${row}-${col}`;
+ effort[row][col] = document.getElementById(name).value;
+ }
+ }
+ document.getElementById("popup").style.display = "none";
+ needs_update = true;
+ measureWords();
+ generateLayout();
}
function copyEffortGridToClipboard() {
- values = []
- for (let row = 0; row < 3; row++){
- for (let col = 0; col < 12; col++){
- const name = "textInput-" + row + "-" + col
- values.push(document.getElementById(name).value);
- }
- }
- var str = values.join(",");
-
- if (!navigator.clipboard) {
- console.error("Clipboard API not supported");
- return;
- }
-
- navigator.clipboard.writeText(str)
- .then(
- // console.log("copied!")
- )
- .catch(err => {
- console.error("Failed to copy to clipboard contents:", err);
- });
-
+ values = [];
+ for (let row = 0; row < 3; row++) {
+ for (let col = 0; col < 12; col++) {
+ const name = `textInput-${row}-${col}`;
+ values.push(document.getElementById(name).value);
+ }
+ }
+ var str = values.join(",");
+
+ if (!navigator.clipboard) {
+ console.error("Clipboard API not supported");
+ return;
+ }
+
+ navigator.clipboard
+ .writeText(str)
+ .then(
+ // console.log("copied!")
+ )
+ .catch((err) => {
+ console.error("Failed to copy to clipboard contents:", err);
+ });
}
function pasteEffortGridFromClipboard() {
- if (!navigator.clipboard) {
- console.error("Clipboard API not supported");
- return;
- }
- // Retrieve clipboard content
- navigator.clipboard.readText()
- .then(text => {
- // console.log("Clipboard content:", text);
- var numbersArray = text.split(",").map(Number);
- if (numbersArray.length != 36) {
- return
- }
-
- for (let row = 0; row < 3; row++){
- for (let col = 0; col < 12; col++){
- const name = "textInput-" + row + "-" + col
- document.getElementById(name).value = numbersArray[row * 12 + col]
- }
- }
- })
- .catch(err => {
- console.error("Failed to read clipboard contents:", err);
- });
+ if (!navigator.clipboard) {
+ console.error("Clipboard API not supported");
+ return;
+ }
+ // (cyanophage) Retrieve clipboard content
+ navigator.clipboard
+ .readText()
+ .then((text) => {
+ // console.log("Clipboard content:", text);
+ var numbersArray = text.split(",").map(Number);
+ if (numbersArray.length !== 36) {
+ return;
+ }
+
+ for (let row = 0; row < 3; row++) {
+ for (let col = 0; col < 12; col++) {
+ const name = `textInput-${row}-${col}`;
+ document.getElementById(name).value = numbersArray[row * 12 + col];
+ }
+ }
+ })
+ .catch((err) => {
+ console.error("Failed to read clipboard contents:", err);
+ });
}
-function getEffort(row, column){
- if (effort[row]){
- if (effort[row][column]){
- return effort[row][column];
- }
- }
- return 0;
+function getEffort(row, column) {
+ if (effort[row]) {
+ if (effort[row][column]) {
+ return effort[row][column];
+ }
+ }
+ return 0;
}
var skip_toggle = false;
function skipToggle() {
- skip_toggle = !skip_toggle
- generatePlots();
+ skip_toggle = !skip_toggle;
+ generatePlots();
}
var scissors_toggle = 0;
function scissorsToggle(v) {
- scissors_toggle += v
- if (scissors_toggle > 2){
- scissors_toggle = 0
- }
- if (scissors_toggle < 0){
- scissors_toggle = 2
- }
- generatePlots();
+ scissors_toggle += v;
+ if (scissors_toggle > 2) {
+ scissors_toggle = 0;
+ }
+ if (scissors_toggle < 0) {
+ scissors_toggle = 2;
+ }
+ generatePlots();
}
var lsb_toggle = 0;
function lsbToggle() {
- lsb_toggle += 1
- if (lsb_toggle > 1){
- lsb_toggle = 0
- }
- generatePlots();
+ lsb_toggle += 1;
+ if (lsb_toggle > 1) {
+ lsb_toggle = 0;
+ }
+ generatePlots();
}
var sfb_toggle = 0;
function sfbToggle(v) {
- sfb_toggle += v
- if (sfb_toggle > 2){
- sfb_toggle = 0
- }
- if (sfb_toggle < 0){
- sfb_toggle = 2
- }
- generatePlots();
+ sfb_toggle += v;
+ if (sfb_toggle > 2) {
+ sfb_toggle = 0;
+ }
+ if (sfb_toggle < 0) {
+ sfb_toggle = 2;
+ }
+ generatePlots();
}
var trigram_toggle = 0;
function trigramToggle(v) {
- trigram_toggle += v
- if (trigram_toggle > 4){
- trigram_toggle = 0
- }
- if (trigram_toggle < 0){
- trigram_toggle = 4
- }
- generatePlots();
+ trigram_toggle += v;
+ if (trigram_toggle > 4) {
+ trigram_toggle = 0;
+ }
+ if (trigram_toggle < 0) {
+ trigram_toggle = 4;
+ }
+ generatePlots();
}
function showTooltip(evt, text) {
- let tooltip = document.getElementById("tooltip");
- tooltip.innerHTML = text;
- tooltip.style.display = "block";
- tooltip.style.left = evt.pageX + 10 + 'px';
- tooltip.style.top = evt.pageY + 10 + 'px';
+ const tooltip = document.getElementById("tooltip");
+ tooltip.innerHTML = text;
+ tooltip.style.display = "block";
+ tooltip.style.left = `${evt.pageX + 10}px`;
+ tooltip.style.top = `${evt.pageY + 10}px`;
}
function hideTooltip() {
- var tooltip = document.getElementById("tooltip");
- tooltip.style.display = "none";
+ var tooltip = document.getElementById("tooltip");
+ tooltip.style.display = "none";
}
function setMode() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("setMode to "+mode);
- if (mode == "ergo") {
- setErgo()
- } else if (mode == "ansi") {
- setAnsi()
- } else if (mode == "iso") {
- setIso()
- }
- generateCoords()
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log(`setMode to ${mode}`);
+ if (mode === "ergo") {
+ setErgo();
+ } else if (mode === "ansi") {
+ setAnsi();
+ } else if (mode === "iso") {
+ setIso();
+ }
+ generateCoords();
}
function activateErgo() {
- needs_update = true;
- setErgo();
- generateCoords();
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
+ needs_update = true;
+ setErgo();
+ generateCoords();
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
}
function setErgo() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("activateErgo");
- rcdata[32][1] = 2
- rcdata[32][2] = 0
- rcdata[32][6] = 1
- rcdata[33][1] = 3
- rcdata[33][2] = 4
- rcdata[33][6] = 1
- rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1, 34]
- rcdata[35] = [rcdata[35][0], 1, 0, 0, 0, 0, 1, rcdata[35][7]]
- rcdata[36] = ["enter", 2, 11, 0, 0, 0, 1, 36]
- rcdata[37] = ["mod", 3, 5, 0, 0, 0, 1, 37]
- rcdata[38] = ["back", 3, 6, 0, 0, 0, 1, 38]
- rcdata[39] = [rcdata[39][0], 3, 7, 0, 0, 0, 1, rcdata[39][7]]
- mode = "ergo"
- fingerAssignment = [
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10]
- ]
-
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- queryParams.set("thumb",thumb)
- history.replaceState(null, null, "?"+queryParams.toString());
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log("activateErgo");
+ rcdata[32][1] = 2;
+ rcdata[32][2] = 0;
+ rcdata[32][6] = 1;
+ rcdata[33][1] = 3;
+ rcdata[33][2] = 4;
+ rcdata[33][6] = 1;
+ rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1, 34];
+ rcdata[35] = [rcdata[35][0], 1, 0, 0, 0, 0, 1, rcdata[35][7]];
+ rcdata[36] = ["enter", 2, 11, 0, 0, 0, 1, 36];
+ rcdata[37] = ["mod", 3, 5, 0, 0, 0, 1, 37];
+ rcdata[38] = ["back", 3, 6, 0, 0, 0, 1, 38];
+ rcdata[39] = [rcdata[39][0], 3, 7, 0, 0, 0, 1, rcdata[39][7]];
+ mode = "ergo";
+ fingerAssignment = [
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ ];
+
+ var queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ queryParams.set("thumb", thumb);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
}
function activateIso(anglemod) {
- needs_update = true;
- setIso(anglemod);
- generateCoords();
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
+ needs_update = true;
+ setIso(anglemod);
+ generateCoords();
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
}
function setIso(anglemod) {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- hasshift = false
- for(let i = 0; i < 34; i++){
- if (rcdata[i][0] == "shift" || rcdata[i][0] == "^") {
- hasshift = true
- }
- }
- if (hasshift == true) {
- rcdata[32][1] = 2
- rcdata[32][2] = 0
- rcdata[32][6] = 1
- rcdata[33][1] = 2
- rcdata[33][2] = -1
- rcdata[33][6] = 1.25
- rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1.5, 34]
- rcdata[35] = ["back", 0, 12, 0, 0, 0, 2.25, 35]
- rcdata[36] = ["$", 1, 0, 0, 0, 0, 1.75, 36]
- rcdata[37] = ["enter", 1, 12, 0, 0, 0, 2, 37]
- rcdata[38] = ["rshift", 2, 12, 0, 0, 0, 2.5, 38]
- rcdata[39] = ["space", 3, 3, 0, 0, 0, 6.5, 39]
- if (anglemod){
- fingerAssignment = [ // angle mod
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 2, 3, 4, 4, 4, 7, 7, 8, 9, 10, 10, 10]
- ]
- } else {
- fingerAssignment = [
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10]
- ]
- }
- mode = "iso"
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- history.replaceState(null, null, "?"+queryParams.toString());
- } else {
- console.log("You can't have layouts with thumb letters on ISO/ANSI")
- }
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ hasshift = false;
+ for (let i = 0; i < 34; i++) {
+ if (rcdata[i][0] === "shift" || rcdata[i][0] === "^") {
+ hasshift = true;
+ }
+ }
+ if (hasshift === true) {
+ rcdata[32][1] = 2;
+ rcdata[32][2] = 0;
+ rcdata[32][6] = 1;
+ rcdata[33][1] = 2;
+ rcdata[33][2] = -1;
+ rcdata[33][6] = 1.25;
+ rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1.5, 34];
+ rcdata[35] = ["back", 0, 12, 0, 0, 0, 2.25, 35];
+ rcdata[36] = ["$", 1, 0, 0, 0, 0, 1.75, 36];
+ rcdata[37] = ["enter", 1, 12, 0, 0, 0, 2, 37];
+ rcdata[38] = ["rshift", 2, 12, 0, 0, 0, 2.5, 38];
+ rcdata[39] = ["space", 3, 3, 0, 0, 0, 6.5, 39];
+ if (anglemod) {
+ fingerAssignment = [
+ // (cyanophage) angle mod
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 2, 3, 4, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ ];
+ } else {
+ fingerAssignment = [
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ ];
+ }
+ mode = "iso";
+ const queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
+ } else {
+ console.log("You can't have layouts with thumb letters on ISO/ANSI");
+ }
}
function activateAnsi() {
- needs_update = true;
- setAnsi();
- generateCoords();
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
+ needs_update = true;
+ setAnsi();
+ generateCoords();
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
}
function setAnsi() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- hasshift = false
- for(let i = 0; i < 34; i++){
- if (rcdata[i][0] == "shift" || rcdata[i][0] == "^") {
- hasshift = true
- }
- }
- if (hasshift == true) {
- // rcdata[32] = [rcdata[32][0], 0, 12, 0.2753001, 0, 0, 1, rcdata[32][7]]
- // rcdata[33] = [rcdata[33][0], 2, -1, 0, 0, 0, 2.25, rcdata[33][7]]
-
- // backslash key
- rcdata[32][1] = 0
- rcdata[32][2] = 12
- rcdata[32][6] = 1
-
- // left shift key
- rcdata[33][1] = 2
- rcdata[33][2] = -1
- rcdata[33][6] = 2.25
-
- rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1.5, 34]
- rcdata[35] = ["back", 0, 13, 0, 0, 0, 1.25, 35]
- rcdata[36] = ["$", 1, 0, 0, 0, 0, 1.75, 36]
- rcdata[37] = ["enter", 1, 12, 0, 0, 0, 2, 37]
- rcdata[38] = ["rshift", 2, 11, 0, 0, 0, 2.5, 38]
- rcdata[39] = ["space", 3, 3, 0, 0, 0, 6.5, 39]
- fingerAssignment = [
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
- [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10]
- ]
- mode = "ansi"
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- history.replaceState(null, null, "?"+queryParams.toString());
- } else {
- console.log("You can't have layouts with thumb letters on ISO/ANSI")
- }
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ hasshift = false;
+ for (let i = 0; i < 34; i++) {
+ if (rcdata[i][0] === "shift" || rcdata[i][0] === "^") {
+ hasshift = true;
+ }
+ }
+ if (hasshift === true) {
+ // rcdata[32] = [rcdata[32][0], 0, 12, 0.2753001, 0, 0, 1, rcdata[32][7]]
+ // rcdata[33] = [rcdata[33][0], 2, -1, 0, 0, 0, 2.25, rcdata[33][7]]
+
+ // backslash key
+ rcdata[32][1] = 0;
+ rcdata[32][2] = 12;
+ rcdata[32][6] = 1;
+
+ // left shift key
+ rcdata[33][1] = 2;
+ rcdata[33][2] = -1;
+ rcdata[33][6] = 2.25;
+
+ rcdata[34] = ["tab", 0, 0, 0, 0, 0, 1.5, 34];
+ rcdata[35] = ["back", 0, 13, 0, 0, 0, 1.25, 35];
+ rcdata[36] = ["$", 1, 0, 0, 0, 0, 1.75, 36];
+ rcdata[37] = ["enter", 1, 12, 0, 0, 0, 2, 37];
+ rcdata[38] = ["rshift", 2, 11, 0, 0, 0, 2.5, 38];
+ rcdata[39] = ["space", 3, 3, 0, 0, 0, 6.5, 39];
+ fingerAssignment = [
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ [1, 1, 2, 3, 4, 4, 7, 7, 8, 9, 10, 10, 10],
+ ];
+ mode = "ansi";
+ const queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
+ } else {
+ console.log("You can't have layouts with thumb letters on ISO/ANSI");
+ }
}
function importLayout(layout) {
- if (layout.length == 35) {
- var decodedString = decodeURIComponent(layout);
- console.log("importing: "+decodedString)
- layout = decodedString
- // change shift to =
- for (let i = 0; i < 34; i++) {
- if (rcdata[i][0] == "^") {
- rcdata[i][0] = "*"
- }
- }
- // change ctrl to *
- for (let i = 0; i < 37; i++) {
- if (rcdata[i][0] == "$") {
- rcdata[i][0] = "="
- console.log("setting "+i+" to *")
- }
- }
- //
- for (let i = 0; i < 34; i++) { // qwertyuiop-asdfghjkl;'zxcvbnm,./\^ - 34
- for (let j = 0; j < 34; j++) {
- if (layout.charAt(i) == rcdata[j][0]) {
- // console.log("swap "+layout.charAt(i)+" at " + i + " with position " + j)
- // swap
- indices = [0, 3, 7] // letter, freq, keyname
- for (let id = 0; id < indices.length; id++){
- var k = indices[id];
- tmp = rcdata[i][k];
- rcdata[i][k] = rcdata[j][k];
- rcdata[j][k] = tmp;
- }
- }
- }
- }
- // last letter
- var swap1 = 0
- var swap2 = 0
- for (let i = 0; i < 36; i++) {
- if (rcdata[i][7] == 35) {
- swap1 = i
- }
- }
- for (let i = 0; i < 36; i++) {
- if (rcdata[i][0] == layout.charAt(34)) {
- swap2 = i
- }
- }
- indices = [0, 3, 7] // letter, freq, keyname
- for (let id = 0; id < indices.length; id++){
- var k = indices[id];
- tmp = rcdata[swap1][k];
- rcdata[swap1][k] = rcdata[swap2][k];
- rcdata[swap2][k] = tmp;
- }
- } else {
- var decodedString = decodeURIComponent(layout);
- console.log("importing: "+decodedString)
- layout = decodedString
- for (let i = 0; i < 34; i++) { // qwertyuiop-asdfghjkl;'zxcvbnm,./\^ - 34
- for (let j = 0; j < 34; j++) {
- if (layout.charAt(i) == rcdata[j][0]) {
- // console.log("swap "+layout.charAt(i)+" at " + i + " with position " + j)
- // swap
- indices = [0, 3, 7] // letter, freq, keyname
- for (let id = 0; id < indices.length; id++){
- var k = indices[id];
- tmp = rcdata[i][k];
- rcdata[i][k] = rcdata[j][k];
- rcdata[j][k] = tmp;
- }
- }
- }
- }
- for (let i = 0; i < 34; i++) {
- if (rcdata[i][0] == "^") {
- if (rcdata[i][1] == 3 && rcdata[i][2] == 4) {
- // cool
- } else {
- rcdata[i][0] = "="
- }
- }
- }
- }
- if (thumb == "r") {
- indices = [0, 3, 7] // letter, freq, keyname
- for (let id = 0; id < indices.length; id++){
- var k = indices[id];
- tmp = rcdata[33][k];
- rcdata[33][k] = rcdata[39][k];
- rcdata[39][k] = tmp;
- }
- }
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- queryParams.set("thumb",thumb)
- history.replaceState(null, null, "?"+queryParams.toString());
+ if (layout.length === 35) {
+ const decodedString = decodeURIComponent(layout);
+ console.log(`importing: ${decodedString}`);
+ layout = decodedString;
+
+ // change shift to =
+ for (let i = 0; i < 34; i++) {
+ if (rcdata[i][0] === "^") {
+ rcdata[i][0] = "*";
+ }
+ }
+
+ // change ctrl to *
+ for (let i = 0; i < 37; i++) {
+ if (rcdata[i][0] === "$") {
+ rcdata[i][0] = "=";
+ console.log(`setting ${i} to *`);
+ }
+ }
+
+ for (let i = 0; i < 34; i++) {
+ // qwertyuiop-asdfghjkl;'zxcvbnm,./\^ - 34
+ for (let j = 0; j < 34; j++) {
+ if (layout.charAt(i) === rcdata[j][0]) {
+ // console.log("swap "+layout.charAt(i)+" at " + i + " with position " + j)
+ // swap
+ indices = [0, 3, 7]; // letter, freq, keyname
+ for (let id = 0; id < indices.length; id++) {
+ const k = indices[id];
+ tmp = rcdata[i][k];
+ rcdata[i][k] = rcdata[j][k];
+ rcdata[j][k] = tmp;
+ }
+ }
+ }
+ }
+ // last letter
+ let swap1 = 0;
+ let swap2 = 0;
+ for (let i = 0; i < 36; i++) {
+ if (rcdata[i][7] === 35) {
+ swap1 = i;
+ }
+ }
+ for (let i = 0; i < 36; i++) {
+ if (rcdata[i][0] === layout.charAt(34)) {
+ swap2 = i;
+ }
+ }
+ indices = [0, 3, 7]; // letter, freq, keyname
+ for (let id = 0; id < indices.length; id++) {
+ const k = indices[id];
+ tmp = rcdata[swap1][k];
+ rcdata[swap1][k] = rcdata[swap2][k];
+ rcdata[swap2][k] = tmp;
+ }
+ } else {
+ const decodedString = decodeURIComponent(layout);
+ console.log(`importing: ${decodedString}`);
+ layout = decodedString;
+ for (let i = 0; i < 34; i++) {
+ // qwertyuiop-asdfghjkl;'zxcvbnm,./\^ - 34
+ for (let j = 0; j < 34; j++) {
+ if (layout.charAt(i) === rcdata[j][0]) {
+ // console.log("swap "+layout.charAt(i)+" at " + i + " with position " + j)
+ // swap
+ indices = [0, 3, 7]; // letter, freq, keyname
+ for (let id = 0; id < indices.length; id++) {
+ const k = indices[id];
+ tmp = rcdata[i][k];
+ rcdata[i][k] = rcdata[j][k];
+ rcdata[j][k] = tmp;
+ }
+ }
+ }
+ }
+ for (let i = 0; i < 34; i++) {
+ if (rcdata[i][0] === "^") {
+ if (rcdata[i][1] === 3 && rcdata[i][2] === 4) {
+ // (cyanophage) cool
+ } else {
+ rcdata[i][0] = "=";
+ }
+ }
+ }
+ }
+ if (thumb === "r") {
+ indices = [0, 3, 7]; // letter, freq, keyname
+ for (let id = 0; id < indices.length; id++) {
+ const k = indices[id];
+ tmp = rcdata[33][k];
+ rcdata[33][k] = rcdata[39][k];
+ rcdata[39][k] = tmp;
+ }
+ }
+ var queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ queryParams.set("thumb", thumb);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
}
function exportLayout() {
- var str = "";
- for (let i = 0; i <= 32; i++) {
- str += rcdata[i][0]
- }
-
- maybe_space = rcdata[33][0]
- if (maybe_space == "space"){
- str += "space";
- thumb = "r"
- } else {
- thumb = "l"
- str += maybe_space
- }
-
- ch35 = rcdata[35][0]
- if (ch35 != "$") {
- str += ch35;
- }
- return str;
+ var str = "";
+ for (let i = 0; i <= 32; i++) {
+ str += rcdata[i][0];
+ }
+
+ maybe_space = rcdata[33][0];
+ if (maybe_space === "space") {
+ str += "space";
+ thumb = "r";
+ } else {
+ thumb = "l";
+ str += maybe_space;
+ }
+
+ ch35 = rcdata[35][0];
+ if (ch35 !== "$") {
+ str += ch35;
+ }
+ return str;
}
function getX(name, row, col) {
- dx = 55;
- if (mode == "iso") {
- if (row == 0){
- if (name === "tab") {
- off = 0
- } else {
- off = w*0.5;
- }
- } else if (row == 1) {
- if (name === "$") {
- off = 0;
- } else {
- off = w*0.75;
- }
- } else if (row >= 2) {
- if (col == -1) {
- return dx
- } else {
- if (name === "space") {
- off = 0;
- } else if (name == "rshift") {
- off = w*0.25;
- } else {
- off = w*1.25;
- }
- }
- }
- return dx + off + col * w
- } else if (mode == "ansi") {
- if (row == 0){
- if (name === "tab") {
- off = 0
- } else {
- off = w*0.5;
- }
- } else if (row == 1){
- if (name === "$") {
- off = 0;
- } else {
- off = w*0.75;
- }
- } else if (row >= 2){
- if (col == -1) {
- return dx
- } else {
- if (name === "space") {
- off = 0;
- } else {
- off = w*1.25;
- }
- }
- }
- return dx + off + col * w
- } else if (mode == "ergo") {
- if (col > 5) {
- dx = dx + 40;
- }
- return dx + col * w
- }
+ dx = 55;
+ if (mode === "iso") {
+ if (row === 0) {
+ if (name === "tab") {
+ off = 0;
+ } else {
+ off = w * 0.5;
+ }
+ } else if (row === 1) {
+ if (name === "$") {
+ off = 0;
+ } else {
+ off = w * 0.75;
+ }
+ } else if (row >= 2) {
+ if (col === -1) {
+ return dx;
+ } else {
+ if (name === "space") {
+ off = 0;
+ } else if (name === "rshift") {
+ off = w * 0.25;
+ } else {
+ off = w * 1.25;
+ }
+ }
+ }
+ return dx + off + col * w;
+ } else if (mode === "ansi") {
+ if (row === 0) {
+ if (name === "tab") {
+ off = 0;
+ } else {
+ off = w * 0.5;
+ }
+ } else if (row === 1) {
+ if (name === "$") {
+ off = 0;
+ } else {
+ off = w * 0.75;
+ }
+ } else if (row >= 2) {
+ if (col === -1) {
+ return dx;
+ } else {
+ if (name === "space") {
+ off = 0;
+ } else {
+ off = w * 1.25;
+ }
+ }
+ }
+ return dx + off + col * w;
+ } else if (mode === "ergo") {
+ if (col > 5) {
+ dx = dx + 40;
+ }
+ return dx + col * w;
+ }
}
-function getY(name, row, col) {
- return 10 + row * w
+
+function getY(row) {
+ return 10 + row * w;
}
function getCol(letter) {
- for (let i = 0; i < rcdata_len; i++) {
- const key = rcdata[i];
- if (key[0] === letter) {
- return key[2];
- }
- }
- return -1;
+ for (let i = 0; i < rcdata_len; i++) {
+ const key = rcdata[i];
+ if (key[0] === letter) {
+ return key[2];
+ }
+ }
+ return -1;
}
function getRow(letter) {
- for (let i = 0; i < rcdata_len; i++) {
- const key = rcdata[i];
- if (key[0] === letter) {
- return key[1];
- }
- }
- return -1;
+ for (let i = 0; i < rcdata_len; i++) {
+ const key = rcdata[i];
+ if (key[0] === letter) {
+ return key[1];
+ }
+ }
+ return -1;
}
-function getChar(row,col) {
- for (let i = 0; i < rcdata_len; i++) {
- const key = rcdata[i];
- if (key[1] == row && key[2] == col) {
- return key[0];
- }
- }
- return "!";
+function getChar(row, col) {
+ for (let i = 0; i < rcdata_len; i++) {
+ const key = rcdata[i];
+ if (key[1] === row && key[2] === col) {
+ return key[0];
+ }
+ }
+ return "!";
}
function getFinger(row, col) {
- if (row > 2) {
- if (col <= 4) {
- return 5
- } else {
- return 6
- }
- } else {
- return fingerAssignment[row][col];
- }
+ if (row > 2) {
+ if (col <= 4) {
+ return 5;
+ } else {
+ return 6;
+ }
+ } else {
+ return fingerAssignment[row][col];
+ }
}
function dist(x1, y1, x2, y2) {
- dx = x1 - x2
- dy = y1 - y2
- return inv_w * Math.sqrt(dx*dx + dy*dy); // pow is slow
+ dx = x1 - x2;
+ dy = y1 - y2;
+ return inv_w * Math.sqrt(dx * dx + dy * dy); // (narglab) pow is slow
}
function generateCoords() {
- console.log("generateCoords")
- for (let i = 0; i < rcdata_len; i++) {
- rcdata[i][4] = getY(rcdata[i][0], rcdata[i][1],rcdata[i][2]); // Y
- rcdata[i][5] = getX(rcdata[i][0], rcdata[i][1],rcdata[i][2]); // X
- }
+ console.log("generateCoords");
+ for (let i = 0; i < rcdata_len; i++) {
+ rcdata[i][4] = getY(rcdata[i][1]); // Y
+ rcdata[i][5] = getX(rcdata[i][0], rcdata[i][1], rcdata[i][2]); // X
+ }
}
function generateLayout() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("generateLayout")
- svg.selectAll("*").remove();
- if (mode == "iso" || mode == "ansi") {
- outlinewidth = 572;
- } else {
- outlinewidth = 510;
- }
- svg.append("rect").attr("x", 45).attr("y", 0).attr("width", outlinewidth).attr("height", 170)
- .attr("stroke", "#777777").attr("fill", "#1b1c1f").attr("fill-opactiy", "0.0").attr("rx", 8).attr("ry", 8)
- for (let i = 0; i < rcdata_len; i++) {
- dtx = 0;
- letter = rcdata[i][0];
- if (letter == "^"){
- letter = "shift"
- }
- x = rcdata[i][5];
- y = rcdata[i][4];
- per = rcdata[i][3];
- keywidth = rcdata[i][6];
- red = Math.floor(127 * per * inv_default_max) + 128
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255;}
- hex_red = red.toString(16);
- hex_bg = green.toString(16);
-
- fontsize = 16;
- if (letter == "$") { letter = "ctrl"}
- if (letter.length > 1) { fontsize = 10; }
- if (letter.length > 4 && mode == "ergo") { fontsize = 9; }
-
- svg.append("rect").attr("x", x).attr("y", y)
- .attr("width", keywidth*w-gap).attr("height", w-gap).attr("rx", 4).attr("ry", 4)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "black")
- .attr("stroke-width", "1").attr("class", "draggable");
- if (letter.length > 1 && mode != "ergo") {
- svg.append("text").attr("x", x + 5).attr("y", y + 19)
- .attr("font-size", fontsize).attr("font-family", "Roboto Mono")
- .attr("text-anchor", "left").attr("class", "draggable legend").text(letter);
- } else {
- svg.append("text").attr("x", x + 15).attr("y", y + 19)
- .attr("font-size", fontsize).attr("font-family", "Roboto Mono")
- .attr("text-anchor", "middle").attr("class", "draggable legend").text(letter);
- }
- }
- //
- if (m_total_word_effort == 0){
- // console.log("m_total_word_effort == 0")
- measureDictionary();
- measureWords();
- }
- svg.append("text").attr("x", 640).attr("y", 135).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Total Word Effort "+(m_total_word_effort/100.0).toFixed(1))
- // effort text
- svg.append("text").attr("x", 640).attr("y", 165).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Effort " + (577 * m_effort * inv_m_input_length).toFixed(2))
- // edit button
- svg.append("rect").attr("x", 760).attr("y", 147).attr("width", 40).attr("height", 25).attr("rx",0).attr("ry",0)
- .attr("fill","#777777").attr("stroke","black").attr("stroke-width","1").attr("onclick", "openPopup()")
- .attr("onmouseover", "showTooltip(evt,'Edit effort values for each key')").attr("onmouseout", "hideTooltip()")
-
- svg.append("text").attr("x", 760+20).attr("y", 164).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#111111").attr("text-anchor", "middle").attr("pointer-events","none").text("Edit")
-
-
- // ergo button
- svg.append("rect").attr("x", 640).attr("y", 10).attr("width", 46).attr("height", 25).attr("rx",0).attr("ry",0)
- .attr("fill","#777777").attr("stroke","black").attr("stroke-width","1").attr("onclick", "activateErgo()")
- .attr("onmouseover", "showTooltip(evt,'Switch layout to Ergo')").attr("onmouseout", "hideTooltip()")
- svg.append("text").attr("x", 640+23).attr("y", 10+18).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#111111").attr("text-anchor", "middle").attr("pointer-events","none").text("Ergo")
- // iso button
- svg.append("rect").attr("x", 640).attr("y", 10+35).attr("width", 46).attr("height", 25).attr("rx",0).attr("ry",0)
- .attr("fill","#777777").attr("stroke","black").attr("stroke-width","1").attr("onclick", "activateIso(false)")
- .attr("onmouseover", "showTooltip(evt,'Switch layout to ISO')").attr("onmouseout", "hideTooltip()")
- svg.append("text").attr("x", 640+23).attr("y", 10+18+35).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#111111").attr("text-anchor", "middle").attr("pointer-events","none").text("ISO")
-
- // anglemod button
- svg.append("rect").attr("x", 695).attr("y", 10+35).attr("width", 80).attr("height", 25).attr("rx",0).attr("ry",0)
- .attr("fill","#777777").attr("stroke","black").attr("stroke-width","1").attr("onclick", "activateIso(true)")
- .attr("onmouseover", "showTooltip(evt,'Switch layout to ISO with angle mod')").attr("onmouseout", "hideTooltip()")
- svg.append("text").attr("x", 695+40).attr("y", 10+18+35).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#111111").attr("text-anchor", "middle").attr("pointer-events","none").text("anglemod")
-
- // ansi button
- svg.append("rect").attr("x", 640).attr("y", 10+35+35).attr("width", 46).attr("height", 25).attr("rx",0).attr("ry",0)
- .attr("fill","#777777").attr("stroke","black").attr("stroke-width","1").attr("onclick", "activateAnsi()")
- .attr("onmouseover", "showTooltip(evt,'Switch layout to ANSI')").attr("onmouseout", "hideTooltip()")
- svg.append("text").attr("x", 640+23).attr("y", 10+18+35+35).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#111111").attr("text-anchor", "middle").attr("pointer-events","none").text("ANSI")
-
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log("generateLayout");
+ svg.selectAll("*").remove();
+ if (mode === "iso" || mode === "ansi") {
+ outlinewidth = 572;
+ } else {
+ outlinewidth = 510;
+ }
+
+ svg
+ .append("rect")
+ .attr("x", 45)
+ .attr("y", 0)
+ .attr("width", outlinewidth)
+ .attr("height", 170)
+ .attr("stroke", "#777777")
+ .attr("fill", "#1b1c1f")
+ .attr("fill-opactiy", "0.0")
+ .attr("rx", 8)
+ .attr("ry", 8);
+
+ for (let i = 0; i < rcdata_len; i++) {
+ dtx = 0;
+ letter = rcdata[i][0];
+ if (letter === "^") {
+ letter = "shift";
+ }
+
+ x = rcdata[i][5];
+ y = rcdata[i][4];
+
+ per = rcdata[i][3];
+ keywidth = rcdata[i][6];
+ red = Math.floor(127 * per * inv_default_max) + 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ hex_red = red.toString(16);
+ hex_bg = green.toString(16);
+
+ fontsize = 16;
+ if (letter === "$") {
+ letter = "ctrl";
+ }
+ if (letter.length > 1) {
+ fontsize = 10;
+ }
+ if (letter.length > 4 && mode === "ergo") {
+ fontsize = 9;
+ }
+
+ svg
+ .append("rect")
+ .attr("x", x)
+ .attr("y", y)
+ .attr("width", keywidth * w - gap)
+ .attr("height", w - gap)
+ .attr("rx", 4)
+ .attr("ry", 4)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("class", "draggable");
+
+ if (letter.length > 1 && mode !== "ergo") {
+ svg
+ .append("text")
+ .attr("x", x + 5)
+ .attr("y", y + 19)
+ .attr("font-size", fontsize)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "left")
+ .attr("class", "draggable legend")
+ .text(letter);
+ } else {
+ svg
+ .append("text")
+ .attr("x", x + 15)
+ .attr("y", y + 19)
+ .attr("font-size", fontsize)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "middle")
+ .attr("class", "draggable legend")
+ .text(letter);
+ }
+ }
+
+ if (m_total_word_effort === 0) {
+ // console.log("m_total_word_effort === 0")
+ measureDictionary();
+ measureWords();
+ }
+ svg
+ .append("text")
+ .attr("x", 640)
+ .attr("y", 135)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Total Word Effort ${(0.01 * m_total_word_effort).toFixed(1)}`);
+
+ // effort text
+ svg
+ .append("text")
+ .attr("x", 640)
+ .attr("y", 165)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Effort ${(577 * m_effort * inv_m_input_length).toFixed(2)}`);
+
+ // edit button
+ svg
+ .append("rect")
+ .attr("x", 760)
+ .attr("y", 147)
+ .attr("width", 40)
+ .attr("height", 25)
+ .attr("rx", 0)
+ .attr("ry", 0)
+ .attr("fill", "#777777")
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("onclick", "openPopup()")
+ .attr("onmouseover", "showTooltip(evt,'Edit effort values for each key')")
+ .attr("onmouseout", "hideTooltip()");
+
+ svg
+ .append("text")
+ .attr("x", 760 + 20)
+ .attr("y", 164)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#111111")
+ .attr("text-anchor", "middle")
+ .attr("pointer-events", "none")
+ .text("Edit");
+
+ // ergo button
+ svg
+ .append("rect")
+ .attr("x", 640)
+ .attr("y", 10)
+ .attr("width", 46)
+ .attr("height", 25)
+ .attr("rx", 0)
+ .attr("ry", 0)
+ .attr("fill", "#777777")
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("onclick", "activateErgo()")
+ .attr("onmouseover", "showTooltip(evt,'Switch layout to Ergo')")
+ .attr("onmouseout", "hideTooltip()");
+
+ svg
+ .append("text")
+ .attr("x", 640 + 23)
+ .attr("y", 10 + 18)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#111111")
+ .attr("text-anchor", "middle")
+ .attr("pointer-events", "none")
+ .text("Ergo");
+
+ // iso button
+ svg
+ .append("rect")
+ .attr("x", 640)
+ .attr("y", 10 + 35)
+ .attr("width", 46)
+ .attr("height", 25)
+ .attr("rx", 0)
+ .attr("ry", 0)
+ .attr("fill", "#777777")
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("onclick", "activateIso(false)")
+ .attr("onmouseover", "showTooltip(evt,'Switch layout to ISO')")
+ .attr("onmouseout", "hideTooltip()");
+ svg
+ .append("text")
+ .attr("x", 640 + 23)
+ .attr("y", 10 + 18 + 35)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#111111")
+ .attr("text-anchor", "middle")
+ .attr("pointer-events", "none")
+ .text("ISO");
+
+ // anglemod button
+ svg
+ .append("rect")
+ .attr("x", 695)
+ .attr("y", 10 + 35)
+ .attr("width", 80)
+ .attr("height", 25)
+ .attr("rx", 0)
+ .attr("ry", 0)
+ .attr("fill", "#777777")
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("onclick", "activateIso(true)")
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Switch layout to ISO with angle mod')",
+ )
+ .attr("onmouseout", "hideTooltip()");
+ svg
+ .append("text")
+ .attr("x", 695 + 40)
+ .attr("y", 10 + 18 + 35)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#111111")
+ .attr("text-anchor", "middle")
+ .attr("pointer-events", "none")
+ .text("anglemod");
+
+ // ansi button
+ svg
+ .append("rect")
+ .attr("x", 640)
+ .attr("y", 10 + 35 + 35)
+ .attr("width", 46)
+ .attr("height", 25)
+ .attr("rx", 0)
+ .attr("ry", 0)
+ .attr("fill", "#777777")
+ .attr("stroke", "black")
+ .attr("stroke-width", "1")
+ .attr("onclick", "activateAnsi()")
+ .attr("onmouseover", "showTooltip(evt,'Switch layout to ANSI')")
+ .attr("onmouseout", "hideTooltip()");
+ svg
+ .append("text")
+ .attr("x", 640 + 23)
+ .attr("y", 10 + 18 + 35 + 35)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#111111")
+ .attr("text-anchor", "middle")
+ .attr("pointer-events", "none")
+ .text("ANSI");
}
var m_column_usage = {};
var m_finger_usage = {};
var m_finger_distance = {};
var m_finger_pairs = {};
-var m_same_finger = {}; // per bigram
+var m_same_finger = {}; // per bigram
var m_same_finger2 = {}; // per finger
var m_same_finger3 = {}; // per bigram 2u
var m_skip_bigram = {};
var m_skip_bigram2 = {};
-var m_redirects = {};
+// var m_redirects = {};
var m_scissors = {};
var m_all_scissors = {};
var m_pinky_scissors = {};
@@ -1092,1432 +1380,2585 @@ var m_trigram_count_alt = {};
var m_trigram_count_red = {};
var m_trigram_count_roll_in = {};
var m_trigram_count_roll_out = {};
-var m_pinky_off = 0;
+// var m_pinky_off = 0;
var m_input_length = 0;
var inv_m_input_length = 1;
var m_effort = 0;
var m_total_word_effort = 0;
// var m_simple_effort = {};
-var finger_pos = [[0, 0], [1, 1], [1, 2], [1, 3], [1, 4], [3, 4], [3, 7], [1, 7], [1, 8], [1, 9], [1, 10]];
+var finger_pos = [
+ [0, 0],
+ [1, 1],
+ [1, 2],
+ [1, 3],
+ [1, 4],
+ [3, 4],
+ [3, 7],
+ [1, 7],
+ [1, 8],
+ [1, 9],
+ [1, 10],
+];
-var word_effort = Object.create(null)
+var word_effort = Object.create(null);
var samehandstrings = {};
var samehandcount = {};
function measureDictionary() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("measureDictionary");
- // console.log("measuring effort of each word in the dictionary");
- var total=0, word, char1, char2, col1, row1, col2, row2, hand1, hand2, samehand,count = 0;
- word_effort = Object.create(null)
- for(var wordi in dictionary) {
- count += 1;
- total = 0.0;
- word = dictionary[wordi];
- word_len = word.length // Compute once
- char1 = word.charAt(0);
- samehand = `${char1}`;
- for (let i = 1; i < word_len; i++) {
- char1 = word.charAt(i-1);
- char2 = word.charAt(i);
- col1 = getCol(char1);
- row1 = getRow(char1);
- col2 = getCol(char2);
- row2 = getRow(char2);
- if (bigram_effort[col1]) {
- if (bigram_effort[col1][row1]) {
- if (bigram_effort[col1][row1][col2]) {
- if (bigram_effort[col1][row1][col2][row2]) {
- var e = bigram_effort[col1][row1][col2][row2]
- total += e;
- }
- }
- }
- }
- }
- char1 = word.charAt(word_len-1);
- char2 = "_"
- col1 = getCol(char1);
- row1 = getRow(char1);
- col2 = 6;
- row2 = 3;
- if (bigram_effort[col1]) {
- if (bigram_effort[col1][row1]) {
- if (bigram_effort[col1][row1][col2]) {
- if (bigram_effort[col1][row1][col2][row2]) {
- var e = bigram_effort[col1][row1][col2][row2]
- total += e;
- }
- }
- }
- }
-
- for (let i = 2; i < word_len; i++) {
- char1 = word.charAt(i-2);
- char2 = word.charAt(i);
- col1 = getCol(char1);
- row1 = getRow(char1);
- col2 = getCol(char2);
- row2 = getRow(char2);
- if (bigram_effort[col1]) {
- if (bigram_effort[col1][row1]) {
- if (bigram_effort[col1][row1][col2]) {
- if (bigram_effort[col1][row1][col2][row2]) {
- var e = bigram_effort[col1][row1][col2][row2]
- total += 0.2 * e;
- }
- }
- }
- }
- }
- char1 = word.charAt(word_len-2);
- char2 = "_"
- col1 = getCol(char1);
- row1 = getRow(char1);
- col2 = 6;
- row2 = 3;
- if (bigram_effort[col1]) {
- if (bigram_effort[col1][row1]) {
- if (bigram_effort[col1][row1][col2]) {
- if (bigram_effort[col1][row1][col2][row2]) {
- var e = bigram_effort[col1][row1][col2][row2]
- total += 0.2 * e;
- }
- }
- }
- }
- if (isNaN(total)){
- console.log(word + " gives NaN for effort")
- }
- word_effort[word] = 0.1 * total;
- }
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log("measureDictionary");
+ // console.log("measuring effort of each word in the dictionary");
+ var total = 0,
+ word,
+ char1,
+ char2,
+ col1,
+ row1,
+ col2,
+ row2,
+ hand1,
+ hand2,
+ samehand,
+ count = 0;
+ word_effort = Object.create(null);
+ for (var wordi in dictionary) {
+ count += 1;
+ total = 0.0;
+ word = dictionary[wordi];
+ word_len = word.length;
+ char1 = word.charAt(0);
+ samehand = `${char1}`;
+ for (let i = 1; i < word_len; i++) {
+ char1 = word.charAt(i - 1);
+ char2 = word.charAt(i);
+ col1 = getCol(char1);
+ row1 = getRow(char1);
+ col2 = getCol(char2);
+ row2 = getRow(char2);
+ if (bigram_effort[col1]) {
+ if (bigram_effort[col1][row1]) {
+ if (bigram_effort[col1][row1][col2]) {
+ if (bigram_effort[col1][row1][col2][row2]) {
+ const e = bigram_effort[col1][row1][col2][row2];
+ total += e;
+ }
+ }
+ }
+ }
+ }
+ char1 = word.charAt(word_len - 1);
+ char2 = "_";
+ col1 = getCol(char1);
+ row1 = getRow(char1);
+ col2 = 6;
+ row2 = 3;
+ if (bigram_effort[col1]) {
+ if (bigram_effort[col1][row1]) {
+ if (bigram_effort[col1][row1][col2]) {
+ if (bigram_effort[col1][row1][col2][row2]) {
+ const e = bigram_effort[col1][row1][col2][row2];
+ total += e;
+ }
+ }
+ }
+ }
+
+ for (let i = 2; i < word_len; i++) {
+ char1 = word.charAt(i - 2);
+ char2 = word.charAt(i);
+ col1 = getCol(char1);
+ row1 = getRow(char1);
+ col2 = getCol(char2);
+ row2 = getRow(char2);
+ if (bigram_effort[col1]) {
+ if (bigram_effort[col1][row1]) {
+ if (bigram_effort[col1][row1][col2]) {
+ if (bigram_effort[col1][row1][col2][row2]) {
+ const e = bigram_effort[col1][row1][col2][row2];
+ total += 0.2 * e;
+ }
+ }
+ }
+ }
+ }
+ char1 = word.charAt(word_len - 2);
+ char2 = "_";
+ col1 = getCol(char1);
+ row1 = getRow(char1);
+ col2 = 6;
+ row2 = 3;
+ if (bigram_effort[col1]) {
+ if (bigram_effort[col1][row1]) {
+ if (bigram_effort[col1][row1][col2]) {
+ if (bigram_effort[col1][row1][col2][row2]) {
+ const e = bigram_effort[col1][row1][col2][row2];
+ total += 0.2 * e;
+ }
+ }
+ }
+ }
+ if (total.isNan) console.log(`${word} gives NaN for effort`);
+
+ word_effort[word] = 0.1 * total;
+ }
}
function getDictionaryFromWords() {
- console.log("getDictionaryFromWords");
- dictionary = [];
- for (let word in words) {
- if (words[word] > 100) {
- dictionary.push(word);
- }
- }
+ console.log("getDictionaryFromWords");
+ dictionary = [];
+ for (const word in words) {
+ if (words[word] > 100) {
+ dictionary.push(word);
+ }
+ }
}
-function getIndexOfKey(name){
- var x = -1;
- for (let i = 0; i < 34; i++) {
- if (rcdata[i][7] == name) {
- x = i;
- }
- }
- return x;
+function getIndexOfKey(name) {
+ let x_key = -1;
+ for (let i = 0; i < 34; i++) {
+ if (rcdata[i][7] === name) {
+ x_key = i;
+ }
+ }
+ return x_key;
}
function updateRcData(lan) {
- // what are the 33 letters ?
- var letters = []
- for (let word in words) {
- if (letters.length>=32){
- break;
- }
- var wordLetters = word.split(""); // Split the word into individual letters
- for (let i = 0; i < wordLetters.length; i++) {
- if (letters.indexOf(wordLetters[i]) === -1) {
- letters.push(wordLetters[i]); // Add letter to the list if not already present
- }
- }
- }
- // my new idea for fixing this issue still didn't work
- // the problem is that the keys that I want to change when switching languages aren't in a consistent position in the grid, or at a consistent position in the array,
- // or have a consistent letter on them. Even the index I added to try to make them consistent didn't work because of the way the import process works
- if (lan == 'german'){
- // letters = ['q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'y','x', 'c', 'v', 'b', 'n', 'm', ',', '.', '\'', 'ß']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'ü' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ö' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = 'ä' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = 'ß' }
- } else if (lan == 'english') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = ';' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'dutch') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = ';' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'french') {
- // letters = ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'é', 'q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'è', '\'', 'w', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 'ç', 'à']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'é' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'è' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = 'ç' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = 'à' }
- } else if (lan == 'italian') {
- // letters = ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'é', 'q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'è', '\'', 'w', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 'ç', 'à']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'è' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'à' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = 'ù' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = 'ò' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = 'ì' }
- } else if (lan == 'swedish') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'z', 'x', 'c', 'v', 'b','n', 'm', '.', ',', '\'', '\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'å' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ö' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = 'ä' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '\'' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'spanish') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ñ', '\'', 'z','x', 'c', 'v', 'b', 'n', 'm',',', '.', '/', '\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ñ' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'portuguese') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ç', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ç' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'norweigan') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ø', 'æ', 'z', 'x','c','v', 'b', 'm', 'n', '.', ',', '\'', '\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'å' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ø' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = 'æ' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '\'' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'finnish') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '\'', '\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'å' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'ö' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = 'ä' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '\'' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'estonian') {
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = 'ä' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = 'õ' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = 'ü' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = 'ö' }
- } else if (lan == 'hungarian') {
- // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = ';' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- } else if (lan == 'polish') {
- if (getIndexOfKey(10) >= 0) { rcdata[getIndexOfKey(10)][0] = '-' }
- if (getIndexOfKey(20) >= 0) { rcdata[getIndexOfKey(20)][0] = ';' }
- if (getIndexOfKey(21) >= 0) { rcdata[getIndexOfKey(21)][0] = '\'' }
- if (getIndexOfKey(31) >= 0) { rcdata[getIndexOfKey(31)][0] = '/' }
- if (getIndexOfKey(32) >= 0) { rcdata[getIndexOfKey(32)][0] = '\\' }
- }
+ // (cyanophage) what are the 33 letters ?
+ var letters = [];
+ for (const word in words) {
+ if (letters.length >= 32) {
+ break;
+ }
+ const wordLetters = word.split(""); // (cyanophage) Split the word into individual letters
+ for (let i = 0; i < wordLetters.length; i++) {
+ if (letters.indexOf(wordLetters[i]) === -1) {
+ letters.push(wordLetters[i]); // (cyanophage) Add letter to the list if not already present
+ }
+ }
+ }
+ /* (cyanophage)
+ * my new idea for fixing this issue still didn't work
+ * the problem is that the keys that I want to change when switching languages aren't in a consistent position in the grid, or at a consistent position in the array,
+ * or have a consistent letter on them. Even the index I added to try to make them consistent didn't work because of the way the import process works
+ */
+ if (lan === "german") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', 'ü', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'y','x', 'c', 'v', 'b', 'n', 'm', ',', '.', '\'', 'ß']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "ü";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ö";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "ä";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "ß";
+ }
+ } else if (lan === "english") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = ";";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "dutch") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = ";";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "french") {
+ // letters = ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'é', 'q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'è', '\'', 'w', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 'ç', 'à']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "é";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "è";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "ç";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "à";
+ }
+ } else if (lan === "italian") {
+ // letters = ['a', 'z', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'é', 'q', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'è', '\'', 'w', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', 'ç', 'à']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "è";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "à";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "ù";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "ò";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "ì";
+ }
+ } else if (lan === "swedish") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'z', 'x', 'c', 'v', 'b','n', 'm', '.', ',', '\'', '\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "å";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ö";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "ä";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "'";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "spanish") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ñ', '\'', 'z','x', 'c', 'v', 'b', 'n', 'm',',', '.', '/', '\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ñ";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "portuguese") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ç', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ç";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "norweigan") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ø', 'æ', 'z', 'x','c','v', 'b', 'm', 'n', '.', ',', '\'', '\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "å";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ø";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "æ";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "'";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "finnish") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', 'å', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'ö', 'ä', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '\'', '\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "å";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "ö";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "ä";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "'";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "estonian") {
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "ä";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = "õ";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "ü";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "ö";
+ }
+ } else if (lan === "hungarian") {
+ // letters = ['q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '-', 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/','\\']
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = ";";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ } else if (lan === "polish") {
+ if (getIndexOfKey(10) >= 0) {
+ rcdata[getIndexOfKey(10)][0] = "-";
+ }
+ if (getIndexOfKey(20) >= 0) {
+ rcdata[getIndexOfKey(20)][0] = ";";
+ }
+ if (getIndexOfKey(21) >= 0) {
+ rcdata[getIndexOfKey(21)][0] = "'";
+ }
+ if (getIndexOfKey(31) >= 0) {
+ rcdata[getIndexOfKey(31)][0] = "/";
+ }
+ if (getIndexOfKey(32) >= 0) {
+ rcdata[getIndexOfKey(32)][0] = "\\";
+ }
+ }
}
function measureWords() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("measureWords");
- if (!needs_update){return;}
- m_column_usage = {};
- m_finger_usage = {};
- m_finger_distance = {};
- m_skip_bigram = {};
- m_skip_bigram2 = {};
- m_redirects = {};
- m_scissors = {};
- m_all_scissors = {};
- m_pinky_scissors = {};
- m_same_finger = {};
- m_same_finger2 = {};
- m_same_finger3 = {};
- m_lat_stretch = {};
- m_lat_stretch2 = {};
- m_letter_freq = {};
- m_row_usage = {};
- m_trigram_count = {};
- m_trigram_count_alt = {};
- m_trigram_count_red = {};
- m_trigram_count_roll_in = {};
- m_trigram_count_roll_out = {};
- m_finger_pairs = {};
- samehandstrings = {};
- samehandcount = {};
- m_pinky_off = 0;
- m_input_length = 0;
- m_effort = 0;
- m_total_word_effort = 0;
- var char = "";
- var prevchar = "";
- var prevfinger = -1;
- var ppchar = "";
- var ppfinger = -1;
- var bigram, trigram, cat, cat2, skip;
- var prevcol = -1;
- var prevrow = -1;
- var pprow = -1;
- var col,row,hand,prevhand;
- var m_effort_per_letter = {};
- var m_effort_per_word = {};
- var word_count = 0
- for (let word in words) {
- if (word_count > 40000){break;}
- word_count += 1
- finger_pos = [[0, 0], [1, 1], [1, 2], [1, 3], [1, 4], [3, 4], [3, 7], [1, 7], [1, 8], [1, 9], [1, 10]];
- const count = words[word];
- word_len = word.length // Compute once
- m_input_length += count * (word_len + 1);
-
- if (word_effort[word]){
- // console.log(word +" "+word_effort[word]);
- m_total_word_effort += word_effort[word] * count;
- }
-
- char = word.charAt(0);
- samehand = char
- for (let i = 0; i < word_len; i++) {
- char = word.charAt(i);
- if (i > 0){prevchar = word.charAt(i-1);}
- // freq //
- if (!m_letter_freq[char]) {
- m_letter_freq[char] = 0;
- }
- m_letter_freq[char] += count;
- // finger usage //
- row = getRow(char);
- col = getCol(char);
- if (i > 0){prevcol = getCol(prevchar);}
- if (col <= 5){
- hand = "L"
- } else {
- hand = "R"
- }
- if (col < 0) { continue; } // this is the part that just skips numbers and other characters
- if (!m_column_usage[col]) {
- m_column_usage[col] = 0;
- }
- if ((row == 0 && col == 1)||(row == 2 && col == 1)||(row == 0 && col == 10)||(row == 2 && col == 10)||(row == 0 && col == 11)||(row == 1 && col == 11)) {
- m_pinky_off += count
- }
- if (row < 3){ m_column_usage[col] += count;}
- // finger usage //
- // effort
- if (!m_effort_per_letter[char]){
- m_effort_per_letter[char] = 0
- }
- m_effort_per_letter[char] += count * getEffort(row,col)
- if (!m_effort_per_word[word]){
- m_effort_per_word[word] = 0
- }
- m_effort_per_word[word] += count * getEffort(row,col)
-
- m_effort += count * getEffort(row, col);
-
- var finger = getFinger(row, col);
- if (!m_finger_usage[finger]) {
- m_finger_usage[finger] = 0;
- }
- m_finger_usage[finger] += count;
- // finger travel distance
- if (row < 0) { break; }
- // d = dist(col, row, finger_pos[finger][1], finger_pos[finger][0]);
- x1 = getX(char,row,col)
- y1 = getY(char,row,col)
- x2 = getX(getChar(finger_pos[finger][0],finger_pos[finger][1]),finger_pos[finger][0],finger_pos[finger][1])
- y2 = getY(getChar(finger_pos[finger][0],finger_pos[finger][1]),finger_pos[finger][0],finger_pos[finger][1])
- d = dist(x1, y1, x2, y2);
- if (!m_finger_distance[finger]) {
- m_finger_distance[finger] = 0;
- }
- m_finger_distance[finger] += d * count;
-
- finger_pos[finger] = [row, col]; // move finger to new position
-
- // finger row //
- if (!m_row_usage[row]) {
- m_row_usage[row] = 0;
- }
- m_row_usage[row] += count;
-
- // bigram stuff
- if (i > 0 && prevcol >= 0) {
- bigram = prevchar + char;
- if (finger == prevfinger && prevchar != char) {
- if (!m_same_finger[bigram]) {
- m_same_finger[bigram] = 0;
- }
- m_same_finger[bigram] += count;
-
- if (!m_same_finger2[finger]) {
- m_same_finger2[finger] = 0;
- }
- m_same_finger2[finger] += count;
-
- if (Math.abs(row-prevrow) >= 2) {
- if (!m_same_finger3[bigram]) {
- m_same_finger3[bigram] = 0;
- }
- m_same_finger3[bigram] += count;
- }
- }
- // lsbs
- if ((prevcol == 3 && col == 5) || (prevcol == 8 && col == 6) || (prevcol == 5 && col == 3) || (prevcol == 6 && col == 8)) {
- if (!m_lat_stretch[bigram]) {
- m_lat_stretch[bigram] = 0;
- }
- m_lat_stretch[bigram] += count;
- }
- if ((prevcol == 2 && col == 5) || (prevcol == 9 && col == 6) || (prevcol == 5 && col == 2) || (prevcol == 6 && col == 9)) {
- if (!m_lat_stretch2[bigram]) {
- m_lat_stretch2[bigram] = 0;
- }
- m_lat_stretch2[bigram] += count;
- }
- // scissors
- if (Math.abs(col-prevcol) == 1 && Math.abs(row-prevrow) >= 2 && ((finger <= 4 && prevfinger <= 4 &&finger!=prevfinger)||(finger >=7 && prevfinger>=7&&finger!=prevfinger))) {
- if (!m_scissors[bigram]) {
- m_scissors[bigram] = 0;
- }
- m_scissors[bigram] += count;
- }
- // all 2u scissors wide scissors
- if (Math.abs(row-prevrow) >= 2 && Math.abs(col-prevcol)>=1 && ((finger <= 4 && prevfinger <= 4)||(finger >=7 && prevfinger>=7))) {
- if (!m_all_scissors[bigram]) {
- m_all_scissors[bigram] = 0;
- }
- m_all_scissors[bigram] += count;
- }
- // pinky/ring scissors
- if (Math.abs(col-prevcol) == 1 && Math.abs(row-prevrow) >= 1 && (finger == 1 ||finger == 10||prevfinger==1||prevfinger==10)) {
- if (!m_pinky_scissors[bigram]) {
- m_pinky_scissors[bigram] = 0;
- }
- m_pinky_scissors[bigram] += count;
- }
- // same hand strings
- if (prevhand == hand) {
- samehand = samehand + char;
- } else {
- if (samehand.length >= 4) {
- if (!samehandstrings[samehand]) {
- samehandstrings[samehand] = 0;
- }
- samehandstrings[samehand] += count;
- }
- if (!samehandcount[samehand.length]){
- samehandcount[samehand.length] = 0;
- }
- samehandcount[samehand.length] += count
- samehand = char;
- }
- // finger pairs
- if (!m_finger_pairs[prevfinger]) {
- m_finger_pairs[prevfinger] = {};
- }
- if (!m_finger_pairs[prevfinger][finger]) {
- m_finger_pairs[prevfinger][finger] = 0;
- }
- if (char != prevchar){
- m_finger_pairs[prevfinger][finger] += count;
- }
- }
- // trigram stuff
- if (i > 1 && prevcol >= 0) {
- skip = ppchar + "_" + char;
- trigram = ppchar + prevchar + char;
- if (finger == ppfinger && ppchar != char) {
- if (!m_skip_bigram[skip]) {
- m_skip_bigram[skip] = 0;
- }
- m_skip_bigram[skip] += count;
-
- if (Math.abs(getRow(ppchar)-row) >= 2) {
- if (!m_skip_bigram2[skip]) {
- m_skip_bigram2[skip] = 0
- }
- m_skip_bigram2[skip] += count;
- }
- }
- cat = "other";
- // cat2 = "other";
- if (ppfinger <= 5 && prevfinger <= 5 && finger <= 5) { // left hand
- if (ppfinger < prevfinger && prevfinger < finger) {
- cat = "roll in"
- } else if (ppfinger > prevfinger && prevfinger > finger) {
- cat = "roll out"
- } else if ((ppfinger < prevfinger && finger < prevfinger && finger != ppfinger) || (ppfinger > prevfinger && finger > prevfinger && finger != ppfinger)) {
- cat = "redirect"
- // if (!m_redirects[trigram]) {
- // m_redirects[trigram] = 0;
- // }
- // m_redirects[trigram] += count;
- if (ppfinger == 4 || prevfinger == 4 || finger == 4) {
- } else {
- cat = "weak redirect"
- }
- }
- }
- if (ppfinger >= 6 && prevfinger >= 6 && finger >= 6) { // right hand
- if (ppfinger > prevfinger && prevfinger > finger) {
- cat = "roll in"
- } else if (ppfinger < prevfinger && prevfinger < finger) {
- cat = "roll out"
- } else if ((ppfinger > prevfinger && finger > prevfinger && finger != ppfinger) || (ppfinger < prevfinger && finger < prevfinger && finger != ppfinger)) {
- cat = "redirect"
- // if (!m_redirects[trigram]) {
- // m_redirects[trigram] = 0;
- // }
- // m_redirects[trigram] += count;
- if (ppfinger == 7 || prevfinger == 7 || finger == 7) {
- } else {
- cat = "weak redirect"
- }
- }
- } //
- if ((ppfinger <= 5 && prevfinger >= 6 && finger <= 5) || (ppfinger >= 6 && prevfinger <= 5 && finger >= 6)) {
- cat = "alt"
- if (ppfinger == finger && ppchar != char) {
- cat = "alt sfs"
- }
- // 1 2 3
- } else if (ppfinger <= 5 && prevfinger <= 5 && finger >= 6 && ppfinger < prevfinger) { // LLR
- cat = "bigram roll in" // LEFT
- }
- else if (ppfinger >= 6 && prevfinger <= 5 && finger <= 5 && prevfinger < finger) { // RLL
- cat = "bigram roll in" // LEFT
- }
- else if (ppfinger <= 5 && prevfinger <= 5 && finger >= 6 && ppfinger > prevfinger) { // LLR
- cat = "bigram roll out" // LEFT
- }
- else if (ppfinger >= 6 && prevfinger <= 5 && finger <= 5 && prevfinger > finger) { // RLL
- cat = "bigram roll out"; // LEFT
- }
- else if (ppfinger >= 6 && prevfinger >= 6 && finger <= 5 && ppfinger > prevfinger) { // RRL
- cat = "bigram roll in" // RIGHT
- }
- else if (ppfinger <= 5 && prevfinger >= 6 && finger >= 6 && prevfinger > finger) { // LRR
- cat = "bigram roll in" // RIGHT
- }
- else if (ppfinger >= 6 && prevfinger >= 6 && finger <= 5 && ppfinger < prevfinger) { // RRL
- cat = "bigram roll out" // RIGHT
- }
- else if (ppfinger <= 5 && prevfinger >= 6 && finger >= 6 && prevfinger < finger) { // LRR
- cat = "bigram roll out" // RIGHT
- }
- if (!m_trigram_count[cat]) {
- m_trigram_count[cat] = 0;
- }
- m_trigram_count[cat] += count;
- if (cat == "alt"){
- if (!m_trigram_count_alt[trigram]) {
- m_trigram_count_alt[trigram] = 0;
- }
- // if (count > 20){
- m_trigram_count_alt[trigram] += count;
- // }
- // if (count > 10){ console.log(trigram + " "+ count);}
- }
- if (cat == "redirect" || cat == "weak redirect"){
- if (!m_trigram_count_red[trigram]) {
- m_trigram_count_red[trigram] = 0;
- }
- // if (count > 20){
- m_trigram_count_red[trigram] += count;
- // }
- }
- if (cat == "roll in" || cat == "bigram roll in"){
- if (!m_trigram_count_roll_in[trigram]) {
- m_trigram_count_roll_in[trigram] = 0;
- }
- // if (count > 20){
- m_trigram_count_roll_in[trigram] += count;
- // }
- }
- if (cat == "roll out" || cat == "bigram roll out"){
- if (!m_trigram_count_roll_out[trigram]) {
- m_trigram_count_roll_out[trigram] = 0;
- }
- // if (count > 20){
- m_trigram_count_roll_out[trigram] += count;
- // }
- }
- }
- pprow = prevrow
- prevcol = col;
- prevrow = row;
- prevhand = hand;
- ppchar = prevchar;
- ppfinger = prevfinger;
- prevchar = char;
- prevfinger = finger;
- }
- if (samehand.length >= 4) {
- if (!samehandstrings[samehand]) {
- samehandstrings[samehand] = 0;
- }
- samehandstrings[samehand] += count;
- }
- if (!samehandcount[samehand.length]){
- samehandcount[samehand.length] = 0;
- }
- samehandcount[samehand.length] += count
- }
- inv_m_input_length = 1.0 / m_input_length;
- var scale = 1006393 * inv_m_input_length;
- m_total_word_effort *= scale;
- // console.log("word count "+word_count)
- var sum = 0;
- for (let letter in m_letter_freq) {
- sum += m_letter_freq[letter]
- }
- const hundred_inv_sum = 100.0 / sum;
- for (let letter in m_letter_freq) {
- for (let i = 0; i < rcdata_len; i++) {
- if (rcdata[i][0] == letter) {
- rcdata[i][3] = hundred_inv_sum * m_letter_freq[letter]
- }
- }
- }
- needs_update = false;
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log("measureWords");
+ if (!needs_update) {
+ return;
+ }
+ m_column_usage = {};
+ m_finger_usage = {};
+ m_finger_distance = {};
+ m_skip_bigram = {};
+ m_skip_bigram2 = {};
+ m_redirects = {};
+ m_scissors = {};
+ m_all_scissors = {};
+ m_pinky_scissors = {};
+ m_same_finger = {};
+ m_same_finger2 = {};
+ m_same_finger3 = {};
+ m_lat_stretch = {};
+ m_lat_stretch2 = {};
+ m_letter_freq = {};
+ m_row_usage = {};
+ m_trigram_count = {};
+ m_trigram_count_alt = {};
+ m_trigram_count_red = {};
+ m_trigram_count_roll_in = {};
+ m_trigram_count_roll_out = {};
+ m_finger_pairs = {};
+ samehandstrings = {};
+ samehandcount = {};
+ m_pinky_off = 0;
+ m_input_length = 0;
+ m_effort = 0;
+ m_total_word_effort = 0;
+ var char = "";
+ var prevchar = "";
+ var prevfinger = -1;
+ var ppchar = "";
+ var ppfinger = -1;
+ var bigram, trigram, cat, cat2, skip;
+ var prevcol = -1;
+ var prevrow = -1;
+ var pprow = -1;
+ var col, row, hand, prevhand;
+ var m_effort_per_letter = {};
+ var m_effort_per_word = {};
+ var word_count = 0;
+
+ for (const word in words) {
+ if (word_count > 40000) break;
+
+ word_count += 1;
+ finger_pos = [
+ [0, 0],
+ [1, 1],
+ [1, 2],
+ [1, 3],
+ [1, 4],
+ [3, 4],
+ [3, 7],
+ [1, 7],
+ [1, 8],
+ [1, 9],
+ [1, 10],
+ ];
+
+ const count = words[word];
+ word_len = word.length;
+ m_input_length += count * (word_len + 1);
+
+ if (word_effort[word]) {
+ // console.log(word +" "+word_effort[word]);
+ m_total_word_effort += word_effort[word] * count;
+ }
+
+ char = word.charAt(0);
+ samehand = char;
+
+ for (let i = 0; i < word_len; i++) {
+ char = word.charAt(i);
+ if (i > 0) {
+ prevchar = word.charAt(i - 1);
+ }
+ // freq //
+ if (!m_letter_freq[char]) {
+ m_letter_freq[char] = 0;
+ }
+ m_letter_freq[char] += count;
+ // finger usage //
+ row = getRow(char);
+ col = getCol(char);
+ if (i > 0) {
+ prevcol = getCol(prevchar);
+ }
+ if (col <= 5) {
+ hand = "L";
+ } else {
+ hand = "R";
+ }
+ if (col < 0) {
+ continue;
+ } // (cyanophage) this is the part that just skips numbers and other characters
+ if (!m_column_usage[col]) {
+ m_column_usage[col] = 0;
+ }
+ if (
+ (row === 0 && col === 1) ||
+ (row === 2 && col === 1) ||
+ (row === 0 && col === 10) ||
+ (row === 2 && col === 10) ||
+ (row === 0 && col === 11) ||
+ (row === 1 && col === 11)
+ ) {
+ m_pinky_off += count;
+ }
+ if (row < 3) {
+ m_column_usage[col] += count;
+ }
+ // finger usage //
+ // effort
+ if (!m_effort_per_letter[char]) {
+ m_effort_per_letter[char] = 0;
+ }
+ m_effort_per_letter[char] += count * getEffort(row, col);
+ if (!m_effort_per_word[word]) {
+ m_effort_per_word[word] = 0;
+ }
+ m_effort_per_word[word] += count * getEffort(row, col);
+
+ m_effort += count * getEffort(row, col);
+
+ const finger = getFinger(row, col);
+ if (!m_finger_usage[finger]) {
+ m_finger_usage[finger] = 0;
+ }
+ m_finger_usage[finger] += count;
+ // finger travel distance
+ if (row < 0) {
+ break;
+ }
+ // d = dist(col, row, finger_pos[finger][1], finger_pos[finger][0]);
+ x1 = getX(char, row, col);
+ y1 = getY(row);
+ x2 = getX(
+ getChar(finger_pos[finger][0], finger_pos[finger][1]),
+ finger_pos[finger][0],
+ finger_pos[finger][1],
+ );
+ y2 = getY(
+ finger_pos[finger][0]
+ );
+ d = dist(x1, y1, x2, y2);
+ if (!m_finger_distance[finger]) {
+ m_finger_distance[finger] = 0;
+ }
+ m_finger_distance[finger] += d * count;
+
+ finger_pos[finger] = [row, col]; // move finger to new position
+
+ // finger row //
+ if (!m_row_usage[row]) {
+ m_row_usage[row] = 0;
+ }
+ m_row_usage[row] += count;
+
+ // bigram stuff
+ if (i > 0 && prevcol >= 0) {
+ bigram = prevchar + char;
+ if (finger === prevfinger && prevchar !== char) {
+ if (!m_same_finger[bigram]) {
+ m_same_finger[bigram] = 0;
+ }
+ m_same_finger[bigram] += count;
+
+ if (!m_same_finger2[finger]) {
+ m_same_finger2[finger] = 0;
+ }
+ m_same_finger2[finger] += count;
+
+ if (Math.abs(row - prevrow) >= 2) {
+ if (!m_same_finger3[bigram]) {
+ m_same_finger3[bigram] = 0;
+ }
+ m_same_finger3[bigram] += count;
+ }
+ }
+ // lsbs
+ if (
+ (prevcol === 3 && col === 5) ||
+ (prevcol === 8 && col === 6) ||
+ (prevcol === 5 && col === 3) ||
+ (prevcol === 6 && col === 8)
+ ) {
+ if (!m_lat_stretch[bigram]) {
+ m_lat_stretch[bigram] = 0;
+ }
+ m_lat_stretch[bigram] += count;
+ }
+ if (
+ (prevcol === 2 && col === 5) ||
+ (prevcol === 9 && col === 6) ||
+ (prevcol === 5 && col === 2) ||
+ (prevcol === 6 && col === 9)
+ ) {
+ if (!m_lat_stretch2[bigram]) {
+ m_lat_stretch2[bigram] = 0;
+ }
+ m_lat_stretch2[bigram] += count;
+ }
+ // scissors
+ if (
+ Math.abs(col - prevcol) === 1 &&
+ Math.abs(row - prevrow) >= 2 &&
+ ((finger <= 4 && prevfinger <= 4 && finger !== prevfinger) ||
+ (finger >= 7 && prevfinger >= 7 && finger !== prevfinger))
+ ) {
+ if (!m_scissors[bigram]) {
+ m_scissors[bigram] = 0;
+ }
+ m_scissors[bigram] += count;
+ }
+ // all 2u scissors wide scissors
+ if (
+ Math.abs(row - prevrow) >= 2 &&
+ Math.abs(col - prevcol) >= 1 &&
+ ((finger <= 4 && prevfinger <= 4) || (finger >= 7 && prevfinger >= 7))
+ ) {
+ if (!m_all_scissors[bigram]) {
+ m_all_scissors[bigram] = 0;
+ }
+ m_all_scissors[bigram] += count;
+ }
+ // pinky/ring scissors
+ if (
+ Math.abs(col - prevcol) === 1 &&
+ Math.abs(row - prevrow) >= 1 &&
+ (finger === 1 ||
+ finger === 10 ||
+ prevfinger === 1 ||
+ prevfinger === 10)
+ ) {
+ if (!m_pinky_scissors[bigram]) {
+ m_pinky_scissors[bigram] = 0;
+ }
+ m_pinky_scissors[bigram] += count;
+ }
+ // same hand strings
+ if (prevhand === hand) {
+ samehand = samehand + char;
+ } else {
+ if (samehand.length >= 4) {
+ if (!samehandstrings[samehand]) {
+ samehandstrings[samehand] = 0;
+ }
+ samehandstrings[samehand] += count;
+ }
+ if (!samehandcount[samehand.length]) {
+ samehandcount[samehand.length] = 0;
+ }
+ samehandcount[samehand.length] += count;
+ samehand = char;
+ }
+ // finger pairs
+ if (!m_finger_pairs[prevfinger]) {
+ m_finger_pairs[prevfinger] = {};
+ }
+ if (!m_finger_pairs[prevfinger][finger]) {
+ m_finger_pairs[prevfinger][finger] = 0;
+ }
+ if (char !== prevchar) {
+ m_finger_pairs[prevfinger][finger] += count;
+ }
+ }
+ // trigram stuff
+ if (i > 1 && prevcol >= 0) {
+ skip = `${ppchar}_${char}`;
+ trigram = ppchar + prevchar + char;
+ if (finger === ppfinger && ppchar !== char) {
+ if (!m_skip_bigram[skip]) {
+ m_skip_bigram[skip] = 0;
+ }
+ m_skip_bigram[skip] += count;
+
+ if (Math.abs(getRow(ppchar) - row) >= 2) {
+ if (!m_skip_bigram2[skip]) {
+ m_skip_bigram2[skip] = 0;
+ }
+ m_skip_bigram2[skip] += count;
+ }
+ }
+ cat = "other";
+ // cat2 = "other";
+ if (ppfinger <= 5 && prevfinger <= 5 && finger <= 5) {
+ // left hand
+ if (ppfinger < prevfinger && prevfinger < finger) {
+ cat = "roll in";
+ } else if (ppfinger > prevfinger && prevfinger > finger) {
+ cat = "roll out";
+ } else if (
+ (ppfinger < prevfinger &&
+ finger < prevfinger &&
+ finger !== ppfinger) ||
+ (ppfinger > prevfinger &&
+ finger > prevfinger &&
+ finger !== ppfinger)
+ ) {
+ cat = "redirect";
+ // if (!m_redirects[trigram]) {
+ // m_redirects[trigram] = 0;
+ // }
+ // m_redirects[trigram] += count;
+ if (ppfinger === 4 || prevfinger === 4 || finger === 4) {
+ } else {
+ cat = "weak redirect";
+ }
+ }
+ }
+ if (ppfinger >= 6 && prevfinger >= 6 && finger >= 6) {
+ // right hand
+ if (ppfinger > prevfinger && prevfinger > finger) {
+ cat = "roll in";
+ } else if (ppfinger < prevfinger && prevfinger < finger) {
+ cat = "roll out";
+ } else if (
+ (ppfinger > prevfinger &&
+ finger > prevfinger &&
+ finger !== ppfinger) ||
+ (ppfinger < prevfinger &&
+ finger < prevfinger &&
+ finger !== ppfinger)
+ ) {
+ cat = "redirect";
+ // if (!m_redirects[trigram]) {
+ // m_redirects[trigram] = 0;
+ // }
+ // m_redirects[trigram] += count;
+ if (ppfinger === 7 || prevfinger === 7 || finger === 7) {
+ } else {
+ cat = "weak redirect";
+ }
+ }
+ } //
+ if (
+ (ppfinger <= 5 && prevfinger >= 6 && finger <= 5) ||
+ (ppfinger >= 6 && prevfinger <= 5 && finger >= 6)
+ ) {
+ cat = "alt";
+ if (ppfinger === finger && ppchar !== char) {
+ cat = "alt sfs";
+ }
+ // 1 2 3
+ } else if (
+ ppfinger <= 5 &&
+ prevfinger <= 5 &&
+ finger >= 6 &&
+ ppfinger < prevfinger
+ ) {
+ // LLR
+ cat = "bigram roll in"; // LEFT
+ } else if (
+ ppfinger >= 6 &&
+ prevfinger <= 5 &&
+ finger <= 5 &&
+ prevfinger < finger
+ ) {
+ // RLL
+ cat = "bigram roll in"; // LEFT
+ } else if (
+ ppfinger <= 5 &&
+ prevfinger <= 5 &&
+ finger >= 6 &&
+ ppfinger > prevfinger
+ ) {
+ // LLR
+ cat = "bigram roll out"; // LEFT
+ } else if (
+ ppfinger >= 6 &&
+ prevfinger <= 5 &&
+ finger <= 5 &&
+ prevfinger > finger
+ ) {
+ // RLL
+ cat = "bigram roll out"; // LEFT
+ } else if (
+ ppfinger >= 6 &&
+ prevfinger >= 6 &&
+ finger <= 5 &&
+ ppfinger > prevfinger
+ ) {
+ // RRL
+ cat = "bigram roll in"; // RIGHT
+ } else if (
+ ppfinger <= 5 &&
+ prevfinger >= 6 &&
+ finger >= 6 &&
+ prevfinger > finger
+ ) {
+ // LRR
+ cat = "bigram roll in"; // RIGHT
+ } else if (
+ ppfinger >= 6 &&
+ prevfinger >= 6 &&
+ finger <= 5 &&
+ ppfinger < prevfinger
+ ) {
+ // RRL
+ cat = "bigram roll out"; // RIGHT
+ } else if (
+ ppfinger <= 5 &&
+ prevfinger >= 6 &&
+ finger >= 6 &&
+ prevfinger < finger
+ ) {
+ // LRR
+ cat = "bigram roll out"; // RIGHT
+ }
+ if (!m_trigram_count[cat]) {
+ m_trigram_count[cat] = 0;
+ }
+ m_trigram_count[cat] += count;
+ if (cat === "alt") {
+ if (!m_trigram_count_alt[trigram]) {
+ m_trigram_count_alt[trigram] = 0;
+ }
+ // if (count > 20){
+ m_trigram_count_alt[trigram] += count;
+ // }
+ // if (count > 10){ console.log(trigram + " "+ count);}
+ }
+ if (cat === "redirect" || cat === "weak redirect") {
+ if (!m_trigram_count_red[trigram]) {
+ m_trigram_count_red[trigram] = 0;
+ }
+ // if (count > 20){
+ m_trigram_count_red[trigram] += count;
+ // }
+ }
+ if (cat === "roll in" || cat === "bigram roll in") {
+ if (!m_trigram_count_roll_in[trigram]) {
+ m_trigram_count_roll_in[trigram] = 0;
+ }
+ // if (count > 20){
+ m_trigram_count_roll_in[trigram] += count;
+ // }
+ }
+ if (cat === "roll out" || cat === "bigram roll out") {
+ if (!m_trigram_count_roll_out[trigram]) {
+ m_trigram_count_roll_out[trigram] = 0;
+ }
+ // if (count > 20){
+ m_trigram_count_roll_out[trigram] += count;
+ // }
+ }
+ }
+ pprow = prevrow;
+ prevcol = col;
+ prevrow = row;
+ prevhand = hand;
+ ppchar = prevchar;
+ ppfinger = prevfinger;
+ prevchar = char;
+ prevfinger = finger;
+ }
+
+ if (samehand.length >= 4) {
+ if (!samehandstrings[samehand]) {
+ samehandstrings[samehand] = 0;
+ }
+ samehandstrings[samehand] += count;
+ }
+ if (!samehandcount[samehand.length]) {
+ samehandcount[samehand.length] = 0;
+ }
+ samehandcount[samehand.length] += count;
+ }
+
+ inv_m_input_length = 1.0 / m_input_length;
+ var scale = 1006393 * inv_m_input_length;
+ m_total_word_effort *= scale;
+ // console.log("word count "+word_count)
+
+ let sum_freqs = 0;
+ for (const letter in m_letter_freq) {
+ sum_freqs += m_letter_freq[letter];
+ }
+
+ const hundred_inv_sum_freqs = 100.0 / sum_freqs;
+ for (const letter in m_letter_freq) {
+ for (let i = 0; i < rcdata_len; i++) {
+ if (rcdata[i][0] === letter) {
+ rcdata[i][3] = hundred_inv_sum_freqs * m_letter_freq[letter];
+ }
+ }
+ }
+ needs_update = false;
}
function generatePlots() {
- if (dataloaded == false || dictionaryloaded == false || effortloaded == false) {return;}
- console.log("generatePlots")
- stats.selectAll("*").remove();
- /////////////////////////////////////// C O L U M N U S A G E ////////////////////////////////////////////
- var x = 500;
- var y = 0;
- stats.append("text").attr("x", x + 40).attr("y", 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Column Usage")
- var sum_col_usage = 0;
- for (let col in m_column_usage) {
- sum_col_usage += m_column_usage[col];
- }
- const inv_sum_col_usage = 1.0 / sum_col_usage;
- for (let col in m_column_usage) {
- var height = 300 * m_column_usage[col] * inv_sum_col_usage;
- var tip = parseFloat(100 * m_column_usage[col] * inv_sum_col_usage).toFixed(2);
- var red = Math.floor(275 * m_column_usage[col] * inv_sum_col_usage) + 128
- var green = 128;
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255; }
- var hex_red = red.toString(16);
- var hex_bg = green.toString(16);
-
- stats.append("rect").attr("x", x + col * 20).attr("y", 100 - height).attr("width", 15).attr("height", height)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "#453033").attr("stroke-width", 1)
- .attr("onmouseover", "showTooltip(evt,'" + tip + "%')").attr("onmouseout", "hideTooltip()")
- stats.append("text").attr("x", x + col * 20 + 7).attr("y", 111).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(col)
- //\n"
- }
-
- /////////////////////////////////////// R O W U S A G E ////////////////////////////////////////////
- var x = 770;
- var y = 0;
- stats.append("text").attr("x", x + 40).attr("y", 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Row Usage")
- var sum_row_usage = 0;
- for (let row in m_row_usage) {
- sum_row_usage += m_row_usage[row];
- }
- const inv_sum_row_usage = 1.0 / sum_row_usage;
- for (let row in m_row_usage) {
- var height = 200 * m_row_usage[row] * inv_sum_row_usage;
- var tip = parseFloat(100 * m_row_usage[row] * inv_sum_row_usage).toFixed(2);
- var red = Math.floor(190 * m_row_usage[row] * inv_sum_row_usage) + 128
- var green = 128;
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255; }
- var hex_red = red.toString(16);
- var hex_bg = green.toString(16);
-
- stats.append("rect").attr("x", x + 19).attr("y", y + 40 + row * 20).attr("width", height).attr("height", 14)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "#453033").attr("stroke-width", 1)
- .attr("onmouseover", "showTooltip(evt,'" + tip + "%')").attr("onmouseout", "hideTooltip()")
- stats.append("text").attr("x", x + 9).attr("y", y + 51 + row * 20).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseInt(row) + 1)
- //\n"
- }
- /////////////////////////////////////// F I N G E R U S A G E //////////////////////////////////////
- var x = 0;
- var y = 0;
- stats.append("text").attr("x", x + 40).attr("y", 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Finger Usage")
- var sum = 0;
- var left = 0;
- var right = 0;
- for (let finger in m_finger_usage) {
- sum += m_finger_usage[finger];
- if (finger <= 4) {
- left += m_finger_usage[finger];
- }
- if (finger >= 7) {
- right += m_finger_usage[finger];
- }
- }
- var inv_sum = 1.0 / sum;
- for (let finger in m_finger_usage) {
- var norm_finger_usage = m_finger_usage[finger] * inv_sum
- var height = 300 * norm_finger_usage;
- var tip = parseFloat(100 * norm_finger_usage).toFixed(2);
- var red = Math.floor(275 * norm_finger_usage) + 128
- var green = 128;
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255; }
- var hex_red = red.toString(16);
- var hex_bg = green.toString(16);
- stats.append("rect").attr("x", x + finger * 20).attr("y", 100 - height).attr("width", 15).attr("height", height)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "#453033").attr("stroke-width", 1)
- .attr("onmouseover", "showTooltip(evt,'" + tip + "%')").attr("onmouseout", "hideTooltip()")
- stats.append("text").attr("x", x + finger * 20 + 7).attr("y", 111).attr("fill", "#dfe2eb").attr("font-size", 10)
- .attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(finger)
- }
- stats.append("text").attr("x", x + 57).attr("y", 124).attr("fill", "#dfe2eb").attr("font-size", 11).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseFloat(100 * left * inv_sum).toFixed(2) + "%");
- stats.append("text").attr("x", x + 177).attr("y", 124).attr("fill", "#dfe2eb").attr("font-size", 11).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseFloat(100 * right * inv_sum).toFixed(2) + "%");
- /////////////////////////////////////// F I N G E R D I S T A N C E //////////////////////////////////
- var x = 250;
- var y = 0;
- var max = m_input_length / 5.110882176; // this might be shadowing 'max' above
- sum = 0
- left = 0;
- right = 0;
- for (let finger in m_finger_distance) {
- sum += m_finger_distance[finger];
- if (finger <= 4) {
- left += m_finger_distance[finger];
- }
- if (finger >= 7) {
- right += m_finger_distance[finger];
- }
- }
- var inv_max = 1.0 / max;
- inv_sum = 1.0 / sum;
- stats.append("text").attr("x", x + 40).attr("y", 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Finger Distance")
- for (let finger in m_finger_distance) {
- if (m_finger_distance[finger] > 0) {
- var norm_finger_distance = m_finger_distance[finger] * inv_max;
- var height = 75 * norm_finger_distance;
- var tip = parseFloat(100 * norm_finger_distance).toFixed(2);
- var red = Math.floor(128 * norm_finger_distance) + 128
- var green = 128;
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255; }
- var hex_red = red.toString(16);
- var hex_bg = green.toString(16);
- stats.append("rect").attr("x", x + finger * 20).attr("y", 100 - height).attr("width", 15).attr("height", height)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "#453033").attr("stroke-width", 1)
- .attr("onmouseover", "showTooltip(evt,'" + tip + "')").attr("onmouseout", "hideTooltip()")
- stats.append("text").attr("x", x + finger * 20 + 7).attr("y", 111).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(finger)
- //\n"
- }
- }
- stats.append("text").attr("x", x + 57).attr("y", 124).attr("fill", "#dfe2eb").attr("font-size", 11).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseFloat(100 * left * inv_sum).toFixed(2) + "%");
- stats.append("text").attr("x", x + 177).attr("y", 124).attr("fill", "#dfe2eb").attr("font-size", 11).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseFloat(100 * right * inv_sum).toFixed(2) + "%");
- stats.append("text").attr("x", x + 117).attr("y", 124).attr("fill", "#dfe2eb").attr("font-size", 11).attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(parseFloat(100 * sum * inv_max).toFixed(1));
- // (100*sum/max).toFixed(1)
- /////////////////////////////////// S A M E F I N G E R B I G R A M S ///////////////////////////////
- var x = 0;
- var y = 180;
- sum = 0;
- // toggle button
- stats.append("path").attr("d", `M ${x + 15} ${y - 24} L ${x + 35} ${y - 24} L ${x + 25} ${y - 34} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing same finger bigrams for each bigram, and for each finger')")
- .attr("onmouseout","hideTooltip()").attr("onclick","sfbToggle(-1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 20} L ${x + 35} ${y - 20} L ${x + 25} ${y - 10} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing same finger bigrams for each bigram, and for each finger')")
- .attr("onmouseout","hideTooltip()").attr("onclick","sfbToggle(1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
- if(sfb_toggle == 0) {
- var keyValueArray = Object.entries(m_same_finger);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- m_same_finger = Object.fromEntries(keyValueArray);
-
- for (let bigram in m_same_finger) {
- sum += m_same_finger[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Same Finger Bigrams " + parseFloat(100 * sum).toFixed(2) + "%")
- // stats.append("text").attr("x",x+40).attr("y",y+200).attr("font-size",16).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","left").text("Input Length "+m_input_length);
-
- var i = 0;
- var t = scroll_amount;
- for (let bigram in m_same_finger) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var width = 18000 * m_same_finger[bigram] * inv_m_input_length;
- if (width > 200) { width = 200; }
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", width).attr("height", 10).attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(bigram);
- stats.append("text").attr("x", x + 200).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * m_same_finger[bigram] * inv_m_input_length)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
- } else if(sfb_toggle == 1){
- for (let finger in m_same_finger2) {
- sum += m_same_finger2[finger] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial")
- .attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Same Finger Bigrams " + parseFloat(100 * sum).toFixed(2) + "%")
- for (let finger in m_same_finger2) {
- var height = 30000 * m_same_finger2[finger] * inv_m_input_length;
- if (height > 150) { height = 150;}
- var tip = parseFloat(100 * m_same_finger2[finger] * inv_m_input_length).toFixed(2);
- var red = Math.floor(6000 * m_same_finger2[finger] * inv_m_input_length) + 128
- var green = 128;
- if (red < 16) { red = 16; }
- if (red > 255) { red = 255; }
- var hex_red = red.toString(16);
- var hex_bg = green.toString(16);
- stats.append("rect").attr("x", x + finger * 20).attr("y", y+155 - height).attr("width", 15).attr("height", height)
- .attr("fill", "#" + hex_red + hex_bg + hex_bg).attr("stroke", "#453033").attr("stroke-width", 1)
- .attr("onmouseover", "showTooltip(evt,'" + tip + "%')").attr("onmouseout", "hideTooltip()")
-
- stats.append("text").attr("x", x + finger * 20 + 7).attr("y", y+166).attr("fill", "#dfe2eb").attr("font-size", 10)
- .attr("font-family", "Sans,Arial").attr("text-anchor", "middle").text(finger)
- }
-
- } else {
- var keyValueArray = Object.entries(m_same_finger3);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- m_same_finger3 = Object.fromEntries(keyValueArray);
-
- for (let bigram in m_same_finger3) {
- sum += m_same_finger3[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("2u Same Finger Bigrams " + parseFloat(100 * sum).toFixed(2) + "%")
- // stats.append("text").attr("x",x+40).attr("y",y+200).attr("font-size",16).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","left").text("Input Length "+m_input_length);
-
- var i = 0;
- var t = scroll_amount;
- for (let bigram in m_same_finger3) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var width = 18000 * m_same_finger3[bigram] * inv_m_input_length;
- if (width > 200) { width = 200; }
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", width).attr("height", 10).attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(bigram);
- stats.append("text").attr("x", x + 200).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * m_same_finger3[bigram] * inv_m_input_length)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
-
- }
- /////////////////////////////////// S K I P F I N G E R B I G R A M S ///////////////////////////////
- var x = 250;
- var y = 180;
- sum = 0;
- var tmp;
- if (skip_toggle) {
- var keyValueArray = Object.entries(m_skip_bigram);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Skip Bigrams " + parseFloat(100 * sum).toFixed(2) + "%")
- } else {
- var keyValueArray = Object.entries(m_skip_bigram2);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Skip Bigrams (2u) " + parseFloat(100 * sum).toFixed(2) + "%")
- }
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 24} L ${x + 35} ${y - 24} L ${x + 25} ${y - 34} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing all skip bigrams and only those with a 2u step between 1 and 3')").attr("onmouseout","hideTooltip()").attr("onclick","skipToggle()")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 20} L ${x + 35} ${y - 20} L ${x + 25} ${y - 10} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing all skip bigrams and only those with a 2u step between 1 and 3')").attr("onmouseout","hideTooltip()").attr("onclick","skipToggle()")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
- var i = 0;
- var t = scroll_amount;
- for (let bigram in tmp) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var height = 36000 * tmp[bigram] * inv_m_input_length;
- if (height > 200) { height = 200; }
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", height).attr("height", 10)
- .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 17).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(bigram);
- stats.append("text").attr("x", x + 200).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * tmp[bigram] * inv_m_input_length)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
- //////////////////////////// L A T E R A L S T R E T C H B I G R A M S ///////////////////////////////
- var x = 500;
- var y = 180;
- sum = 0;
- if (lsb_toggle == 0){
- var keyValueArray = Object.entries(m_lat_stretch);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Lat Stretch Bigrams " + parseFloat(100 * sum).toFixed(2) + "%")
- } else {
- var keyValueArray = Object.entries(m_lat_stretch2);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Ring LSBs " + parseFloat(100 * sum).toFixed(2) + "%")
- }
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 24} L ${x + 35} ${y - 24} L ${x + 25} ${y - 34} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing lateral stretches from the middle finger to ring finger')").attr("onmouseout","hideTooltip()").attr("onclick","lsbToggle()")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 20} L ${x + 35} ${y - 20} L ${x + 25} ${y - 10} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing lateral stretches from the middle finger to ring finger')").attr("onmouseout","hideTooltip()").attr("onclick","lsbToggle()")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
- var i = 0;
- var t = scroll_amount;
- for (let bigram in tmp) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var height = 10000 * tmp[bigram] * inv_m_input_length;
- if (height > 200) { height = 200; }
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", height).attr("height", 10)
- .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(bigram);
- stats.append("text").attr("x", x + 200).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * tmp[bigram] * inv_m_input_length)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
- //////////////////////////// S C I S S O R S ///////////////////////////////
- var x = 760;
- var y = 180;
- sum = 0;
-
- if (scissors_toggle == 1) {
- var keyValueArray = Object.entries(m_pinky_scissors);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Pinky/Ring Scissors " + parseFloat(100 * sum).toFixed(2) + "%")
- } else if (scissors_toggle == 0){
- var keyValueArray = Object.entries(m_scissors);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Scissors " + parseFloat(100 * sum).toFixed(2) + "%")
- } else {
- var keyValueArray = Object.entries(m_all_scissors);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let bigram in tmp) {
- sum += tmp[bigram] * inv_m_input_length;
- }
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Wide Scissors " + parseFloat(100 * sum).toFixed(2) + "%")
- }
- stats.append("path").attr("d", `M ${x + 15} ${y - 24} L ${x + 35} ${y - 24} L ${x + 25} ${y - 34} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing scissors on ring and pinky, and all 2u scissors')").attr("onmouseout","hideTooltip()").attr("onclick","scissorsToggle(-1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 20} L ${x + 35} ${y - 20} L ${x + 25} ${y - 10} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Toggle between showing scissors on ring and pinky, and all 2u scissors')").attr("onmouseout","hideTooltip()").attr("onclick","scissorsToggle(1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
- var i = 0;
- var t = scroll_amount;
- for (let bigram in tmp) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var height = 36000 * tmp[bigram] * inv_m_input_length;
- if (height > 180) { height = 180; }
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", height).attr("height", 10)
- .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(bigram);
- stats.append("text").attr("x", x + 190).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * tmp[bigram] * inv_m_input_length)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
- /////////////////////////////////// T R I G R A M S T A T S ///////////////////////////////
- var x = 760;
- var y = 390;
- dx = 105;
- sum = 0;
- scale = 1;
- var trigram_title = "Trigram Stats"
-
- if (trigram_toggle == 0) {
- var keyValueArray = Object.entries(m_trigram_count);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let cat in tmp) {
- sum += tmp[cat]
- }
- trigram_title = "Trigram Stats"
- scale = 1;
- dx = 105;
- } else if (trigram_toggle == 1) {
- var keyValueArray = Object.entries(m_trigram_count_alt);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let cat in tmp) {
- sum += tmp[cat]
- }
- trigram_title = "Trigram Stats (alts)"
- scale = 3;
- dx = 47;
- } else if (trigram_toggle == 2) {
- var keyValueArray = Object.entries(m_trigram_count_red);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let cat in tmp) {
- sum += tmp[cat]
- }
- trigram_title = "Trigram Stats (redirects)"
- scale = 3;
- dx = 47;
- } else if (trigram_toggle == 3) {
- var keyValueArray = Object.entries(m_trigram_count_roll_in);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let cat in tmp) {
- sum += tmp[cat]
- }
- trigram_title = "Trigram Stats (roll in)"
- scale = 3;
- dx = 47;
- } else if (trigram_toggle == 4) {
- var keyValueArray = Object.entries(m_trigram_count_roll_out);
- keyValueArray.sort((a, b) => b[1] - a[1]);
- tmp = Object.fromEntries(keyValueArray);
- for (let cat in tmp) {
- sum += tmp[cat]
- }
- trigram_title = "Trigram Stats (roll out)"
- scale = 3;
- dx = 47;
- }
- const trigram_desc = {
- "alt":"the hands used to type the trigram are either LRL or RLR",
- "alt sfs":"trigram is typed LRL or RLR but finger1 and finger3 are the same and type a different character",
- "bigram roll in":"two adjacent characters in the trigram are typed with the same hand and the first is outside the second",
- "bigram roll out":"two adjacent characters in the trigram are typed with the same hand and the first is inside the second",
- "weak redirect":"a redirect but none of the fingers used are the index finger",
- "redirect":"the three characters of the trigram are typed with the same hand and the direction changes",
- "roll out":"the three characters of the trigram are typed with the same hand and go from the inside to the outside",
- "roll in":"the three characters of the trigram are typed with the same hand and go from the outside to the inside",
- "other":"all other trigrams that don\\'t fit into any of the other categories",
- // "bigram same row":"two adjacent characters in the trigram are typed on the same row",
- // "trigram same row":"the three characters in the trigram are typed on the same row",
- // "double jump":"trigram is typed top, bottom, top or bottom, top, bottom",
- };
- // for(var tri in m_redirects){
- // if (m_redirects[tri] > 40){
- // console.log(tri + " " + m_redirects[tri]);
- // // trigram_desc["redirect"] = trigram_desc["redirect"].concat(" "+tri);
- // }
- // }
- stats.append("path").attr("d", `M ${x + 15} ${y - 20} L ${x + 35} ${y - 20} L ${x + 25} ${y - 10} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Change pages to see different trigram stats')").attr("onmouseout","hideTooltip()").attr("onclick","trigramToggle(-1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("path").attr("d", `M ${x + 15} ${y - 24} L ${x + 35} ${y - 24} L ${x + 25} ${y - 34} Z`)
- .attr("fill", "#777777").attr("stroke", "#989898").attr("stroke-width", 1).attr("onmouseover","showTooltip(evt,'Change pages to see different trigram stats')").attr("onmouseout","hideTooltip()").attr("onclick","trigramToggle(1)")
- .on("mouseover", function() { d3.select(this).attr("fill", "#bbbbbb"); }) .on("mouseout", function() { d3.select(this).attr("fill", "#777777"); });
-
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text(trigram_title)
-
- var i = 0
- var t = trigram_scroll_amount;
- inv_sum = 1.0 / sum;
- for (let cat in tmp) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var tmp_cat_inv_sum = tmp[cat] * inv_sum;
- var width = scale * 200 * tmp_cat_inv_sum;
- if (width > 200) { width = 200; }
- stats.append("rect").attr("x", x + dx).attr("y", y + i * 15).attr("width", width).attr("height", 10)
- .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- .attr("onmouseover","showTooltip(evt,'"+trigram_desc[cat]+"')").attr("onmouseout","hideTooltip()")
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 9).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(cat);
- stats.append("text").attr("x", x + 190).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (100 * tmp_cat_inv_sum)).toFixed(2) + "%");
- //\n"
- i += 1;
- if (i > 10) { break; }
- }
-
- /////////////////////////////////// S A M E H A N D S T R I N G S ///////////////////////////////
- var x = 250;
- var y = 390;
- sum = 0;
-
- var keyValueArray = Object.entries(samehandstrings);
- keyValueArray.sort((a, b) => b[1]*b[0].length - a[1]*a[0].length);
- samehandstrings = Object.fromEntries(keyValueArray);
-
- scale = 30191.79 * inv_m_input_length
- // console.log("input length: "+m_input_length)
- // console.log("scale : "+scale)
- stats.append("text").attr("x", x + 20).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Same Hand Strings")
- var i = 0
- t = sh_scroll_amount;
- for (let word in samehandstrings) {
- if (t > 0){
- t -= 1;
- continue;
- }
- var count = samehandstrings[word];
- // console.log(word + " " + count)
- word_len = word.length
- var word_len_count = word_len * count;
- var width = scale * word_len_count;
- if (width > 100) {width = 100;}
- stats.append("rect").attr("x", x + 70).attr("y", y + i * 15).attr("width", width).attr("height", 10).attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(word);
- stats.append("text").attr("x", x + 135).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (word_len_count)).toFixed(0));//
- i += 1;
- if (i > 10) { break; }
- }
-
- /////////////////////////////////// S A M E H A N D C O U N T S ///////////////////////////////
- var x = 415;
- var y = 390;
- sum = 0;
-
- // var keyValueArray = Object.entries(samehandcount);
- // keyValueArray.sort((a, b) => b - a);
- // samehandcount = Object.fromEntries(keyValueArray);
- scale = 140.89502 * inv_m_input_length
- // console.log("input length: "+m_input_length)
- // console.log("scale : "+scale)
- stats.append("text").attr("x", x + 20).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Same Hand Count")
- var i = 0
- for (let len in samehandcount) {
- var count = samehandcount[len];
- var width = scale * count;
- if (width > 100) {width = 100;}
- stats.append("rect").attr("x", x + 40).attr("y", y + i * 15).attr("width", width).attr("height", 10).attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(len);
- stats.append("text").attr("x", x + 135).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text((scale*7.14285714285714285714285*count).toFixed(1));
- // stats.append("text").attr("x", x + 135).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(count);
- i += 1;
- if (i > 10) { break; }
- }
-
- /////////////////////////////////// H A R D W O R D S ///////////////////////////////
- var x = 580;
- var y = 390;
- sum = 0;
- var keyValueArray = Object.entries(word_effort);
- keyValueArray.sort((a, b) => b[1]/b[0].length - a[1]/a[0].length);
- word_effort = Object.fromEntries(keyValueArray);
- stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Hard Words ")
- var i = 0
- t = hw_scroll_amount;
- for (let word in word_effort) {
- word_len = word.length
- if (word_len > 3 && words[word] > 4){
- if (t > 0){
- t -= 1;
- continue;
- }
- var height = 100*word_effort[word] / word_len;
- stats.append("rect").attr("x", x + 80).attr("y", y + i * 15).attr("width", height).attr("height", 10).attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Roboto Mono").attr("text-anchor", "right").text(word);
- stats.append("text").attr("x", x + 165).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (word_effort[word])).toFixed(2));
- i += 1;
- if (i > 10) { break; }
- }
- }
- /////////////////////////////////// E A S Y W O R D S ///////////////////////////////
- // var x = 610;
- // var y = 390;
- // sum = 0;
- // var keyValueArray = Object.entries(word_effort);
- // keyValueArray.sort((a, b) => a[1] - b[1]);
- // word_effort = Object.fromEntries(keyValueArray);
- // stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Easy Words ")
- // var i = 0
- // for (var word in word_effort) {
- // var height = 10*word_effort[word];
- // if (word.length > 3){
- // stats.append("rect").attr("x", x + 80).attr("y", y + i * 15).attr("width", height).attr("height", 10)
- // .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
- // stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "right").text(word);
- // stats.append("text").attr("x", x + 125).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (word_effort[word])).toFixed(2));
- // i += 1;
- // if (i > 10) { break; }
- // }
- // }
-
-
- /////////////////////////////////// F I N G E R P A I R S ///////////////////////////////
- var x = 10;
- var y = 370;
- var box_x = 26;
- var box_y = 20;
- var per = 0;
- var finger1 = i;
- var finger2 = j;
- var sum = 0;
- stats.append("text").attr("x",0).attr("y",0).attr("font-size",10).attr("font-family","Sans,Arial")
- .attr("fill","#dfe2eb").attr("text-anchor","middle")
- .attr("transform",`translate(${x+2},${y+100}) rotate(-90)`)
- .text("First Finger");
- stats.append("text").attr("x",x+130).attr("y",y).attr("font-size",10).attr("font-family","Sans,Arial")
- .attr("fill","#dfe2eb").attr("text-anchor","middle")
- .text("Second Finger");
- for(var i = 0; i <= 8; i++){
- sum = 0;
- for(var j = 1; j <= 8; j++){
- finger1 = i;
- finger2 = j;
- if (i > 4){finger1 += 2;}
- if (j > 4){finger2 += 2;}
- if (m_finger_pairs[finger1]){
- if (m_finger_pairs[finger1][finger2]){
- sum += m_finger_pairs[finger1][finger2];
- }
- }
- }
- for(var j = 0; j <= 8; j++){
- finger1 = i;
- finger2 = j;
- if (i > 4){finger1 += 2;}
- if (j > 4){finger2 += 2;}
- if (i == 0 && j == 0){
-
- } else if (i == 0 && j > 0) {
- stats.append("text").attr("x",x+box_x*j+14).attr("y",y+box_y*i+14).attr("font-size",10).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","middle").text(finger2);
- } else if (i > 0 && j == 0) {
- stats.append("text").attr("x",x+box_x*j+14).attr("y",y+box_y*i+14).attr("font-size",10).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","middle").text(finger1);
- } else {
- if (m_finger_pairs[finger1]){
- if (m_finger_pairs[finger1][finger2]){
- if (sum > 0){
- per = parseFloat(100 * m_finger_pairs[finger1][finger2] / sum).toFixed(0);
- } else { per = -1;}
- red = Math.floor(128 + 3 * per);
- if (red > 255) {red = 255;}
- hex_red = red.toString(16);
-
- stats.append("rect").attr("x",x+box_x*j).attr("y",y+box_y*i).attr("width",box_x).attr("height",box_y).attr("fill","#"+hex_red+hex_bg+hex_bg).attr("stroke","black").attr("stroke-width","0.5");
- stats.append("text").attr("x",x+box_x*j+14).attr("y",y+box_y*i+14).attr("font-size",10).attr("font-family","Sans,Arial").attr("fill","black").attr("text-anchor","middle").text(per+"%");
- }
- }
- }
- }
- }
+ if (
+ dataloaded === false ||
+ dictionaryloaded === false ||
+ effortloaded === false
+ ) {
+ return;
+ }
+ console.log("generatePlots");
+ stats.selectAll("*").remove();
+
+ // ================================ C O L U M N U S A G E ================================
+ let x = 500;
+ // let y_column_usage = 0;
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Column Usage");
+
+ let sum_col_usage = 0;
+ for (const col in m_column_usage) {
+ sum_col_usage += m_column_usage[col];
+ }
+ const inv_sum_col_usage = 1.0 / sum_col_usage;
+
+ for (const col in m_column_usage) {
+ const height = 300 * m_column_usage[col] * inv_sum_col_usage;
+ const tip = parseFloat(
+ 100 * m_column_usage[col] * inv_sum_col_usage,
+ ).toFixed(2);
+ let red = Math.floor(275 * m_column_usage[col] * inv_sum_col_usage) + 128;
+ const green = 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ const hex_red = red.toString(16);
+ const hex_bg = green.toString(16);
+
+ stats
+ .append("rect")
+ .attr("x", x + col * 20)
+ .attr("y", 100 - height)
+ .attr("width", 15)
+ .attr("height", height)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "#453033")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${tip}%')`)
+ .attr("onmouseout", "hideTooltip()");
+ stats
+ .append("text")
+ .attr("x", x + col * 20 + 7)
+ .attr("y", 111)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(col);
+ //\n"
+ }
+
+ // ================================ R O W U S A G E ================================
+ x = 770;
+ const y_row_usage = 0;
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Row Usage");
+
+ let sum_row_usage = 0;
+ for (const row in m_row_usage) {
+ sum_row_usage += m_row_usage[row];
+ }
+ const inv_sum_row_usage = 1.0 / sum_row_usage;
+
+ for (const row in m_row_usage) {
+ const height = 200 * m_row_usage[row] * inv_sum_row_usage;
+ const tip = parseFloat(100 * m_row_usage[row] * inv_sum_row_usage).toFixed(
+ 2,
+ );
+ let red = Math.floor(190 * m_row_usage[row] * inv_sum_row_usage) + 128;
+ const green = 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ const hex_red = red.toString(16);
+ const hex_bg = green.toString(16);
+
+ stats
+ .append("rect")
+ .attr("x", x + 19)
+ .attr("y", y_row_usage + 40 + row * 20)
+ .attr("width", height)
+ .attr("height", 14)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "#453033")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${tip}%')`)
+ .attr("onmouseout", "hideTooltip()");
+ stats
+ .append("text")
+ .attr("x", x + 9)
+ .attr("y", y_row_usage + 51 + row * 20)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(parseInt(row, 10) + 1);
+ //\n"
+ }
+
+ // ================================ F I N G E R U S A G E ================================
+ x = 0;
+ // let y_finger_usage = 0;
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Finger Usage");
+
+ let sum_finger_usage = 0;
+ var left = 0;
+ var right = 0;
+
+ for (const finger in m_finger_usage) {
+ sum_finger_usage += m_finger_usage[finger];
+ if (finger <= 4) {
+ left += m_finger_usage[finger];
+ }
+ if (finger >= 7) {
+ right += m_finger_usage[finger];
+ }
+ }
+ const inv_sum_finger_usage = 1.0 / sum_finger_usage;
+
+ for (const finger in m_finger_usage) {
+ const norm_finger_usage = m_finger_usage[finger] * inv_sum_finger_usage;
+ const height = 300 * norm_finger_usage;
+ const tip = parseFloat(100 * norm_finger_usage).toFixed(2);
+ let red = Math.floor(275 * norm_finger_usage) + 128;
+ const green = 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ const hex_red = red.toString(16);
+ const hex_bg = green.toString(16);
+ stats
+ .append("rect")
+ .attr("x", x + finger * 20)
+ .attr("y", 100 - height)
+ .attr("width", 15)
+ .attr("height", height)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "#453033")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${tip}%')`)
+ .attr("onmouseout", "hideTooltip()");
+ stats
+ .append("text")
+ .attr("x", x + finger * 20 + 7)
+ .attr("y", 111)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(finger);
+ }
+ stats
+ .append("text")
+ .attr("x", x + 57)
+ .attr("y", 124)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 11)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(`${parseFloat(100 * left * inv_sum_finger_usage).toFixed(2)}%`);
+ stats
+ .append("text")
+ .attr("x", x + 177)
+ .attr("y", 124)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 11)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(`${parseFloat(100 * right * inv_sum_finger_usage).toFixed(2)}%`);
+
+ // ================================ F I N G E R D I S T A N C E ================================
+ x = 250;
+ // const y_finger_distance = 0;
+ var max = m_input_length / 5.110882176; // (narglab) this might be shadowing 'max' above
+ let sum_finger_distance = 0;
+ left = 0;
+ right = 0;
+ for (const finger in m_finger_distance) {
+ sum_finger_distance += m_finger_distance[finger];
+ if (finger <= 4) {
+ left += m_finger_distance[finger];
+ }
+ if (finger >= 7) {
+ right += m_finger_distance[finger];
+ }
+ }
+ var inv_max = 1.0 / max;
+ const inv_sum_finger_distance = 1.0 / sum_finger_distance;
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Finger Distance");
+ for (const finger in m_finger_distance) {
+ if (m_finger_distance[finger] > 0) {
+ const norm_finger_distance = m_finger_distance[finger] * inv_max;
+ const height = 75 * norm_finger_distance;
+ const tip = parseFloat(100 * norm_finger_distance).toFixed(2);
+ let red = Math.floor(128 * norm_finger_distance) + 128;
+ const green = 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ const hex_red = red.toString(16);
+ const hex_bg = green.toString(16);
+ stats
+ .append("rect")
+ .attr("x", x + finger * 20)
+ .attr("y", 100 - height)
+ .attr("width", 15)
+ .attr("height", height)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "#453033")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${tip}')`)
+ .attr("onmouseout", "hideTooltip()");
+ stats
+ .append("text")
+ .attr("x", x + finger * 20 + 7)
+ .attr("y", 111)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(finger);
+ //\n"
+ }
+ }
+ stats
+ .append("text")
+ .attr("x", x + 57)
+ .attr("y", 124)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 11)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(`${parseFloat(100 * left * inv_sum_finger_distance).toFixed(2)}%`);
+ stats
+ .append("text")
+ .attr("x", x + 177)
+ .attr("y", 124)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 11)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(`${parseFloat(100 * right * inv_sum_finger_distance).toFixed(2)}%`);
+ stats
+ .append("text")
+ .attr("x", x + 117)
+ .attr("y", 124)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 11)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(parseFloat(100 * sum_finger_distance * inv_max).toFixed(1));
+
+ // ================================ S A M E F I N G E R B I G R A M S ================================
+ x = 0;
+ const y_same_fb = 180;
+ let sum_sfb = 0;
+ // toggle button
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_same_fb - 24} L ${x + 35} ${y_same_fb - 24} L ${x + 25} ${y_same_fb - 34} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing same finger bigrams for each bigram, and for each finger')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "sfbToggle(-1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_same_fb - 20} L ${x + 35} ${y_same_fb - 20} L ${x + 25} ${y_same_fb - 10} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing same finger bigrams for each bigram, and for each finger')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "sfbToggle(1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+ if (sfb_toggle === 0) {
+ const keyValueArray_same_finger = Object.entries(m_same_finger);
+ keyValueArray_same_finger.sort((a, b) => b[1] - a[1]);
+ m_same_finger = Object.fromEntries(keyValueArray_same_finger);
+
+ for (const bigram in m_same_finger) {
+ sum_sfb += m_same_finger[bigram] * inv_m_input_length;
+ }
+
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_same_fb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Same Finger Bigrams ${parseFloat(100 * sum_sfb).toFixed(2)}%`);
+ // stats.append("text").attr("x",x+40).attr("y",y+200).attr("font-size",16).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","left").text("Input Length "+m_input_length);
+
+ let plot_i = 0;
+ let plot_t = scroll_amount;
+
+ for (const bigram in m_same_finger) {
+ if (plot_t > 0) {
+ plot_t -= 1;
+ continue;
+ }
+ let width = 18000 * m_same_finger[bigram] * inv_m_input_length;
+ if (width > 200) {
+ width = 200;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_same_fb + plot_i * 15)
+ .attr("width", width)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(bigram);
+ stats
+ .append("text")
+ .attr("x", x + 200)
+ .attr("y", y_same_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(
+ `${parseFloat(
+ `${100 * m_same_finger[bigram] * inv_m_input_length}`,
+ ).toFixed(2)}%`,
+ );
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+ } else if (sfb_toggle === 1) {
+ for (const finger in m_same_finger2) {
+ sum_sfb += m_same_finger2[finger] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_same_fb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Same Finger Bigrams ${parseFloat(100 * sum_sfb).toFixed(2)}%`);
+
+ for (const finger in m_same_finger2) {
+ let height = 30000 * m_same_finger2[finger] * inv_m_input_length;
+ if (height > 150) {
+ height = 150;
+ }
+ const tip = parseFloat(
+ 100 * m_same_finger2[finger] * inv_m_input_length,
+ ).toFixed(2);
+ let red =
+ Math.floor(6000 * m_same_finger2[finger] * inv_m_input_length) + 128;
+ const green = 128;
+ if (red < 16) {
+ red = 16;
+ }
+ if (red > 255) {
+ red = 255;
+ }
+ const hex_red = red.toString(16);
+ const hex_bg = green.toString(16);
+ stats
+ .append("rect")
+ .attr("x", x + finger * 20)
+ .attr("y", y_same_fb + 155 - height)
+ .attr("width", 15)
+ .attr("height", height)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "#453033")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${tip}%')`)
+ .attr("onmouseout", "hideTooltip()");
+
+ stats
+ .append("text")
+ .attr("x", x + finger * 20 + 7)
+ .attr("y", y_same_fb + 166)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "middle")
+ .text(finger);
+ }
+ } else {
+ const keyValueArray_same_finger3 = Object.entries(m_same_finger3);
+ keyValueArray_same_finger3.sort((a, b) => b[1] - a[1]);
+ m_same_finger3 = Object.fromEntries(keyValueArray_same_finger3);
+
+ for (const bigram in m_same_finger3) {
+ sum_sfb += m_same_finger3[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_same_fb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`2u Same Finger Bigrams ${parseFloat(100 * sum_sfb).toFixed(2)}%`);
+ // stats.append("text").attr("x",x+40).attr("y",y+200).attr("font-size",16).attr("font-family","Sans,Arial").attr("fill","#dfe2eb").attr("text-anchor","left").text("Input Length "+m_input_length);
+
+ plot_i = 0;
+ plot_t = scroll_amount;
+ for (const bigram in m_same_finger3) {
+ if (plot_t > 0) {
+ plot_t -= 1;
+ continue;
+ }
+ let width = 18000 * m_same_finger3[bigram] * inv_m_input_length;
+ if (width > 200) {
+ width = 200;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_same_fb + plot_i * 15)
+ .attr("width", width)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(bigram);
+ stats
+ .append("text")
+ .attr("x", x + 200)
+ .attr("y", y_same_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(
+ `${parseFloat(
+ `${100 * m_same_finger3[bigram] * inv_m_input_length}`,
+ ).toFixed(2)}%`,
+ );
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+ }
+ // ================================ S K I P F I N G E R B I G R A M S ================================
+ x = 250;
+ const y_skip_fb = 180;
+ let sum_skip_fb = 0;
+ var tmp;
+ if (skip_toggle) {
+ const keyValueArray_skip_bigram = Object.entries(m_skip_bigram);
+ keyValueArray_skip_bigram.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_skip_bigram);
+ for (const bigram in tmp) {
+ sum_skip_fb += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_skip_fb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Skip Bigrams ${parseFloat(100 * sum_skip_fb).toFixed(2)}%`);
+ } else {
+ const keyValueArray_skip_bigram2 = Object.entries(m_skip_bigram2);
+ keyValueArray_skip_bigram2.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_skip_bigram2);
+ for (const bigram in tmp) {
+ sum_skip_fb += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_skip_fb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Skip Bigrams (2u) ${parseFloat(100 * sum_skip_fb).toFixed(2)}%`);
+ }
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_skip_fb - 24} L ${x + 35} ${y_skip_fb - 24} L ${x + 25} ${y_skip_fb - 34} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing all skip bigrams and only those with a 2u step between 1 and 3')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "skipToggle()")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_skip_fb - 20} L ${x + 35} ${y_skip_fb - 20} L ${x + 25} ${y_skip_fb - 10} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing all skip bigrams and only those with a 2u step between 1 and 3')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "skipToggle()")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ plot_i = 0;
+ plot_t = scroll_amount;
+ for (const bigram in tmp) {
+ if (plot_t > 0) {
+ plot_t -= 1;
+ continue;
+ }
+ let height = 36000 * tmp[bigram] * inv_m_input_length;
+ if (height > 200) {
+ height = 200;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_skip_fb + plot_i * 15)
+ .attr("width", height)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 17)
+ .attr("y", y_skip_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(bigram);
+ stats
+ .append("text")
+ .attr("x", x + 200)
+ .attr("y", y_skip_fb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(
+ parseFloat(`${100 * tmp[bigram] * inv_m_input_length}`).toFixed(2) +
+ "%",
+ );
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ L A T E R A L S T R E T C H B I G R A M S ================================
+ x = 500;
+ const y_lat_sb = 180;
+ sum = 0;
+ if (lsb_toggle === 0) {
+ const keyValueArray_lat_stretch = Object.entries(m_lat_stretch);
+ keyValueArray_lat_stretch.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_lat_stretch);
+ for (const bigram in tmp) {
+ sum += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_lat_sb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Lat Stretch Bigrams ${parseFloat(100 * sum).toFixed(2)}%`);
+ } else {
+ const keyValueArray_lat_stretch2 = Object.entries(m_lat_stretch2);
+ keyValueArray_lat_stretch2.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_lat_stretch2);
+ for (const bigram in tmp) {
+ sum += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_lat_sb - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Ring LSBs ${parseFloat(100 * sum).toFixed(2)}%`);
+ }
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_lat_sb - 24} L ${x + 35} ${y_lat_sb - 24} L ${x + 25} ${y_lat_sb - 34} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing lateral stretches from the middle finger to ring finger')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "lsbToggle()")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_lat_sb - 20} L ${x + 35} ${y_lat_sb - 20} L ${x + 25} ${y_lat_sb - 10} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing lateral stretches from the middle finger to ring finger')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "lsbToggle()")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ plot_i = 0;
+ t = scroll_amount;
+ for (const bigram in tmp) {
+ if (plot_t > 0) {
+ plot_t -= 1;
+ continue;
+ }
+ let height = 10000 * tmp[bigram] * inv_m_input_length;
+ if (height > 200) {
+ height = 200;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_lat_sb + plot_i * 15)
+ .attr("width", height)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_lat_sb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(bigram);
+ stats
+ .append("text")
+ .attr("x", x + 200)
+ .attr("y", y_lat_sb + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(
+ parseFloat(`${100 * tmp[bigram] * inv_m_input_length}`).toFixed(2) +
+ "%",
+ );
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ S C I S S O R S ================================
+ x = 760;
+ const y_scissors = 180;
+ sum = 0;
+
+ if (scissors_toggle === 1) {
+ const keyValueArray_pinky_scissors = Object.entries(m_pinky_scissors);
+ keyValueArray_pinky_scissors.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_pinky_scissors);
+ for (const bigram in tmp) {
+ sum += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_scissors - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Pinky/Ring Scissors ${parseFloat(100 * sum).toFixed(2)}%`);
+ } else if (scissors_toggle === 0) {
+ const keyValueArray_scissors = Object.entries(m_scissors);
+ keyValueArray_scissors.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_scissors);
+ for (const bigram in tmp) {
+ sum += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_scissors - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Scissors ${parseFloat(100 * sum).toFixed(2)}%`);
+ } else {
+ const keyValueArray_all_scissors = Object.entries(m_all_scissors);
+ keyValueArray_all_scissors.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_all_scissors);
+ for (const bigram in tmp) {
+ sum += tmp[bigram] * inv_m_input_length;
+ }
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_scissors - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(`Wide Scissors ${parseFloat(100 * sum).toFixed(2)}%`);
+ }
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_scissors - 24} L ${x + 35} ${y_scissors - 24} L ${x + 25} ${y_scissors - 34} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing scissors on ring and pinky, and all 2u scissors')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "scissorsToggle(-1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_scissors - 20} L ${x + 35} ${y_scissors - 20} L ${x + 25} ${y_scissors - 10} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Toggle between showing scissors on ring and pinky, and all 2u scissors')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "scissorsToggle(1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ plot_i = 0;
+ plot_t = scroll_amount;
+ for (const bigram in tmp) {
+ if (t > 0) {
+ t -= 1;
+ continue;
+ }
+ let height = 36000 * tmp[bigram] * inv_m_input_length;
+ if (height > 180) {
+ height = 180;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_scissors + plot_i * 15)
+ .attr("width", height)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_scissors + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(bigram);
+ stats
+ .append("text")
+ .attr("x", x + 190)
+ .attr("y", y_scissors + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(
+ parseFloat(`${100 * tmp[bigram] * inv_m_input_length}`).toFixed(2) +
+ "%",
+ );
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ T R I G R A M S T A T S ================================
+ x = 760;
+ const y_trigram = 390;
+ dx = 105;
+ sum = 0;
+ scale = 1;
+ var trigram_title = "Trigram Stats";
+
+ if (trigram_toggle === 0) {
+ const keyValueArray_trigram_count = Object.entries(m_trigram_count);
+ keyValueArray_trigram_count.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_trigram_count);
+ for (const cat in tmp) {
+ sum += tmp[cat];
+ }
+ trigram_title = "Trigram Stats";
+ scale = 1;
+ dx = 105;
+ } else if (trigram_toggle === 1) {
+ const keyValueArray_trigram_count_alt = Object.entries(m_trigram_count_alt);
+ keyValueArray_trigram_count_alt.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_trigram_count_alt);
+ for (const cat in tmp) {
+ sum += tmp[cat];
+ }
+ trigram_title = "Trigram Stats (alts)";
+ scale = 3;
+ dx = 47;
+ } else if (trigram_toggle === 2) {
+ const keyValueArray_trigram_count_red = Object.entries(m_trigram_count_red);
+ keyValueArray_trigram_count_red.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_trigram_count_red);
+ for (const cat in tmp) {
+ sum += tmp[cat];
+ }
+ trigram_title = "Trigram Stats (redirects)";
+ scale = 3;
+ dx = 47;
+ } else if (trigram_toggle === 3) {
+ const keyValueArray_trigram_count_roll_in = Object.entries(m_trigram_count_roll_in);
+ keyValueArray_trigram_count_roll_in.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_trigram_count_roll_in);
+ for (const cat in tmp) {
+ sum += tmp[cat];
+ }
+ trigram_title = "Trigram Stats (roll in)";
+ scale = 3;
+ dx = 47;
+ } else if (trigram_toggle === 4) {
+ const keyValueArray_trigram_count_roll_out = Object.entries(m_trigram_count_roll_out);
+ keyValueArray_trigram_count_roll_out.sort((a, b) => b[1] - a[1]);
+ tmp = Object.fromEntries(keyValueArray_trigram_count_roll_out);
+ for (const cat in tmp) {
+ sum += tmp[cat];
+ }
+ trigram_title = "Trigram Stats (roll out)";
+ scale = 3;
+ dx = 47;
+ }
+ const trigram_desc = {
+ alt: "the hands used to type the trigram are either LRL or RLR",
+ "alt sfs":
+ "trigram is typed LRL or RLR but finger1 and finger3 are the same and type a different character",
+ "bigram roll in":
+ "two adjacent characters in the trigram are typed with the same hand and the first is outside the second",
+ "bigram roll out":
+ "two adjacent characters in the trigram are typed with the same hand and the first is inside the second",
+ "weak redirect":
+ "a redirect but none of the fingers used are the index finger",
+ redirect:
+ "the three characters of the trigram are typed with the same hand and the direction changes",
+ "roll out":
+ "the three characters of the trigram are typed with the same hand and go from the inside to the outside",
+ "roll in":
+ "the three characters of the trigram are typed with the same hand and go from the outside to the inside",
+ other:
+ "all other trigrams that don\\'t fit into any of the other categories",
+ // "bigram same row":"two adjacent characters in the trigram are typed on the same row",
+ // "trigram same row":"the three characters in the trigram are typed on the same row",
+ // "double jump":"trigram is typed top, bottom, top or bottom, top, bottom",
+ };
+ // for(var tri in m_redirects){
+ // if (m_redirects[tri] > 40){
+ // console.log(tri + " " + m_redirects[tri]);
+ // // trigram_desc["redirect"] = trigram_desc["redirect"].concat(" "+tri);
+ // }
+ // }
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_trigram - 20} L ${x + 35} ${y_trigram - 20} L ${x + 25} ${y_trigram - 10} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Change pages to see different trigram stats')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "trigramToggle(-1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("path")
+ .attr(
+ "d",
+ `M ${x + 15} ${y_trigram - 24} L ${x + 35} ${y_trigram - 24} L ${x + 25} ${y_trigram - 34} Z`,
+ )
+ .attr("fill", "#777777")
+ .attr("stroke", "#989898")
+ .attr("stroke-width", 1)
+ .attr(
+ "onmouseover",
+ "showTooltip(evt,'Change pages to see different trigram stats')",
+ )
+ .attr("onmouseout", "hideTooltip()")
+ .attr("onclick", "trigramToggle(1)")
+ .on("mouseover", function () {
+ d3.select(this).attr("fill", "#bbbbbb");
+ })
+ .on("mouseout", function () {
+ d3.select(this).attr("fill", "#777777");
+ });
+
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_trigram - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text(trigram_title);
+
+ plot_i = 0;
+ plot_t = trigram_scroll_amount;
+ inv_sum = 1.0 / sum;
+
+ for (const cat in tmp) {
+ if (t > 0) {
+ t -= 1;
+ continue;
+ }
+ const tmp_cat_inv_sum = tmp[cat] * inv_sum;
+ let width = scale * 200 * tmp_cat_inv_sum;
+ if (width > 200) {
+ width = 200;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + dx)
+ .attr("y", y_trigram + plot_i * 15)
+ .attr("width", width)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1)
+ .attr("onmouseover", `showTooltip(evt,'${trigram_desc[cat]}')`)
+ .attr("onmouseout", "hideTooltip()");
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_trigram + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 9)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(cat);
+ stats
+ .append("text")
+ .attr("x", x + 190)
+ .attr("y", y_trigram + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(`${parseFloat(`${100 * tmp_cat_inv_sum}`).toFixed(2)}%`);
+ //\n"
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ S A M E H A N D S T R I N G S ================================
+ x = 250;
+ const y_same_hand_strings = 390;
+ sum = 0;
+
+ const keyValueArray_same_hand_strings = Object.entries(samehandstrings);
+ keyValueArray_same_hand_strings.sort((a, b) => b[1] * b[0].length - a[1] * a[0].length);
+ samehandstrings = Object.fromEntries(keyValueArray_same_hand_strings);
+
+ scale = 30191.79 * inv_m_input_length;
+ // console.log("input length: "+m_input_length)
+ // console.log("scale : "+scale)
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_hand_strings - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Same Hand Strings");
+
+ plot_i = 0;
+ plot_t = sh_scroll_amount;
+ for (const word in samehandstrings) {
+ if (plot_t > 0) {
+ plot_t -= 1;
+ continue;
+ }
+ const count = samehandstrings[word];
+ // console.log(word + " " + count)
+ word_len = word.length;
+ const word_len_count = word_len * count;
+ let width = scale * word_len_count;
+ if (width > 100) {
+ width = 100;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 70)
+ .attr("y", y_same_hand_strings + plot_i * 15)
+ .attr("width", width)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_hand_strings + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(word);
+ stats
+ .append("text")
+ .attr("x", x + 135)
+ .attr("y", y_same_hand_strings + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(parseFloat(`${word_len_count}`).toFixed(0));
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ S A M E H A N D C O U N T S ================================
+ x = 415;
+ const y_same_hand_counts = 390;
+ sum = 0;
+
+ // var keyValueArray = Object.entries(samehandcount);
+ // keyValueArray.sort((a, b) => b - a);
+ // samehandcount = Object.fromEntries(keyValueArray);
+ scale = 140.89502 * inv_m_input_length;
+ // console.log("input length: "+m_input_length)
+ // console.log("scale : "+scale)
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_hand_counts - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Same Hand Count");
+ plot_i = 0;
+ for (const len in samehandcount) {
+ const count = samehandcount[len];
+ let width = scale * count;
+ if (width > 100) {
+ width = 100;
+ }
+ stats
+ .append("rect")
+ .attr("x", x + 40)
+ .attr("y", y_same_hand_counts + plot_i * 15)
+ .attr("width", width)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_same_hand_counts + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(len);
+ stats
+ .append("text")
+ .attr("x", x + 135)
+ .attr("y", y_same_hand_counts + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text((scale * 7.142857142857143 * count).toFixed(1)); // (narglab) was 7.14285714285714285714285, lint/correctness/noPrecisionLoss
+ // stats.append("text").attr("x", x + 135).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(count);
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+
+ // ================================ H A R D W O R D S ================================
+ x = 580;
+ const y_hard_words = 390;
+ sum = 0;
+
+ const keyValueArray_hard_words = Object.entries(word_effort);
+ keyValueArray_hard_words.sort((a, b) => b[1] / b[0].length - a[1] / a[0].length);
+ word_effort = Object.fromEntries(keyValueArray_hard_words);
+ stats
+ .append("text")
+ .attr("x", x + 40)
+ .attr("y", y_hard_words - 16)
+ .attr("font-size", 16)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "left")
+ .text("Hard Words ");
+
+ plot_i = 0;
+ plot_t = hw_scroll_amount;
+
+ for (const word in word_effort) {
+ word_len = word.length;
+ if (word_len > 3 && words[word] > 4) {
+ if (t > 0) {
+ t -= 1;
+ continue;
+ }
+ const height = (100 * word_effort[word]) / word_len;
+ stats
+ .append("rect")
+ .attr("x", x + 80)
+ .attr("y", y_hard_words + plot_i * 15)
+ .attr("width", height)
+ .attr("height", 10)
+ .attr("fill", "#7777bb")
+ .attr("stroke", "#9898d6")
+ .attr("stroke-width", 1);
+ stats
+ .append("text")
+ .attr("x", x + 20)
+ .attr("y", y_hard_words + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Roboto Mono")
+ .attr("text-anchor", "right")
+ .text(word);
+ stats
+ .append("text")
+ .attr("x", x + 165)
+ .attr("y", y_hard_words + plot_i * 15 + 8)
+ .attr("fill", "#dfe2eb")
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("text-anchor", "left")
+ .text(parseFloat(`${word_effort[word]}`).toFixed(2));
+ plot_i += 1;
+ if (plot_i > 10) {
+ break;
+ }
+ }
+ }
+
+ // ================================ E A S Y W O R D S ================================
+ /*
+ var x = 610;
+ var y = 390;
+ sum = 0;
+ var keyValueArray = Object.entries(word_effort);
+ keyValueArray.sort((a, b) => a[1] - b[1]);
+ word_effort = Object.fromEntries(keyValueArray);
+ stats.append("text").attr("x", x + 40).attr("y", y - 16).attr("font-size", 16).attr("font-family", "Sans,Arial").attr("fill", "#dfe2eb").attr("text-anchor", "left").text("Easy Words ")
+ var i = 0
+ for (var word in word_effort) {
+ var height = 10*word_effort[word];
+ if (word.length > 3){
+ stats.append("rect").attr("x", x + 80).attr("y", y + i * 15).attr("width", height).attr("height", 10)
+ .attr("fill", "#7777bb").attr("stroke", "#9898d6").attr("stroke-width", 1)
+ stats.append("text").attr("x", x + 20).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "right").text(word);
+ stats.append("text").attr("x", x + 125).attr("y", y + i * 15 + 8).attr("fill", "#dfe2eb").attr("font-size", 10).attr("font-family", "Sans,Arial").attr("text-anchor", "left").text(parseFloat("" + (word_effort[word])).toFixed(2));
+ i += 1;
+ if (i > 10) { break; }
+ }
+ }
+ */
+
+ // ================================ F I N G E R P A I R S ================================
+ x = 10;
+ const y_finger_pairs = 370;
+ var box_x = 26;
+ var box_y = 20;
+ var per = 0;
+
+ var j = 1;
+
+ let finger1 = plot_i;
+ let finger2 = j;
+
+ let sum_finger_pairs = 0;
+ stats
+ .append("text")
+ .attr("x", 0)
+ .attr("y", 0)
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "middle")
+ .attr(
+ "transform",
+ `translate(${x + 2},${y_finger_pairs + 100}) rotate(-90)`,
+ )
+ .text("First Finger");
+ stats
+ .append("text")
+ .attr("x", x + 130)
+ .attr("y", y_finger_pairs)
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "middle")
+ .text("Second Finger");
+
+ plot_i = 0;
+
+ for (let i = 0; i <= 8; i++) {
+ sum_finger_pairs = 0;
+ for (j = 1; j <= 8; j++) {
+ finger1 = i;
+ finger2 = j;
+ if (i > 4) {
+ finger1 += 2;
+ }
+ if (j > 4) {
+ finger2 += 2;
+ }
+ if (m_finger_pairs[finger1]) {
+ if (m_finger_pairs[finger1][finger2]) {
+ sum_finger_pairs += m_finger_pairs[finger1][finger2];
+ }
+ }
+ }
+ for (j = 0; j <= 8; j++) {
+ finger1 = i;
+ finger2 = j;
+ if (i > 4) {
+ finger1 += 2;
+ }
+ if (j > 4) {
+ finger2 += 2;
+ }
+ if (i === 0 && j === 0) {
+ } else if (i === 0 && j > 0) {
+ stats
+ .append("text")
+ .attr("x", x + box_x * j + 14)
+ .attr("y", y_finger_pairs + box_y * i + 14)
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "middle")
+ .text(finger2);
+ } else if (i > 0 && j === 0) {
+ stats
+ .append("text")
+ .attr("x", x + box_x * j + 14)
+ .attr("y", y_finger_pairs + box_y * i + 14)
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "#dfe2eb")
+ .attr("text-anchor", "middle")
+ .text(finger1);
+ } else {
+ if (m_finger_pairs[finger1]) {
+ if (m_finger_pairs[finger1][finger2]) {
+ if (sum_finger_pairs > 0) {
+ per = parseFloat(
+ (100 * m_finger_pairs[finger1][finger2]) / sum_finger_pairs,
+ ).toFixed(0);
+ } else {
+ per = -1;
+ }
+ red = Math.floor(128 + 3 * per);
+ if (red > 255) {
+ red = 255;
+ }
+ hex_red = red.toString(16);
+
+ stats
+ .append("rect")
+ .attr("x", x + box_x * j)
+ .attr("y", y_finger_pairs + box_y * i)
+ .attr("width", box_x)
+ .attr("height", box_y)
+ .attr("fill", `#${hex_red}${hex_bg}${hex_bg}`)
+ .attr("stroke", "black")
+ .attr("stroke-width", "0.5");
+ stats
+ .append("text")
+ .attr("x", x + box_x * j + 14)
+ .attr("y", y_finger_pairs + box_y * i + 14)
+ .attr("font-size", 10)
+ .attr("font-family", "Sans,Arial")
+ .attr("fill", "black")
+ .attr("text-anchor", "middle")
+ .text(`${per}%`);
+ }
+ }
+ }
+ }
+ }
}
-
function makeDraggable(svg) {
- svg.addEventListener('mousedown', startDrag, false);
- svg.addEventListener('mousemove', drag, false);
- svg.addEventListener('mouseup', endDrag, false);
- svg.addEventListener('mouseleave', endDrag);
-
- svg.addEventListener('touchstart', startDrag);
- svg.addEventListener('touchmove', drag);
- svg.addEventListener('touchend', endDrag);
- svg.addEventListener('touchleave', endDrag);
- svg.addEventListener('touchcancel', endDrag);
-
- function getMousePosition(evt) {
- var CTM = svg.getScreenCTM();
- if (evt.touches) { evt = evt.touches[0]; }
- return {
- x: (evt.clientX - CTM.e) / CTM.a,
- y: (evt.clientY - CTM.f) / CTM.d
- };
- }
-
- var selectedElement, offset, offset2, sibling;
- var starti, dropi, startx, starty;
-
- function startDrag(evt) {
- if (evt.target.classList.contains('draggable')) {
- selectedElement = evt.target;
- if (selectedElement.classList.contains('legend')){
- selectedElement = selectedElement.previousElementSibling;
- sibling = evt.target;
- } else {
- sibling = selectedElement.nextElementSibling; // dude this is super useful!
- }
- if (selectedElement) {
- // move to the end so they appear on top while dragging
- svg.insertBefore(selectedElement, svg.lastChild);
- svg.insertBefore(sibling, svg.lastChild);
-
- x = selectedElement.getAttributeNS(null, "x");
- y = selectedElement.getAttributeNS(null, "y");
- startx = x;
- starty = y;
- // scan through rcdata to find out which key are we closest to
- closestdist = 9999;
- starti = -1;
- var keyname = ""
- for (let i = 0; i < rcdata_len; i++) {
- d = dist(x, y, rcdata[i][5], rcdata[i][4]);
- if (d < closestdist) {
- closestdist = d;
- starti = i;
- keyname = rcdata[i][0];
- }
- }
- // console.log("keyname = "+keyname);
- if (keyname == "mod" || keyname == "back" || keyname == "tab" || keyname == "enter"){
- selectedElement = null;
- return;
- }
- offset = getMousePosition(evt);
- offset2 = getMousePosition(evt);
- offset.x -= parseFloat(selectedElement.getAttributeNS(null, "x"));
- offset.y -= parseFloat(selectedElement.getAttributeNS(null, "y"));
- offset2.x -= parseFloat(sibling.getAttributeNS(null, "x"));
- offset2.y -= parseFloat(sibling.getAttributeNS(null, "y"));
- }
- }
- }
-
- function drag(evt) {
- if (selectedElement) {
- if (sibling) {
- evt.preventDefault();
- var coord = getMousePosition(evt);
- selectedElement.setAttributeNS(null, "x", coord.x - offset.x);
- selectedElement.setAttributeNS(null, "y", coord.y - offset.y);
- sibling.setAttributeNS(null, "x", coord.x - offset2.x);
- sibling.setAttributeNS(null, "y", coord.y - offset2.y);
- }
- }
- }
-
- function endDrag(evt) {
- if (selectedElement) {
- x = selectedElement.getAttributeNS(null, "x");
- y = selectedElement.getAttributeNS(null, "y");
- // console.log("drop at "+x+" "+y);
- // scan through rcdata to find out which key are we closest to
- closestdist = 9999;
- var keyname = ""
- for (let i = 0; i < rcdata_len; i++) {
- d = dist(x, y, rcdata[i][5], rcdata[i][4]);
- keyname = rcdata[i][0];
- if (d < closestdist) {
- if (keyname == "mod" || keyname == "back" || keyname == "tab" || keyname == "enter") {
- } else {
- closestdist = d;
- dropi = i;
- }
- }
- }
- if (dropi == starti) {
- selectedElement.setAttributeNS(null, "x", startx);
- selectedElement.setAttributeNS(null, "y", starty);
- sibling.setAttributeNS(null, "x", parseInt(startx)+15);
- sibling.setAttributeNS(null, "y", parseInt(starty)+19);
- selectedElement = false;
- sibling = false;
- return;
- }
- if (rcdata[starti][0] == "space") {
- if (rcdata[dropi][1] < 3) {
- selectedElement.setAttributeNS(null, "x", startx);
- selectedElement.setAttributeNS(null, "y", starty);
- sibling.setAttributeNS(null, "x", parseInt(startx)+15);
- sibling.setAttributeNS(null, "y", parseInt(starty)+19);
- selectedElement = false;
- sibling = false;
- return;
- }
- }
- if (rcdata[dropi][0] == "space") {
- if (rcdata[starti][1] < 3) {
- selectedElement.setAttributeNS(null, "x", startx);
- selectedElement.setAttributeNS(null, "y", starty);
- sibling.setAttributeNS(null, "x", parseInt(startx)+15);
- sibling.setAttributeNS(null, "y", parseInt(starty)+19);
- selectedElement = false;
- sibling = false;
- return;
- }
- }
- if (closestdist > 0.8){
- selectedElement.setAttributeNS(null, "x", startx);
- selectedElement.setAttributeNS(null, "y", starty);
- sibling.setAttributeNS(null, "x", parseInt(startx)+15);
- sibling.setAttributeNS(null, "y", parseInt(starty)+19);
- selectedElement = false;
- sibling = false;
- return;
- }
- selectedElement = false;
- sibling = false;
-
- // indices = [1,2,4,5,6]
- indices = [0, 3, 7]
- for (let i = 0; i < indices.length; i++){
- var k = indices[i];
- tmp = rcdata[starti][k];
- rcdata[starti][k] = rcdata[dropi][k];
- rcdata[dropi][k] = tmp;
- }
- if (rcdata[33][0] == "space" && rcdata[33][1] == 3 && rcdata[33][2] == 4){
- thumb = "r"
- }
- if (rcdata[39][0] == "space" && rcdata[39][1] == 3 && rcdata[39][2] == 7){
- thumb = "l"
- }
-
- var queryParams = new URLSearchParams(window.location.search);
- queryParams.set("layout", exportLayout());
- queryParams.set("mode",mode)
- queryParams.set("lan",lang)
- queryParams.set("thumb",thumb)
- history.replaceState(null, null, "?"+queryParams.toString());
-
- d3.select(svg).selectAll("*").remove();
- needs_update = true;
- measureDictionary();
- measureWords();
- generateLayout();
- generatePlots();
- }
- }
+ svg.addEventListener("mousedown", startDrag, false);
+ svg.addEventListener("mousemove", drag, false);
+ svg.addEventListener("mouseup", endDrag, false);
+ svg.addEventListener("mouseleave", endDrag);
+
+ svg.addEventListener("touchstart", startDrag);
+ svg.addEventListener("touchmove", drag);
+ svg.addEventListener("touchend", endDrag);
+ svg.addEventListener("touchleave", endDrag);
+ svg.addEventListener("touchcancel", endDrag);
+
+ function getMousePosition(evt) {
+ var CTM = svg.getScreenCTM();
+ if (evt.touches) {
+ evt = evt.touches[0];
+ }
+ return {
+ x: (evt.clientX - CTM.e) / CTM.a,
+ y: (evt.clientY - CTM.f) / CTM.d,
+ };
+ }
+
+ var selectedElement, offset, offset2, sibling;
+ var starti, dropi, startx, starty;
+
+ function startDrag(evt) {
+ if (evt.target.classList.contains("draggable")) {
+ selectedElement = evt.target;
+ if (selectedElement.classList.contains("legend")) {
+ selectedElement = selectedElement.previousElementSibling;
+ sibling = evt.target;
+ } else {
+ sibling = selectedElement.nextElementSibling; // (cyanophage) dude this is super useful!
+ }
+ if (selectedElement) {
+ // (cyanophage) move to the end so they appear on top while dragging
+ svg.insertBefore(selectedElement, svg.lastChild);
+ svg.insertBefore(sibling, svg.lastChild);
+
+ x = selectedElement.getAttributeNS(null, "x");
+ y = selectedElement.getAttributeNS(null, "y");
+ startx = x;
+ starty = y;
+ // (cyanophage) scan through rcdata to find out which key are we closest to
+ closestdist = 9999;
+ starti = -1;
+ let keyname = "";
+ for (let i = 0; i < rcdata_len; i++) {
+ d = dist(x, y, rcdata[i][5], rcdata[i][4]);
+ if (d < closestdist) {
+ closestdist = d;
+ starti = i;
+ keyname = rcdata[i][0];
+ }
+ }
+ // console.log("keyname = "+keyname);
+ if (
+ keyname === "mod" ||
+ keyname === "back" ||
+ keyname === "tab" ||
+ keyname === "enter"
+ ) {
+ selectedElement = null;
+ return;
+ }
+ offset = getMousePosition(evt);
+ offset2 = getMousePosition(evt);
+ offset.x -= parseFloat(selectedElement.getAttributeNS(null, "x"));
+ offset.y -= parseFloat(selectedElement.getAttributeNS(null, "y"));
+ offset2.x -= parseFloat(sibling.getAttributeNS(null, "x"));
+ offset2.y -= parseFloat(sibling.getAttributeNS(null, "y"));
+ }
+ }
+ }
+
+ function drag(evt) {
+ if (selectedElement) {
+ if (sibling) {
+ evt.preventDefault();
+ const coord = getMousePosition(evt);
+ selectedElement.setAttributeNS(null, "x", coord.x - offset.x);
+ selectedElement.setAttributeNS(null, "y", coord.y - offset.y);
+ sibling.setAttributeNS(null, "x", coord.x - offset2.x);
+ sibling.setAttributeNS(null, "y", coord.y - offset2.y);
+ }
+ }
+ }
+
+ function endDrag(evt) {
+ if (selectedElement) {
+ x = selectedElement.getAttributeNS(null, "x");
+ y = selectedElement.getAttributeNS(null, "y");
+ // console.log("drop at "+x+" "+y);
+ // (cyanophage) scan through rcdata to find out which key are we closest to
+ closestdist = 9999;
+ let keyname = "";
+ for (let i = 0; i < rcdata_len; i++) {
+ d = dist(x, y, rcdata[i][5], rcdata[i][4]);
+ keyname = rcdata[i][0];
+ if (d < closestdist) {
+ if (
+ keyname === "mod" ||
+ keyname === "back" ||
+ keyname === "tab" ||
+ keyname === "enter"
+ ) {
+ } else {
+ closestdist = d;
+ dropi = i;
+ }
+ }
+ }
+ if (dropi === starti) {
+ selectedElement.setAttributeNS(null, "x", startx);
+ selectedElement.setAttributeNS(null, "y", starty);
+ sibling.setAttributeNS(null, "x", parseInt(startx, 10) + 15);
+ sibling.setAttributeNS(null, "y", parseInt(starty, 10) + 19);
+ selectedElement = false;
+ sibling = false;
+ return;
+ }
+ if (rcdata[starti][0] === "space") {
+ if (rcdata[dropi][1] < 3) {
+ selectedElement.setAttributeNS(null, "x", startx);
+ selectedElement.setAttributeNS(null, "y", starty);
+ sibling.setAttributeNS(null, "x", parseInt(startx, 10) + 15);
+ sibling.setAttributeNS(null, "y", parseInt(starty, 10) + 19);
+ selectedElement = false;
+ sibling = false;
+ return;
+ }
+ }
+ if (rcdata[dropi][0] === "space") {
+ if (rcdata[starti][1] < 3) {
+ selectedElement.setAttributeNS(null, "x", startx);
+ selectedElement.setAttributeNS(null, "y", starty);
+ sibling.setAttributeNS(null, "x", parseInt(startx, 10) + 15);
+ sibling.setAttributeNS(null, "y", parseInt(starty, 10) + 19);
+ selectedElement = false;
+ sibling = false;
+ return;
+ }
+ }
+ if (closestdist > 0.8) {
+ selectedElement.setAttributeNS(null, "x", startx);
+ selectedElement.setAttributeNS(null, "y", starty);
+ sibling.setAttributeNS(null, "x", parseInt(startx, 10) + 15);
+ sibling.setAttributeNS(null, "y", parseInt(starty, 10) + 19);
+ selectedElement = false;
+ sibling = false;
+ return;
+ }
+ selectedElement = false;
+ sibling = false;
+
+ // indices = [1,2,4,5,6]
+ indices = [0, 3, 7];
+ for (let i = 0; i < indices.length; i++) {
+ const k = indices[i];
+ tmp = rcdata[starti][k];
+ rcdata[starti][k] = rcdata[dropi][k];
+ rcdata[dropi][k] = tmp;
+ }
+ if (
+ rcdata[33][0] === "space" &&
+ rcdata[33][1] === 3 &&
+ rcdata[33][2] === 4
+ ) {
+ thumb = "r";
+ }
+ if (
+ rcdata[39][0] === "space" &&
+ rcdata[39][1] === 3 &&
+ rcdata[39][2] === 7
+ ) {
+ thumb = "l";
+ }
+
+ const queryParams = new URLSearchParams(window.location.search);
+ queryParams.set("layout", exportLayout());
+ queryParams.set("mode", mode);
+ queryParams.set("lan", lang);
+ queryParams.set("thumb", thumb);
+ history.replaceState(null, null, `?${queryParams.toString()}`);
+
+ d3.select(svg).selectAll("*").remove();
+ needs_update = true;
+ measureDictionary();
+ measureWords();
+ generateLayout();
+ generatePlots();
+ }
+ }
}
if (url_layout) {
- importLayout(url_layout)
+ importLayout(url_layout);
}
-loadAllData()
+loadAllData();
if (params.lan) {
- lang = params.lan;
- if (lang != "english"){
- selectLanguage(lang);
- }
-}
\ No newline at end of file
+ lang = params.lan;
+ if (lang !== "english") {
+ selectLanguage(lang);
+ }
+}