Grafana Business Dashboard
Grafana shines at server monitoring, and it serves business teams just as well. Revenue, orders, sign-ups, and support tickets all sit in databases. A business dashboard puts those numbers on one screen, so managers see how the company performs without writing a single query. This project builds a sales dashboard from a SQL database.
The Shop Counter Analogy
A shop owner glances at the till and the shelves each morning to judge the day. Takings, customers, and stock tell the story. A business dashboard works as a digital till and shelf count. The owner opens one page and knows whether the day looks good.
+---------+---------+---------+---------+
| Revenue | Orders | Avg | New |
| today | today | order | users |
+---------+---------+---------+---------+
| Revenue over time (line) |
+---------------------+-----------------+
| Sales by category | Top products |
| (bar chart) | (table) |
+---------------------+-----------------+
Prepare the Data
The sample uses two tables in a MySQL or PostgreSQL database.
orders(id, created_at, customer_id, category, region, total_amount)
users(id, created_at, name, region)
Connect the database as a data source with a read-only user. Report numbers should never put production data at risk.
Plan Before You Build
Ask the business team three questions.
- Which five numbers do you check every morning?
- What counts as good, and what counts as a warning?
- Who needs to see the dashboard, and how often?
The answers decide the panels, the thresholds, and the refresh rate.
Build the Top Row of Key Numbers
Revenue
SELECT SUM(total_amount) AS revenue
FROM orders
WHERE $__timeFilter(created_at)
Use a stat panel with a currency unit. Turn on the sparkline to show the trend behind the number.
Order Count
SELECT COUNT(*) AS orders
FROM orders
WHERE $__timeFilter(created_at)
Average Order Value
SELECT AVG(total_amount) AS avg_order
FROM orders
WHERE $__timeFilter(created_at)
New Users
SELECT COUNT(*) AS new_users
FROM users
WHERE $__timeFilter(created_at)
Revenue Over Time
SELECT
$__timeGroup(created_at, '1d') AS time,
SUM(total_amount) AS revenue
FROM orders
WHERE $__timeFilter(created_at)
GROUP BY 1
ORDER BY 1
Draw this in a time series panel. Add a second query with the same SQL and set Time shift to 7d in the query options. The shifted line shows last week, so readers compare this week against the previous one.
Sales by Category
SELECT category, SUM(total_amount) AS revenue
FROM orders
WHERE $__timeFilter(created_at)
GROUP BY category
ORDER BY revenue DESC
Choose the format Table and display the result in a bar chart. Bars let readers compare categories at a glance.
Top Products Table
SELECT product_name, SUM(quantity) AS sold
FROM order_items
GROUP BY product_name
ORDER BY sold DESC
LIMIT 10
A table panel with colour bars inside the cells makes the ranking easy to scan.
Add Targets With Thresholds
Numbers mean more beside a goal. Take a daily revenue target of 10,000. Set thresholds on the revenue stat panel: red below 7,000, yellow between 7,000 and 10,000, and green above 10,000. Managers read the colour first and the number second.
Add a Region Selector
Create a variable named region with the query below.
SELECT DISTINCT region FROM orders
Add AND region IN ($region) to every panel query, and enable multi-value with the All option. One dashboard serves every regional manager.
Choose Time and Refresh Settings
Business numbers change slowly. Set the default range to the last 7 days and the refresh to 5 minutes or longer. Frequent refreshes waste database capacity without adding insight.
Share the Dashboard
- Place the dashboard in a folder named Business and give the management team the View permission.
- Create a playlist or a link for wall displays.
- Send alerts to a business channel when revenue falls below target for several hours.
Design Rules for Business Readers
- Use plain labels such as "Revenue" and skip technical names.
- Limit the page to ten or twelve panels.
- Place the most important numbers at the top left.
- Keep colour meaning consistent: green good, red needs action.
- Show units and the time range clearly on every panel.
