Tableau Dashboard Creator
Kilo-Org/kilo-marketplace
Takes a plain-language dashboard request through brand setup, data exploration, planning, an interactive HTML mock and a Tableau implementation spec.
Build self-contained interactive HTML dashboards with Chart.js, dropdown filters, and professional styling.
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builder --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .claude/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .claude/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builderType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builder --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .agents/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .agents/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .agents/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builder --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .cursor/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .cursor/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/w95/awesome-claude-corporate-skills.git --path 10-data-analytics/interactive-dashboard-builder--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builder --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .gemini/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .gemini/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builderInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .github/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .github/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .github/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install w95/awesome-claude-corporate-skills interactive-dashboard-builder --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/w95/awesome-claude-corporate-skills.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/10-data-analytics/interactive-dashboard-builder .opencode/skills/interactive-dashboard-builder && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "interactive-dashboard-builder" agent skill from https://github.com/w95/awesome-claude-corporate-skills/tree/main/10-data-analytics/interactive-dashboard-builder into .opencode/skills/interactive-dashboard-builder/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "interactive-dashboard-builder", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
interactive-dashboard-builderBuild self-contained interactive HTML dashboards with Chart.js, dropdown filters, and professional styling.
Interactive Dashboard Builder is an agent skill from w95/awesome-claude-corporate-skills. Build self-contained interactive HTML dashboards with Chart.js, dropdown filters, and professional styling. Use when creating dashboards, building interactive reports, or generating shareable HTML files with charts and filters that work without a server.
Its SKILL.md is about 5.1k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Data & Analytics, covering HTML artifacts and Data analysis. It works with Chart.js. The repository describes itself as: 166 production-ready Claude AI skills organized by corporate role — executive leadership, finance, HR, marketing, sales, legal, operations, engineering, product, data, customer…. The licence is MIT.
Read from SKILL.md and the folder at commit 78dbc7c. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript, css and html).
From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
cdn.jsdelivr.netFrom URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Interactive Dashboard Builder loads about 5.1k tokens when it runs. Until then it costs about 71 tokens; SKILL.md has 226 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from w95/awesome-claude-corporate-skills at commit 78dbc7c, republished under its MIT licence (© w95). 226 words, ~5,128 tokens.
.claude/skills/interactive-dashboard-builder/SKILL.md (or your agent's skills folder).Patterns and techniques for building self-contained HTML/JS dashboards with Chart.js, filters, interactivity, and professional styling.
Every dashboard follows this structure:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard Title</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1" integrity="sha384-jb8JQMbMoBUzgWatfe6COACi2ljcDdZQ2OxczGA3bGNeWe+6DChMTBJemed7ZnvJ" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0" integrity="sha384-cVMg8E3QFwTvGCDuK+ET4PD341jF3W8nO1auiXfuZNQkzbUUiBGLsIQUE+b1mxws" crossorigin="anonymous"></script>
<style>
/* Dashboard styles go here */
</style>
</head>
<body>
<div class="dashboard-container">
<header class="dashboard-header">
<h1>Dashboard Title</h1>
<div class="filters">
<!-- Filter controls -->
</div>
</header>
<section class="kpi-row">
<!-- KPI cards -->
</section>
<section class="chart-row">
<!-- Chart containers -->
</section>
<section class="table-section">
<!-- Data table -->
</section>
<footer class="dashboard-footer">
<span>Data as of: <span id="data-date"></span></span>
</footer>
</div>
<script>
// Embedded data
const DATA = [];
// Dashboard logic
class Dashboard {
constructor(data) {
this.rawData = data;
this.filteredData = data;
this.charts = {};
this.init();
}
init() {
this.setupFilters();
this.renderKPIs();
this.renderCharts();
this.renderTable();
}
applyFilters() {
// Filter logic
this.filteredData = this.rawData.filter(row => {
// Apply each active filter
return true; // placeholder
});
this.renderKPIs();
this.updateCharts();
this.renderTable();
}
// ... methods for each section
}
const dashboard = new Dashboard(DATA);
</script>
</body>
</html><div class="kpi-card">
<div class="kpi-label">Total Revenue</div>
<div class="kpi-value" id="kpi-revenue">$0</div>
<div class="kpi-change positive" id="kpi-revenue-change">+0%</div>
</div>function renderKPI(elementId, value, previousValue, format = 'number') {
const el = document.getElementById(elementId);
const changeEl = document.getElementById(elementId + '-change');
// Format the value
el.textContent = formatValue(value, format);
// Calculate and display change
if (previousValue && previousValue !== 0) {
const pctChange = ((value - previousValue) / previousValue) * 100;
const sign = pctChange >= 0 ? '+' : '';
changeEl.textContent = `${sign}${pctChange.toFixed(1)}% vs prior period`;
changeEl.className = `kpi-change ${pctChange >= 0 ? 'positive' : 'negative'}`;
}
}
function formatValue(value, format) {
switch (format) {
case 'currency':
if (value >= 1e6) return `$${(value / 1e6).toFixed(1)}M`;
if (value >= 1e3) return `$${(value / 1e3).toFixed(1)}K`;
return `$${value.toFixed(0)}`;
case 'percent':
return `${value.toFixed(1)}%`;
case 'number':
if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}K`;
return value.toLocaleString();
default:
return value.toString();
}
}<div class="chart-container">
<h3 class="chart-title">Monthly Revenue Trend</h3>
<canvas id="revenue-chart"></canvas>
</div>function createLineChart(canvasId, labels, datasets) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: datasets.map((ds, i) => ({
label: ds.label,
data: ds.data,
borderColor: COLORS[i % COLORS.length],
backgroundColor: COLORS[i % COLORS.length] + '20',
borderWidth: 2,
fill: ds.fill || false,
tension: 0.3,
pointRadius: 3,
pointHoverRadius: 6,
}))
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'top',
labels: { usePointStyle: true, padding: 20 }
},
tooltip: {
callbacks: {
label: function(context) {
return `${context.dataset.label}: ${formatValue(context.parsed.y, 'currency')}`;
}
}
}
},
scales: {
x: {
grid: { display: false }
},
y: {
beginAtZero: true,
ticks: {
callback: function(value) {
return formatValue(value, 'currency');
}
}
}
}
}
});
}function createBarChart(canvasId, labels, data, options = {}) {
const ctx = document.getElementById(canvasId).getContext('2d');
const isHorizontal = options.horizontal || labels.length > 8;
return new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: options.label || 'Value',
data: data,
backgroundColor: options.colors || COLORS.map(c => c + 'CC'),
borderColor: options.colors || COLORS,
borderWidth: 1,
borderRadius: 4,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
indexAxis: isHorizontal ? 'y' : 'x',
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: function(context) {
return formatValue(context.parsed[isHorizontal ? 'x' : 'y'], options.format || 'number');
}
}
}
},
scales: {
x: {
beginAtZero: true,
grid: { display: isHorizontal },
ticks: isHorizontal ? {
callback: function(value) {
return formatValue(value, options.format || 'number');
}
} : {}
},
y: {
beginAtZero: !isHorizontal,
grid: { display: !isHorizontal },
ticks: !isHorizontal ? {
callback: function(value) {
return formatValue(value, options.format || 'number');
}
} : {}
}
}
}
});
}function createDoughnutChart(canvasId, labels, data) {
const ctx = document.getElementById(canvasId).getContext('2d');
return new Chart(ctx, {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: COLORS.map(c => c + 'CC'),
borderColor: '#ffffff',
borderWidth: 2,
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '60%',
plugins: {
legend: {
position: 'right',
labels: { usePointStyle: true, padding: 15 }
},
tooltip: {
callbacks: {
label: function(context) {
const total = context.dataset.data.reduce((a, b) => a + b, 0);
const pct = ((context.parsed / total) * 100).toFixed(1);
return `${context.label}: ${formatValue(context.parsed, 'number')} (${pct}%)`;
}
}
}
}
}
});
}function updateChart(chart, newLabels, newData) {
chart.data.labels = newLabels;
if (Array.isArray(newData[0])) {
// Multiple datasets
newData.forEach((data, i) => {
chart.data.datasets[i].data = data;
});
} else {
chart.data.datasets[0].data = newData;
}
chart.update('none'); // 'none' disables animation for instant update
}<div class="filter-group">
<label for="filter-region">Region</label>
<select id="filter-region" onchange="dashboard.applyFilters()">
<option value="all">All Regions</option>
</select>
</div>function populateFilter(selectId, data, field) {
const select = document.getElementById(selectId);
const values = [...new Set(data.map(d => d[field]))].sort();
// Keep the "All" option, add unique values
values.forEach(val => {
const option = document.createElement('option');
option.value = val;
option.textContent = val;
select.appendChild(option);
});
}
function getFilterValue(selectId) {
const val = document.getElementById(selectId).value;
return val === 'all' ? null : val;
}<div class="filter-group">
<label>Date Range</label>
<input type="date" id="filter-date-start" onchange="dashboard.applyFilters()">
<span>to</span>
<input type="date" id="filter-date-end" onchange="dashboard.applyFilters()">
</div>function filterByDateRange(data, dateField, startDate, endDate) {
return data.filter(row => {
const rowDate = new Date(row[dateField]);
if (startDate && rowDate < new Date(startDate)) return false;
if (endDate && rowDate > new Date(endDate)) return false;
return true;
});
}applyFilters() {
const region = getFilterValue('filter-region');
const category = getFilterValue('filter-category');
const startDate = document.getElementById('filter-date-start').value;
const endDate = document.getElementById('filter-date-end').value;
this.filteredData = this.rawData.filter(row => {
if (region && row.region !== region) return false;
if (category && row.category !== category) return false;
if (startDate && row.date < startDate) return false;
if (endDate && row.date > endDate) return false;
return true;
});
this.renderKPIs();
this.updateCharts();
this.renderTable();
}function renderTable(containerId, data, columns) {
const container = document.getElementById(containerId);
let sortCol = null;
let sortDir = 'desc';
function render(sortedData) {
let html = '<table class="data-table">';
// Header
html += '<thead><tr>';
columns.forEach(col => {
const arrow = sortCol === col.field
? (sortDir === 'asc' ? ' ▲' : ' ▼')
: '';
html += `<th onclick="sortTable('${col.field}')" style="cursor:pointer">${col.label}${arrow}</th>`;
});
html += '</tr></thead>';
// Body
html += '<tbody>';
sortedData.forEach(row => {
html += '<tr>';
columns.forEach(col => {
const value = col.format ? formatValue(row[col.field], col.format) : row[col.field];
html += `<td>${value}</td>`;
});
html += '</tr>';
});
html += '</tbody></table>';
container.innerHTML = html;
}
window.sortTable = function(field) {
if (sortCol === field) {
sortDir = sortDir === 'asc' ? 'desc' : 'asc';
} else {
sortCol = field;
sortDir = 'desc';
}
const sorted = [...data].sort((a, b) => {
const aVal = a[field], bVal = b[field];
const cmp = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
return sortDir === 'asc' ? cmp : -cmp;
});
render(sorted);
};
render(data);
}:root {
/* Background layers */
--bg-primary: #f8f9fa;
--bg-card: #ffffff;
--bg-header: #1a1a2e;
/* Text */
--text-primary: #212529;
--text-secondary: #6c757d;
--text-on-dark: #ffffff;
/* Accent colors for data */
--color-1: #4C72B0;
--color-2: #DD8452;
--color-3: #55A868;
--color-4: #C44E52;
--color-5: #8172B3;
--color-6: #937860;
/* Status colors */
--positive: #28a745;
--negative: #dc3545;
--neutral: #6c757d;
/* Spacing */
--gap: 16px;
--radius: 8px;
}* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.5;
}
.dashboard-container {
max-width: 1400px;
margin: 0 auto;
padding: var(--gap);
}
.dashboard-header {
background: var(--bg-header);
color: var(--text-on-dark);
padding: 20px 24px;
border-radius: var(--radius);
margin-bottom: var(--gap);
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 12px;
}
.dashboard-header h1 {
font-size: 20px;
font-weight: 600;
}.kpi-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--gap);
margin-bottom: var(--gap);
}
.kpi-card {
background: var(--bg-card);
border-radius: var(--radius);
padding: 20px 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.kpi-label {
font-size: 13px;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 4px;
}
.kpi-value {
font-size: 28px;
font-weight: 700;
color: var(--text-primary);
margin-bottom: 4px;
}
.kpi-change {
font-size: 13px;
font-weight: 500;
}
.kpi-change.positive { color: var(--positive); }
.kpi-change.negative { color: var(--negative); }.chart-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: var(--gap);
margin-bottom: var(--gap);
}
.chart-container {
background: var(--bg-card);
border-radius: var(--radius);
padding: 20px 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
}
.chart-container h3 {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 16px;
}
.chart-container canvas {
max-height: 300px;
}.filters {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.filter-group {
display: flex;
align-items: center;
gap: 6px;
}
.filter-group label {
font-size: 12px;
color: rgba(255, 255, 255, 0.7);
}
.filter-group select,
.filter-group input[type="date"] {
padding: 6px 10px;
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
background: rgba(255, 255, 255, 0.1);
color: var(--text-on-dark);
font-size: 13px;
}
.filter-group select option {
background: var(--bg-header);
color: var(--text-on-dark);
}.table-section {
background: var(--bg-card);
border-radius: var(--radius);
padding: 20px 24px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
overflow-x: auto;
}
.data-table {
width: 100%;
border-collapse: collapse;
font-size: 13px;
}
.data-table thead th {
text-align: left;
padding: 10px 12px;
border-bottom: 2px solid #dee2e6;
color: var(--text-secondary);
font-weight: 600;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
white-space: nowrap;
user-select: none;
}
.data-table thead th:hover {
color: var(--text-primary);
background: #f8f9fa;
}
.data-table tbody td {
padding: 10px 12px;
border-bottom: 1px solid #f0f0f0;
}
.data-table tbody tr:hover {
background: #f8f9fa;
}
.data-table tbody tr:last-child td {
border-bottom: none;
}@media (max-width: 768px) {
.dashboard-header {
flex-direction: column;
align-items: flex-start;
}
.kpi-row {
grid-template-columns: repeat(2, 1fr);
}
.chart-row {
grid-template-columns: 1fr;
}
.filters {
flex-direction: column;
align-items: flex-start;
}
}
@media print {
body { background: white; }
.dashboard-container { max-width: none; }
.filters { display: none; }
.chart-container { break-inside: avoid; }
.kpi-card { border: 1px solid #dee2e6; box-shadow: none; }
}| Data Size | Approach |
|---|---|
| <1,000 rows | Embed directly in HTML. Full interactivity. |
| 1,000 - 10,000 rows | Embed in HTML. May need to pre-aggregate for charts. |
| 10,000 - 100,000 rows | Pre-aggregate server-side. Embed only aggregated data. |
| >100,000 rows | Not suitable for client-side dashboard. Use a BI tool or paginate. |
Instead of embedding raw data and aggregating in the browser:
// DON'T: embed 50,000 raw rows
const RAW_DATA = [/* 50,000 rows */];
// DO: pre-aggregate before embedding
const CHART_DATA = {
monthly_revenue: [
{ month: '2024-01', revenue: 150000, orders: 1200 },
{ month: '2024-02', revenue: 165000, orders: 1350 },
// ... 12 rows instead of 50,000
],
top_products: [
{ product: 'Widget A', revenue: 45000 },
// ... 10 rows
],
kpis: {
total_revenue: 1980000,
total_orders: 15600,
avg_order_value: 127,
}
};animation: false in Chart.js optionsChart.update('none') instead of Chart.update() for filter-triggered updatesrequestAnimationFrame for coordinated chart updates// Efficient table pagination
function renderTablePage(data, page, pageSize = 50) {
const start = page * pageSize;
const end = Math.min(start + pageSize, data.length);
const pageData = data.slice(start, end);
// Render only pageData
// Show pagination controls: "Showing 1-50 of 2,340"
}© w95, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in 10-data-analytics/interactive-dashboard-builder of w95/awesome-claude-corporate-skills.
Open the folder on GitHubat commit 78dbc7c
We found 4 copies of this SKILL.md (exact, near-identical or edited) in other folders, from 2 other GitHub owners. This page covers the copy in w95/awesome-claude-corporate-skills, which our catalogue first saw on October 7, 2026.
Interactive Dashboard Builder next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Interactive Dashboard Builder this skillw95/awesome-claude-corporate-skills | 235 | 2 repos | ~5.1k | Automated safety check: Pass | MIT | |
| Tableau Dashboard CreatorKilo-Org/kilo-marketplace | 189 | — | ~3.8k | Automated safety check: Notes | MIT | |
| Lieflat Chartslarashero3-dotcom/lieflat-charts | 6k | 1 repos | ~4.5k | Automated safety check: Pass | CC-BY-NC-4.0 | |
| Tufte Reportglebis/claude-skills | 388 | — | ~2.4k | Automated safety check: Pass | MIT | |
| Chart Visualizationstophobia/deerflow2.0-enhanced | 820 | — | ~2.1k | Automated safety check: Pass | MIT | |
| Mvizmatsonj/mviz | 226 | — | ~11k | Automated safety check: Pass | None |
Kilo-Org/kilo-marketplace
Takes a plain-language dashboard request through brand setup, data exploration, planning, an interactive HTML mock and a Tableau implementation spec.
larashero3-dotcom/lieflat-charts
Generates single-file HTML charts and full-page reports from real gallery templates, using a grayscale base with optional color presets.
glebis/claude-skills
Create Tufte-inspired data reports and infographic dashboards as standalone HTML files.
stophobia/deerflow2.0-enhanced
This skill should be used when the user wants to visualize data.
matsonj/mviz
A chart & report builder for AI. An agent skill from matsonj/mviz.
benchflow-ai/skillsbench
Build deterministic, verifiable data visualizations with D3.js (v6).
w95/awesome-claude-corporate-skills
Generate or improve a company-specific data analysis skill by extracting tribal knowledge from analysts.
w95/awesome-claude-corporate-skills
Framework for competitive landscape analysis across any industry.
w95/awesome-claude-corporate-skills
Research a company using Common Room data. An agent skill from w95/awesome-claude-corporate-skills.
w95/awesome-claude-corporate-skills
Prepare for a customer or prospect call using Common Room signals.
w95/awesome-claude-corporate-skills
Generate personalized outreach messages using Common Room signals.
w95/awesome-claude-corporate-skills
Write correct, performant SQL across all major data warehouse dialects (Snowflake, BigQuery, Databricks, PostgreSQL, etc.).
Works with
Categories
Build self-contained interactive HTML dashboards with Chart.js, dropdown filters, and professional styling. Interactive Dashboard Builder is an agent skill from w95/awesome-claude-corporate-skills.js, dropdown filters, and professional styling.
Interactive Dashboard Builder fits situations like: creating dashboards; building interactive reports; generating shareable HTML files with charts and filters that work without a server.
Run `npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a claude-code`. Or copy the skill folder (10-data-analytics/interactive-dashboard-builder in w95/awesome-claude-corporate-skills) into .claude/skills/interactive-dashboard-builder in your project. Claude Code loads it when a task matches its description.
Run `npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a codex`. Or copy the skill folder (10-data-analytics/interactive-dashboard-builder in w95/awesome-claude-corporate-skills) into .agents/skills/interactive-dashboard-builder in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add w95/awesome-claude-corporate-skills --skill interactive-dashboard-builder -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/interactive-dashboard-builder, .gemini/skills/interactive-dashboard-builder, .github/skills/interactive-dashboard-builder and .opencode/skills/interactive-dashboard-builder in your project.
SKILL.md names no scripts, command-line tools or credentials: Interactive Dashboard Builder is instructions for the agent only.
SKILL.md names 1 domain. In commands or code: cdn.jsdelivr.net; the agent is likely to contact it when it follows the instructions. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Interactive Dashboard Builder is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.1k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Interactive Dashboard Builder: Tableau Dashboard Creator (Kilo-Org/kilo-marketplace, 189 stars), Lieflat Charts (larashero3-dotcom/lieflat-charts, 6k stars), Tufte Report (glebis/claude-skills, 388 stars) and Chart Visualization (stophobia/deerflow2.0-enhanced, 820 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
w95 (a GitHub user) maintains it in w95/awesome-claude-corporate-skills, which has 235 GitHub stars. The repository holds 43 skills in this directory. The repository was last updated on February 26, 2026.
Source: w95/awesome-claude-corporate-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.