Make Follower Study's cumulative tables tell the monthly story, not just repeat it
Per feedback: a monthly report showing the same near-identical cumulative tables every month, marginally bigger each time, isn't earning its keep. Fixed by making the cumulative views themselves show where this month's people landed, instead of adding that only as a separate summary: - Account Clusters now annotates each company's growth inline (e.g. "DESY: 5 (+3 this month)") instead of a flat all-time count with no monthly story. - Notable Contacts highlights rows added this month in place, in context with everyone else at that seniority level, instead of only being named in a separate bullet list above. - Dropped the cumulative Sector/Function/Seniority/Country table entirely — Audience Composition already owns that exact breakdown for the month, so repeating the all-time version here was pure duplication with no monthly-specific value. - Kept the Sector x Seniority crosstab as pure cumulative reference (still needs the full ~100+ scale to mean anything, no individual-level "new" story to tell). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5e20823947
commit
9155e708b4
1 file changed
+36
-19
@@ -4066,38 +4066,51 @@ def _follower_study_insights_page(month_value="2026-07"):
|
||||
from collections import Counter
|
||||
companies = Counter(d.get("company", "").strip() for d in non_team if d.get("company", "").strip())
|
||||
clusters = [(c, n) for c, n in companies.most_common() if n >= 2]
|
||||
month_companies = Counter(d.get("company", "").strip() for d in month_rows
|
||||
if d.get("company", "").strip())
|
||||
# Followers column shows this month's contribution inline (e.g. "5 (+3 this
|
||||
# month)") rather than a flat all-time count with no monthly story — the whole
|
||||
# point of surfacing this in an End of Month report is seeing where this
|
||||
# month's people actually landed, not repeating a near-identical cumulative
|
||||
# table every month with a marginally bigger number.
|
||||
cluster_table = dbc.Table([
|
||||
html.Thead(html.Tr([html.Th("Company", style={"backgroundColor": "#fdf6d8"}),
|
||||
html.Th("Followers", style={"backgroundColor": "#fdf6d8"})])),
|
||||
html.Tbody([html.Tr([html.Td(c), html.Td(str(n))]) for c, n in clusters]),
|
||||
html.Tbody([
|
||||
html.Tr([
|
||||
html.Td(c),
|
||||
html.Td([str(n), html.Span(f" (+{month_companies[c]} this month)",
|
||||
style={"color": "#2e7d32", "fontWeight": "600"})
|
||||
if month_companies.get(c) else None]),
|
||||
]) for c, n in clusters
|
||||
]),
|
||||
], bordered=True, size="sm", style={"fontSize": "0.8rem"})
|
||||
|
||||
notable = [d for d in non_team if d.get("seniority") in _NOTABLE_SENIORITIES]
|
||||
notable.sort(key=lambda d: (d.get("seniority") != "C-Level/Founder", d.get("name", "")))
|
||||
|
||||
def _notable_row(d):
|
||||
# Rows added this month are highlighted in place, in context with everyone
|
||||
# else at that seniority level, rather than only being called out in a
|
||||
# separate list. Bootstrap's table CSS sets its own background on <td>
|
||||
# itself, which paints over a <tr>-level style — the highlight has to go
|
||||
# on each cell.
|
||||
td_style = {"backgroundColor": "#e8f5e9"} if d.get("followedSort") == month_value else {}
|
||||
return html.Tr([html.Td(d.get("name", ""), style=td_style),
|
||||
html.Td(d.get("seniority", ""), style=td_style),
|
||||
html.Td(d.get("company", ""), style=td_style),
|
||||
html.Td(d.get("country", ""), style=td_style)])
|
||||
|
||||
notable_table = dbc.Table([
|
||||
html.Thead(html.Tr([html.Th(c) for c in ["Name", "Seniority", "Company", "Country"]])),
|
||||
html.Tbody([
|
||||
html.Tr([html.Td(d.get("name", "")), html.Td(d.get("seniority", "")),
|
||||
html.Td(d.get("company", "")), html.Td(d.get("country", ""))])
|
||||
for d in notable
|
||||
]),
|
||||
html.Tbody([_notable_row(d) for d in notable]),
|
||||
], bordered=True, size="sm")
|
||||
|
||||
return dbc.Container([
|
||||
_follower_study_findings(whole, non_team, period_label, month_rows, clusters),
|
||||
dbc.Card([
|
||||
dbc.CardHeader(f"All {whole['total']} Followers to Date (through {period_label}), by "
|
||||
f"Sector, Function, Seniority and Country"),
|
||||
dbc.CardBody(dbc.Row([
|
||||
dbc.Col(_composition_count_table(whole["sector"], "Sector"), md=3),
|
||||
dbc.Col(_composition_count_table(whole["function"], "Function"), md=3),
|
||||
dbc.Col(_composition_count_table(whole["seniority"], "Seniority"), md=3),
|
||||
dbc.Col(_composition_count_table(whole["country"], "Country"), md=3),
|
||||
])),
|
||||
], className="mb-3 shadow-sm"),
|
||||
dbc.Row([
|
||||
dbc.Col(dbc.Card([
|
||||
dbc.CardHeader("Sector x Seniority"),
|
||||
dbc.CardHeader("Sector x Seniority (cumulative, to date)"),
|
||||
dbc.CardBody(_sector_seniority_crosstab(non_team)),
|
||||
], className="mb-3 shadow-sm h-100"), md=7),
|
||||
dbc.Col(dbc.Card([
|
||||
@@ -4108,8 +4121,12 @@ def _follower_study_insights_page(month_value="2026-07"):
|
||||
dbc.Card([
|
||||
dbc.CardHeader("Notable Contacts (C-Level/Founder and Director/Head/Principal)"),
|
||||
dbc.CardBody([
|
||||
html.P(f"{len(notable)} followers sit at C-Level/Founder or Director/Head/Principal "
|
||||
f"seniority (internal team members excluded).", style={"fontSize": "0.85rem"}),
|
||||
html.P([
|
||||
f"{len(notable)} followers sit at C-Level/Founder or Director/Head/Principal "
|
||||
"seniority (internal team members excluded). ",
|
||||
html.Span("Highlighted rows", style={"backgroundColor": "#e8f5e9", "fontWeight": "600"}),
|
||||
" joined this month.",
|
||||
], style={"fontSize": "0.85rem"}),
|
||||
notable_table,
|
||||
]),
|
||||
], className="mb-3 shadow-sm"),
|
||||
|
||||
Reference in new issue
Block a user