Add batch API endpoints for cents calculation, client fetches cents from server
This commit is contained in:
parent
c6bb3a12ce
commit
8f332fac52
|
|
@ -581,13 +581,37 @@
|
|||
// Load from Flask API - get chords and compute graphs client-side
|
||||
async function loadAllGraphs() {
|
||||
try {
|
||||
// Step 1: Get raw chord data
|
||||
const response = await fetch("/api/chords");
|
||||
if (!response.ok) throw new Error("API not available");
|
||||
const data = await response.json();
|
||||
|
||||
// Compute graphs from raw chord data client-side
|
||||
// Step 2: Collect all fractions from all chords
|
||||
const allFractions = [];
|
||||
const chordFractions = []; // Track which fractions belong to which chord
|
||||
|
||||
for (const chord of data.chords) {
|
||||
const fractions = [];
|
||||
for (const pitch of chord) {
|
||||
fractions.push(pitch.fraction || "1");
|
||||
}
|
||||
chordFractions.push(fractions);
|
||||
allFractions.push(...fractions);
|
||||
}
|
||||
|
||||
// Step 3: Batch fetch cents from server (avoid N+1 problem)
|
||||
const centsResponse = await fetch("/api/batch-calculate-cents", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({ fractions: allFractions })
|
||||
});
|
||||
const centsData = await centsResponse.json();
|
||||
const allCents = centsData.results.map(r => r.cents);
|
||||
|
||||
// Step 4: Build graphs with cached cents values
|
||||
let centsIndex = 0;
|
||||
const graphs = data.chords.map((chord, index) => {
|
||||
return calculateGraph(chord, index);
|
||||
return calculateGraph(chord, index, () => allCents[centsIndex++]);
|
||||
});
|
||||
|
||||
allGraphsData = {
|
||||
|
|
@ -611,18 +635,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Compute graph (nodes + edges) from raw chord data - client-side version
|
||||
function calculateGraph(chord, index) {
|
||||
// Compute graph (nodes + edges) from raw chord data - using API for cents
|
||||
function calculateGraph(chord, index, getNextCent) {
|
||||
if (!chord) return { nodes: [], edges: [] };
|
||||
|
||||
const nodes = [];
|
||||
const dims = [2, 3, 5, 7];
|
||||
|
||||
// Calculate cents for each pitch
|
||||
// Calculate cents for each pitch (fetched from server)
|
||||
for (let i = 0; i < chord.length; i++) {
|
||||
const pitch = chord[i];
|
||||
const fraction = parseFraction(pitch.fraction || "1");
|
||||
const cents = fraction > 0 ? 1200 * Math.log2(fraction) : 0;
|
||||
const cents = getNextCent();
|
||||
|
||||
nodes.push({
|
||||
id: i,
|
||||
|
|
@ -689,18 +712,6 @@
|
|||
return { nodes, edges, index };
|
||||
}
|
||||
|
||||
// Parse fraction string to number
|
||||
function parseFraction(fracStr) {
|
||||
if (typeof fracStr === 'number') return fracStr;
|
||||
if (!fracStr) return 1;
|
||||
|
||||
if (fracStr.includes('/')) {
|
||||
const [num, den] = fracStr.split('/').map(Number);
|
||||
return num / den;
|
||||
}
|
||||
return Number(fracStr);
|
||||
}
|
||||
|
||||
// Update UI elements
|
||||
function updateUI() {
|
||||
hasPrev = currentIndex > 0;
|
||||
|
|
|
|||
|
|
@ -406,6 +406,45 @@ def load_file():
|
|||
return jsonify({"error": f"Invalid JSON in: {filepath}"}), 400
|
||||
|
||||
|
||||
@app.route("/api/parse-fraction", methods=["POST"])
|
||||
def parse_fraction_api():
|
||||
"""Parse a fraction string to float."""
|
||||
data = request.json
|
||||
fraction = data.get("fraction", "1")
|
||||
try:
|
||||
value = parse_fraction(fraction)
|
||||
return jsonify({"fraction": fraction, "value": value})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 400
|
||||
|
||||
|
||||
@app.route("/api/calculate-cents", methods=["POST"])
|
||||
def calculate_cents_api():
|
||||
"""Calculate cents from fraction string."""
|
||||
data = request.json
|
||||
fraction = data.get("fraction", "1")
|
||||
try:
|
||||
cents = calculate_cents(fraction)
|
||||
return jsonify({"fraction": fraction, "cents": cents})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 400
|
||||
|
||||
|
||||
@app.route("/api/batch-calculate-cents", methods=["POST"])
|
||||
def batch_calculate_cents_api():
|
||||
"""Calculate cents for multiple fractions at once."""
|
||||
data = request.json
|
||||
fractions = data.get("fractions", [])
|
||||
try:
|
||||
results = []
|
||||
for fraction in fractions:
|
||||
cents = calculate_cents(fraction)
|
||||
results.append({"fraction": fraction, "cents": cents})
|
||||
return jsonify({"results": results})
|
||||
except Exception as e:
|
||||
return jsonify({"error": str(e)}), 400
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Starting Path Navigator server...")
|
||||
print(f"Loading chords from: {get_chords_file()}")
|
||||
|
|
|
|||
Loading…
Reference in a new issue