メインコンテンツへスキップ

🎨 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 / 絶対位置

    次のステップ

    1. リアルデータに接続: index=your_index でサーチを変更

    2. リアルタイム更新: <refresh> タグを追加

    3. クリックイベント: 図形クリックでドリルダウン

    4. アニメーション: 点滅や拡大縮小を追加


    📖 参考リンク


    お疲れ様でした!🎊 このチートシートを参考に、ステータス連動の図形ダッシュボードを作成してみてください!


    あなたへのおすすめ