Files
MujicaUI/examples/gallery/pages_charts2_stats.go
T

195 lines
6.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"fmt"
"github.com/egoist/mygo/ui"
mujica "mujicaui"
"mujicaui/internal"
)
func c2LegendDemo(c *ui.Context, log func(string)) {
type state struct {
hidden map[string]bool
vertical, disabled bool
max float64
}
s := ui.Local(c.Root(), "121", func() state { return state{hidden: map[string]bool{}, max: 3} })
c1Section(c, "ChartLegend", func() {
c2Check(c, &s.vertical, "Vertical", log)
c2Check(c, &s.disabled, "Disabled", log)
c2Number(c, &s.max, "Max items", 0, 6, 1, log)
}, func() {
pal := internal.Palette(mujica.Tokens(c))
names := []string{"Matins", "Lauds", "Prime", "Terce", "Sext", "None"}
items := make([]mujica.ChartLegendItem, len(names))
for i, n := range names {
items[i] = mujica.ChartLegendItem{Name: n, Color: pal[i], Shape: i % 5}
}
ui.Column(c).Disabled(s.disabled).Children(func() {
r := mujica.ChartLegend(c, &s.hidden, items, mujica.ChartLegendOptions{Vertical: s.vertical, MaxItems: int(s.max)})
if expanded, ok := r.Expanded(); ok {
log(fmt.Sprintf("ChartLegend: expanded %v", expanded))
}
if n, ok := r.Toggled(); ok {
log("ChartLegend: toggled " + n)
}
})
ui.Text(c, fmt.Sprintf("Hidden: %v", s.hidden))
})
}
func c2BrushDemo(c *ui.Context, log func(string)) {
type state struct {
value [2]float64
disabled bool
step float64
}
s := ui.Local(c.Root(), "126", func() state { return state{value: [2]float64{20, 60}, step: 1} })
c1Section(c, "ChartBrush", func() {
c2Check(c, &s.disabled, "Disabled", log)
c2Number(c, &s.step, "Step", 1, 10, 1, log)
}, func() {
vals := []float64{1, 4, 2, 7, 3, 8, 4, 9}
r := mujica.ChartBrush(c, &s.value, mujica.ChartBrushOptions{Label: "Months", Max: 100, Step: s.step, Values: vals, Disabled: s.disabled})
if r.Changed() {
log(fmt.Sprintf("ChartBrush: range %g–%g", s.value[0], s.value[1]))
}
x := mujica.ChartAxis(c, mujica.ChartAxisOptions{Min: s.value[0], Max: s.value[1]})
y := mujica.ChartAxis(c, mujica.ChartAxisOptions{Side: mujica.SideLeft, Max: 10})
xs := []float64{0, 15, 30, 45, 60, 75, 90, 100}
var visible []int
for i, v := range xs {
if v >= s.value[0] && v <= s.value[1] {
visible = append(visible, i)
}
}
plotOf := func(r ui.Rect) ui.Rect { return ui.Rect{X: r.X + 40, Y: r.Y + 8, W: max(1, r.W-60), H: max(1, r.H-40)} }
at := func(r ui.Rect, i int) (float32, float32) {
plot := plotOf(r)
return x.Map(plot, xs[visible[i]]), y.Map(plot, vals[visible[i]])
}
c1Log(log, "Zoom preview", mujica.Chart(c, mujica.ChartFrame{Label: "Zoom preview", Height: 140}, mujica.ChartSpec{
Marks: len(visible), Anchor: at,
Pick: func(r ui.Rect, px, py float32) int {
return internal.Nearest(len(visible), func(i int) (float32, float32) { return at(r, i) }, px, py, 24, false)
},
Readout: func(i int) string { return fmt.Sprintf("x %g · y %g", xs[visible[i]], vals[visible[i]]) },
Draw: func(p *ui.Painter, r ui.Rect, active int) {
plot := plotOf(r)
x.Draw(p, plot)
y.Draw(p, plot)
for i := range visible {
px, py := at(r, i)
internal.Marker(p, 0, px, py, 8, mujica.Tokens(c).AccentText)
}
},
}))
})
}
func c2ExportDemo(c *ui.Context, log func(string)) {
type state struct {
width, height, scale float64
disabled bool
bitmap *ui.Bitmap
bytes int
error string
}
s := ui.Local(c.Root(), "128", func() state { return state{width: 400, height: 240, scale: 2} })
c1Section(c, "ChartExport", func() {
c2Number(c, &s.width, "Width", 200, 600, 50, log)
c2Number(c, &s.height, "Height", 160, 400, 40, log)
c2Number(c, &s.scale, "Scale", 1, 3, 0.5, log)
c2Check(c, &s.disabled, "Disabled", log)
}, func() {
if mujica.Button(c, "Export PNG", mujica.ButtonOptions{Disabled: s.disabled}).Clicked() {
data, err := mujica.ChartExport(c, func(c *ui.Context) {
mujica.BarChart(c, []string{"Nave", "Choir", "Crypt"}, []mujica.ChartSeries{{Name: "Pews", Values: []float64{3, 5, 2}}}, mujica.BarChartOptions{Frame: mujica.ChartFrame{Label: "Exported chart", Height: float32(s.height) - 80}})
}, mujica.ChartExportOptions{Width: int(s.width), Height: int(s.height), Scale: float32(s.scale)})
if err == nil {
s.bitmap, err = ui.DecodeBitmap(data)
}
if err != nil {
s.error = err.Error()
log("ChartExport: " + s.error)
} else {
s.error = ""
s.bytes = len(data)
log(fmt.Sprintf("ChartExport: %d bytes", s.bytes))
}
}
if s.error != "" {
ui.Text(c, s.error).TextColor(mujica.Tokens(c).Danger).Role(ui.RoleStatus)
}
if s.bitmap != nil {
ui.Image(c, s.bitmap).Size(float32(s.width), float32(s.height))
ui.Text(c, fmt.Sprintf("PNG: %d bytes", s.bytes))
}
})
}
func c2SparkBarDemo(c *ui.Context, log func(string)) {
type state struct {
status string
width float64
disabled bool
}
s := ui.Local(c.Root(), "132", func() state { return state{status: "Ready", width: 10} })
c1Section(c, "SparkBar", func() {
c2Number(c, &s.width, "Bar width", 2, 20, 1, log)
c2Check(c, &s.disabled, "Disabled", log)
}, func() {
f, show := c2Frame(c, "Alms", &s.status, log)
vals := []float64{3, -2, 4, 1, -3}
if !show {
vals = nil
}
ui.Column(c).Disabled(s.disabled).Children(func() {
c1Log(log, "SparkBar", mujica.SparkBar(c, vals, mujica.SparkBarOptions{Frame: f, BarWidth: float32(s.width)}))
})
})
}
func c2TrendDemo(c *ui.Context, log func(string)) {
type state struct {
change, precision float64
invert bool
}
s := ui.Local(c.Root(), "133", func() state { return state{change: 12.5, precision: 1} })
c1Section(c, "TrendIndicator", func() {
c2Number(c, &s.change, "Change", -100, 100, 0.5, log)
c2Number(c, &s.precision, "Precision", 0, 3, 1, log)
c2Check(c, &s.invert, "Invert", log)
}, func() {
mujica.TrendIndicator(c, s.change, mujica.TrendIndicatorOptions{Precision: int(s.precision), Unit: "%", Note: "vs Lent", Invert: s.invert})
ui.Row(c).Gap(24).Children(func() {
mujica.TrendIndicator(c, 3, mujica.TrendIndicatorOptions{})
mujica.TrendIndicator(c, -3, mujica.TrendIndicatorOptions{})
mujica.TrendIndicator(c, 0, mujica.TrendIndicatorOptions{})
})
})
}
func c2EmptyDemo(c *ui.Context, log func(string)) {
type state struct {
status string
height float64
disabled bool
}
s := ui.Local(c.Root(), "140", func() state { return state{status: "Failed", height: 180} })
c1Section(c, "ChartEmptyState", func() {
c2Number(c, &s.height, "Height", 160, 320, 40, log)
c2Check(c, &s.disabled, "Disabled", log)
}, func() {
f, _ := c2Frame(c, "ChartEmptyState", &s.status, log)
ui.Column(c).Disabled(s.disabled).Border(1, mujica.Tokens(c).Border).Children(func() {
if mujica.ChartEmptyState(c, f.Status, mujica.ChartEmptyStateOptions{Height: float32(s.height), Error: f.Error}).Changed() {
log("ChartEmptyState: retry")
s.status = "Loading"
}
})
})
}