Skip to content

Commit 09882f5

Browse files
committed
update efficiency
1 parent eb50dcd commit 09882f5

File tree

2 files changed

+180
-18
lines changed

2 files changed

+180
-18
lines changed

_site/index.html

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ <h2>Efficiency Indicators</h2>
7575
<thead>
7676
<tr>
7777
<th>Method</th>
78-
<th>Selected Dataset Fraction (SDF)</th>
78+
7979
<th>Performance Improvement Ratio (PIR)</th>
80+
<th>Selected Dataset Fraction (SDF)</th>
8081
<th>Actions</th> <!-- NEW column for delete buttons -->
8182
</tr>
8283
</thead>
@@ -188,6 +189,9 @@ <h2>Feasibility Indicators</h2>
188189
{ method: "CaR", sdf: 0.0196, pir: 1.343 },
189190
{ method: "SelectIT", sdf: 0.2, pir: 1.653 }
190191
];
192+
// --- NEW: assign a global order to each work for tie-breaking ---
193+
let nextEfficiencyOrder = 1;
194+
efficiencyData.forEach(d => { d.order = nextEfficiencyOrder++; });
191195

192196
function linearTransform(x, x_vals, y_vals) {
193197
let x1 = x_vals[0], x2 = x_vals[1];
@@ -268,14 +272,81 @@ <h2>Feasibility Indicators</h2>
268272
document.getElementById("BM").addEventListener("input", updateEfficiencyInputStates);
269273
document.getElementById("PIR").addEventListener("input", updateEfficiencyInputStates);
270274

275+
// --- NEW: Function to compute signed efficiency values and sort the efficiencyData array ---
276+
function sortEfficiencyData() {
277+
const canvas = document.getElementById("efficiencyCanvas");
278+
if (!canvas) return;
279+
const dpr = window.devicePixelRatio || 1;
280+
const W = canvas.width / dpr;
281+
const H = canvas.height / dpr;
282+
const pad = 60;
283+
const innerPad = 20;
284+
const minSDFdata = Math.min(...efficiencyData.map(d => d.sdf));
285+
const maxSDFdata = Math.max(...efficiencyData.map(d => d.sdf));
286+
const minSDF = Math.min(0.0, minSDFdata);
287+
const maxSDF = (maxSDFdata > 0.2 ? maxSDFdata : 0.2) * 1.05;
288+
const minPIRdata = Math.min(...efficiencyData.map(d => d.pir));
289+
let maxPIR = Math.max(...efficiencyData.map(d => d.pir));
290+
const minPIR = minPIRdata * 0.95;
291+
maxPIR = (maxPIR > 1.75 ? maxPIR : 1.75) * 1.05 + 0.01;
292+
const xScale = val => pad + ((val - minSDF) / (maxSDF - minSDF)) * (W - 2 * pad);
293+
const yScale = val => (H - pad) - ((val - minPIR) / (maxPIR - minPIR)) * (H - 2 * pad);
294+
295+
const A = efficiencyData.find(d => d.method === "Instruction-Mining");
296+
const B = efficiencyData.find(d => d.method === "InstructionGPT-4");
297+
if (!A || !B) return;
298+
const dx = B.sdf - A.sdf;
299+
if (Math.abs(dx) < 1e-12) return;
300+
const slope = (B.pir - A.pir) / (B.sdf - A.sdf);
301+
const colorRectLeft = pad + innerPad;
302+
const colorRectRight = W - pad - innerPad;
303+
const leftSDF = minSDF + ((colorRectLeft - pad) / (W - 2 * pad)) * (maxSDF - minSDF);
304+
const rightSDF = minSDF + ((colorRectRight - pad) / (W - 2 * pad)) * (maxSDF - minSDF);
305+
const yAtLeft = A.pir + slope * (leftSDF - A.sdf);
306+
const yAtRight = A.pir + slope * (rightSDF - A.sdf);
307+
const X1 = colorRectLeft;
308+
const Y1 = yScale(yAtLeft);
309+
const X2 = colorRectRight;
310+
const Y2 = yScale(yAtRight);
311+
312+
// Normal vector of baseline: n = (-(Y2 - Y1), X2 - X1) normalized
313+
const dxBase = X2 - X1;
314+
const dyBase = Y2 - Y1;
315+
const norm = Math.sqrt(dxBase * dxBase + dyBase * dyBase);
316+
const nx = -dyBase / norm;
317+
const ny = dxBase / norm;
318+
319+
efficiencyData.forEach(d => {
320+
const px = xScale(d.sdf);
321+
const py = yScale(d.pir);
322+
const proj = projectPointToLine(px, py, X1, Y1, X2, Y2);
323+
const dxProj = px - proj[0];
324+
const dyProj = py - proj[1];
325+
const distance = Math.sqrt(dxProj * dxProj + dyProj * dyProj);
326+
const dot = dxProj * nx + dyProj * ny;
327+
const sign = (dot >= 0) ? 1 : -1;
328+
d.effVal = sign * distance;
329+
});
330+
331+
// Sort: descending by effVal, then alphabetically by method name, then by order (old first)
332+
efficiencyData.sort((a, b) => {
333+
if (a.effVal !== b.effVal) {
334+
return a.effVal - b.effVal;
335+
}
336+
if (a.method.toLowerCase() < b.method.toLowerCase()) return -1;
337+
if (a.method.toLowerCase() > b.method.toLowerCase()) return 1;
338+
return a.order - b.order;
339+
});
340+
}
341+
271342
// --- Modified Efficiency Table Update Function ---
272343
function populateEfficiencyTable() {
273344
const effTbody = document.querySelector("#efficiencyTable tbody");
274345
effTbody.innerHTML = "";
275346
const SEMInput = document.getElementById("SEM").value.trim();
276347
const BMInput = document.getElementById("BM").value.trim();
277-
const SDFInput = document.getElementById("SDF").value.trim();
278348
const PIRInputVal = document.getElementById("PIR").value.trim();
349+
const SDFInput = document.getElementById("SDF").value.trim();
279350

280351
// If new efficiency input is provided, update the global efficiencyData array.
281352
if (SDFInput !== "") {
@@ -308,37 +379,43 @@ <h2>Feasibility Indicators</h2>
308379
pirValue = result.result;
309380
}
310381

311-
// Append new entries (one for each SDF value)
382+
// Append new entries (one for each SDF value) with an order property.
312383
for (let i = 0; i < SDF.length; i++) {
313384
const methodName = methods[i] ? methods[i] : "Method " + (efficiencyData.length + 1);
314385
efficiencyData.push({
315386
method: methodName,
316387
sdf: SDF[i],
317-
pir: pirValue
388+
pir: pirValue,
389+
order: nextEfficiencyOrder++
318390
});
319391
}
320392

321393
// Clear the input fields after adding.
322394
document.getElementById("effMethodNames").value = "";
323395
document.getElementById("SEM").value = "";
324396
document.getElementById("BM").value = "";
325-
document.getElementById("SDF").value = "";
397+
326398
document.getElementById("PIR").value = "";
399+
document.getElementById("SDF").value = "";
327400
updateEfficiencyInputStates();
328401
}
329402
}
330403

