Skip to content

Commit ca31912

Browse files
Add a new UI (Interface 3) for testing
1 parent ee2c764 commit ca31912

4 files changed

Lines changed: 251 additions & 23 deletions

File tree

_includes/heatmap-ui2.html

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,45 @@
1010
<label for="all-fingers">
1111
{{ e.total }}
1212
</label>
13-
<input type="radio" id="all-fingers" name="finger-select" value="total" checked><br>
13+
<input checked id="all-fingers" name="finger-select" type="radio" value="total"><br>
1414
<label for="best-finger">
1515
{{ e.preferred }}
1616
</label>
17-
<input type="radio" id="best-finger" name="finger-select" value="preferred"><br>
17+
<input id="best-finger" name="finger-select" type="radio" value="preferred"><br>
1818
<label for="right-hand">
1919
{{ e.hf_format | replace: '%h%', e.right | replace: '%f%', e.hand }}
2020
</label>
21-
<input type="radio" id="right-hand" name="finger-select" value="R"><br>
21+
<input id="right-hand" name="finger-select" type="radio" value="R"><br>
2222
<label for="left-hand">
2323
{{ e.hf_format | replace: '%h%', e.left | replace: '%f%', e.hand }}
2424
</label>
25-
<input type="radio" id="left-hand" name="finger-select" value="L"><br>
25+
<input id="left-hand" name="finger-select" type="radio" value="L"><br>
2626
</p>
27-
<p id="finger-radio" class="finger-radio" style="display: none">
27+
<p class="finger-radio" id="finger-radio" style="display: none">
2828
<label for="finger-all">
2929
{{ e.all_button }}
3030
</label>
31-
<input type="radio" id="finger-all" name="finger" value="H" checked><br>
31+
<input checked id="finger-all" name="finger" type="radio" value="H"><br>
3232
<label for="finger-thumb">
3333
{{ e.thumb }}
3434
</label>
35-
<input type="radio" id="finger-thumb" name="finger" value="T"><br>
35+
<input id="finger-thumb" name="finger" type="radio" value="T"><br>
3636
<label for="finger-index">
3737
{{ e.index }}
3838
</label>
39-
<input type="radio" id="finger-index" name="finger" value="I"><br>
39+
<input id="finger-index" name="finger" type="radio" value="I"><br>
4040
<label for="finger-middle">
4141
{{ e.middle }}
4242
</label>
43-
<input type="radio" id="finger-middle" name="finger" value="M"><br>
43+
<input id="finger-middle" name="finger" type="radio" value="M"><br>
4444
<label for="finger-ring">
4545
{{ e.ring }}
4646
</label>
47-
<input type="radio" id="finger-ring" name="finger" value="R"><br>
47+
<input id="finger-ring" name="finger" type="radio" value="R"><br>
4848
<label for="finger-little">
4949
{{ e.little }}
5050
</label>
51-
<input type="radio" id="finger-little" name="finger" value="L"><br>
51+
<input id="finger-little" name="finger" type="radio" value="L"><br>
5252
</p>
5353
</div>
5454

@@ -66,7 +66,7 @@
6666

6767
<script src="/assets/js/dataviz.js"></script>
6868
<script type="module">
69-
import langFinger from '/assets/js/ui-lang.json' with {type:"json"};
69+
import langFinger from '/assets/js/ui-lang.json' with {type: 'json'};
7070

7171
document.addEventListener('DOMContentLoaded', function () {
7272
const selectionText = document.getElementById('selection-text');
@@ -91,10 +91,24 @@
9191
let min = fixedRange ? fixedRange.min : Infinity;
9292
let max = fixedRange ? fixedRange.max : -Infinity;
9393
if (!fixedRange) {
94-
FACES.forEach(function (f) { data[f].forEach(function (v) { if (v < min) min = v; if (v > max) max = v; }); });
94+
FACES.forEach(function (f) {
95+
data[f].forEach(function (v) {
96+
if (v < min) min = v;
97+
if (v > max) max = v;
98+
});
99+
});
95100
}
96101
if (window.updateModel) {
97-
window.updateModel({ heatmap: data, heatmapMin: min, heatmapMax: max, scores: data, showScores: true, isReachability: true, scoreFormat: 'integer', figure6View: false });
102+
window.updateModel({
103+
heatmap: data,
104+
heatmapMin: min,
105+
heatmapMax: max,
106+
scores: data,
107+
showScores: true,
108+
isReachability: true,
109+
scoreFormat: 'integer',
110+
figure6View: false
111+
});
98112
}
99113
}
100114

@@ -106,7 +120,9 @@
106120
let sum = 0;
107121
fingers.forEach(function (f) {
108122
const fData = window.perFingerReachability[f];
109-
if (fData) fData.forEach(function (p) { sum += p[face][i]; });
123+
if (fData) fData.forEach(function (p) {
124+
sum += p[face][i];
125+
});
110126
});
111127
result[face].push(sum);
112128
}
@@ -138,12 +154,16 @@
138154
const fData = window.perFingerReachability[f];
139155
if (fData) {
140156
let s = 0;
141-
fData.forEach(function (p) { s += p[face][i]; }); if (s > best) best = s; }
157+
fData.forEach(function (p) {
158+
s += p[face][i];
159+
});
160+
if (s > best) best = s;
161+
}
142162
});
143163
result[face].push(best);
144164
}
145165
});
146-
applyHeatmap(result, { min: 0, max: 66 });
166+
applyHeatmap(result, {min: 0, max: 66});
147167
updateUI('best', ALL_FINGERS);
148168
}
149169

