You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Extract the archive into your Grafana plugins directory:
Linux/Docker: /var/lib/grafana/plugins/
Windows: data/plugins/
Restart Grafana and verify under Administration → Plugins.
Development Install (from source)
git clone https://github.com/tim0-12432/calendar-heatmap-panel.git
cd calendar-heatmap-panel
npm install
npm run build
# Copy dist/ to your Grafana plugins directory
📖 Getting Started
Create a panel and select Calendar Heatmap Panel.
Add a query returning a timestamp field and numeric value.
Choose aggregation (Sum/Count/Avg/Max/Min) for days with multiple points.
Customize appearance: color scheme, cell size/spacing, labels, legend, and tooltips.
Example Queries
PostgreSQL – Daily Signups
SELECT
date_trunc('day', created_at) AStime,
COUNT(*) AS value
FROM users
WHERE $__timeFilter(created_at)
GROUP BY1ORDER BY1;
MySQL – Revenue per Day
SELECTDATE(order_date) AStime,
SUM(total_amount) AS value
FROM orders
WHERE $__timeFilter(order_date)
GROUP BYDATE(order_date)
ORDER BYDATE(order_date);
Microsoft SQL Server – Error Incidents
SELECT
CAST(timestampASdate) AStime,
COUNT(*) AS value
FROM logs
WHERE $__timeFilter(timestamp) AND level ='Error'GROUP BY CAST(timestampASdate)
ORDER BY CAST(timestampASdate);
BigQuery – Sessions per Day
SELECTDATE(session_start) AStime,
COUNT(*) AS value
FROM`project.dataset.sessions`WHERE session_start BETWEEN $__timeFrom() AND $__timeTo()
GROUP BY1ORDER BY1;
ClickHouse – Requests per Day
SELECT
toDate(timestamp) AStime,
count() AS value
FROM requests
WHEREtimestamp BETWEEN $__timeFrom() AND $__timeTo()
GROUP BY toDate(timestamp)
ORDER BY toDate(timestamp);
Infrastructure: CPU throttling events, network errors, database slow queries.
SQL Patterns by Use Case
Deployment Frequency (PostgreSQL):
SELECT date_trunc('day', deployed_at) AStime, COUNT(*) AS value
FROM deployments
WHERE $__timeFilter(deployed_at)
GROUP BY1ORDER BY1;
DAU (MySQL):
SELECTDATE(event_time) AStime, COUNT(DISTINCT user_id) AS value
FROM events
WHERE $__timeFilter(event_time)
GROUP BYDATE(event_time)
ORDER BYDATE(event_time);
Security Incidents (SQL Server):
SELECT CAST(happened_at ASdate) AStime, COUNT(*) AS value
FROM security_incidents
WHERE $__timeFilter(happened_at)
GROUP BY CAST(happened_at ASdate)
ORDER BY CAST(happened_at ASdate);
🛠️ Development
Prerequisites
Node.js 22+
npm (bundled with Node 22)
Docker (for running Grafana locally via npm run server)
Setup
npm install
npm run dev # Hot reload for plugin code
npm run server # Launch Grafana in Docker with the plugin mounted
Scripts
npm run dev # Start Vite/webpack dev workflow (hot reload)
npm run build # Production build
npm run lint # ESLint
npm run lint:fix # Autofix lint issues
npm run typecheck # TypeScript type checking
npm run test# Unit tests (watch)
npm run test:ci # Unit tests (CI mode)
npm run e2e # Playwright end-to-end tests
npm run sign # Sign plugin for distribution
Packaging & Signing
Run npm run build to generate dist/.
Run npm run sign with your Grafana signature credentials configured.
Copy or publish the signed bundle according to Grafana plugin distribution guidelines.
Development Tips
Keep data processing pure and memoized (useMemo, useCallback).
Validate data frames: require one time field and one numeric field.
Test in both light and dark themes for color contrast.
Prefer aggregation on the data source when possible to reduce payload size.