ToMermaid generates a Mermaid diagram
(focusTaskID string)
| 189 | |
| 190 | // ToMermaid generates a Mermaid diagram |
| 191 | func (g *Graph) ToMermaid(focusTaskID string) string { |
| 192 | var sb strings.Builder |
| 193 | sb.WriteString("graph TD\n") |
| 194 | |
| 195 | // Sort tasks by ID for consistent output |
| 196 | sortedTasks := make([]*model.Task, len(g.Tasks)) |
| 197 | copy(sortedTasks, g.Tasks) |
| 198 | sort.Slice(sortedTasks, func(i, j int) bool { |
| 199 | return sortedTasks[i].ID < sortedTasks[j].ID |
| 200 | }) |
| 201 | |
| 202 | // Define nodes |
| 203 | for _, task := range sortedTasks { |
| 204 | nodeStyle := "" |
| 205 | if task.ID == focusTaskID { |
| 206 | nodeStyle = ":::focus" |
| 207 | } else { |
| 208 | switch task.Status { |
| 209 | case model.StatusCompleted: |
| 210 | nodeStyle = ":::completed" |
| 211 | case model.StatusInProgress: |
| 212 | nodeStyle = ":::inprogress" |
| 213 | case model.StatusBlocked: |
| 214 | nodeStyle = ":::blocked" |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | // Escape special characters in title |
| 219 | title := strings.ReplaceAll(task.Title, "\"", """) |
| 220 | sb.WriteString(fmt.Sprintf(" %s[\"%s: %s\"]%s\n", task.ID, task.ID, title, nodeStyle)) |
| 221 | } |
| 222 | |
| 223 | // Define edges |
| 224 | edges := make(map[string]bool) // Track unique edges |
| 225 | for _, task := range sortedTasks { |
| 226 | for _, depID := range task.Dependencies { |
| 227 | edgeKey := depID + "->" + task.ID |
| 228 | if !edges[edgeKey] { |
| 229 | edges[edgeKey] = true |
| 230 | sb.WriteString(fmt.Sprintf(" %s --> %s\n", depID, task.ID)) |
| 231 | } |
| 232 | } |
| 233 | } |
| 234 | |
| 235 | // Add styles |
| 236 | sb.WriteString("\n") |
| 237 | sb.WriteString(" classDef focus fill:#ff6b6b,stroke:#c92a2a,color:#fff\n") |
| 238 | sb.WriteString(" classDef completed fill:#51cf66,stroke:#2f9e44,color:#000\n") |
| 239 | sb.WriteString(" classDef inprogress fill:#ffd43b,stroke:#fab005,color:#000\n") |
| 240 | sb.WriteString(" classDef blocked fill:#868e96,stroke:#495057,color:#fff\n") |
| 241 | |
| 242 | return sb.String() |
| 243 | } |
| 244 | |
| 245 | // ToDot generates a Graphviz DOT format |
| 246 | func (g *Graph) ToDot(focusTaskID string) string { |
no outgoing calls