@@ -172,10 +192,9 @@
172192
}
173193
}
174194

175-
if (document.querySelectorAll('input[type="radio"]'))
176-
document.querySelectorAll('input[type="radio"]').forEach(elem => {
177-
elem.addEventListener('change', handleSelect);
178-
});
195+
document.querySelectorAll('input[type="radio"]').forEach(elem => {
196+
elem.addEventListener('change', handleSelect);
197+
});
179198

180199
handleSelect();
181200
document.getElementById('model-container').classList.add('active');

_includes/heatmap-ui3.html

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
{% assign e = site.data[page.lang]['heatmap-ui'] %}
2+
3+
<!-- 3D Render of the Keycube -->
4+
{% include dataviz-data.html %}
5+
6+
<!-- ── Bottom bar: badge + finger context + legend + reset ── -->
7+
<div class="bottom-bar">
8+
<div class="row" id="first-row">
9+
<button class="first-row" id="all-fingers" name="finger-select" value="total">
10+
{{ e.total }}
11+
</button>
12+
<button class="first-row" id="best-finger" name="finger-select" value="preferred">
13+
{{ e.preferred }}
14+
</button>
15+
<button class="first-row" id="right-hand" name="finger-select" value="R">
16+
{{ e.hf_format | replace: '%h%', e.right | replace: '%f%', e.hand }}
17+
</button>
18+
<button class="first-row" id="left-hand" name="finger-select" value="L">
19+
{{ e.hf_format | replace: '%h%', e.left | replace: '%f%', e.hand }}
20+
</button>
21+
</div>
22+
<div class="row" id="second-row">
23+
<button class="second-row" id="finger-thumb" name="finger" value="T">{{ e.thumb }}</button>
24+
<button class="second-row" id="finger-index" name="finger" value="I">{{ e.index }}</button>
25+
<button class="second-row" id="finger-middle" name="finger" value="M">{{ e.middle }}</button>
26+
<button class="second-row" id="finger-ring" name="finger" value="R">{{ e.ring }}</button>
27+
<button class="second-row" id="finger-little" name="finger" value="L">{{ e.little }}</button>
28+
</div>
29+
30+
<div class="finger-context" id="finger-context">
31+
{{ e.finger_context }}
32+
</div>
33+
34+
<div class="heatmap-legend" style="flex-basis: 100%; display: flex; justify-content: center; align-items: center;">
35+
<span>{{ e.unreachable }}</span>
36+
<div class="heatmap-gradient"></div>
37+
<span>{{ e.reachable }}</span>
38+
<button class="reset-view-btn" id="reset-view-btn">{{ e.reset_view }}</button>
39+
</div>
40+
</div>
41+
42+
<script src="/assets/js/dataviz.js"></script>
43+
<script type="module">
44+
import langFinger from '/assets/js/ui-lang.json' with {type: 'json'};
45+
46+
document.addEventListener('DOMContentLoaded', function () {
47+
let selectedHand = '';
48+
49+
const selectionText = document.getElementById('selection-text');
50+
const selectionIcon = document.querySelector('#selection-badge .selection-icon');
51+
const fingerContext = document.getElementById('finger-context');
52+
53+
const FACES = ['R', 'B', 'G', 'W', 'Y'];
54+
const ALL_FINGERS = ['LT', 'LI', 'LM', 'LR', 'LL', 'RT', 'RI', 'RM', 'RR', 'RL'];
55+
56+
const lang = document.documentElement.lang
57+
const fingerData = langFinger[lang] ? langFinger[lang] : langFinger["en"];
58+
59+
function updateUI(key) {
60+
const data = fingerData[key] || {name: key, icon: '', info: ''};
61+
if (selectionText) selectionText.textContent = data.name;
62+
if (selectionIcon) selectionIcon.textContent = data.icon;
63+
if (fingerContext) fingerContext.textContent = data.info;
64+
}
65+
66+
function applyHeatmap(data, fixedRange) {
67+
let min = fixedRange ? fixedRange.min : Infinity;
68+
let max = fixedRange ? fixedRange.max : -Infinity;
69+
if (!fixedRange) {
70+
FACES.forEach(function (f) {
71+
data[f].forEach(function (v) {
72+
if (v < min) min = v;
73+
if (v > max) max = v;
74+
});
75+
});
76+
}
77+
if (window.updateModel) {
78+
window.updateModel({
79+
heatmap: data,
80+
heatmapMin: min,
81+
heatmapMax: max,
82+
scores: data,
83+
showScores: true,
84+
isReachability: true,
85+
scoreFormat: 'integer',
86+
figure6View: false
87+
});
88+
}
89+
}
90+
91+
function computeHandData(fingers) {
92+
const result = {};
93+
FACES.forEach(function (face) {
94+
result[face] = [];
95+
for (let i = 0; i < 16; i++) {
96+
let sum = 0;
97+
fingers.forEach(function (f) {
98+
const fData = window.perFingerReachability[f];
99+
if (fData) fData.forEach(function (p) {
100+
sum += p[face][i];
101+
});
102+
});
103+
result[face].push(sum);
104+
}
105+
});
106+
return result;
107+
}
108+
109+
function updateSelection(fingerValue) {
110+
applyHeatmap(computeHandData(fingerValue === 'total' ? ALL_FINGERS : [fingerValue]));
111+
updateUI(fingerValue, fingerValue === 'total' ? ALL_FINGERS : null);
112+
}
113+
114+
function handleHandAll(hand) {
115+
const fingers = hand === 'left' ? ['LT', 'LI', 'LM', 'LR', 'LL'] : ['RT', 'RI', 'RM', 'RR', 'RL'];
116+
applyHeatmap(computeHandData(fingers));
117+
updateUI(hand + '-all', fingers);
118+
}
119+
120+
function handleBestFinger() {
121+
const preferenceAggregate = window.preferenceAggregate;
122+
if (!preferenceAggregate) return;
123+
const result = {};
124+
FACES.forEach(function (face) {
125+
result[face] = [];
126+
for (let i = 0; i < 16; i++) {
127+
let best = 0;
128+
const preferredFingers = preferenceAggregate.tiedFingers[face][i];
129+
preferredFingers.forEach(function (f) {
130+
const fData = window.perFingerReachability[f];
131+
if (fData) {
132+
let s = 0;
133+
fData.forEach(function (p) {
134+
s += p[face][i];
135+
});
136+
if (s > best) best = s;
137+
}
138+
});
139+
result[face].push(best);
140+
}
141+
});
142+
applyHeatmap(result, {min: 0, max: 66});
143+
updateUI('best', ALL_FINGERS);
144+
}
145+
146+
function firstRowHandleSelect(value) {
147+
//console.log(value)
148+
if (value === "total") {
149+
updateSelection("total");
150+
} else if (value === "preferred") {
151+
handleBestFinger();
152+
} else {
153+
selectedHand = value;
154+
if (value === 'L') {
155+
handleHandAll('left');
156+
} else {
157+
handleHandAll('right');
158+
}
159+
}
160+
}
161+
162+
function secondRowHandleSelect(value) {
163+
//console.log(value)
164+
if (selectedHand !== '')
165+
updateSelection(selectedHand + value)
166+
}
167+
168+
document.querySelectorAll('.first-row').forEach(elem => {
169+
elem.addEventListener('click', () => firstRowHandleSelect(elem.value))
170+
})
171+
172+
document.querySelectorAll('.second-row').forEach(elem => {
173+
elem.addEventListener('click', () => secondRowHandleSelect(elem.value))
174+
})
175+
176+
firstRowHandleSelect("total");
177+
document.getElementById('model-container').classList.add('active');
178+
});
179+
</script>

