Trwth Dashboard Guide

Trwth is a local-first dashboard framework built in pure JavaScript and CSS. It emphasizes transparent formulas, offline capability, and keeping data on your machine by default.

What makes Trwth different?

  • Local-first: works fully offline; no external CDNs or package managers are required.
  • Formula-centric: dashboards are configured with a declarative appConfig and column formulas.
  • Secure by default: avoids third-party scripts; optional encryption for persisted data.

Philosophy: every view should clearly show who it’s about (keys), what it measures (columns & formulas), and why the result is true (transparent config & totals).

Browser Support

  • Chrome 90+
  • Firefox 90+
  • Safari 14+
  • Edge 90+

Installation

Local Files (recommended)

Place the framework files into your project and include them directly—no internet required.

<!-- Include your local build(s) -->
<link rel="stylesheet" href="../css/base.css">
<script src="../js/trwth.core.js"></script>
<script src="../js/trwth.dashboard.js"></script>

Project Structure

/project
  /css
    base.css
  /js
    trwth.core.js
    trwth.dashboard.js
  /data
    loans.csv
  guide/index.html

Note: Avoid remote CDNs to ensure offline operation and minimize supply-chain risk.

Basic Usage

HTML

Add a container for the dashboard UI.

<div id="dashboard"></div>

Config + Mount

Trwth reads a declarative window.appConfig that defines columns, formulas, and filters.

<script>
// Minimal example
window.appConfig = {
  description: "Branch performance overview",
  table: [
    { heading: "Branch", id: "Branch_Number", column_type: "data", data_type: "integer", source: "loan" },
    { heading: "Principal", id: "Principal", column_type: "data", data_type: "currency", source: "loan" },
    { heading: "Loan Count", id: "loan_count", column_type: "formula", formula: "count", data_type: "integer", source: "loan" },
    { heading: "Avg Principal", id: "avg_principal", column_type: "formula", formula: "average", data_type: "currency", source: "loan", target_id: "Principal" }
  ],
  primary_key: "Portfolio"
};

// Mount the dashboard
Trwth.Dashboard.mount("#dashboard", { appConfig: window.appConfig });
</script>

Formulas

Formulas compute per-group values after filters and translation are applied. Supported built-ins:

columns: [
  { heading: "Branch", id: "Branch_Number", column_type: "data", data_type: "integer", source: "loan" },
  { heading: "Principal", id: "Principal", column_type: "data", data_type: "currency", source: "loan" },

  // COUNT (target_id optional)
  { heading: "Loan Count", id: "loan_count", column_type: "formula", formula: "count", data_type: "integer", source: "loan" },

  // DISTINCT COUNT
  { heading: "Distinct Borrowers", id: "distinct_borrowers", column_type: "formula", formula: "distinct_count", data_type: "integer", source: "loan", target_id: "Borrower_ID" },

  // AVERAGE / AVG
  { heading: "Avg Principal", id: "avg_principal", column_type: "formula", formula: "average", data_type: "currency", source: "loan", target_id: "Principal" },

  // SUM
  { heading: "Total Principal", id: "sum_principal", column_type: "formula", formula: "sum", data_type: "currency", source: "loan", target_id: "Principal" },

  // MIN / MAX (dates resolve to earliest/latest)
  { heading: "Earliest Open", id: "min_open", column_type: "formula", formula: "min", data_type: "date", source: "loan", target_id: "Open_Date" },
  { heading: "Largest Balance", id: "max_balance", column_type: "formula", formula: "max", data_type: "currency", source: "loan", target_id: "Average_Balance" },

  // DISTINCT — joined by ", "
  { heading: "Product Types", id: "product_types", column_type: "formula", formula: "distinct", data_type: "string", source: "loan", target_id: "Product_Code" },
]

Formula Reference

