gantt.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // Package renderer provides Gantt chart rendering
  2. package renderer
  3. import (
  4. "fmt"
  5. "strings"
  6. "mermaid-go/pkg/ast"
  7. )
  8. // GanttRenderer implements Gantt chart rendering
  9. type GanttRenderer struct{}
  10. // NewGanttRenderer creates a new Gantt renderer
  11. func NewGanttRenderer() *GanttRenderer {
  12. return &GanttRenderer{}
  13. }
  14. // Render renders a Gantt chart to mermaid syntax
  15. func (r *GanttRenderer) Render(diagram *ast.GanttDiagram) (string, error) {
  16. var result strings.Builder
  17. // Start with gantt declaration
  18. result.WriteString("gantt\n")
  19. // Add title if present
  20. if diagram.Title != nil {
  21. result.WriteString(fmt.Sprintf(" title %s\n", *diagram.Title))
  22. }
  23. // Add date format if present
  24. if diagram.DateFormat != "" {
  25. result.WriteString(fmt.Sprintf(" dateFormat %s\n", diagram.DateFormat))
  26. }
  27. // Add axis format if not default
  28. if diagram.AxisFormat != "" && diagram.AxisFormat != "%Y-%m-%d" {
  29. result.WriteString(fmt.Sprintf(" axisFormat %s\n", diagram.AxisFormat))
  30. }
  31. // Render sections and tasks
  32. if len(diagram.Sections) > 0 {
  33. for _, section := range diagram.Sections {
  34. result.WriteString(fmt.Sprintf(" section %s\n", section.Name))
  35. for _, task := range section.Tasks {
  36. r.renderTask(&result, task)
  37. }
  38. }
  39. } else {
  40. // Render tasks without sections
  41. for _, task := range diagram.Tasks {
  42. r.renderTask(&result, task)
  43. }
  44. }
  45. return result.String(), nil
  46. }
  47. // renderTask renders a single task
  48. func (r *GanttRenderer) renderTask(result *strings.Builder, task *ast.GanttTask) {
  49. result.WriteString(fmt.Sprintf(" %s : ", task.Name))
  50. // Add task data
  51. var taskData []string
  52. // Add dependencies first (task IDs)
  53. for _, dep := range task.Dependencies {
  54. taskData = append(taskData, dep)
  55. }
  56. // Add status if not default (only render explicit status)
  57. if task.Status != ast.GanttStatusActive {
  58. taskData = append(taskData, string(task.Status))
  59. }
  60. // Add start date
  61. if task.Start != nil {
  62. taskData = append(taskData, *task.Start)
  63. }
  64. // Add end date or duration
  65. if task.End != nil {
  66. taskData = append(taskData, *task.End)
  67. } else if task.Duration != nil {
  68. taskData = append(taskData, *task.Duration)
  69. }
  70. if len(taskData) > 0 {
  71. result.WriteString(strings.Join(taskData, " "))
  72. }
  73. result.WriteString("\n")
  74. }