Skip to content

Instantly share code, notes, and snippets.

@AnnMarieW
Last active June 7, 2026 00:10
Show Gist options
  • Select an option

  • Save AnnMarieW/c77b15fccaf7602c66301925d5dc168e to your computer and use it in GitHub Desktop.

Select an option

Save AnnMarieW/c77b15fccaf7602c66301925d5dc168e to your computer and use it in GitHub Desktop.
dash-ag-grid styled like a 1950 census table
import dash_ag_grid as dag
from dash import Dash, html
app = Dash()
rowData = [
{"idx": "", "occupation": "Fishing and mining", "group": True},
{"idx": 86, "occupation": "Fishermen and oystermen", "louisville_m": 36, "louisville_f": "", "lowell_m": 2, "lowell_f": ""},
{"idx": 87, "occupation": "Miners and quarrymen", "louisville_m": 89, "louisville_f": "", "lowell_m": "", "lowell_f": ""},
{"idx": "", "occupation": "Food and kindred products", "group": True},
{"idx": 88, "occupation": "Bakers", "louisville_m": 639, "louisville_f": 39, "lowell_m": 199, "lowell_f": 3},
{"idx": 89, "occupation": "Butchers", "louisville_m": 444, "louisville_f": 12, "lowell_m": 118, "lowell_f": ""},
]
valueFormatter = {
"function": "params.value === '' ? '......' : params.value"
}
columnDefs = [
{"field": "idx", "headerName": "", "width": 60},
{
"field": "occupation",
"headerName": "Occupations",
"flex": 1,
"cellClass": "dot-leader-column",
"maxWidth": 250,
},
{
"headerName": "Louisville, KY",
"children": [
{"field": "louisville_m", "headerName": "Males", "valueFormatter": valueFormatter},
{"field": "louisville_f", "headerName": "Females", "valueFormatter": valueFormatter},
],
},
{"type": "separator"},
{
"headerName": "Lowell, MA",
"children": [
{"field": "lowell_m", "headerName": "Males", "valueFormatter": valueFormatter},
{"field": "lowell_f", "headerName": "Females", "valueFormatter": valueFormatter},
],
},
{"type": "separator"},
]
columnTypes = {
"separator": {
"headerName": "",
"maxWidth": 8,
"headerClass": "separator-column",
"cellClass": "separator-cell",
}
}
dashGridOptions = {
"theme": {
"function": """
themeQuartz.withParams({
headerBackgroundColor: '#ffffff',
fontFamily: 'Georgia, serif',
fontSize: 11,
spacing: 2,
rowBorder: false,
columnBorder: { style: 'solid', width: 1, color: '#e2e2e2' },
headerColumnBorder: { style: 'solid', width: 1, color: '#e2e2e2' },
headerRowBorder: false,
wrapperBorder: false,
})
"""
},
"rowClassRules": {
"group-row": "params.data.group === true"
},
"getRowHeight": {
"function": "params.data.group ? 36 : 20"
},
"columnTypes": columnTypes,
}
app.layout = html.Div(
dag.AgGrid(
id="theme-grid",
rowData=rowData,
columnDefs=columnDefs,
defaultColDef={
"resizable": False,
"sortable": False,
"type": "numericColumn",
},
columnSize="autoSize",
dashGridOptions=dashGridOptions,
),
style={"marginTop": 50},
)
if __name__ == "__main__":
app.run(debug=True)
/* row group titles */
.ag-row.group-row .ag-cell {
display: flex;
align-items: flex-end;
justify-content: center;
font-style: italic;
}
/* Dot leader effect */
.ag-row:not(.group-row) .dot-leader-column.ag-cell-value::after {
content: " . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .";
overflow: hidden;
text-overflow: clip;
padding-left: 4px;
}
/* Header alignment */
.ag-header-cell-label {
justify-content: center;
}
.ag-header-group-cell-label {
justify-content: center;
width: 100%;
}
.ag-header-group-cell:not(.separator-column),
.ag-header-cell:not(.separator-column) {
border-bottom: 1px solid #e2e2e2;
}
.ag-header-row:first-child {
border-top: 1px solid #e2e2e2;
}
.ag-row:last-child {
border-bottom: 1px solid #e2e2e2;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment