🎨 Splunkクラシックダッシュボード 図形作成チートシート~ステータス連動で色が変わる!四角・丸・棒・三角を自由自在に配置~
📚 この記事で学べること
項目 内容 対象者 Splunk初心者・新人エンジニア 目標 HTML/CSS/SPLで図形を作成し、データに応じて色を変える 所要時間 約30分
🏗️ 全体構成イメージ
┌─────────────────────────────────────────────────────┐
│ Splunk クラシックダッシュボード │
│ ┌─────────────────────────────────────────────┐ │
│ │ HTML Panel(図形を描画するエリア) │ │
│ │ │ │
│ │ ■ 四角 ● 丸 ▬ 棒 ▼ 三角 │ │
│ │ (緑) (黄) (赤) (青) │ │
│ │ │ │
│ │ ← SPLで取得したステータスに応じて色が変化 │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ [データ取得] → [ステータス判定] → [色の反映] │
└─────────────────────────────────────────────────────┘
📂 Part 1: サンプルデータの準備
1-1. テスト用インデックスとデータ作成
まず、動作確認用のサンプルデータを作成します。
| makeresults count=4
| streamstats count as id
| eval device_name = case(
id==1, "サーバーA",
id==2, "サーバーB",
id==3, "ネットワーク機器C",
id==4, "データベースD"
)
| eval status = case(
id==1, "正常",
id==2, "警告",
id==3, "異常",
id==4, "停止"
)
| eval status_code = case(
status=="正常", 0,
status=="警告", 1,
status=="異常", 2,
status=="停止", 3
)
| table device_name, status, status_code
🔍 SPL解説(一行ずつ)
| makeresults count=4
<!-- ▲ 4行の空データを生成する。テスト用データ作成の起点 -->
| streamstats count as id
<!-- ▲ 各行に連番(1,2,3,4)を「id」という名前で付与 -->
| eval device_name = case(
id==1, "サーバーA",
id==2, "サーバーB",
id==3, "ネットワーク機器C",
id==4, "データベースD"
)
<!-- ▲ idの値に応じて「device_name」フィールドに機器名を設定 --> <!-- ▲ case関数: 条件, 値, 条件, 値... の形式で条件分岐 -->
| eval status = case(
status=="正常", 0,
status=="警告", 1,
status=="異常", 2,
status=="停止", 3
)
<!-- ▲ ステータス文字列に対応する数値コードを設定 --> <!-- ▲ 後でJavaScriptで色を判定する際に使用 -->
| table device_name, status, status_code
<!-- ▲ 最終的に表示するフィールドを指定 -->
📊 出力結果イメージ
device_name status status_code サーバーA 正常 0 サーバーB 警告 1 ネットワーク機器C 異常 2 データベースD 停止 3
📂 Part 2: ダッシュボードXML基本構造
2-1. ダッシュボードの骨格
<dashboard>
<!-- ダッシュボードのルート要素 -->
<label>図形サンプルダッシュボード</label>
<!-- ダッシュボード名(画面上部に表示) -->
<row>
<!-- 行(横並びのコンテナ) -->
<panel>
<!-- パネル(各コンテンツを格納する箱) -->
<html>
<!-- HTMLパネル(自由にHTML/CSS/JSを記述可能) -->
</html>
</panel>
</row>
</dashboard>
📂 Part 3: 図形の作成(HTML/CSS)
3-1. 🟦 四角形(Rectangle)
<html>
<style>
/* ===== 四角形のスタイル定義 ===== */
.shape-rectangle {
/* 幅を100ピクセルに設定 */
width: 100px;
/* 高さを60ピクセルに設定 */
height: 60px;
/* 背景色(初期値:グレー) */
background-color: #808080 ;
/* 角を少し丸める(0pxで完全な四角) */
border-radius: 5px;
/* 枠線:1ピクセルの黒い実線 */
border: 1px solid #333 ;
/* テキストを中央揃え */
display: flex;
justify-content: center; /* 横方向中央 */
align-items: center; /* 縦方向中央 */
/* 文字色を白に */
color: white;
/* 文字サイズ */
font-size: 12px;
/* 太字 */
font-weight: bold;
}
</style>
<div class="shape-rectangle">
四角形
</div>
</html>
🔍 CSS解説ポイント
プロパティ 役割 よく使う値 width / height サイズ px, %, em background-color 背景色 カラーコード, 色名 border-radius 角の丸み 0px=角張り, 50%=丸 display: flex 中央揃えの準備 -
3-2. 🔴 丸(Circle)
<html>
<style>
/* ===== 丸のスタイル定義 ===== */
.shape-circle {
/* 幅と高さを同じにする(正方形の土台) */
width: 80px;
height: 80px;
/* 背景色(初期値:グレー) */
background-color: #808080 ;
/* ★重要★ border-radiusを50%にすると丸になる */
border-radius: 50%;
/* 枠線 */
border: 2px solid #333 ;
/* テキスト中央揃え */
display: flex;
justify-content: center;
align-items: center;
/* 文字スタイル */
color: white;
font-size: 12px;
font-weight: bold;
}
</style>
<div class="shape-circle">
丸
</div>
</html>
💡 丸を作るコツ
┌──────────────────────────────────────┐
│ border-radius: 50% → 正円になる │
│ │
│ ★条件:width と height が同じ値 │
│ │
│ width: 80px ─┬─→ ● │
│ height: 80px ─┘ │
└──────────────────────────────────────┘
3-3. ▬ 棒(Bar / Rectangle)
<html>
<style>
/* ===== 棒のスタイル定義 ===== */
.shape-bar {
/* 横長の形状:幅 > 高さ */
width: 150px;
height: 30px;
/* 背景色 */
background-color: #808080 ;
/* 少しだけ角を丸める */
border-radius: 3px;
/* 枠線 */
border: 1px solid #333 ;
/* テキスト中央揃え */
display: flex;
justify-content: center;
align-items: center;
/* 文字スタイル */
color: white;
font-size: 11px;
font-weight: bold;
}
</style>
<div class="shape-bar">
棒(ステータスバー)
</div>
</html>
3-4. 🔻 三角形(Triangle)▽
<html>
<style>
/* ===== 三角形のスタイル定義 ===== */
.shape-triangle {
/* ★重要★ 三角形はサイズを0にしてborderで形を作る */
width: 0;
height: 0;
/* 左右の辺:透明 */
border-left: 40px solid transparent;
border-right: 40px solid transparent;
/* 上辺:色を付ける(下向き三角 ▼) */
border-top: 60px solid #808080 ;
/* 下向き三角の底辺は不要なのでなし */
/* border-bottom: なし */
}
/* ===== 上向き三角形 △ ===== */
.shape-triangle-up {
width: 0;
height: 0;
border-left: 40px solid transparent;
border-right: 40px solid transparent;
/* 下辺に色を付ける(上向き三角 △) */
border-bottom: 60px solid #808080 ;
}
</style>
<!-- 下向き三角 ▼ -->
<div class="shape-triangle"></div>
<!-- 上向き三角 △ -->
<div class="shape-triangle-up"></div>
</html>
💡 三角形の仕組み(図解)
【CSS三角形の原理】
通常のborder: 三角形の作り方:
┌─────────────┐
│ ╲ ╱ │ border-top: 色付き
│ ╲ ╱ │ ▼
│ ╲ ╱ │ ┌─────────┐
│ ╱ ╲ │ │╲ ╱│
│ ╱ ╲ │ │ ╲ ╱ │
│ ╱ ╲ │ │ ▼ │
└─────────────┘ └─────────┘
↑ ↑
transparent transparent
(左辺) (右辺)
📂 Part 4: ステータスに応じた色変更(JavaScript連携)
4-1. 完全版コード(SPL + HTML + CSS + JavaScript)
<dashboard>
<label>ステータス連動図形ダッシュボード</label>
<!-- ===== データ取得用サーチ ===== -->
<search id="status_search">
<query>
| makeresults count=4
| streamstats count as id
| eval device_name = case(
id==1, "サーバーA",
id==2, "サーバーB",
id==3, "ネットワーク機器C",
id==4, "データベースD"
)
| eval status = case(
id==1, "正常",
id==2, "警告",
id==3, "異常",
id==4, "停止"
)
| eval status_code = case(
status=="正常", 0,
status=="警告", 1,
status=="異常", 2,
status=="停止", 3
)
| table device_name, status, status_code
</query>
<earliest>-24h@h</earliest>
<latest>now</latest>
</search>
<row>
<panel>
<title>ステータス連動図形</title>
<html>
<style>
/* ===== コンテナ(図形を並べる箱) ===== */
.shapes-container {
/* 横並びにする */
display: flex;
/* 図形間の余白 */
gap: 20px;
/* 内側の余白 */
padding: 20px;
/* 折り返しを許可 */
flex-wrap: wrap;
}
/* ===== 各図形の共通スタイル ===== */
.shape-item {
/* 縦並びにする(図形 + ラベル) */
display: flex;
flex-direction: column;
/* 中央揃え */
align-items: center;
/* 図形間の余白 */
gap: 8px;
}
/* ===== 四角形 ===== */
.rectangle {
width: 100px;
height: 60px;
background-color: #808080 ;
border-radius: 5px;
border: 2px solid #333 ;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-weight: bold;
font-size: 14px;
/* アニメーション(色が滑らかに変化) */
transition: background-color 0.3s ease;
}
/* ===== 丸 ===== */
.circle {
width: 70px;
height: 70px;
background-color: #808080 ;
border-radius: 50%;
border: 2px solid #333 ;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-weight: bold;
font-size: 12px;
transition: background-color 0.3s ease;
}
/* ===== 棒 ===== */
.bar {
width: 120px;
height: 25px;
background-color: #808080 ;
border-radius: 3px;
border: 1px solid #333 ;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-weight: bold;
font-size: 11px;
transition: background-color 0.3s ease;
}
/* ===== 三角形(下向き)===== */
.triangle {
width: 0;
height: 0;
border-left: 35px solid transparent;
border-right: 35px solid transparent;
border-top: 50px solid #808080 ;
transition: border-top-color 0.3s ease;
}
/* ===== ラベル(機器名) ===== */
.device-label {
font-size: 12px;
color: #333 ;
font-weight: bold;
}
/* ===== ステータスラベル ===== */
.status-label {
font-size: 11px;
color: #666 ;
}
/* ===== 色の定義(ステータス別) ===== */
.status-normal { background-color: #28a745 ; } /* 緑:正常 */
.status-warning { background-color: #ffc107 ; } /* 黄:警告 */
.status-error { background-color: #dc3545 ; } /* 赤:異常 */
.status-stop { background-color: #6c757d ; } /* グレー:停止 */
/* 三角形用(border-topで色を指定) */
.triangle.status-normal { border-top-color: #28a745 ; }
.triangle.status-warning { border-top-color: #ffc107 ; }
.triangle.status-error { border-top-color: #dc3545 ; }
.triangle.status-stop { border-top-color: #6c757d ; }
</style>
<!-- 図形を配置するコンテナ -->
<div class="shapes-container" id="shapesContainer">
<!-- JavaScriptで動的に生成される -->
</div>
<script>
// ===== Splunkのデータを取得してUIに反映 =====
require([
'splunkjs/mvc',
'splunkjs/mvc/searchmanager',
'splunkjs/mvc/simplexml/ready!'
], function(mvc) {
// サーチマネージャーを取得
// "status_search" は <search id="status_search"> と対応
var searchManager = mvc.Components.get("status_search");
// サーチ結果を取得
var results = searchManager.data("results");
// データが変更されたら実行
results.on("data", function() {
// 結果が存在するかチェック
if (results.hasData()) {
// 結果をJSON形式で取得
var rows = results.data().rows;
var fields = results.data().fields;
// コンテナを取得
var container = document.getElementById('shapesContainer');
// コンテナを空にする(再描画のため)
container.innerHTML = '';
// 各行のデータをループ処理
rows.forEach(function(row, index) {
// フィールド名からインデックスを取得
var deviceIndex = fields.indexOf('device_name');
var statusIndex = fields.indexOf('status');
var codeIndex = fields.indexOf('status_code');
// 値を取得
var deviceName = row[deviceIndex];
var status = row[statusIndex];
var statusCode = parseInt(row[codeIndex]);
// ステータスコードに応じたCSSクラスを決定
var statusClass = '';
switch(statusCode) {
case 0: statusClass = 'status-normal'; break; // 正常
case 1: statusClass = 'status-warning'; break; // 警告
case 2: statusClass = 'status-error'; break; // 異常
case 3: statusClass = 'status-stop'; break; // 停止
default: statusClass = '';
}
// 図形の種類を決定(例:インデックスで振り分け)
var shapeTypes = ['rectangle', 'circle', 'bar', 'triangle'];
var shapeType = shapeTypes[index % shapeTypes.length];
// 図形のHTMLを生成
var shapeHtml = '';
if (shapeType === 'rectangle') {
shapeHtml = '<div class="rectangle ' + statusClass + '">' + status + '</div>';
} else if (shapeType === 'circle') {
shapeHtml = '<div class="circle ' + statusClass + '">' + status + '</div>';
} else if (shapeType === 'bar') {
shapeHtml = '<div class="bar ' + statusClass + '">' + status + '</div>';
} else if (shapeType === 'triangle') {
shapeHtml = '<div class="triangle ' + statusClass + '"></div>';
}
// 図形アイテム全体のHTMLを生成
var itemHtml =
'<div class="shape-item">' +
shapeHtml +
'<div class="device-label">' + deviceName + '</div>' +
'<div class="status-label">' + status + '</div>' +
'</div>';
// コンテナに追加
container.innerHTML += itemHtml;
});
}
});
});
</script>
</html>
</panel>
</row>
</dashboard>
📂 Part 5: JavaScript解説(一行ずつ)
5-1. Splunk連携の基本構造
require([
'splunkjs/mvc', // SplunkのMVCフレームワーク
'splunkjs/mvc/searchmanager', // サーチ管理
'splunkjs/mvc/simplexml/ready!' // 準備完了を待つ
], function(mvc) {
// この中にコードを書く
});
🔍 解説
コード 意味 require([...], function) 必要なモジュールを読み込んでから実行 splunkjs/mvc SplunkのUI操作に必要 simplexml/ready! ダッシュボードの準備完了を待つ
5-2. サーチ結果の取得
// サーチマネージャーを取得
var searchManager = mvc.Components.get("status_search");
// └─ "status_search" は XMLの <search id="status_search"> と対応
// サーチ結果を取得
var results = searchManager.data("results");
// └─ "results" は完了した結果を取得
// └─ 他に "preview"(途中結果)もある
5-3. データ変更時の処理
results.on("data", function() {
// データが更新されたら実行される
if (results.hasData()) {
// 結果がある場合のみ処理
var rows = results.data().rows; // 行データ(2次元配列)
var fields = results.data().fields; // フィールド名の配列
// 例: rows = [["サーバーA", "正常", "0"], ["サーバーB", "警告", "1"], ...]
// 例: fields = ["device_name", "status", "status_code"]
}
});
5-4. ステータスに応じた色クラスの決定
// ステータスコードに応じたCSSクラスを決定
var statusClass = '';
switch(statusCode) {
case 0: // status_code が 0 の場合
statusClass = 'status-normal'; // → 緑色(正常)
break;
case 1: // status_code が 1 の場合
statusClass = 'status-warning'; // → 黄色(警告)
break;
case 2: // status_code が 2 の場合
statusClass = 'status-error'; // → 赤色(異常)
break;
case 3: // status_code が 3 の場合
statusClass = 'status-stop'; // → グレー(停止)
break;
default: // それ以外
statusClass = ''; // → デフォルト色
}
📂 Part 6: 図形の自由配置(CSS Grid / Flexbox)
6-1. Flexboxで横並び
.shapes-container {
display: flex; /* 横並びにする */
flex-wrap: wrap; /* 折り返しを許可 */
gap: 20px; /* 図形間の余白 */
justify-content: flex-start; /* 左寄せ */
}
6-2. CSS Gridで自由配置
.shapes-container {
display: grid;
/* 3列のグリッド */
grid-template-columns: repeat(3, 1fr);
/* 行と列の余白 */
gap: 20px;
/* パディング */
padding: 20px;
}
6-3. 絶対位置指定(完全自由配置)
.shapes-container {
position: relative; /* 基準点を設定 */
width: 100%;
height: 400px;
}
.shape-item {
position: absolute; /* 絶対位置指定 */
}
/* 個別の位置指定 */
.shape-item:nth-child(1) { top: 20px; left: 50px; }
.shape-item:nth-child(2) { top: 100px; left: 200px; }
.shape-item:nth-child(3) { top: 50px; left: 350px; }
.shape-item:nth-child(4) { top: 150px; left: 100px; }
📂 Part 7: 実用カラーパレット
7-1. ステータス別推奨カラー
ステータス カラーコード 色名 用途 正常 #28a745 緑 問題なし 警告 #ffc107 黄 注意が必要 異常 #dc3545 赤 即時対応 停止 #6c757d グレー 稼働停止 情報 #17a2b8 水色 参考情報 不明 #343a40 濃灰 状態不明
7-2. CSSクラス定義
/* ===== ステータス別の色定義 ===== */
/* 通常の図形用(background-color) */
.status-normal { background-color: #28a745 !important; }
.status-warning { background-color: #ffc107 !important; color: #333 !important; }
.status-error { background-color: #dc3545 !important; }
.status-stop { background-color: #6c757d !important; }
.status-info { background-color: #17a2b8 !important; }
.status-unknown { background-color: #343a40 !important; }
/* 三角形用(border-top-color) */
.triangle.status-normal { border-top-color: #28a745 !important; }
.triangle.status-warning { border-top-color: #ffc107 !important; }
.triangle.status-error { border-top-color: #dc3545 !important; }
.triangle.status-stop { border-top-color: #6c757d !important; }
.triangle.status-info { border-top-color: #17a2b8 !important; }
.triangle.status-unknown { border-top-color: #343a40 !important; }
📂 Part 8: よくあるエラーと対処法
8-1. 図形が表示されない
原因 対処法 サーチIDの不一致 <search id="xxx"> と mvc.Components.get("xxx") を確認 JavaScriptエラー ブラウザのF12 → Console でエラー確認 CSSが効いていない クラス名のスペルミスを確認
8-2. 色が変わらない
原因 対処法 statusClassが空 console.log(statusCode) でデバッグ CSSの優先度 !important を追加 データ型の違い parseInt() で数値に変換
8-3. デバッグ用コード
// コンソールに出力(F12で確認)
console.log("=== デバッグ情報 ===");
console.log("rows:", rows);
console.log("fields:", fields);
console.log("deviceName:", deviceName);
console.log("status:", status);
console.log("statusCode:", statusCode, typeof statusCode);
console.log("statusClass:", statusClass);
📂 Part 9: 完成版テンプレート(コピペ用)
9-1. 最小構成(すぐ動く版)
<dashboard>
<label>図形ステータスダッシュボード</label>
<search id="mySearch">
<query>
| makeresults count=4
| streamstats count as id
| eval name=case(id==1,"A",id==2,"B",id==3,"C",id==4,"D")
| eval status=case(id==1,"正常",id==2,"警告",id==3,"異常",id==4,"停止")
| eval code=case(status=="正常",0,status=="警告",1,status=="異常",2,status=="停止",3)
| table name, status, code
</query>
</search>
<row>
<panel>
<html>
<style>
.container{display:flex;gap:20px;padding:20px;flex-wrap:wrap;}
.item{display:flex;flex-direction:column;align-items:center;gap:5px;}
.rect{width:80px;height:50px;border-radius:5px;display:flex;justify-content:center;align-items:center;color:#fff;font-weight:bold;}
.circle{width:60px;height:60px;border-radius:50%;display:flex;justify-content:center;align-items:center;color:#fff;font-weight:bold;}
.bar{width:100px;height:20px;border-radius:3px;display:flex;justify-content:center;align-items:center;color:#fff;font-size:11px;}
.tri{width:0;height:0;border-left:30px solid transparent;border-right:30px solid transparent;border-top:45px solid gray;}
.c0{background-color:#28a745;}.c1{background-color:#ffc107;color:#333;}.c2{background-color:#dc3545;}.c3{background-color:#6c757d;}
.tri.c0{border-top-color:#28a745;}.tri.c1{border-top-color:#ffc107;}.tri.c2{border-top-color:#dc3545;}.tri.c3{border-top-color:#6c757d;}
.label{font-size:11px;color:#333;}
</style>
<div class="container" id="box"></div>
<script>
require(['splunkjs/mvc','splunkjs/mvc/simplexml/ready!'],function(mvc){
var sm=mvc.Components.get("mySearch");
sm.data("results").on("data",function(){
if(this.hasData()){
var r=this.data().rows,f=this.data().fields,box=document.getElementById('box');
box.innerHTML='';
var shapes=['rect','circle','bar','tri'];
r.forEach(function(row,i){
var n=row[f.indexOf('name')],s=row[f.indexOf('status')],c=parseInt(row[f.indexOf('code')]);
var cls='c'+c,sh=shapes[i%4];
var html='<div class="item">';
if(sh==='tri'){html+='<div class="tri '+cls+'"></div>';}
else{html+='<div class="'+sh+' '+cls+'">'+s+'</div>';}
html+='<div class="label">'+n+'</div></div>';
box.innerHTML+=html;
});
}
});
});
</script>
</html>
</panel>
</row>
</dashboard>
🎉 まとめ
覚えておくべきポイント
カテゴリ ポイント 四角 border-radius: 5px で少し丸く 丸 border-radius: 50% + 幅=高さ 棒 幅 > 高さ の四角形 三角 border のトリックで作成 色変更 CSSクラスを動的に付与 配置 Flexbox / Grid / 絶対位置
次のステップ
リアルデータに接続: index=your_index でサーチを変更
リアルタイム更新: <refresh> タグを追加
クリックイベント: 図形クリックでドリルダウン
アニメーション: 点滅や拡大縮小を追加
📖 参考リンク
お疲れ様でした!🎊 このチートシートを参考に、ステータス連動の図形ダッシュボードを作成してみてください!