パネル情報

ダッシュボードパネルの設定にアクセス

ダッシュボード内の可視化パネルを表示および作成できます。レイアウト、位置、設定項目を含みます。

ダッシュボードパネルを取得

GET /api/{tenantId}/{projectId}/dashboard/{dashboardId}/panels

ダッシュボードに設定されているすべての可視化パネルを取得します。パネルの種類、位置、サイズ、および設定項目を含みます。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
dashboardId GUID はい ダッシュボード識別子

レスポンス (200 OK)

{
  "dashboardId": "880e8400-e29b-41d4-a716-446655440000",
  "panels": [
    {
      "panelId": "990e8400-e29b-41d4-a716-446655440000",
      "name": "Process Flow Chart",
      "panelType": "DashboardPanelProcessMap",
      "position": "Row: 1, Col: 1",
      "width": 6,
      "height": 4,
      "configuration": "{\"dataSource\": \"MainProcess\", \"visualization\": \"flow\"}"
    },
    {
      "panelId": "aa0e8400-e29b-41d4-a716-446655440000",
      "name": "KPI Summary",
      "panelType": "DashboardPanelSingleValue",
      "position": "Row: 1, Col: 7",
      "width": 3,
      "height": 2,
      "configuration": "{\"metric\": \"avgCycleTime\", \"format\": \"duration\"}"
    }
  ]
}

レスポンスフィールド

フィールド 説明
dashboardId GUID これらのパネルを含むダッシュボード
panels 配列 パネルオブジェクトの一覧

パネルオブジェクトのフィールド

フィールド 説明
panelId GUID パネルの一意識別子
name 文字列 パネルの表示タイトル
panelType 文字列 可視化の種類(パネルタイプセクション参照)
position 文字列 グリッド上の位置("Row: X, Col: Y")
width 整数 パネルの幅(グリッド単位)
height 整数 パネルの高さ(グリッド単位)
configuration 文字列 パネル固有の設定を含むJSON文字列

エラーレスポンス

Not Found (404):

{
  "Error": "Dashboard not found",
  "DashboardId": "880e8400-e29b-41d4-a716-446655440000"
}

ダッシュボードパネルを作成

POST /api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel

ダッシュボードに新しい可視化パネルを作成します。パネルの種類と設定に基づき、APIが適切なセレクタブロックを自動で作成します。

パスパラメータ

パラメータ 必須 説明
tenantId GUID はい テナント識別子
projectId GUID はい プロジェクト識別子
dashboardId GUID はい ダッシュボード識別子

リクエストボディ

{
  "title": "string (required)",
  "description": "string (optional)",
  "panelType": "string (required)",
  "blockId": "GUID (required for data panels)",
  "row": "integer (required, 0-based)",
  "column": "integer (required, 0-based)",
  "width": "integer (required, 1-12)",
  "height": "integer (required, 1-20)",
  "settings": "string (optional, JSON for selector configuration)"
}

リクエストボディのフィールド

フィールド 必須 説明
title 文字列 はい パネルの表示タイトル
description 文字列 いいえ 任意の説明
panelType 文字列 はい パネルタイプのクラス名(パネルタイプセクション参照)
blockId GUID はい* 表示対象の計算ブロックID(DashboardPanelDashboardNoteの場合は不要)
row 整数 はい 行位置(0開始)
column 整数 はい 列位置(0開始)
width 整数 はい パネル幅(グリッド単位、1〜12)
height 整数 はい パネル高さ(グリッド単位、1〜20)
settings 文字列 いいえ セレクタ設定を含むJSON文字列

レスポンス (201 Created)

{
  "panelId": "5b54172c-b15c-4dd9-bab6-6cfceb7389df",
  "title": "My KPI Panel",
  "dashboardPanelClassName": "DashboardPanelSingleValue",
  "row": 0,
  "column": 0,
  "width": 2,
  "height": 1,
  "blockId": "db0dd1b9-63b5-4754-92b1-2764f4a3fb68"
}

注意: レスポンス中のblockIdはセレクタブロックIDであり、元の計算ブロックIDではありません。APIは計算ブロックをラップするセレクタブロックを自動で作成します。

エラーレスポンス

Bad Request (400) - ブロック未指定:

{
  "Error": "VALIDATION_ERROR",
  "Message": "BlockId is required for panel type 'DashboardPanelSingleValue'"
}

Bad Request (400) - 不正なパネルタイプ:

{
  "Error": "VALIDATION_ERROR",
  "Message": "Invalid panel type 'InvalidType'. Valid types: DashboardPanelSingleValue, DashboardPanelCalculator, ..."
}

