feat: restyle chart v2 colors, end labels and legend

- CTF line: black instead of red
- WorstOf line: red + end label shows "Name (value)" format
- Other underlyings: vivid palette (teal/amber/purple/sky/indigo/orange) instead of grey shades; end label shows name
- Barriera Capitale: brown to avoid confusion with WorstOf red
- PrezzoWorst dashed line: red aligned with WorstOf
- Legend font increased 10→12px
- Legend entry for WorstOf shows "Name (Worst Of)"

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-28 11:10:43 +02:00
parent 336e0eb3b8
commit 5579915fbc

View File

@@ -16,21 +16,23 @@ namespace CertReports.Syncfusion.Services.Implementations;
public static class SkiaChartRendererV2
{
// ── Colori ────────────────────────────────────────────────────────
private static readonly SKColor CertColor = new(204, 0, 0);
private static readonly SKColor WorstOfColor = new(21, 101, 192);
private static readonly SKColor CertColor = new(0, 0, 0); // nero
private static readonly SKColor WorstOfColor = new(204, 0, 0); // rosso
private static readonly SKColor StrikeColor = new(46, 125, 50);
private static readonly SKColor CapitaleColor = new(204, 0, 0);
private static readonly SKColor CapitaleColor = new(121, 85, 72); // marrone
private static readonly SKColor CouponColor = new(128, 0, 128);
private static readonly SKColor AutocallColor = new(230, 81, 0);
private static readonly SKColor PrezzoWorstColor = new(21, 101, 192);
private static readonly SKColor PrezzoWorstColor = new(204, 0, 0); // rosso (allineato WorstOf)
private static readonly SKColor TitleColor = new(21, 101, 192);
private static readonly SKColor[] OtherUlColors =
{
new(120, 120, 120),
new(160, 160, 160),
new(90, 90, 90),
new(140, 140, 140),
new(0, 150, 136), // teal
new(255, 152, 0), // amber
new(156, 39, 176), // viola
new( 3, 169, 244), // celeste
new( 63, 81, 181), // indigo
new(255, 87, 34), // arancio scuro
};
// ── Font helper ───────────────────────────────────────────────────
@@ -138,19 +140,26 @@ public static class SkiaChartRendererV2
SKColor color;
float thickness;
string seriesLabel;
string endLabel;
if (ul.IsWorstOf == 1)
{
color = WorstOfColor;
thickness = 2f;
seriesLabel = $"{ul.Sottostante} (Worst Of)";
endLabel = $"{ul.Sottostante} ({ul.PriceWorst:0.00})";
}
else
{
color = OtherUlColors[otherColorIdx++ % OtherUlColors.Length];
thickness = 1f;
seriesLabel = ul.Sottostante;
endLabel = ul.Sottostante;
}
DrawSeriesV2(canvas, plotArea, ulPoints, minDate, maxDate, minY, maxY, color, thickness);
seriesLegend.Add((ul.Sottostante, color, false, thickness));
DrawSeriesEndLabel(canvas, plotArea, ulPoints, minDate, maxDate, minY, maxY, color, endLabel);
seriesLegend.Add((seriesLabel, color, false, thickness));
}
// Bordo area plot
@@ -358,6 +367,25 @@ public static class SkiaChartRendererV2
canvas.Restore();
}
// ═══════════════════════════════════════════════════════════════════
// Label al termine di una serie (estremo destro)
// ═══════════════════════════════════════════════════════════════════
private static void DrawSeriesEndLabel(SKCanvas canvas, SKRect area,
List<ChartSeriesPoint> points,
DateTime minDate, DateTime maxDate, double minY, double maxY,
SKColor color, string label)
{
if (points.Count == 0) return;
var last = points.Last();
float y = ValueToY((double)last.Performance, area, minY, maxY);
y = Math.Max(area.Top, Math.Min(area.Bottom, y));
var font = CreateFont(9.5f);
using var textPaint = new SKPaint { Color = color, IsAntialias = true };
canvas.DrawText(label, area.Right + 5, y + 4, SKTextAlign.Left, font, textPaint);
}
// ═══════════════════════════════════════════════════════════════════
// Linea orizzontale costante con label a destra
// ═══════════════════════════════════════════════════════════════════
@@ -400,7 +428,7 @@ public static class SkiaChartRendererV2
const float itemGap = 14;
const float rowHeight = 19;
var font = CreateFont(10f);
var font = CreateFont(12f);
foreach (var (name, color, dashed, thickness) in items)
{