feat: add GET /api/chart/underlying/{idUnderlyings} endpoint
This commit is contained in:
@@ -21,17 +21,20 @@ public class ChartController : ControllerBase
|
||||
{
|
||||
private readonly IChartDataService _chartDataService;
|
||||
private readonly IChartDataServiceV2 _chartDataServiceV2;
|
||||
private readonly IUnderlyingChartDataService _underlyingChartDataService;
|
||||
private readonly ILogger<ChartController> _logger;
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
public ChartController(
|
||||
IChartDataService chartDataService,
|
||||
IChartDataServiceV2 chartDataServiceV2,
|
||||
IUnderlyingChartDataService underlyingChartDataService,
|
||||
ILogger<ChartController> logger,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
_chartDataService = chartDataService;
|
||||
_chartDataServiceV2 = chartDataServiceV2;
|
||||
_underlyingChartDataService = underlyingChartDataService;
|
||||
_logger = logger;
|
||||
_configuration = configuration;
|
||||
}
|
||||
@@ -175,6 +178,67 @@ public class ChartController : ControllerBase
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Endpoint standalone: grafico con solo la linea prezzo storico di UN sottostante,
|
||||
/// identificato da IDUnderlyings — nessun contesto certificato (no strike/barriere/legenda).
|
||||
/// Richiede SP cedlab_Chart_UnderlyingOnly nel DB.
|
||||
/// Formati supportati: png (default), jpg/jpeg, pdf. Non supporta jpgEnc né ?save=true
|
||||
/// (nessun alias-certificato applicabile a un sottostante puro).
|
||||
/// </summary>
|
||||
[HttpGet("underlying/{idUnderlyings:int}")]
|
||||
public async Task<IActionResult> GenerateChartUnderlying(
|
||||
int idUnderlyings,
|
||||
[FromQuery] int width = 1100,
|
||||
[FromQuery] int height = 700,
|
||||
[FromQuery] string format = "png")
|
||||
{
|
||||
if (idUnderlyings <= 0)
|
||||
return BadRequest("IDUnderlyings non valido.");
|
||||
|
||||
width = Math.Clamp(width, 400, 2000);
|
||||
height = Math.Clamp(height, 300, 1500);
|
||||
|
||||
try
|
||||
{
|
||||
var chartData = await _underlyingChartDataService.GetChartDataAsync(idUnderlyings);
|
||||
|
||||
if (chartData == null || chartData.Points.Count == 0)
|
||||
{
|
||||
return NotFound(new
|
||||
{
|
||||
status = "KO",
|
||||
message = $"Nessun dato per il grafico del sottostante {idUnderlyings}.",
|
||||
});
|
||||
}
|
||||
|
||||
bool isJpeg = format.Equals("jpg", StringComparison.OrdinalIgnoreCase)
|
||||
|| format.Equals("jpeg", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
byte[] imgBytes = SkiaChartRendererV2.RenderSingleSeriesToPng(chartData, width, height, jpeg: isJpeg);
|
||||
|
||||
if (format.Equals("pdf", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
byte[] pdfBytes = WrapPngInPdf(imgBytes);
|
||||
Response.Headers.Append("Content-Disposition", $"inline; filename=chart_underlying_{idUnderlyings}.pdf");
|
||||
return File(pdfBytes, "application/pdf");
|
||||
}
|
||||
|
||||
if (isJpeg)
|
||||
{
|
||||
Response.Headers.Append("Content-Disposition", $"inline; filename=chart_underlying_{idUnderlyings}.jpg");
|
||||
return File(imgBytes, "image/jpeg");
|
||||
}
|
||||
|
||||
Response.Headers.Append("Content-Disposition", $"inline; filename=chart_underlying_{idUnderlyings}.png");
|
||||
return File(imgBytes, "image/png");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Errore generazione chart sottostante per IDUnderlyings {IDUnderlyings}", idUnderlyings);
|
||||
return StatusCode(500, new { status = "KO", message = "Errore nella generazione del grafico sottostante." });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Salva il JPEG su disco nei percorsi configurati in appsettings.json (ChartSettings).
|
||||
/// format=jpg/jpeg → SavePath/{isin}.jpg
|
||||
|
||||
Reference in New Issue
Block a user