fix: X-axis dates now use month-based intervals (fixes missing dates for short/long date ranges)

This commit is contained in:
2026-05-27 18:24:39 +02:00
parent a848d21519
commit d60296aebd

View File

@@ -270,15 +270,17 @@ public static class SkiaChartRendererV2
canvas.DrawLine(area.Left, y, area.Right, y, gridPaint);
}
var totalDays = (maxDate - minDate).TotalDays;
int step = totalDays > 1000 ? 365 : totalDays > 500 ? 180 : 90;
var d = new DateTime(minDate.Year, minDate.Month > 6 ? 7 : 1, 1);
while (d <= maxDate)
int intervalMonths = XAxisIntervalMonths(minDate, maxDate);
if (intervalMonths > 0)
{
float x = DateToX(d, area, minDate, maxDate);
if (x >= area.Left && x <= area.Right)
canvas.DrawLine(x, area.Top, x, area.Bottom, gridPaint);
d = d.AddDays(step);
var d = XAxisStart(minDate, intervalMonths);
while (d <= maxDate)
{
float x = DateToX(d, area, minDate, maxDate);
if (x >= area.Left && x <= area.Right)
canvas.DrawLine(x, area.Top, x, area.Bottom, gridPaint);
d = d.AddMonths(intervalMonths);
}
}
}
@@ -300,18 +302,26 @@ public static class SkiaChartRendererV2
canvas.DrawText($"{val:F0} %", area.Left - 55, y + 4, SKTextAlign.Left, font, paint);
}
var totalDays = (maxDate - minDate).TotalDays;
int step = totalDays > 1000 ? 365 : totalDays > 500 ? 180 : 90;
var d = new DateTime(minDate.Year, minDate.Month > 6 ? 7 : 1, 1);
while (d <= maxDate)
double totalDays = (maxDate - minDate).TotalDays;
int intervalMonths = XAxisIntervalMonths(minDate, maxDate);
string fmt = totalDays > 365 ? "MMM yy" : "dd/MM/yy";
if (intervalMonths > 0)
{
float x = DateToX(d, area, minDate, maxDate);
if (x >= area.Left && x <= area.Right)
var d = XAxisStart(minDate, intervalMonths);
while (d <= maxDate)
{
string text = totalDays > 500 ? d.ToString("yyyy") : d.ToString("MMM yyyy");
canvas.DrawText(text, x, area.Bottom + 20, SKTextAlign.Center, font, paint);
float x = DateToX(d, area, minDate, maxDate);
if (x >= area.Left && x <= area.Right)
canvas.DrawText(d.ToString(fmt), x, area.Bottom + 20, SKTextAlign.Center, font, paint);
d = d.AddMonths(intervalMonths);
}
d = d.AddDays(step);
}
else
{
// Range < 30gg: mostra solo data inizio e fine
canvas.DrawText(minDate.ToString("dd/MM/yy"), area.Left, area.Bottom + 20, SKTextAlign.Left, font, paint);
canvas.DrawText(maxDate.ToString("dd/MM/yy"), area.Right, area.Bottom + 20, SKTextAlign.Right, font, paint);
}
}
@@ -425,6 +435,27 @@ public static class SkiaChartRendererV2
// Conversioni coordinate
// ═══════════════════════════════════════════════════════════════════
/// <summary>Intervallo in mesi per l'asse X in base alla durata del range.</summary>
private static int XAxisIntervalMonths(DateTime minDate, DateTime maxDate)
{
double days = (maxDate - minDate).TotalDays;
if (days > 1000) return 12;
if (days > 365) return 6;
if (days > 90) return 3;
if (days > 30) return 1;
return 0; // range < 30gg: gestito a parte (inizio/fine)
}
/// <summary>Prima data "tonda" (primo del mese) dentro il range, allineata all'intervallo scelto.</summary>
private static DateTime XAxisStart(DateTime minDate, int intervalMonths)
{
// Parte dal primo del mese di minDate
var d = new DateTime(minDate.Year, minDate.Month, 1);
// Se è prima di minDate avanza di un intervallo
if (d < minDate) d = d.AddMonths(intervalMonths);
return d;
}
private static float DateToX(DateTime date, SKRect area, DateTime minDate, DateTime maxDate)
{
double totalDays = (maxDate - minDate).TotalDays;