diff --git a/backend/app/api/v1/parcels.py b/backend/app/api/v1/parcels.py index 56dba94b..b2b73422 100644 --- a/backend/app/api/v1/parcels.py +++ b/backend/app/api/v1/parcels.py @@ -902,7 +902,9 @@ def analyze_parcel( else: center_bonus = 0.0 - # X1 (#47): centrality как отдельный synthetic factor в breakdown + # X1 (#47): centrality как отдельный synthetic factor в breakdown. + # NB: для centrality decay не применяется (bonus IS the value), поэтому + # weight=1.0 семантически — "no decay multiplier"; contribution = center_bonus. if center_bonus > 0: factors_detailed.append( { @@ -911,7 +913,7 @@ def analyze_parcel( "category_ru": "Центральность", "group": "Локация", "value": round(dist_to_center_km, 2), - "weight": center_bonus, + "weight": 1.0, "contribution": round(center_bonus, 2), "verbal": ( f"Близость к центру ЕКБ ({dist_to_center_km:.1f}км) — " diff --git a/frontend/src/components/site-finder/ScoreBreakdownPanel.tsx b/frontend/src/components/site-finder/ScoreBreakdownPanel.tsx index 74d382a1..5f86c52e 100644 --- a/frontend/src/components/site-finder/ScoreBreakdownPanel.tsx +++ b/frontend/src/components/site-finder/ScoreBreakdownPanel.tsx @@ -111,7 +111,8 @@ export function ScoreBreakdownPanel({ color: "#6b7280", }} > - {byGroup.map((g) => ( + {/* Positive groups — visible в баре */} + {positiveGroups.map((g) => (
))}
+ {/* Negative groups — отдельной "drag" линией под баром (legend для bar + использует только positive, чтобы не было orphan swatches без сегмента) */} + {byGroup + .filter((g) => g.contribution < 0) + .map((g) => ( +
+ + + Снижают балл — {g.group}:{" "} + + {fmtContribution(g.contribution)} + + +
+ ))} )}