fix(site-finder): address PR #87 auto-review minor feedback
Backend (parcels.py):
- Centrality factor: weight=1.0 вместо weight=center_bonus (semantic — decay
для bonus не применяется, contribution = bonus IS the value). Защищает
future PDF-export/UI который мог бы показать weight отдельно от contribution.
- group_totals type: dict[str, dict[str, float | int]] — count это int,
contribution и contribution_pct это float. Уточняет hint для future mypy.
- Top-3 sort convention — добавлен inline-комментарий: positives "[:3] от
descending" (most-positive first); negatives "[-3:][::-1]" (most-negative
first). Оба "dominant first".
Frontend (ScoreBreakdownPanel.tsx):
- Stacked bar legend orphan fix: positive groups идут в legend под баром (как
до того); negative groups показываются отдельной строкой ниже "Снижают балл —
Шум/трамвай: −0.46". Никаких swatch'ей без bar-сегмента.
Per auto-review on 1d1c169.
This commit is contained in:
parent
1002214f12
commit
b5a218160d
2 changed files with 39 additions and 3 deletions
|
|
@ -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}км) — "
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ export function ScoreBreakdownPanel({
|
|||
color: "#6b7280",
|
||||
}}
|
||||
>
|
||||
{byGroup.map((g) => (
|
||||
{/* Positive groups — visible в баре */}
|
||||
{positiveGroups.map((g) => (
|
||||
<div
|
||||
key={g.group}
|
||||
style={{ display: "flex", alignItems: "center", gap: 4 }}
|
||||
|
|
@ -134,6 +135,39 @@ export function ScoreBreakdownPanel({
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Negative groups — отдельной "drag" линией под баром (legend для bar
|
||||
использует только positive, чтобы не было orphan swatches без сегмента) */}
|
||||
{byGroup
|
||||
.filter((g) => g.contribution < 0)
|
||||
.map((g) => (
|
||||
<div
|
||||
key={`neg-${g.group}`}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: 4,
|
||||
marginTop: 6,
|
||||
fontSize: 12,
|
||||
color: "#6b7280",
|
||||
}}
|
||||
>
|
||||
<span
|
||||
style={{
|
||||
display: "inline-block",
|
||||
width: 10,
|
||||
height: 10,
|
||||
borderRadius: 2,
|
||||
background: GROUP_COLORS[g.group] ?? GROUP_COLORS.Прочее,
|
||||
}}
|
||||
/>
|
||||
<span>
|
||||
Снижают балл — {g.group}:{" "}
|
||||
<strong style={{ color: "#dc2626" }}>
|
||||
{fmtContribution(g.contribution)}
|
||||
</strong>
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue