ToJSON generates a JSON graph structure
()
| 425 | |
| 426 | // ToJSON generates a JSON graph structure |
| 427 | func (g *Graph) ToJSON() map[string]any { |
| 428 | nodes := []map[string]any{} |
| 429 | edges := []map[string]string{} |
| 430 | |
| 431 | // Sort tasks by ID |
| 432 | sortedTasks := make([]*model.Task, len(g.Tasks)) |
| 433 | copy(sortedTasks, g.Tasks) |
| 434 | sort.Slice(sortedTasks, func(i, j int) bool { |
| 435 | return sortedTasks[i].ID < sortedTasks[j].ID |
| 436 | }) |
| 437 | |
| 438 | // Build nodes |
| 439 | for _, task := range sortedTasks { |
| 440 | node := map[string]any{ |
| 441 | "id": task.ID, |
| 442 | "title": task.Title, |
| 443 | "status": string(task.Status), |
| 444 | } |
| 445 | if task.Priority != "" { |
| 446 | node["priority"] = string(task.Priority) |
| 447 | } |
| 448 | if task.Group != "" { |
| 449 | node["group"] = task.Group |
| 450 | } |
| 451 | nodes = append(nodes, node) |
| 452 | } |
| 453 | |
| 454 | // Build edges |
| 455 | edgeSet := make(map[string]bool) |
| 456 | for _, task := range sortedTasks { |
| 457 | for _, depID := range task.Dependencies { |
| 458 | edgeKey := depID + "->" + task.ID |
| 459 | if !edgeSet[edgeKey] { |
| 460 | edgeSet[edgeKey] = true |
| 461 | edges = append(edges, map[string]string{ |
| 462 | "from": depID, |
| 463 | "to": task.ID, |
| 464 | }) |
| 465 | } |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | // Detect cycles |
| 470 | cycles := g.DetectCycles() |
| 471 | cyclesData := [][]string{} |
| 472 | if len(cycles) > 0 { |
| 473 | cyclesData = cycles |
| 474 | } |
| 475 | |
| 476 | result := map[string]any{ |
| 477 | "nodes": nodes, |
| 478 | "edges": edges, |
| 479 | } |
| 480 | |
| 481 | if len(cyclesData) > 0 { |
| 482 | result["cycles"] = cyclesData |
| 483 | } |
| 484 |