404+
// --- NEW: Sort the efficiencyData array based on computed efficiency values ---
405+
sortEfficiencyData();
406+
331407
// Re-populate table from the entire efficiencyData array.
332408
efficiencyData.forEach(d => {
333409
const tr = document.createElement("tr");
334410
let deleteButtonHTML = "";
335411
// Only allow deletion for non-baseline methods.
336412
if (d.method !== "Instruction-Mining" && d.method !== "InstructionGPT-4") {
337-
deleteButtonHTML = `<button class="deleteBtn" data-method="${d.method}">Delete</button>`;
413+
deleteButtonHTML = `<button class="deleteBtn" data-method="${d.method}" data-order="${d.order}">Delete</button>`;
338414
}
339415
tr.innerHTML = `<td>${d.method}</td>
340-
<td>${d.sdf}</td>
416+
341417
<td>${(typeof d.pir === "number") ? d.pir.toFixed(4) : d.pir}</td>
418+
<td>${d.sdf}</td>
342419
<td>${deleteButtonHTML}</td>`;
343420
effTbody.appendChild(tr);
344421
});
@@ -347,7 +424,11 @@ <h2>Feasibility Indicators</h2>
347424
document.querySelectorAll(".deleteBtn").forEach(btn => {
348425
btn.addEventListener("click", function() {
349426
const methodToDelete = this.getAttribute("data-method");
350-
efficiencyData = efficiencyData.filter(d => d.method !== methodToDelete);
427+
const orderToDelete = parseInt(this.getAttribute("data-order"));
428+
efficiencyData = efficiencyData.filter(d => {
429+
// Match both method and order to ensure uniqueness.
430+
return !(d.method === methodToDelete && d.order === orderToDelete);
431+
});
351432
populateEfficiencyTable();
352433
drawEfficiencyPlot();
353434
});
@@ -930,7 +1011,7 @@ <h2>Feasibility Indicators</h2>
9301011
// ===============================================================
9311012
// Master update and Save functions
9321013
// ===============================================================
933-
// Remove the old global update button and use separate ones.
1014+
// Use separate update buttons.
9341015
window.onload = () => {
9351016
populateEfficiencyTable();
9361017
populateFeasibilityTable();

index.html

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ <h2>Efficiency Indicators</h2>
7575
<thead>
7676
<tr>
7777
<th>Method</th>
78-
<th>Selected Dataset Fraction (SDF)</th>
78+
7979
<th>Performance Improvement Ratio (PIR)</th>
80+
<th>Selected Dataset Fraction (SDF)</th>
8081
<th>Actions</th> <!-- NEW column for delete buttons -->
8182
</tr>
8283
</thead>
@@ -188,6 +189,9 @@ <h2>Feasibility Indicators</h2>
188189
{ method: "CaR", sdf: 0.0196, pir: 1.343 },
189190
{ method: "SelectIT", sdf: 0.2, pir: 1.653 }
190191
];
192+
// --- NEW: assign a global order to each work for tie-breaking ---
193+
let nextEfficiencyOrder = 1;
194+
efficiencyData.forEach(d => { d.order = nextEfficiencyOrder++; });
191195

192196
function linearTransform(x, x_vals, y_vals) {
193197
let x1 = x_vals[0], x2 = x_vals[1];
@@ -268,14 +272,81 @@ <h2>Feasibility Indicators</h2>
268272
document.getElementById("BM").addEventListener("input", updateEfficiencyInputStates);
269273
document.getElementById("PIR").addEventListener("input", updateEfficiencyInputStates);
270274

275+
// --- NEW: Function to compute signed efficiency values and sort the efficiencyData array ---
276+
function sortEfficiencyData() {
277+
const canvas = document.getElementById("efficiencyCanvas");
278+
if (!canvas) return;
279+
const dpr = window.devicePixelRatio || 1;
280+
const W = canvas.width / dpr;
281+
const H = canvas.height / dpr;
282+
const pad = 60;
283+
const innerPad = 20;
284+
const minSDFdata = Math.min(...efficiencyData.map(d => d.sdf));
285+
const maxSDFdata = Math.max(...efficiencyData.map(d => d.sdf));
286+
const minSDF = Math.min(0.0, minSDFdata);
287+
const maxSDF = (maxSDFdata > 0.2 ? maxSDFdata : 0.2) * 1.05;
288+
const minPIRdata = Math.min(...efficiencyData.map(d => d.pir));
289+
let maxPIR = Math.max(...efficiencyData.map(d => d.pir));
290+
const minPIR = minPIRdata * 0.95;
291+
maxPIR = (maxPIR > 1.75 ? maxPIR : 1.75) * 1.05 + 0.01;
292+
const xScale = val => pad + ((val - minSDF) / (maxSDF - minSDF)) * (W - 2 * pad);
293+
const yScale = val => (H - pad) - ((val - minPIR) / (maxPIR - minPIR)) * (H - 2 * pad);
294+
295+
const A = efficiencyData.find(d => d.method === "Instruction-Mining");
296+
const B = efficiencyData.find(d => d.method === "InstructionGPT-4");
297+
if (!A || !B) return;
298+
const dx = B.sdf - A.sdf;
299+
if (Math.abs(dx) < 1e-12) return;
300+
const slope = (B.pir - A.pir) / (B.sdf - A.sdf);
301+
const colorRectLeft = pad + innerPad;
302+
const colorRectRight = W - pad - innerPad;
303+
const leftSDF = minSDF + ((colorRectLeft - pad) / (W - 2 * pad)) * (maxSDF - minSDF);
304+
const rightSDF = minSDF + ((colorRectRight - pad) / (W - 2 * pad)) * (maxSDF - minSDF);
305+
const yAtLeft = A.pir + slope * (leftSDF - A.sdf);
306+
const yAtRight = A.pir + slope * (rightSDF - A.sdf);
307+
const X1 = colorRectLeft;
308+
const Y1 = yScale(yAtLeft);
309+
const X2 = colorRectRight;
310+
const Y2 = yScale(yAtRight);
311+
312+
// Normal vector of baseline: n = (-(Y2 - Y1), X2 - X1) normalized
313+
const dxBase = X2 - X1;
314+
const dyBase = Y2 - Y1;
315+
const norm = Math.sqrt(dxBase * dxBase + dyBase * dyBase);
316+
const nx = -dyBase / norm;
317+
const ny = dxBase / norm;
318+
319+
efficiencyData.forEach(d => {
320+
const px = xScale(d.sdf);
321+
const py = yScale(d.pir);
322+
const proj = projectPointToLine(px, py, X1, Y1, X2, Y2);
323+
const dxProj = px - proj[0];
324+
const dyProj = py - proj[1];
325+
const distance = Math.sqrt(dxProj * dxProj + dyProj * dyProj);
326+
const dot = dxProj * nx + dyProj * ny;
327+
const sign = (dot >= 0) ? 1 : -1;
328+
d.effVal = sign * distance;
329+
});
330+
331+
// Sort: descending by effVal, then alphabetically by method name, then by order (old first)
332+
efficiencyData.sort((a, b) => {
333+
if (a.effVal !== b.effVal) {
334+
return a.effVal - b.effVal;
335+
}
336+
if (a.method.toLowerCase() < b.method.toLowerCase()) return -1;
337+
if (a.method.toLowerCase() > b.method.toLowerCase()) return 1;
338+
return a.order - b.order;
339+
});
340+
}
341+
271342
// --- Modified Efficiency Table Update Function ---
272343
function populateEfficiencyTable() {
273344
const effTbody = document.querySelector("#efficiencyTable tbody");
274345
effTbody.innerHTML = "";
275346
const SEMInput = document.getElementById("SEM").value.trim();
276347
const BMInput = document.getElementById("BM").value.trim();
277-
const SDFInput = document.getElementById("SDF").value.trim();
278348
const PIRInputVal = document.getElementById("PIR").value.trim();
349+
const SDFInput = document.getElementById("SDF").value.trim();
279350

280351
// If new efficiency input is provided, update the global efficiencyData array.
281352
if (SDFInput !== "") {
@@ -308,37 +379,43 @@ <h2>Feasibility Indicators</h2>
308379
pirValue = result.result;
309380
}
310381

311-
// Append new entries (one for each SDF value)
382+
// Append new entries (one for each SDF value) with an order property.
312383
for (let i = 0; i < SDF.length; i++) {
313384
const methodName = methods[i] ? methods[i] : "Method " + (efficiencyData.length + 1);
314385
efficiencyData.push({
315386
method: methodName,
316387
sdf: SDF[i],
317-
pir: pirValue
388+
pir: pirValue,
389+
order: nextEfficiencyOrder++
318390
});
319391
}
320392

321393
// Clear the input fields after adding.
322394
document.getElementById("effMethodNames").value = "";
323395
document.getElementById("SEM").value = "";
324396
document.getElementById("BM").value = "";
325-
document.getElementById("SDF").value = "";
397+
326398
document.getElementById("PIR").value = "";
399+
document.getElementById("SDF").value = "";
327400
updateEfficiencyInputStates();
328401
}
329402
}
330403

404+
// --- NEW: Sort the efficiencyData array based on computed efficiency values ---
405+
sortEfficiencyData();
406+
331407
// Re-populate table from the entire efficiencyData array.
332408
efficiencyData.forEach(d => {
333409
const tr = document.createElement("tr");
334410
let deleteButtonHTML = "";
335411
// Only allow deletion for non-baseline methods.
336412
if (d.method !== "Instruction-Mining" && d.method !== "InstructionGPT-4") {
337-
deleteButtonHTML = `<button class="deleteBtn" data-method="${d.method}">Delete</button>`;
413+
deleteButtonHTML = `<button class="deleteBtn" data-method="${d.method}" data-order="${d.order}">Delete</button>`;
338414
}
339415
tr.innerHTML = `<td>${d.method}</td>
340-
<td>${d.sdf}</td>
416+
341417
<td>${(typeof d.pir === "number") ? d.pir.toFixed(4) : d.pir}</td>
418+
<td>${d.sdf}</td>
342419
<td>${deleteButtonHTML}</td>`;
343420
effTbody.appendChild(tr);
344421
});
@@ -347,7 +424,11 @@ <h2>Feasibility Indicators</h2>
347424
document.querySelectorAll(".deleteBtn").forEach(btn => {
348425
btn.addEventListener("click", function() {
349426
const methodToDelete = this.getAttribute("data-method");
350-
efficiencyData = efficiencyData.filter(d => d.method !== methodToDelete);
427+
const orderToDelete = parseInt(this.getAttribute("data-order"));
428+
efficiencyData = efficiencyData.filter(d => {
429+
// Match both method and order to ensure uniqueness.
430+
return !(d.method === methodToDelete && d.order === orderToDelete);
431+
});
351432
populateEfficiencyTable();
352433
drawEfficiencyPlot();
353434
});
@@ -930,7 +1011,7 @@ <h2>Feasibility Indicators</h2>
9301011
// ===============================================================
9311012
// Master update and Save functions
9321013
// ===============================================================
933-
// Remove the old global update button and use separate ones.
1014+
// Use separate update buttons.
9341015
window.onload = () => {
9351016
populateEfficiencyTable();
9361017
populateFeasibilityTable();

0 commit comments

Comments
 (0)