管理画面にダッシュボードを付ける依頼はよくありますが、
作ったのに誰も見ていないケースが非常に多いです。
実際に運用に乗ったものと、そうでないものの差を整理します。
使われないダッシュボードの共通点
- グラフが10個以上ある
- 「見た後に何をすればいいか」が分からない
- 読み込みに5秒以上かかる
特に3つ目が致命的で、遅いダッシュボードは開かれなくなります。
使われたダッシュボードの構成
実際に毎日開かれるようになったのは、この3層構成でした。
1段目:今日どうなっているか(数字3つ)
本日の受注 12件(前日比 +3)
未対応 4件
今月の売上 ¥1,240,000(目標比 62%)
グラフではなく大きな数字です。一目で分かることが最優先。
2段目:異常があるか(要対応リスト)
・入金期限を過ぎた請求 2件 → クリックで一覧へ
・7日間動きのない案件 5件 → クリックで一覧へ
ここが本体です。「見たら次の行動が決まる」のが、使われる条件でした。
3段目:傾向(グラフ1〜2枚)
売上推移など、月次で確認するものだけを置きます。
実装:集計は毎回やらない
素直に書くと、ダッシュボードを開くたびに重い集計が走ります。
# これを毎回やると遅い
total = Order.objects.filter(created_at__year=y).aggregate(Sum("amount"))
日次のスナップショットを持たせます。
class DailyStat(models.Model):
date = models.DateField(unique=True)
order_count = models.IntegerField()
revenue = models.BigIntegerField()
当日分だけ実集計し、過去分はスナップショットを読むようにすると、
表示が一定時間内に収まります。
グラフ描画の注意
グラフライブラリを CDN から読むと、CSP を厳しくしたときに動かなくなります。
セルフホストしておくのが安全です。
データはテンプレートに直接埋め込まず、json_script を使います。
{{ chart_data|json_script:"chart-data" }}
const data = JSON.parse(document.getElementById("chart-data").textContent);
new Chart(ctx, { type: "line", data });
数字の定義を画面に書く
「売上」が税込なのか税抜なのか、キャンセルを含むのか。
定義が曖昧な数字は、そのうち誰も信じなくなります。
<span class="stat-note">※税抜・キャンセル分を除く・入金ベース</span>
この一行があるかないかで、ダッシュボードの寿命が変わります。
まとめ
- 数字3つ + 要対応リスト + グラフ1〜2枚に絞る
- 「見たら次の行動が決まる」ものだけを載せる
- 集計はスナップショット化して、表示速度を確保する
- 数字の定義を画面に明記する