Code Snippets
Copy-paste these snippets to quickly build dashboard components.
Query Helpers
Basic Query Wrapper
javascript
const DATASOURCE = 'my_database';
async function runQuery(sql) {
try {
const rows = await gluon.query(sql, { datasource: DATASOURCE });
return { ok: true, rows };
} catch (err) {
console.error('Query error:', err);
return { ok: false, error: err.message };
}
}
Query with Metadata
javascript
async function runQueryWithMeta(sql) {
try {
const result = await gluon.queryWithMeta(sql, { datasource: DATASOURCE });
return { ok: true, ...result };
} catch (err) {
return { ok: false, error: err.message };
}
}
Number Formatting
javascript
function formatNumber(num) {
if (num === undefined || num === null) return '-';
const n = Number(num);
if (isNaN(n)) return '-';
if (n >= 1000000) return (n / 1000000).toFixed(1) + 'M';
if (n >= 1000) return (n / 1000).toFixed(1) + 'K';
return n.toLocaleString();
}
function formatCurrency(num) {
return '$' + Number(num || 0).toFixed(2);
}
function formatBytes(bytes) {
if (!bytes) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function formatPercent(value, decimals = 1) {
return (Number(value) * 100).toFixed(decimals) + '%';
}
Chart.js Templates
Line Chart
javascript
function renderLineChart(canvasId, labels, data, label, color) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: [{
label,
data,
borderColor: color,
backgroundColor: color + '20',
tension: 0.4,
fill: true,
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true } }
}
});
}
Bar Chart
javascript
function renderBarChart(canvasId, labels, data, colors) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'bar',
data: {
labels,
datasets: [{
data,
backgroundColor: colors || '#6366f1',
borderRadius: 6
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { display: false } },
scales: { y: { beginAtZero: true } }
}
});
}
Doughnut Chart
javascript
function renderDoughnutChart(canvasId, labels, data) {
const ctx = document.getElementById(canvasId).getContext('2d');
const colors = ['#6366f1', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6'];
return new Chart(ctx, {
type: 'doughnut',
data: {
labels,
datasets: [{
data,
backgroundColor: colors.slice(0, labels.length),
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: { legend: { position: 'right' } }
}
});
}
Multi-Line Chart
javascript
function renderMultiLineChart(canvasId, labels, datasets) {
const ctx = document.getElementById(canvasId).getContext('2d');
const colors = ['#6366f1', '#10b981', '#f59e0b', '#ef4444'];
return new Chart(ctx, {
type: 'line',
data: {
labels,
datasets: datasets.map((ds, i) => ({
label: ds.label,
data: ds.data,
borderColor: colors[i % colors.length],
tension: 0.3,
fill: false
}))
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: { mode: 'index', intersect: false }
}
});
}
Common SQL Queries
Daily Aggregation
sql
SELECT
DATE(created_at) as date,
COUNT(*) as count
FROM your_table
WHERE created_at > NOW() - INTERVAL '30 days'
GROUP BY DATE(created_at)
ORDER BY date ASC
KPI Summary
sql
SELECT
COUNT(*) as total,
COUNT(*) FILTER (WHERE created_at > NOW() - INTERVAL '30 days') as recent,
SUM(amount) as total_amount,
AVG(amount) as avg_amount
FROM your_table
Group by Category
sql
SELECT
category,
COUNT(*) as count,
SUM(amount) as total
FROM your_table
GROUP BY category
ORDER BY total DESC
LIMIT 10
Time-Series by Hour
sql
SELECT
DATE_TRUNC('hour', created_at) as hour,
COUNT(*) as count
FROM your_table
WHERE created_at > NOW() - INTERVAL '24 hours'
GROUP BY DATE_TRUNC('hour', created_at)
ORDER BY hour ASC
CSS Snippets
Dark Theme Base
css
:root {
--bg-dark: #1a1a2e;
--bg-card: #252540;
--text-primary: #e4e4e7;
--text-secondary: #a1a1aa;
--accent: #6366f1;
--success: #10b981;
--warning: #f59e0b;
--danger: #ef4444;
--border: rgba(255, 255, 255, 0.1);
}
body {
font-family: system-ui, -apple-system, sans-serif;
background: var(--bg-dark);
color: var(--text-primary);
margin: 0;
padding: 20px;
}
KPI Card
css
.kpi-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 24px;
transition: transform 0.2s;
}
.kpi-card:hover {
transform: translateY(-2px);
}
.kpi-label {
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: var(--text-secondary);
margin-bottom: 8px;
}
.kpi-value {
font-size: 32px;
font-weight: 700;
color: var(--accent);
}
Responsive Grid
css
.grid {
display: grid;
gap: 20px;
}
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 768px) {
.grid-2, .grid-3, .grid-4 {
grid-template-columns: 1fr;
}
}
Data Table
css
table {
width: 100%;
border-collapse: collapse;
}
th {
padding: 12px 16px;
text-align: left;
font-size: 12px;
text-transform: uppercase;
color: var(--text-secondary);
background: rgba(255, 255, 255, 0.05);
border-bottom: 1px solid var(--border);
}
td {
padding: 12px 16px;
border-bottom: 1px solid var(--border);
}
tbody tr:hover {
background: rgba(255, 255, 255, 0.05);
}
Status Badge
css
.badge {
display: inline-block;
padding: 4px 12px;
border-radius: 12px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
}
.badge-success {
background: rgba(16, 185, 129, 0.2);
color: var(--success);
}
.badge-warning {
background: rgba(245, 158, 11, 0.2);
color: var(--warning);
}
.badge-danger {
background: rgba(239, 68, 68, 0.2);
color: var(--danger);
}
Loading States
Skeleton Loader
html
<div class="skeleton" style="width: 100%; height: 200px;"></div>
css
.skeleton {
background: linear-gradient(
90deg,
var(--bg-card) 25%,
rgba(255, 255, 255, 0.1) 50%,
var(--bg-card) 75%
);
background-size: 200% 100%;
animation: skeleton-loading 1.5s infinite;
border-radius: 8px;
}
@keyframes skeleton-loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
Spinner
html
<div class="spinner"></div>
css
.spinner {
width: 40px;
height: 40px;
border: 3px solid var(--border);
border-top-color: var(--accent);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}