Formula What it does target_id Source Example
count Counts rows after filters Optional Optional {formula:"count", id:"loan_count", source:"loan"}
average / avg Mean of numeric field Required Optional {formula:"avg", id:"avg_principal", source:"loan", target_id:"Principal"}
sum Total of numeric field Required Optional {formula:"sum", id:"sum_principal", source:"loan", target_id:"Principal"}
min Minimum value (earliest date) Required Optional {formula:"min", id:"min_open", data_type:"date", target_id:"Open_Date"}
max Maximum value (latest date) Required Optional {formula:"max", id:"max_balance", data_type:"currency", target_id:"Average_Balance"}
distinct Unique values joined by “, ” Required Optional {formula:"distinct", id:"product_types", target_id:"Product_Code"}
distinct_count Count of unique values Required Optional {formula:"distinct_count", id:"distinct_borrowers", target_id:"Borrower_ID"}

Config Reference

Trwth uses a single appConfig object as the source of truth.

Top-level

KeyTypeDescription
descriptionstringMarkdown/HTML description for the page
tableArray<Column>Column definitions (data & formulas)
primary_keystringUnique identifier field (e.g., Portfolio)
filtersobjectOptional global filters

Column

KeyTypeRequiredDescription
headingstringYesColumn header
idstringYesField key
column_type"data" | "formula"YesData source column or computed
data_typestringYese.g., integer, currency, date, string
sourcestringNoSource name (CSV/JSON alias)
formulastringWhen formulaOne of the formula names above
target_idstringAs neededTarget field for aggregation
filterstringNoInline filter expression

Data Sources

CSV (local)

Load CSV via file input (no network):

<input type="file" id="csvLoans" accept=".csv">
<script>
document.getElementById('csvLoans').addEventListener('change', e => {
  Trwth.Dashboard.loadCsv('loan', e.target.files[0], { headers: true });
});
</script>

JSON (local)

<input type="file" id="jsonUsers" accept=".json">
<script>
document.getElementById('jsonUsers').addEventListener('change', async e => {
  const file = e.target.files[0];
  const text = await file.text();
  const data = JSON.parse(text);
  Trwth.Dashboard.updateData('users', data);
});
</script>

Security Note: All parsing happens locally in the browser; no data leaves your machine unless you explicitly export/sync.

Customization

Theme

Trwth.Dashboard.setTheme({
  colors: {
    primary: '#2E8BC0',
    secondary: '#58C6B1'
  },
  fonts: {
    primary: 'Inter, sans-serif',
    monospace: 'Fira Code, monospace'
  }
});

Custom CSS

.trwth-table th, .trwth-table td { padding: 8px 12px; }
.trwth-badge { border-radius: 8px; padding: 2px 8px; }

Security

Local-first defaults

Trwth avoids third-party scripts and external calls by default.

Optional Encryption

Trwth.Security.enable({
  encryption: true,
  algorithm: 'AES-256-GCM',
  getKey: async () => myKeyBytes
});

Examples

Branch Performance

Demonstrates formula aggregation and filtering.

window.appConfig = {
  description: "Branch performance (local CSV)",
  primary_key: "Portfolio",
  table: [
    { heading: "Portfolio", id: "Portfolio", column_type: "data", data_type: "unique", source: "loan" },
    { heading: "Principal", id: "Principal", column_type: "data", data_type: "currency", source: "loan" },
    { heading: "Loan Count", id: "loan_count", column_type: "formula", formula: "count", data_type: "integer", source: "loan" },
    { heading: "Avg Principal", id: "avg_principal", column_type: "formula", formula: "average", data_type: "currency", source: "loan", target_id: "Principal" },
    { heading: "Earliest Open", id: "min_open", column_type: "formula", formula: "min", data_type: "date", source: "loan", target_id: "Open_Date" }
  ]
};
Trwth.Dashboard.mount("#dashboard", { appConfig: window.appConfig });

Troubleshooting

Overflow or horizontal scrolling?

  • Ensure your container uses the updated styles (min-width: 0 on grid children).
  • Keep tables/code inside the provided .api-table / .code-block wrappers.

Data not appearing?

  • Verify your source alias matches column.source.
  • Confirm the primary_key is present in your data.