assets/css/heatmap.css

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,38 @@
6363
border-radius: 5px;
6464
}
6565

66+
.row {
67+
flex-basis: 100%;
68+
display: flex;
69+
justify-content: space-around;
70+
align-items: center;
71+
}
72+
73+
.row button {
74+
font: inherit;
75+
font-size: 80%;
76+
background: #fff;
77+
border: 1px solid #c8c8c8;
78+
79+
height: 26px;
80+
border-radius: 13px;
81+
pointer-events: auto;
82+
}
83+
6684
/* Finger context */
67-
.finger-context { font-size: 11px; color: #555; text-align: center; line-height: 1.3; min-height: 16px; font-style: italic; max-width: 320px; }
85+
.finger-context {
86+
display: flex;
87+
align-items: center;
88+
font-size: 11px;
89+
color: #555;
90+
text-align: center;
91+
line-height: 1.3;
92+
min-height: 16px;
93+
font-style: italic;
94+
max-width: 320px;
95+
height: 30px;
96+
max-height: 45px;
97+
}
6898

6999
.bottom-bar {
70100
left: 0;

heatmap.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ This 3D render is an interactive visual analysis of the one of the [keycube stud
1515

1616
{% include heatmap.html %}
1717

18-
{% include heatmap-ui2.html %}
18+
{% include heatmap-ui3.html %}

0 commit comments

Comments
 (0)