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 IChartDataService _chartDataService;
|
||||||
private readonly IChartDataServiceV2 _chartDataServiceV2;
|
private readonly IChartDataServiceV2 _chartDataServiceV2;
|
||||||
|
private readonly IUnderlyingChartDataService _underlyingChartDataService;
|
||||||
private readonly ILogger<ChartController> _logger;
|
private readonly ILogger<ChartController> _logger;
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
public ChartController(
|
public ChartController(
|
||||||
IChartDataService chartDataService,
|
IChartDataService chartDataService,
|
||||||
IChartDataServiceV2 chartDataServiceV2,
|
IChartDataServiceV2 chartDataServiceV2,
|
||||||
|
IUnderlyingChartDataService underlyingChartDataService,
|
||||||
ILogger<ChartController> logger,
|
ILogger<ChartController> logger,
|
||||||
IConfiguration configuration)
|
IConfiguration configuration)
|
||||||
{
|
{
|
||||||
_chartDataService = chartDataService;
|
_chartDataService = chartDataService;
|
||||||
_chartDataServiceV2 = chartDataServiceV2;
|
_chartDataServiceV2 = chartDataServiceV2;
|
||||||
|
_underlyingChartDataService = underlyingChartDataService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_configuration = configuration;
|
_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>
|
/// <summary>
|
||||||
/// Salva il JPEG su disco nei percorsi configurati in appsettings.json (ChartSettings).
|
/// Salva il JPEG su disco nei percorsi configurati in appsettings.json (ChartSettings).
|
||||||
/// format=jpg/jpeg → SavePath/{isin}.jpg
|
/// format=jpg/jpeg → SavePath/{isin}.jpg
|
||||||
|
|||||||
Reference in New Issue
Block a user