fix(mail): legend rows justify-between + per-connection chart sparse-data zoom
1. Donut-Legend-Rows als space-between: Name links + dot, Count rechts. Vorher: alle Elemente eng aneinander (gap:6), Count direkt nach Name. Jetzt: feste Legend-Width 180px, jede Row hat Name+Dot links (flex:1) und Count rechts mit Whitespace dazwischen. 2. Per-Connection-Bar-Chart in Account-Card: sparse-data-zoom. Vorher: bei nonEmpty.length > 0 && days <= 7 wurde gezoomt — bei 30-Tage- Range mit nur 1-2 Hits passierte das aber NICHT → 30 leere Bars + 1 Bar ganz rechts (Screenshot bei GMX-expanded). Jetzt: zoom IMMER wenn nonEmpty.length * 3 < raw.length (= mehr als 2/3 der Range sind leer). Trim auf die echte Hit-Range. User sieht damit nur die Tage mit Daten + die paar dazwischen, statt 30 leere Slots. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
aac6c00720
commit
b47ac2427e
@ -112,7 +112,7 @@ export function MailDistributionChart({ data, hero, totalBlocked, isLegend }: Pr
|
|||||||
centerLabel={centerLabel}
|
centerLabel={centerLabel}
|
||||||
width={DONUT_WIDTH}
|
width={DONUT_WIDTH}
|
||||||
/>
|
/>
|
||||||
<View style={{ gap: 6 }}>
|
<View style={{ gap: 6, width: 180 }}>
|
||||||
{slices.map((slice) => (
|
{slices.map((slice) => (
|
||||||
<LegendRow key={slice.label} slice={slice} colors={colors} />
|
<LegendRow key={slice.label} slice={slice} colors={colors} />
|
||||||
))}
|
))}
|
||||||
@ -159,7 +159,15 @@ function LegendRow({
|
|||||||
colors: ReturnType<typeof useColors>;
|
colors: ReturnType<typeof useColors>;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
|
<View
|
||||||
|
style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
gap: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6, flex: 1, minWidth: 0 }}>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
width: 8,
|
width: 8,
|
||||||
@ -173,12 +181,13 @@ function LegendRow({
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontFamily: slice.isOther ? 'Nunito_400Regular' : 'Nunito_600SemiBold',
|
fontFamily: slice.isOther ? 'Nunito_400Regular' : 'Nunito_600SemiBold',
|
||||||
color: slice.isOther ? colors.textMuted : colors.text,
|
color: slice.isOther ? colors.textMuted : colors.text,
|
||||||
maxWidth: 160,
|
flexShrink: 1,
|
||||||
}}
|
}}
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
>
|
>
|
||||||
{slice.label}
|
{slice.label}
|
||||||
</Text>
|
</Text>
|
||||||
|
</View>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
|||||||
@ -73,8 +73,10 @@ export function useMailConnectionStats(
|
|||||||
data = aggregateToWeeks(raw);
|
data = aggregateToWeeks(raw);
|
||||||
} else if (granularity === 'month') {
|
} else if (granularity === 'month') {
|
||||||
data = aggregateToMonths(raw);
|
data = aggregateToMonths(raw);
|
||||||
} else if (nonEmpty.length > 0 && days <= 7) {
|
} else if (nonEmpty.length > 0 && nonEmpty.length * 3 < raw.length) {
|
||||||
// Short window: keep only days with data + days between first and last hit
|
// Sparse data (z.B. nur 1-2 Tage von 30): zoom in auf die echte Range
|
||||||
|
// zwischen erstem und letztem Hit. Vermeidet 30 leere Bars + 1 Bar
|
||||||
|
// ganz rechts wie bei einer frischen Outlook-Connection.
|
||||||
const firstDate = nonEmpty[0].date;
|
const firstDate = nonEmpty[0].date;
|
||||||
const lastDate = nonEmpty[nonEmpty.length - 1].date;
|
const lastDate = nonEmpty[nonEmpty.length - 1].date;
|
||||||
data = raw.filter((e) => e.date >= firstDate && e.date <= lastDate);
|
data = raw.filter((e) => e.date >= firstDate && e.date <= lastDate);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user