Skip to content

Widgets Data

mike-ward edited this page May 17, 2026 · 2 revisions

Data Widgets

Data widgets display and manipulate structured datasets. Go-gui's data layer is built for production scale: DataGrid virtualises rendering so a million-row table uses the same resources as a ten-row one.


Table

gui.Table(gui.TableCfg{...}) renders a static data table. It is the right choice for smaller datasets where every row is always visible.

gui.Table(gui.TableCfg{
    ID: "results",
    Columns: []gui.TableColumnCfg{
        {Header: "Name",  Field: "name",  Width: 200},
        {Header: "Score", Field: "score", Width: 80, Align: gui.HAlignRight},
        {Header: "Date",  Field: "date",  Width: 120},
    },
    Rows: app.TableRows,  // []map[string]string
    Sizing: gui.FillFit,
})

Columns are sortable by default; click a header to toggle ascending/descending order.


DataGrid

w.DataGrid(gui.DataGridCfg{...}) is the high-capability data grid. It virtualises row rendering — only visible rows are laid out and drawn — so it handles large datasets without manual tuning.

Feature summary:

  • Virtual rows (only visible rows rendered)
  • Multi-column sort
  • Per-column filters
  • Row selection (single or multi)
  • Inline cell editing
  • Pagination
  • Export to CSV, TSV, XLSX, PDF
  • Async data sources
w.DataGrid(gui.DataGridCfg{
    ID:    "orders",
    Sizing: gui.FillFill,
    Columns: []gui.DataGridColumnCfg{
        {
            ID:     "order_id",
            Header: "Order #",
            Width:  100,
            Sortable: true,
        },
        {
            ID:       "customer",
            Header:   "Customer",
            Width:    200,
            Sortable: true,
            Filter:   gui.DataGridFilterText,
        },
        {
            ID:       "total",
            Header:   "Total",
            Width:    100,
            Align:    gui.HAlignRight,
            Sortable: true,
        },
    },
    DataSource: app.OrdersDataSource,
    OnSelect: func(selectedIDs []string, w *gui.Window) {
        gui.State[App](w).SelectedOrders = selectedIDs
    },
})

Note the factory is w.DataGrid(...) (method on *gui.Window) rather than a package-level function, because the grid needs access to window services for async operations.


Tree

gui.Tree(gui.TreeCfg{...}) renders a collapsible hierarchical tree. Nodes can carry icons. The tree supports virtualization for large datasets and simulated lazy loading (load children on first expand).

gui.Tree(gui.TreeCfg{
    ID:      "file-tree",
    IDFocus: 1,
    Sizing:  gui.FillFit,
    Nodes: []gui.TreeNodeCfg{
        {
            Text: "src",
            Icon: gui.IconFolder,
            Nodes: []gui.TreeNodeCfg{
                {Text: "main.go",  Icon: gui.IconFile},
                {Text: "state.go", Icon: gui.IconFile},
            },
        },
        {
            Text: "docs",
            Icon: gui.IconFolder,
            Nodes: []gui.TreeNodeCfg{
                {Text: "README.md", Icon: gui.IconFile},
            },
        },
    },
    OnSelect: func(id string, _ *gui.Event, w *gui.Window) {
        gui.State[App](w).SelectedFile = id
    },
})

For a virtualized tree that handles thousands of nodes, add IDScroll:

gui.Tree(gui.TreeCfg{
    ID:       "large-tree",
    IDFocus:  2,
    IDScroll: 200,
    MaxHeight: 400,
    Sizing:   gui.FillFit,
    Nodes:    buildLargeTree(),
    OnSelect: onSelect,
})

DatePicker and DatePickerRoller

See Input Widgets — DatePicker for configuration details. DatePicker and DatePickerRoller are catalogued in the Data category because they produce structured time.Time values rather than raw strings.

Clone this wiki locally