Bad Request (400) - ブロックが見つからない:

{
  "Error": "VALIDATION_ERROR",
  "Message": "Block 'guid' does not exist"
}

パネルタイプ

mindzieStudioのダッシュボードは以下のパネルタイプをサポートしています:

パネルタイプクラス 作成されるセレクタ 説明
DashboardPanelCalculator SelectorFullCalculator フル計算結果の出力(プロセスマップ、トレンド、チャート)
DashboardPanelSingleValue SelectorSingleValueFromLabel 単一値 / KPIカード
DashboardPanelHorizontalBarChart SelectorMultiColumns 横棒グラフ、ランキングリスト
DashboardPanelDataTable SelectorFullCalculator データテーブル表示
DashboardPanelProcessMap SelectorFullCalculator プロセスマップの可視化
DashboardPanelDashboardNote (なし) テキスト・ノートパネル(blockId不要)
DashboardPanelRecommendationSentence (なし) AI推奨表示

パネル設定(タイプ別)

DashboardPanelSingleValue (KPIカード)

panelTypeDashboardPanelSingleValueの場合は、計算出力から単一値を抽出する設定を行います:

{
  "tableIndex": 0,
  "labelColumnName": "Name",
  "labelName": "Total Case Count",
  "valueColumnName": "Value",
  "formatText": "N0"
}
設定名 説明
tableIndex 整数 使用する出力テーブル(通常は0)
labelColumnName 文字列 ラベルを含む列名(通常は"Name")
labelName 文字列 探すラベル名称(例:"Total Case Count")
valueColumnName 文字列 値を含む列名(通常は"Value")
formatText 文字列 .NETの書式指定文字列(N0、F2、P0など)

推奨用途: CalculatorDataInformation、CalculatorOverview

DashboardPanelHorizontalBarChart (横棒グラフ)

panelTypeDashboardPanelHorizontalBarChartの場合、columnNamesを設定に含めるとSelectorMultiColumnsがトリガーされます:

{
  "tableIndex": 0,
  "columnNames": ["ActivityName", "Count"],
  "sortColumnName": "Count",
  "sortAscending": false,
  "maxRows": 10
}
設定名 説明
tableIndex 整数 使用する出力テーブル
columnNames 配列 チャートに含める列(計算出力と完全に一致する必要があります)
sortColumnName 文字列 ソート対象の列
sortAscending ブール ソート方向
maxRows 整数 表示する最大行数

重要: 列名は計算結果の列名と正確に一致させる必要があります。例えばCalculatorActivityFrequencyはデータセットの活動列名("ActivityName"など)を使い、一般的な"Activity"ではありません。

推奨用途: CalculatorActivityFrequency、CalculatorResourceFrequency

DashboardPanelCalculator (フル可視化)

計算結果の全体表示に特別な設定は不要です:

{}

またはsettingsパラメータ自体を省略してください。

パネル構成

ダッシュボードのパネルは計算ブロックに直接接続しません。代わりに3層構造を採用しています:

Panel.InputBlockId -> Selector Block -> Calculator Block (parent_id経由)

なぜセレクタが必要か? セレクタブロックは計算結果を「どのように」表示するかを定義します:

  • SelectorFullCalculator: 可視化設定を適用して全出力を表示
  • SelectorSingleValueFromLabel: ラベル検索によって単一値を抽出
  • SelectorMultiColumns: 特定列を抽出してソート・絞り込み

パネル作成時、APIが対象の計算ブロックに合ったセレクタを自動作成します。

パネルレイアウトシステム

ダッシュボードパネルはグリッドベースのレイアウトシステムを使います:

  • グリッド単位: 12列のグリッドシステム
  • 位置: 行と列の座標(0開始)
  • サイズ: 幅(1-12列)、高さ(1-20行)
  • レスポンシブ: 画面サイズに応じて自動調整

実装例

ダッシュボードパネルを取得

cURL

curl -X GET "https://your-mindzie-instance.com/api/12345678-1234-1234-1234-123456789012/87654321-4321-4321-4321-210987654321/dashboard/880e8400-e29b-41d4-a716-446655440000/panels" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

KPIパネル (シングルバリュー) を作成

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Total Cases",
    "panelType": "DashboardPanelSingleValue",
    "blockId": "calculator-data-information-guid",
    "row": 0,
    "column": 0,
    "width": 2,
    "height": 1,
    "settings": "{\"tableIndex\":0,\"labelColumnName\":\"Name\",\"labelName\":\"Total Case Count\",\"valueColumnName\":\"Value\",\"formatText\":\"N0\"}"
  }'

