Skip to content

Commit b6f12b3

Browse files
committed
new pattern for recharts demo
1 parent 28e79db commit b6f12b3

2 files changed

Lines changed: 106 additions & 180 deletions

File tree

tsunami/demo/recharts/app.go

Lines changed: 106 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"context"
54
"math"
65
"time"
76

@@ -42,7 +41,7 @@ func generateNewDataPoint(currentData []DataPoint) DataPoint {
4241
lastTime = currentData[len(currentData)-1].Time
4342
}
4443
newTime := lastTime + 1
45-
44+
4645
return DataPoint{
4746
Time: newTime,
4847
CPU: 50 + 30*math.Sin(float64(newTime)*0.3) + 10*math.Sin(float64(newTime)*0.7),
@@ -51,68 +50,67 @@ func generateNewDataPoint(currentData []DataPoint) DataPoint {
5150
}
5251
}
5352

54-
var InfoSection = app.DefineComponent("InfoSection",
55-
func(ctx context.Context, _ struct{}) any {
56-
return vdom.H("div", map[string]any{
57-
"className": "bg-blue-50 border border-blue-200 rounded-lg p-4",
53+
var InfoSection = app.DefineComponent("InfoSection", func(_ struct{}) any {
54+
return vdom.H("div", map[string]any{
55+
"className": "bg-blue-50 border border-blue-200 rounded-lg p-4",
56+
},
57+
vdom.H("h3", map[string]any{
58+
"className": "text-lg font-semibold text-blue-900 mb-2",
59+
}, "Recharts Integration Features"),
60+
vdom.H("ul", map[string]any{
61+
"className": "space-y-2 text-blue-800",
5862
},
59-
vdom.H("h3", map[string]any{
60-
"className": "text-lg font-semibold text-blue-900 mb-2",
61-
}, "Recharts Integration Features"),
62-
vdom.H("ul", map[string]any{
63-
"className": "space-y-2 text-blue-800",
63+
vdom.H("li", map[string]any{
64+
"className": "flex items-start gap-2",
6465
},
65-
vdom.H("li", map[string]any{
66-
"className": "flex items-start gap-2",
67-
},
68-
vdom.H("span", map[string]any{
69-
"className": "text-blue-500 mt-1",
70-
}, "•"),
71-
"Support for all major Recharts components (LineChart, AreaChart, BarChart, etc.)",
72-
),
73-
vdom.H("li", map[string]any{
74-
"className": "flex items-start gap-2",
75-
},
76-
vdom.H("span", map[string]any{
77-
"className": "text-blue-500 mt-1",
78-
}, "•"),
79-
"Live data updates with animation support",
80-
),
81-
vdom.H("li", map[string]any{
82-
"className": "flex items-start gap-2",
83-
},
84-
vdom.H("span", map[string]any{
85-
"className": "text-blue-500 mt-1",
86-
}, "•"),
87-
"Responsive containers that resize with the window",
88-
),
89-
vdom.H("li", map[string]any{
90-
"className": "flex items-start gap-2",
91-
},
92-
vdom.H("span", map[string]any{
93-
"className": "text-blue-500 mt-1",
94-
}, "•"),
95-
"Full prop support for customization and styling",
96-
),
97-
vdom.H("li", map[string]any{
98-
"className": "flex items-start gap-2",
99-
},
100-
vdom.H("span", map[string]any{
101-
"className": "text-blue-500 mt-1",
102-
}, "•"),
103-
"Uses recharts: namespace to dispatch to the recharts handler",
104-
),
66+
vdom.H("span", map[string]any{
67+
"className": "text-blue-500 mt-1",
68+
}, "•"),
69+
"Support for all major Recharts components (LineChart, AreaChart, BarChart, etc.)",
10570
),
106-
)
107-
},
71+
vdom.H("li", map[string]any{
72+
"className": "flex items-start gap-2",
73+
},
74+
vdom.H("span", map[string]any{
75+
"className": "text-blue-500 mt-1",
76+
}, "•"),
77+
"Live data updates with animation support",
78+
),
79+
vdom.H("li", map[string]any{
80+
"className": "flex items-start gap-2",
81+
},
82+
vdom.H("span", map[string]any{
83+
"className": "text-blue-500 mt-1",
84+
}, "•"),
85+
"Responsive containers that resize with the window",
86+
),
87+
vdom.H("li", map[string]any{
88+
"className": "flex items-start gap-2",
89+
},
90+
vdom.H("span", map[string]any{
91+
"className": "text-blue-500 mt-1",
92+
}, "•"),
93+
"Full prop support for customization and styling",
94+
),
95+
vdom.H("li", map[string]any{
96+
"className": "flex items-start gap-2",
97+
},
98+
vdom.H("span", map[string]any{
99+
"className": "text-blue-500 mt-1",
100+
}, "•"),
101+
"Uses recharts: namespace to dispatch to the recharts handler",
102+
),
103+
),
104+
)
105+
},
108106
)
109107

110108
type MiniChartsProps struct {
111109
ChartData []DataPoint `json:"chartData"`
112110
}
113111

114112
var MiniCharts = app.DefineComponent("MiniCharts",
115-
func(ctx context.Context, props MiniChartsProps) any {
113+
func(props MiniChartsProps) any {
116114
return vdom.H("div", map[string]any{
117115
"className": "grid grid-cols-1 md:grid-cols-3 gap-6 mb-6",
118116
},
@@ -134,11 +132,11 @@ var MiniCharts = app.DefineComponent("MiniCharts",
134132
"data": props.ChartData,
135133
},
136134
vdom.H("recharts:Line", map[string]any{
137-
"type": "monotone",
138-
"dataKey": "cpu",
139-
"stroke": "#8884d8",
140-
"strokeWidth": 2,
141-
"dot": false,
135+
"type": "monotone",
136+
"dataKey": "cpu",
137+
"stroke": "#8884d8",
138+
"strokeWidth": 2,
139+
"dot": false,
142140
}),
143141
),
144142
),
@@ -203,55 +201,27 @@ var MiniCharts = app.DefineComponent("MiniCharts",
203201
)
204202

205203
var App = app.DefineComponent("App",
206-
func(ctx context.Context, _ struct{}) any {
204+
func(_ struct{}) any {
207205
app.UseSetAppTitle("Recharts Demo")
208206

209-
// Get atom values once at the top
210-
chartData := chartDataAtom.Get()
211-
chartType := chartTypeAtom.Get()
212-
isAnimating := isAnimatingAtom.Get()
213-
214-
// Local state for timer
215-
_, _, setTickerFn := app.UseState(0)
216-
217-
// Timer effect for live data updates
218-
app.UseEffect(func() func() {
219-
if !isAnimating {
220-
return nil
207+
tickerFn := func() {
208+
if !isAnimatingAtom.Get() {
209+
return
221210
}
222-
223-
ticker := time.NewTicker(1 * time.Second)
224-
done := make(chan bool)
225-
226-
go func() {
227-
for {
228-
select {
229-
case <-done:
230-
return
231-
case <-ticker.C:
232-
// Add new data point and keep only last 20 points
233-
chartDataAtom.SetFn(func(currentData []DataPoint) []DataPoint {
234-
newData := append(currentData, generateNewDataPoint(currentData))
235-
if len(newData) > 20 {
236-
newData = newData[1:]
237-
}
238-
return newData
239-
})
240-
// Trigger a re-render
241-
setTickerFn(func(t int) int { return t + 1 })
242-
app.SendAsyncInitiation()
243-
}
211+
chartDataAtom.SetFn(func(currentData []DataPoint) []DataPoint {
212+
currentData = app.DeepCopy(currentData)
213+
newData := append(currentData, generateNewDataPoint(currentData))
214+
if len(newData) > 20 {
215+
newData = newData[1:]
244216
}
245-
}()
246-
247-
return func() {
248-
ticker.Stop()
249-
close(done)
250-
}
251-
}, []any{isAnimating})
217+
return newData
218+
})
219+
app.SendAsyncInitiation()
220+
}
221+
app.UseTicker(time.Second, tickerFn, []any{})
252222

253223
handleStartStop := func() {
254-
isAnimatingAtom.Set(!isAnimating)
224+
isAnimatingAtom.Set(!isAnimatingAtom.Get())
255225
}
256226

257227
handleReset := func() {
@@ -263,6 +233,10 @@ var App = app.DefineComponent("App",
263233
chartTypeAtom.Set(newType)
264234
}
265235

236+
chartData := chartDataAtom.Get()
237+
chartType := chartTypeAtom.Get()
238+
isAnimating := isAnimatingAtom.Get()
239+
266240
return vdom.H("div", map[string]any{
267241
"className": "min-h-screen bg-gray-50 p-6",
268242
},
@@ -372,22 +346,22 @@ var App = app.DefineComponent("App",
372346
vdom.H("recharts:Tooltip", nil),
373347
vdom.H("recharts:Legend", nil),
374348
vdom.H("recharts:Line", map[string]any{
375-
"type": "monotone",
376-
"dataKey": "cpu",
377-
"stroke": "#8884d8",
378-
"name": "CPU %",
349+
"type": "monotone",
350+
"dataKey": "cpu",
351+
"stroke": "#8884d8",
352+
"name": "CPU %",
379353
}),
380354
vdom.H("recharts:Line", map[string]any{
381-
"type": "monotone",
382-
"dataKey": "mem",
383-
"stroke": "#82ca9d",
384-
"name": "Memory %",
355+
"type": "monotone",
356+
"dataKey": "mem",
357+
"stroke": "#82ca9d",
358+
"name": "Memory %",
385359
}),
386360
vdom.H("recharts:Line", map[string]any{
387-
"type": "monotone",
388-
"dataKey": "disk",
389-
"stroke": "#ffc658",
390-
"name": "Disk %",
361+
"type": "monotone",
362+
"dataKey": "disk",
363+
"stroke": "#ffc658",
364+
"name": "Disk %",
391365
}),
392366
),
393367
),
@@ -410,28 +384,28 @@ var App = app.DefineComponent("App",
410384
vdom.H("recharts:Tooltip", nil),
411385
vdom.H("recharts:Legend", nil),
412386
vdom.H("recharts:Area", map[string]any{
413-
"type": "monotone",
414-
"dataKey": "cpu",
415-
"stackId": "1",
416-
"stroke": "#8884d8",
417-
"fill": "#8884d8",
418-
"name": "CPU %",
387+
"type": "monotone",
388+
"dataKey": "cpu",
389+
"stackId": "1",
390+
"stroke": "#8884d8",
391+
"fill": "#8884d8",
392+
"name": "CPU %",
419393
}),
420394
vdom.H("recharts:Area", map[string]any{
421-
"type": "monotone",
422-
"dataKey": "mem",
423-
"stackId": "1",
424-
"stroke": "#82ca9d",
425-
"fill": "#82ca9d",
426-
"name": "Memory %",
395+
"type": "monotone",
396+
"dataKey": "mem",
397+
"stackId": "1",
398+
"stroke": "#82ca9d",
399+
"fill": "#82ca9d",
400+
"name": "Memory %",
427401
}),
428402
vdom.H("recharts:Area", map[string]any{
429-
"type": "monotone",
430-
"dataKey": "disk",
431-
"stackId": "1",
432-
"stroke": "#ffc658",
433-
"fill": "#ffc658",
434-
"name": "Disk %",
403+
"type": "monotone",
404+
"dataKey": "disk",
405+
"stackId": "1",
406+
"stroke": "#ffc658",
407+
"fill": "#ffc658",
408+
"name": "Disk %",
435409
}),
436410
),
437411
),

0 commit comments

Comments
 (0)