fix(rflows): match overflow pipe widths to edge width formula
Compute overflow/spending pipe widths as proportional shares of outflowWidthPx (matching edge formula: outflowWidthPx * flow/total) instead of independent globalMaxFlow scaling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6bda676680
commit
6ab9790373
|
|
@ -2452,28 +2452,27 @@ class FolkFlowsApp extends HTMLElement {
|
|||
const inflowFillRatio = neededInflow > 0 ? Math.min(nf.totalInflow / neededInflow, 1) : 0;
|
||||
const inflowWidthPx = nf.totalInflow > 0 ? MIN_PX + (nf.totalInflow / globalMaxFlow) * (MAX_PX - MIN_PX) : MIN_PX;
|
||||
|
||||
// Overflow pipe width: excess beyond max threshold (funnels) or funding target (outcomes)
|
||||
let overflowAmount = 0;
|
||||
if (n.type === "funnel") {
|
||||
const d = n.data as FunnelNodeData;
|
||||
overflowAmount = Math.max(0, d.currentValue - d.maxThreshold);
|
||||
} else if (n.type === "outcome") {
|
||||
const d = n.data as OutcomeNodeData;
|
||||
overflowAmount = Math.max(0, d.fundingReceived - d.fundingTarget);
|
||||
}
|
||||
const overflowWidthPx = overflowAmount > 0 ? MIN_PX + (overflowAmount / globalMaxFlow) * (MAX_PX - MIN_PX) : MIN_PX;
|
||||
|
||||
// Spending pipe width: drain rate for funnels
|
||||
let spendingAmount = 0;
|
||||
// Overflow/spending pipe widths as proportional shares of outflowWidthPx
|
||||
// (matches how edges compute: outflowWidthPx * edgeFlow / totalOutflow)
|
||||
let overflowFlow = 0;
|
||||
let spendingFlow = 0;
|
||||
if (n.type === "funnel") {
|
||||
const d = n.data as FunnelNodeData;
|
||||
const excess = Math.max(0, d.currentValue - d.maxThreshold);
|
||||
for (const alloc of d.overflowAllocations) overflowFlow += excess * (alloc.percentage / 100);
|
||||
let rateMultiplier: number;
|
||||
if (d.currentValue > d.maxThreshold) rateMultiplier = 0.8;
|
||||
else if (d.currentValue >= d.minThreshold) rateMultiplier = 0.5;
|
||||
else rateMultiplier = 0.1;
|
||||
spendingAmount = d.inflowRate * rateMultiplier;
|
||||
const drain = d.inflowRate * rateMultiplier;
|
||||
for (const alloc of d.spendingAllocations) spendingFlow += drain * (alloc.percentage / 100);
|
||||
} else if (n.type === "outcome") {
|
||||
const d = n.data as OutcomeNodeData;
|
||||
const excess = Math.max(0, d.fundingReceived - d.fundingTarget);
|
||||
for (const alloc of (d.overflowAllocations || [])) overflowFlow += excess * (alloc.percentage / 100);
|
||||
}
|
||||
const spendingWidthPx = spendingAmount > 0 ? MIN_PX + (spendingAmount / globalMaxFlow) * (MAX_PX - MIN_PX) : MIN_PX;
|
||||
const overflowWidthPx = nf.totalOutflow > 0 ? outflowWidthPx * (overflowFlow / nf.totalOutflow) : 0;
|
||||
const spendingWidthPx = nf.totalOutflow > 0 ? outflowWidthPx * (spendingFlow / nf.totalOutflow) : 0;
|
||||
|
||||
this._currentFlowWidths.set(n.id, { totalOutflow: nf.totalOutflow, totalInflow: nf.totalInflow, outflowWidthPx, inflowWidthPx, inflowFillRatio, overflowWidthPx, spendingWidthPx });
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue