- 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
86 lines
2.0 KiB
Go
86 lines
2.0 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/picoclaw/chart/internal/renderer"
|
|
"github.com/picoclaw/chart/internal/types"
|
|
)
|
|
|
|
type ChartService struct {
|
|
svgRenderer *renderer.SVGRenderer
|
|
pngRenderer *renderer.PNGRenderer
|
|
ansiRenderer *renderer.ANSIRenderer
|
|
textRenderer *renderer.TextRenderer
|
|
chartCache map[string]*types.Chart
|
|
}
|
|
|
|
func NewChartService() *ChartService {
|
|
return &ChartService{
|
|
svgRenderer: renderer.NewSVGRenderer(),
|
|
pngRenderer: renderer.NewPNGRenderer(),
|
|
ansiRenderer: renderer.NewANSIRenderer(),
|
|
textRenderer: renderer.NewTextRenderer(),
|
|
chartCache: make(map[string]*types.Chart),
|
|
}
|
|
}
|
|
|
|
func (s *ChartService) CreateChart(req *types.ChartRequest) (*types.ChartResponse, error) {
|
|
chart := &types.Chart{
|
|
ID: uuid.New().String(),
|
|
Type: req.Type,
|
|
Title: req.Title,
|
|
Data: req.Data,
|
|
}
|
|
|
|
svgData, err := s.svgRenderer.Render(chart)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to render SVG: %w", err)
|
|
}
|
|
chart.SVG = svgData
|
|
|
|
pngData, err := s.pngRenderer.Render(chart)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to render PNG: %w", err)
|
|
}
|
|
chart.PNG = pngData
|
|
|
|
ansiData, err := s.ansiRenderer.Render(chart)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to render ANSI: %w", err)
|
|
}
|
|
|
|
textData, err := s.textRenderer.Render(chart)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to render text: %w", err)
|
|
}
|
|
|
|
s.chartCache[chart.ID] = chart
|
|
|
|
return &types.ChartResponse{
|
|
ChartID: chart.ID,
|
|
Text: string(textData),
|
|
ANSI: string(ansiData),
|
|
SVG: string(chart.SVG),
|
|
PNGURL: fmt.Sprintf("/api/v1/chart/%s.png", chart.ID),
|
|
Markdown: fmt.Sprintf("", chart.Title, chart.ID),
|
|
}, nil
|
|
}
|
|
|
|
func (s *ChartService) GetChart(id string) (*types.Chart, error) {
|
|
chart, ok := s.chartCache[id]
|
|
if !ok {
|
|
return nil, fmt.Errorf("chart not found: %s", id)
|
|
}
|
|
return chart, nil
|
|
}
|
|
|
|
func (s *ChartService) GetChartPNG(id string) ([]byte, error) {
|
|
chart, err := s.GetChart(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return chart.PNG, nil
|
|
}
|