Add cents/frequency toggle for node labels
- Add toggle button and 'f' keyboard shortcut - Calculate frequencies on-demand using fundamental * fraction - Use direct style updates for reliable label refresh
This commit is contained in:
parent
e09fbbae45
commit
1a56c35276
|
|
@ -283,6 +283,7 @@
|
||||||
<input type="number" id="fundamentalInput" value="110" style="width: 60px;">
|
<input type="number" id="fundamentalInput" value="110" style="width: 60px;">
|
||||||
<span style="margin-left: 15px;">Octave:</span>
|
<span style="margin-left: 15px;">Octave:</span>
|
||||||
<input type="number" id="octaveInput" value="2" style="width: 40px;">
|
<input type="number" id="octaveInput" value="2" style="width: 40px;">
|
||||||
|
<button id="toggleUnitBtn" style="margin-left: 15px;">Show: Cents</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
|
|
@ -317,6 +318,53 @@
|
||||||
let hasPrev = false;
|
let hasPrev = false;
|
||||||
let hasNext = false;
|
let hasNext = false;
|
||||||
let allGraphsData = null;
|
let allGraphsData = null;
|
||||||
|
let displayMode = 'cents';
|
||||||
|
|
||||||
|
// Parse fraction string like "3/2" or "1" into a number
|
||||||
|
function parseFraction(fracStr) {
|
||||||
|
if (!fracStr || fracStr === "1") return 1;
|
||||||
|
const parts = fracStr.split('/');
|
||||||
|
if (parts.length === 2) {
|
||||||
|
return parseInt(parts[0]) / parseInt(parts[1]);
|
||||||
|
}
|
||||||
|
return parseFloat(fracStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle between cents and frequency display
|
||||||
|
function toggleDisplayUnit() {
|
||||||
|
displayMode = displayMode === 'cents' ? 'frequency' : 'cents';
|
||||||
|
const btn = document.getElementById('toggleUnitBtn');
|
||||||
|
if (btn) {
|
||||||
|
btn.textContent = displayMode === 'cents' ? 'Show: Cents' : 'Show: Frequency';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cy) return;
|
||||||
|
|
||||||
|
const fundamental = parseFloat(document.getElementById("fundamentalInput").value) || 110;
|
||||||
|
|
||||||
|
cy.nodes().forEach(node => {
|
||||||
|
const cents = node.data('cents');
|
||||||
|
const fraction = node.data('fraction');
|
||||||
|
|
||||||
|
if (displayMode === 'frequency' && fraction) {
|
||||||
|
const frac = parseFraction(fraction);
|
||||||
|
const freq = fundamental * frac;
|
||||||
|
node.data('displayLabel', Math.round(freq * 10) / 10);
|
||||||
|
} else {
|
||||||
|
node.data('displayLabel', cents);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.style('label', node.data('displayLabel'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up toggle button listener after DOM loads
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const toggleBtn = document.getElementById('toggleUnitBtn');
|
||||||
|
if (toggleBtn) {
|
||||||
|
toggleBtn.addEventListener('click', toggleDisplayUnit);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Cytoscape instance
|
// Cytoscape instance
|
||||||
let cy = null;
|
let cy = null;
|
||||||
|
|
@ -343,7 +391,7 @@
|
||||||
'background-color': 'data(color)',
|
'background-color': 'data(color)',
|
||||||
'width': 32,
|
'width': 32,
|
||||||
'height': 32,
|
'height': 32,
|
||||||
'label': 'data(cents)',
|
'label': function(ele) { return ele.data('displayLabel'); },
|
||||||
'text-valign': 'center',
|
'text-valign': 'center',
|
||||||
'text-halign': 'center',
|
'text-halign': 'center',
|
||||||
'color': '#000000',
|
'color': '#000000',
|
||||||
|
|
@ -572,6 +620,8 @@
|
||||||
id: nodeId,
|
id: nodeId,
|
||||||
localId: n.id,
|
localId: n.id,
|
||||||
cents: n.cents,
|
cents: n.cents,
|
||||||
|
displayLabel: n.cents,
|
||||||
|
fraction: n.fraction || "1",
|
||||||
chordIndex: chordIdx,
|
chordIndex: chordIdx,
|
||||||
chordLabel: `c${chordIdx}`,
|
chordLabel: `c${chordIdx}`,
|
||||||
color: voiceColors[n.id % voiceColors.length],
|
color: voiceColors[n.id % voiceColors.length],
|
||||||
|
|
@ -724,6 +774,7 @@
|
||||||
nodes.push({
|
nodes.push({
|
||||||
id: i,
|
id: i,
|
||||||
cents: Math.round(cents),
|
cents: Math.round(cents),
|
||||||
|
displayLabel: Math.round(cents),
|
||||||
fraction: pitch.fraction || "1",
|
fraction: pitch.fraction || "1",
|
||||||
hs_array: pitch.hs_array || []
|
hs_array: pitch.hs_array || []
|
||||||
});
|
});
|
||||||
|
|
@ -1020,6 +1071,8 @@
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log('Error sending kill:', err);
|
console.log('Error sending kill:', err);
|
||||||
});
|
});
|
||||||
|
} else if (e.key === "f" || e.key === "F") {
|
||||||
|
toggleDisplayUnit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue