───────────────────────────────────────────────────────────────────────────── Animation goroutines ───────────────────────────────────────────────────────────────────────────── animateVisualize feeds Tab 3 with rolling data.
(ctx context.Context, w *vizWidgets)
| 2796 | |
| 2797 | // animateVisualize feeds Tab 3 with rolling data. |
| 2798 | func animateVisualize(ctx context.Context, w *vizWidgets) { |
| 2799 | ticker := time.NewTicker(200 * time.Millisecond) |
| 2800 | defer ticker.Stop() |
| 2801 | |
| 2802 | var lineVals []float64 |
| 2803 | radarAngle := 0.0 |
| 2804 | loadPct := 62.0 |
| 2805 | lineStep := 0 |
| 2806 | |
| 2807 | for { |
| 2808 | select { |
| 2809 | case <-ctx.Done(): |
| 2810 | return |
| 2811 | case <-ticker.C: |
| 2812 | w.mu.Lock() |
| 2813 | w.phase += 0.3 |
| 2814 | phase := w.phase |
| 2815 | w.mu.Unlock() |
| 2816 | |
| 2817 | // Radar contacts – rotate slowly around the sweep |
| 2818 | radarAngle = math.Mod(radarAngle+3.0, 360.0) |
| 2819 | contacts := []*radar.Contact{ |
| 2820 | {Angle: math.Mod(radarAngle+42, 360), Distance: 0.35 + 0.08*math.Sin(phase*0.7), Label: "A1"}, |
| 2821 | {Angle: math.Mod(radarAngle+158, 360), Distance: 0.62 + 0.06*math.Cos(phase*0.5), Label: "B2"}, |
| 2822 | {Angle: math.Mod(radarAngle+270, 360), Distance: 0.80, Label: "C3"}, |
| 2823 | } |
| 2824 | if err := w.radarW.SetContacts(contacts); err != nil { |
| 2825 | log.Printf("radar: %v", err) |
| 2826 | } |
| 2827 | |
| 2828 | // Donut – system load |
| 2829 | loadPct = 45 + 30*math.Sin(phase*0.18) |
| 2830 | if loadPct < 10 { |
| 2831 | loadPct = 10 |
| 2832 | } |
| 2833 | if err := w.donut2.Percent(int(loadPct), donut.Label(fmt.Sprintf("%.0f%%", loadPct))); err != nil { |
| 2834 | log.Printf("donut2: %v", err) |
| 2835 | } |
| 2836 | |
| 2837 | // LineChart with threshold at 0.75 |
| 2838 | lineStep = (lineStep + 1) % 360 |
| 2839 | v := 0.5 + 0.55*math.Sin(float64(lineStep)*math.Pi/60) + 0.2*math.Cos(float64(lineStep)*math.Pi/24) |
| 2840 | lineVals = appendRollingFloat(lineVals, v, 96) |
| 2841 | if err := w.lineW.Series("signal", append([]float64(nil), lineVals...), |
| 2842 | linechart.SeriesCellOpts(cell.FgColor(cell.ColorNumber(75))), |
| 2843 | ); err != nil { |
| 2844 | log.Printf("linechart: %v", err) |
| 2845 | } |
| 2846 | |
| 2847 | // Heatmaps |
| 2848 | xl, yl, hv := vizHeatmapFrame(phase) |
| 2849 | if err := w.heatW.Values(xl, yl, hv); err != nil { |
| 2850 | log.Printf("heatmap: %v", err) |
| 2851 | } |
| 2852 | xl2, yl2, hv2 := vizHeatmap2Frame(phase) |
| 2853 | if err := w.heatW2.Values(xl2, yl2, hv2); err != nil { |
| 2854 | log.Printf("heatmap2: %v", err) |
| 2855 | } |
no test coverage detected