- Support 9 chart types: line, bar, pie, scatter, bubble, donut, mixed, polar, radar - Multi-format output: ANSI, SVG, PNG, Markdown - Go + Fiber + gonum/plot - Docker support - Morandi color palette
97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/picoclaw/chart/internal/service"
|
|
"github.com/picoclaw/chart/internal/types"
|
|
)
|
|
|
|
type ChartHandler struct {
|
|
chartService *service.ChartService
|
|
}
|
|
|
|
func NewChartHandler(chartService *service.ChartService) *ChartHandler {
|
|
return &ChartHandler{
|
|
chartService: chartService,
|
|
}
|
|
}
|
|
|
|
func (h *ChartHandler) CreateChart(c *fiber.Ctx) error {
|
|
var req types.ChartRequest
|
|
if err := c.BodyParser(&req); err != nil {
|
|
return c.Status(fiber.StatusBadRequest).JSON(types.ErrorResponse{
|
|
Error: "invalid request body: " + err.Error(),
|
|
})
|
|
}
|
|
|
|
if req.Type == "" {
|
|
req.Type = types.ChartTypeLine
|
|
}
|
|
|
|
if len(req.Data.Datasets) == 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(types.ErrorResponse{
|
|
Error: "datasets are required",
|
|
})
|
|
}
|
|
|
|
for _, dataset := range req.Data.Datasets {
|
|
if len(dataset.Values) == 0 {
|
|
return c.Status(fiber.StatusBadRequest).JSON(types.ErrorResponse{
|
|
Error: "dataset values cannot be empty",
|
|
})
|
|
}
|
|
}
|
|
|
|
resp, err := h.chartService.CreateChart(&req)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusInternalServerError).JSON(types.ErrorResponse{
|
|
Error: err.Error(),
|
|
})
|
|
}
|
|
|
|
return c.Status(fiber.StatusCreated).JSON(resp)
|
|
}
|
|
|
|
func (h *ChartHandler) GetChart(c *fiber.Ctx) error {
|
|
id := c.Params("id")
|
|
if id == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(types.ErrorResponse{
|
|
Error: "chart id is required",
|
|
})
|
|
}
|
|
|
|
chart, err := h.chartService.GetChart(id)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(types.ErrorResponse{
|
|
Error: err.Error(),
|
|
})
|
|
}
|
|
|
|
return c.Send(chart.SVG)
|
|
}
|
|
|
|
func (h *ChartHandler) GetChartPNG(c *fiber.Ctx) error {
|
|
id := c.Params("id")
|
|
if id == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(types.ErrorResponse{
|
|
Error: "chart id is required",
|
|
})
|
|
}
|
|
|
|
pngData, err := h.chartService.GetChartPNG(id)
|
|
if err != nil {
|
|
return c.Status(fiber.StatusNotFound).JSON(types.ErrorResponse{
|
|
Error: err.Error(),
|
|
})
|
|
}
|
|
|
|
c.Set("Content-Type", "image/png")
|
|
return c.Send(pngData)
|
|
}
|
|
|
|
func (h *ChartHandler) Health(c *fiber.Ctx) error {
|
|
return c.JSON(fiber.Map{
|
|
"status": "ok",
|
|
})
|
|
}
|