update heatmap, add wasm charts
This commit is contained in:
@@ -1157,43 +1157,99 @@ func searchSection() func() *VNode {
|
||||
|
||||
// ---- charts --------------------------------------------------------------
|
||||
|
||||
var chartDaysWasm = []string{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}
|
||||
var pieLabelsWasm = []string{"Direct", "Search", "Social", "Email", "Referral"}
|
||||
var regionsWasm = []string{"East", "Central", "Mountain", "Pacific"}
|
||||
|
||||
// A made-up per-state metric for the choropleth, and a few cities (lat/lng) — Anchorage
|
||||
// and Honolulu land on albersUsa's Alaska and Hawaii insets.
|
||||
var usSignups = map[string]float64{
|
||||
"CA": 4820, "TX": 3910, "NY": 3120, "FL": 2870, "IL": 1740, "PA": 1610, "OH": 1490, "GA": 1450,
|
||||
"NC": 1360, "MI": 1280, "WA": 1230, "AZ": 1180, "MA": 1120, "VA": 1090, "CO": 980, "TN": 940,
|
||||
"NJ": 910, "OR": 720, "MN": 690, "WI": 610, "MO": 560, "MD": 540, "IN": 520, "NV": 480,
|
||||
"UT": 430, "AL": 390, "SC": 360, "KY": 310, "LA": 300, "OK": 280, "CT": 260, "IA": 210,
|
||||
"KS": 180, "AK": 140, "HI": 160, "ME": 120, "MT": 90, "WY": 60, "ND": 70, "SD": 80,
|
||||
}
|
||||
var usCities = []ui.USHeatmapPoint{
|
||||
{Label: "Seattle", Lat: 47.6062, Lng: -122.3321, Value: 1230},
|
||||
{Label: "San Francisco", Lat: 37.7749, Lng: -122.4194, Value: 2110},
|
||||
{Label: "Denver", Lat: 39.7392, Lng: -104.9903, Value: 980},
|
||||
{Label: "Chicago", Lat: 41.8781, Lng: -87.6298, Value: 1740},
|
||||
{Label: "New York", Lat: 40.7128, Lng: -74.006, Value: 3120},
|
||||
{Label: "Miami", Lat: 25.7617, Lng: -80.1918, Value: 1460},
|
||||
{Label: "Anchorage", Lat: 61.2181, Lng: -149.9003, Value: 140},
|
||||
{Label: "Honolulu", Lat: 21.3069, Lng: -157.8583, Value: 160},
|
||||
}
|
||||
|
||||
func chartsSection() func() *VNode {
|
||||
values := NewSignal(fixedChartData())
|
||||
drawn := newChartDrawing()
|
||||
seed := NewSignal(0)
|
||||
threeD := NewSignal(false)
|
||||
barC, donutC, areaC, lineC := ui.NewChart(), ui.NewChart(), ui.NewChart(), ui.NewChart()
|
||||
horizC, stackC := ui.NewChart(), ui.NewChart()
|
||||
heat := ui.NewUSHeatmap()
|
||||
|
||||
return func() *VNode {
|
||||
v := values.Get()
|
||||
sh := seed.Get()
|
||||
shuffle := func(base []float64) []float64 {
|
||||
out := make([]float64, len(base))
|
||||
for i, b := range base {
|
||||
if sh == 0 {
|
||||
out[i] = b
|
||||
continue
|
||||
}
|
||||
m := (int(b)*7 + sh*13) % 80
|
||||
if m < 4 {
|
||||
m = 4
|
||||
}
|
||||
out[i] = float64(m)
|
||||
}
|
||||
return out
|
||||
}
|
||||
requests := ui.ChartSeries{Name: "Requests", Data: shuffle([]float64{42, 17, 63, 28, 55, 9, 71})}
|
||||
errs := ui.ChartSeries{Name: "Errors", Data: shuffle([]float64{8, 3, 12, 6, 9, 2, 14})}
|
||||
pie := ui.ChartSeries{Name: "Traffic", Data: shuffle([]float64{40, 25, 20, 15, 8})}
|
||||
threeDLabel := "3D"
|
||||
if threeD.Get() {
|
||||
threeDLabel = "Flat"
|
||||
}
|
||||
|
||||
return docSection("charts", "Charts",
|
||||
prose("These are SVG, produced by go-chart — a plain Go library that knows nothing about "+
|
||||
"browsers. They are drawn by the WEBASSEMBLY, in your browser. The server never enters "+
|
||||
"the drawing code at all; it renders a placeholder, and the wasm replaces it on its first "+
|
||||
"commit."),
|
||||
prose("A Go charting library, compiled to wasm, drawing an SVG in the browser is the thing "+
|
||||
"this layer claims it can do. Server-rendering a picture of a chart would look identical "+
|
||||
"and prove the opposite point."),
|
||||
prose("webui.Chart draws its own SVG — nice-scale axes, rounded columns, arc slices, a "+
|
||||
"pointer crosshair — with no charting library. The geometry is pure Go, so the same shapes "+
|
||||
"the Solid kit draws on /js run here in the WebAssembly, against the same theme tokens. Change "+
|
||||
"the data and only the marks that moved re-render."),
|
||||
|
||||
demo("Drawn in the browser, by Go",
|
||||
row("grid gap-4 lg:grid-cols-12",
|
||||
chartBox("lg:col-span-7 rounded-default border border-line bg-surface p-3 shadow-xs overflow-auto",
|
||||
"h-[260px]", drawn.Get(), func() string { return barSVG(v) }),
|
||||
chartBox("lg:col-span-5 rounded-default border border-line bg-surface p-3 shadow-xs overflow-auto",
|
||||
"h-[320px]", drawn.Get(), func() string { return pieSVG(v) }),
|
||||
demo("Bar, donut, smooth area, two lines — one data set, and a 3D toggle",
|
||||
row("grid gap-6 lg:grid-cols-12",
|
||||
Div(Attr("class", "lg:col-span-7"), barC.Render(ui.ChartProps{Kind: ui.ChartBar, Labels: chartDaysWasm, Series: []ui.ChartSeries{requests, errs}, Height: 260, ThreeD: threeD.Get()})),
|
||||
Div(Attr("class", "lg:col-span-5"), donutC.Render(ui.ChartProps{Kind: ui.ChartDonut, Labels: pieLabelsWasm, Series: []ui.ChartSeries{pie}, Height: 260, ThreeD: threeD.Get()})),
|
||||
Div(Attr("class", "lg:col-span-7"), areaC.Render(ui.ChartProps{Kind: ui.ChartArea, Smooth: true, Labels: chartDaysWasm, Series: []ui.ChartSeries{requests}, Height: 220})),
|
||||
Div(Attr("class", "lg:col-span-5"), lineC.Render(ui.ChartProps{Kind: ui.ChartLine, Labels: chartDaysWasm, Series: []ui.ChartSeries{requests, errs}, Height: 220})),
|
||||
),
|
||||
row("mt-4 flex items-center gap-2",
|
||||
ui.Button(ui.ButtonProps{Color: ui.ButtonPrimary, Small: true, Text: "New data",
|
||||
OnClick: func() { values.Set(randomValues()) }}),
|
||||
Span(Attr("class", "text-xs text-ink-muted"),
|
||||
Text("Re-drawn in Go, in the browser. No request is made.")),
|
||||
row("mt-4 flex items-center gap-3",
|
||||
ui.Button(ui.ButtonProps{Color: ui.ButtonPrimary, Small: true, Text: "New data", OnClick: func() { seed.Set(seed.Get() + 1) }}),
|
||||
ui.Button(ui.ButtonProps{Color: ui.ButtonNeutral, Small: true, Text: threeDLabel, OnClick: func() { threeD.Set(!threeD.Get()) }}),
|
||||
Span(Attr("class", "text-xs text-ink-muted"), Text("Hover any chart. 3D extrudes the bars and tilts the donut.")),
|
||||
),
|
||||
),
|
||||
|
||||
note("webui.Chart is a stub, and says so",
|
||||
"The Solid kit's Chart draws its own SVG — nice-scale axes, rounded columns, arc slices, "+
|
||||
"a pointer-driven crosshair — with no charting library at all. That geometry has not "+
|
||||
"been ported to the neutral Go runtime yet, so the Go port keeps the props shape for "+
|
||||
"parity and renders only its box. This example draws with go-chart "+
|
||||
"instead, as above. Pretending the port drew charts would be the one thing this site refuses to do."),
|
||||
demo("Horizontal bars, and stacked",
|
||||
row("grid gap-6 lg:grid-cols-2",
|
||||
horizC.Render(ui.ChartProps{Kind: ui.ChartBar, Horizontal: true, Labels: chartDaysWasm, Series: []ui.ChartSeries{requests, errs}, Height: 260}),
|
||||
stackC.Render(ui.ChartProps{Kind: ui.ChartBar, Stacked: true, Labels: regionsWasm, Series: []ui.ChartSeries{
|
||||
{Name: "Requests", Data: shuffle([]float64{42, 55, 28, 63})},
|
||||
{Name: "Errors", Data: shuffle([]float64{8, 9, 6, 12})},
|
||||
{Name: "Retries", Data: shuffle([]float64{5, 7, 3, 9})},
|
||||
}, Height: 260}),
|
||||
),
|
||||
),
|
||||
|
||||
demo("US heatmap — a value per state, with proportional lat/lng points on top",
|
||||
heat.Render(ui.USHeatmapProps{Data: usSignups, Points: usCities, Proportional: true}),
|
||||
Span(Attr("class", "mt-3 block text-xs text-ink-muted"),
|
||||
Text("webui.USHeatmap shades each state on the choropleth ramp and projects lat/lng points "+
|
||||
"with a Go albersUsa port — Anchorage and Honolulu land on the insets. Hover a state or a point.")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1337,7 +1393,6 @@ func languageOptions() []ui.FormSelectOption {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const kitSnippet = `// A component is a function taking a props struct.
|
||||
ui.Button(ui.ButtonProps{
|
||||
Color: ui.ButtonPrimary,
|
||||
|
||||
Reference in New Issue
Block a user