横棒グラフを作成

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Activity Distribution",
    "panelType": "DashboardPanelHorizontalBarChart",
    "blockId": "calculator-activity-frequency-guid",
    "row": 1,
    "column": 0,
    "width": 6,
    "height": 3,
    "settings": "{\"tableIndex\":0,\"columnNames\":[\"ActivityName\",\"Count\"],\"sortColumnName\":\"Count\",\"sortAscending\":false,\"maxRows\":10}"
  }'

フル計算パネルを作成

curl -X POST "https://your-mindzie-instance.com/api/{tenantId}/{projectId}/dashboard/{dashboardId}/panel" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Case Count",
    "panelType": "DashboardPanelCalculator",
    "blockId": "calculator-case-count-guid",
    "row": 0,
    "column": 2,
    "width": 2,
    "height": 1
  }'

JavaScript/Node.js

const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const PROJECT_ID = '87654321-4321-4321-4321-210987654321';
const BASE_URL = 'https://your-mindzie-instance.com';

async function getDashboardPanels(dashboardId, token) {
  const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dashboard/${dashboardId}/panels`;

  const response = await fetch(url, {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    }
  });

  if (response.ok) {
    return await response.json();
  } else if (response.status === 404) {
    throw new Error('Dashboard not found');
  } else {
    throw new Error(`Failed to get panels: ${response.status}`);
  }
}

async function createDashboardPanel(dashboardId, panelData, token) {
  const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/dashboard/${dashboardId}/panel`;

  const response = await fetch(url, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(panelData)
  });

  if (response.ok) {
    return await response.json();
  } else {
    const error = await response.json();
    throw new Error(error.Message || `Failed to create panel: ${response.status}`);
  }
}

// 使用例 - パネル取得
const panels = await getDashboardPanels('dashboard-guid', 'your-auth-token');
console.log(`Dashboard: ${panels.dashboardId}`);
console.log(`Panels: ${panels.panels.length}`);

// 使用例 - KPIパネル作成
const newPanel = await createDashboardPanel('dashboard-guid', {
  title: 'Total Cases',
  panelType: 'DashboardPanelSingleValue',
  blockId: 'calculator-data-information-guid',
  row: 0,
  column: 0,
  width: 2,
  height: 1,
  settings: JSON.stringify({
    tableIndex: 0,
    labelColumnName: 'Name',
    labelName: 'Total Case Count',
    valueColumnName: 'Value',
    formatText: 'N0'
  })
}, 'your-auth-token');

console.log(`Created panel: ${newPanel.panelId}`);

Python

import requests
import json

TENANT_ID = '12345678-1234-1234-1234-123456789012'
PROJECT_ID = '87654321-4321-4321-4321-210987654321'
BASE_URL = 'https://your-mindzie-instance.com'

def get_dashboard_panels(dashboard_id, token):
    """ダッシュボード内の全パネルを取得。"""
    url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dashboard/{dashboard_id}/panels'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    response = requests.get(url, headers=headers)

    if response.ok:
        return response.json()
    elif response.status_code == 404:
        raise Exception('Dashboard not found')
    else:
        raise Exception(f'Failed to get panels: {response.status_code}')


def create_dashboard_panel(dashboard_id, panel_data, token):
    """ダッシュボードに新規パネルを作成。"""
    url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/dashboard/{dashboard_id}/panel'
    headers = {
        'Authorization': f'Bearer {token}',
        'Content-Type': 'application/json'
    }

    response = requests.post(url, headers=headers, json=panel_data)

    if response.ok:
        return response.json()
    else:
        error = response.json()
        raise Exception(error.get('Message', f'Failed to create panel: {response.status_code}'))


# 使用例 - パネル取得
panels = get_dashboard_panels('dashboard-guid', 'your-auth-token')
print(f"Dashboard: {panels['dashboardId']}")
print(f"Panel count: {len(panels['panels'])}")

# 使用例 - KPIパネル作成
settings = {
    'tableIndex': 0,
    'labelColumnName': 'Name',
    'labelName': 'Total Case Count',
    'valueColumnName': 'Value',
    'formatText': 'N0'
}

new_panel = create_dashboard_panel('dashboard-guid', {
    'title': 'Total Cases',
    'panelType': 'DashboardPanelSingleValue',
    'blockId': 'calculator-data-information-guid',
    'row': 0,
    'column': 0,
    'width': 2,
    'height': 1,
    'settings': json.dumps(settings)
}, 'your-auth-token')

print(f"Created panel: {new_panel['panelId']}")

C#

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

public class DashboardPanelsResponse
{
    public Guid DashboardId { get; set; }
    public List<PanelInfo> Panels { get; set; }
}

public class PanelInfo
{
    public Guid PanelId { get; set; }
    public string Name { get; set; }
    public string PanelType { get; set; }
    public string Position { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public string Configuration { get; set; }
}

public class CreatePanelRequest
{
    public string Title { get; set; }
    public string Description { get; set; }
    public string PanelType { get; set; }
    public Guid BlockId { get; set; }
    public int Row { get; set; }
    public int Column { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public string Settings { get; set; }
}

public class CreatePanelResponse
{
    public Guid PanelId { get; set; }
    public string Title { get; set; }
    public string DashboardPanelClassName { get; set; }
    public int Row { get; set; }
    public int Column { get; set; }
    public int Width { get; set; }
    public int Height { get; set; }
    public Guid BlockId { get; set; }
}

public class DashboardPanelClient
{
    private readonly HttpClient _httpClient;
    private readonly string _baseUrl;
    private readonly Guid _tenantId;
    private readonly Guid _projectId;
    private readonly JsonSerializerOptions _jsonOptions;

    public DashboardPanelClient(string baseUrl, Guid tenantId, Guid projectId, string accessToken)
    {
        _baseUrl = baseUrl;
        _tenantId = tenantId;
        _projectId = projectId;
        _httpClient = new HttpClient();
        _httpClient.DefaultRequestHeaders.Authorization =
            new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
        _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
    }

    public async Task<DashboardPanelsResponse> GetDashboardPanelsAsync(Guid dashboardId)
    {
        var url = $"{_baseUrl}/api/{_tenantId}/{_projectId}/dashboard/{dashboardId}/panels";
        var response = await _httpClient.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            var json = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<DashboardPanelsResponse>(json, _jsonOptions);
        }
        else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            throw new Exception($"Dashboard {dashboardId} not found");
        }

        throw new Exception($"Failed to get panels: {response.StatusCode}");
    }

    public async Task<CreatePanelResponse> CreatePanelAsync(Guid dashboardId, CreatePanelRequest request)
    {
        var url = $"{_baseUrl}/api/{_tenantId}/{_projectId}/dashboard/{dashboardId}/panel";
        var json = JsonSerializer.Serialize(request, _jsonOptions);
        var content = new StringContent(json, Encoding.UTF8, "application/json");

        var response = await _httpClient.PostAsync(url, content);

        if (response.IsSuccessStatusCode)
        {
            var responseJson = await response.Content.ReadAsStringAsync();
            return JsonSerializer.Deserialize<CreatePanelResponse>(responseJson, _jsonOptions);
        }

        var errorJson = await response.Content.ReadAsStringAsync();
        throw new Exception($"Failed to create panel: {errorJson}");
    }
}

// 使用例
var client = new DashboardPanelClient(
    "https://your-mindzie-instance.com",
    Guid.Parse("12345678-1234-1234-1234-123456789012"),
    Guid.Parse("87654321-4321-4321-4321-210987654321"),
    "your-access-token");

// パネル取得
var panels = await client.GetDashboardPanelsAsync(Guid.Parse("dashboard-guid"));
Console.WriteLine($"Dashboard: {panels.DashboardId}");
foreach (var panel in panels.Panels)
{
    Console.WriteLine($"- {panel.Name} ({panel.PanelType})");
}

// KPIパネル作成
var newPanel = await client.CreatePanelAsync(Guid.Parse("dashboard-guid"), new CreatePanelRequest
{
    Title = "Total Cases",
    PanelType = "DashboardPanelSingleValue",
    BlockId = Guid.Parse("calculator-data-information-guid"),
    Row = 0,
    Column = 0,
    Width = 2,
    Height = 1,
    Settings = JsonSerializer.Serialize(new
    {
        tableIndex = 0,
        labelColumnName = "Name",
        labelName = "Total Case Count",
        valueColumnName = "Value",
        formatText = "N0"
    })
});

Console.WriteLine($"Created panel: {newPanel.PanelId}");

重要な注意点

APIの機能

  • 読み取り: GETエンドポイントでパネル設定を取得可能
  • 作成: POSTエンドポイントで新規パネル作成可能(自動でセレクタブロック作成)
  • 変更: パネルの変更は現時点でmindzieStudio UIで操作
  • 削除: パネルの削除は現時点でmindzieStudio UIで操作

設定の解析

configurationフィールドはJSON文字列であり、解析して設定項目を参照する必要があります。

レイアウトシステム

パネルの配置は行・列のグリッドシステムを用い、サイズ指定が可能です。行・列の数値はパネル作成時に0ベースで指定します。