ダッシュボード · ダッシュボード

アイソメトリック倉庫の在庫ダッシュボード

保存した一覧を見る 0 →

このブラウザー内に保存します。別の端末との同期はなく、サイトデータを消すと保存も消えます。

印刷時は見本を静止画にし、プロンプトと解説を出力します。PDF保存はブラウザーの印刷画面から選べます。

Vibehaus · デザイン資料
https://vibe.itlibra.com/design/isometric-warehouse-dashboard/
完全無料・著作権フリー(CC0)· 料金¥0 · 商用利用・改変自由

プレビュー

画面に合わせる

指定幅で実際に組み替えて表示します。表示領域より広い場合は、この枠の中で横へスクロールできます。

vibe.itlibra.com/preview/isometric-warehouse-dashboard/

AIへの指示文

物流倉庫の在庫管理ダッシュボードを、アイソメトリック(45度の等角投影)のフロアマップ付きで作ってください。

要件:
- 配色: 濃紺の背景 #101725、パネル #172031、罫線 #26324a、文字 #e9eef7。ラックは上面 #7aa2f7 / 左面 #4d6fc4 / 右面 #35508f。状態色は 適正 #7aa2f7 / 逼迫 #ffc46b / 要対応 #ff7a7a。
- 最上部に4つのKPIカード(充填率・入庫数・出庫数・アラート件数)。前日比・前週比を上下の矢印付きで添える。
- 本体は2カラム。左がフロアマップ、右がゾーン別充填率のリスト。
- フロアマップは `transform: rotateX(56deg) rotateZ(-45deg)` を親に当て、`transform-style: preserve-3d` で立体にする。
- ラック1つは3面で構成する。上面は `translateZ(高さ)`、手前の壁は下辺を軸に `rotateX(-90deg)`、右の壁は右辺を軸に `rotateY(90deg)`。
- ラックの高さ(--h)で在庫量、上面の色で充填率を表す。hover で上面を明るくする。
- 床は方眼のグラデーションで敷く。
- 右カラムのリストは充填率の高い順に並べ、各行に細いバーを敷く。
- 最下部に「今日の推奨アクション」を1文だけ置く。
- 凡例を必ず付ける(色が何を意味するか、立体だけでは伝わらないため)。
- JSは不要。980px 以下は1カラム、620px 以下はマップを縮小する。

バリエーション

工場ライン版

ラックを製造ラインのセルに置き換え、高さを稼働率、色を異常検知の状態にする。
ライン間の搬送を細い線でつなぐ。

データセンター版

ラックをサーバーラックに読み替え、高さを消費電力、色を温度にする。
凡例を「温度(℃)」の連続スケールに変更する。

このプレビューのコード

HTMLとCSSの1ファイルです。外部依存・広告・解析コードはありません。架空の倉庫の8ラックと充填率を表示する見本です。立体図と一覧で固定の数値を確認でき、在庫取得・変更・移送・詳細画面は実装していません。

CC0 · 改変・商用利用自由 · revision fb6c9e9d3e90

コードを表示
<!doctype html>
<!-- Vibehaus · CC0 · 架空のデータを使う1ファイルの表示見本。外部依存・送信・永続保存なし。 -->
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="robots" content="noindex" />
    <title>アイソメトリック倉庫の在庫ダッシュボード — Vibehaus プレビュー</title>
    <style>
      :root {
        --bg: #101725;
        --panel: #17203180;
        --panel-solid: #172031;
        --line: #26324a;
        --fg: #e9eef7;
        --fg-dim: #94a3bd;
        --top: #7aa2f7;
        --left: #4d6fc4;
        --right: #35508f;
        --ok: #6ee7a8;
        --warn: #ffc46b;
        --alert: #ff7a7a;
      }
      * { box-sizing: border-box; }
      html, body { margin: 0; padding: 0; }
      body {
        font-family: "Inter", "Helvetica Neue", "Hiragino Kaku Gothic ProN",
          "Noto Sans JP", "Yu Gothic", "Meiryo", sans-serif;
        background: radial-gradient(120% 90% at 70% -10%, #1b2740 0%, var(--bg) 55%);
        color: var(--fg);
        line-height: 1.8;
        min-height: 100vh;
        -webkit-font-smoothing: antialiased;
      }

      .app {
        max-width: 1280px;
        margin: 0 auto;
        padding: clamp(1rem, 3vw, 2rem);
      }

      header.bar {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        flex-wrap: wrap;
        padding-bottom: 1rem;
        border-bottom: 1px solid var(--line);
      }
      .brand { display: flex; align-items: center; gap: 0.65rem; font-weight: 700; }
      .brand .cube {
        width: 20px; height: 20px;
        background: linear-gradient(135deg, var(--top), var(--right));
        transform: rotate(45deg) skewX(-8deg);
        border-radius: 3px;
      }
      .brand span { font-size: 1rem; line-height: 1.5; }
      .clock {
        font-family: "JetBrains Mono", ui-monospace, monospace;
        font-size: 0.76rem;
        letter-spacing: 0.1em;
        color: var(--fg-dim);
      }

      .kpis {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 12px;
        margin: 1.25rem 0;
      }
      @media (max-width: 860px) { .kpis { grid-template-columns: repeat(2, 1fr); } }
      .kpi {
        background: var(--panel);
        border: 1px solid var(--line);
        border-radius: 12px;
        padding: 0.85rem 1rem;
      }
      .kpi p {
        margin: 0;
        font-family: "JetBrains Mono", ui-monospace, monospace;
        font-size: 0.66rem;
        letter-spacing: 0.16em;
        text-transform: uppercase;
        color: var(--fg-dim);
      }
      .kpi b {
        display: block;
        font-size: clamp(1.3rem, 3vw, 1.75rem);
        line-height: 1.4;
        font-weight: 700;
      }
      .kpi .delta { font-size: 0.78rem; line-height: 1.7; }
      .up { color: var(--ok); }
      .down { color: var(--alert); }

      .main {
        display: grid;
        grid-template-columns: 1.55fr 1fr;
        gap: 12px;
      }
      @media (max-width: 980px) { .main { grid-template-columns: 1fr; } }

      .panel {
        background: var(--panel);
        border: 1px solid var(--line);
        border-radius: 14px;
        padding: 1rem 1.1rem 1.25rem;
      }
      .panel h2 {
        margin: 0 0 0.15rem;
        font-size: 0.98rem;
        line-height: 1.5;
        font-weight: 700;
      }
      .panel .cap {
        margin: 0 0 1rem;
        font-size: 0.8rem;
        line-height: 1.75;
        color: var(--fg-dim);
      }

      /* --- Isometric floor plan ------------------------------------------ */
      .stage {
        position: relative;
        height: 400px;
        display: grid;
        place-items: center;
        overflow: hidden;
      }
      .iso {
        position: relative;
        width: 460px;
        height: 300px;
        transform: rotateX(56deg) rotateZ(-45deg) scale(0.92);
        transform-style: preserve-3d;
      }
      @media (max-width: 620px) { .iso { transform: rotateX(56deg) rotateZ(-45deg) scale(0.62); } }

      .floor {
        position: absolute;
        inset: 0;
        background:
          linear-gradient(rgba(122,162,247,0.16) 1px, transparent 1px),
          linear-gradient(90deg, rgba(122,162,247,0.16) 1px, transparent 1px),
          #16203399;
        background-size: 46px 46px, 46px 46px;
        border: 1px solid var(--line);
      }

      /* Each rack is a stack of three faces to fake a solid box. */
      .rack {
        position: absolute;
        transform-style: preserve-3d;
        cursor: pointer;
      }
      /* top: the lid, lifted by the rack's height.
         side-a / side-b: two walls hinged on the bottom and right edges so
         the box reads as solid from this camera angle. */
      .rack .top-f {
        position: absolute;
        inset: 0;
        background: var(--top);
        transform: translateZ(var(--h));
      }
      .rack .side-a {
        position: absolute;
        left: 0;
        bottom: 0;
        width: 100%;
        height: var(--h);
        background: var(--left);
        transform-origin: bottom center;
        transform: rotateX(-90deg);
      }
      .rack .side-b {
        position: absolute;
        top: 0;
        right: 0;
        width: var(--h);
        height: 100%;
        background: var(--right);
        transform-origin: right center;
        transform: rotateY(90deg);
      }
      .rack:hover .top-f { background: #9dbcff; }
      .rack.warn  .top-f { background: var(--warn); }
      .rack.warn:hover .top-f { background: #ffd79b; }
      .rack.alert .top-f { background: var(--alert); }
      .rack.alert:hover .top-f { background: #ff9d9d; }
      .rack .tag {
        position: absolute;
        top: 50%; left: 50%;
        transform: translate(-50%, -50%) translateZ(calc(var(--h) + 1px)) rotate(45deg);
        font-family: "JetBrains Mono", ui-monospace, monospace;
        font-size: 10px;
        letter-spacing: 0.06em;
        color: #0d1424;
        font-weight: 700;
        pointer-events: none;
      }

      .legend {
        display: flex;
        gap: 1rem;
        flex-wrap: wrap;
        margin-top: 0.5rem;
        font-size: 0.78rem;
        line-height: 1.7;
        color: var(--fg-dim);
      }
      .legend i {
        display: inline-block;
        width: 11px; height: 11px;
        border-radius: 3px;
        margin-right: 0.4rem;
        vertical-align: -1px;
      }

      /* --- Right column -------------------------------------------------- */
      .rows { display: grid; gap: 0.55rem; }
      .row {
        display: grid;
        grid-template-columns: auto 1fr auto;
        align-items: center;
        gap: 0.7rem;
        padding: 0.6rem 0.7rem;
        border: 1px solid var(--line);
        border-radius: 10px;
        background: rgba(23, 32, 49, 0.55);
      }
      .row .zone {
        font-family: "JetBrains Mono", ui-monospace, monospace;
        font-size: 0.74rem;
        color: var(--fg-dim);
      }
      .row .name { font-size: 0.88rem; line-height: 1.6; }
      .row .pct { font-family: "JetBrains Mono", ui-monospace, monospace; font-size: 0.82rem; }
      .track {
        grid-column: 1 / -1;
        height: 5px;
        border-radius: 999px;
        background: #1e293f;
        overflow: hidden;
      }
      .track i { display: block; height: 100%; border-radius: 999px; }

      .tip {
        margin-top: 1rem;
        padding: 0.7rem 0.85rem;
        border: 1px dashed var(--line);
        border-radius: 10px;
        font-size: 0.8rem;
        line-height: 1.8;
        color: var(--fg-dim);
      }
      .tip b { color: var(--fg); }

/* 配布見本の操作・説明。配色と主構成は維持する。 */
[hidden]{display:none!important} :focus-visible{outline:3px solid currentColor;outline-offset:3px}
.demo-note{margin:2rem 0 0;padding:1rem;border-top:1px solid currentColor;font:14px/1.8 system-ui,"Hiragino Sans","Meiryo",sans-serif;letter-spacing:0;overflow-wrap:anywhere}
.demo-note h2{font:700 16px/1.5 system-ui,"Hiragino Sans","Meiryo",sans-serif;letter-spacing:0}
.demo-note p{letter-spacing:0;scroll-margin-top:7rem}.demo-note a{display:inline-flex;align-items:center;min-height:44px}
.demo-banner{font:13px/1.7 system-ui,"Hiragino Sans","Meiryo",sans-serif;letter-spacing:0;margin:0 0 1rem}
[data-dashboard-scroll]{max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-gutter:stable}
[data-motion-toggle]{font:inherit;color:inherit;background:transparent;border:1px solid currentColor;border-radius:4px;min-height:44px;padding:.5rem .8rem;margin:0 0 1rem;cursor:pointer;letter-spacing:0}
html:not(.demo-js) *,html[data-motion-paused] *{animation-play-state:paused!important}
html:not(.demo-js) *::before,html:not(.demo-js) *::after,html[data-motion-paused] *::before,html[data-motion-paused] *::after{animation:none!important}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}

.main{grid-template-columns:minmax(0,1.55fr) minmax(0,1fr)}.main>*,.panel,.stage,.kpi{min-width:0}.iso{flex-shrink:0}.stage{display:flex;align-items:center;justify-content:center}.rack{cursor:default}.row{grid-template-columns:auto minmax(0,1fr) auto}.clock{letter-spacing:0;overflow-wrap:anywhere}.kpi p{letter-spacing:0}.app{overflow-wrap:anywhere}.kpis{grid-template-columns:repeat(4,minmax(0,1fr))}
@media(max-width:980px){.main{grid-template-columns:minmax(0,1fr)}}@media(max-width:860px){.kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:400px){.iso{transform:rotateX(56deg) rotateZ(-45deg) scale(.46)}.stage{height:300px}.kpi{padding:.75rem}.panel{padding:1rem .75rem}}
/* 高いラックの面とラベルが枠外へ出ない高さを確保する。 */
.stage{height:480px}
@media(max-width:620px){.stage{height:400px}}
@media(max-width:400px){.stage{height:340px}}
</style>
  </head>
  <body>
    <div class="app">
      <header class="bar">
        <div class="brand">
          <span class="cube" aria-hidden="true"></span>
          <span>KURA — 倉庫在庫モニター</span>
        </div>
        <span class="clock">東京第2倉庫 · 2026.08.02 16:40 JST</span>
      </header>

      <p class="demo-banner">架空の倉庫・固定の在庫データを使った表示見本です。ラックは表示専用です。</p><section class="kpis">
        <div class="kpi">
          <p>Occupancy</p>
          <b>78.4%</b>
          <span class="delta up">▲ 3.1pt / 前週</span>
        </div>
        <div class="kpi">
          <p>Inbound today</p>
          <b>1,284</b>
          <span class="delta up">▲ 12% / 前日</span>
        </div>
        <div class="kpi">
          <p>Outbound today</p>
          <b>1,097</b>
          <span class="delta down">▼ 4% / 前日</span>
        </div>
        <div class="kpi">
          <p>Alerts</p>
          <b>2</b>
          <span class="delta down">要対応ゾーン</span>
        </div>
      </section>

      <div class="main">
        <section class="panel">
          <h2>フロアマップ</h2>
          <p class="cap">ラックの高さは在庫量のイメージ、色は充填率です。詳細操作はなく、数値は下の一覧でも確認できます。</p>

          <div class="stage">
            <div class="iso" role="img" aria-label="8ラックの立体図。B-01は97%、A-02は91%、C-01は88%で高充填。すべての充填率はゾーン一覧に記載">
              <div class="floor" aria-hidden="true"></div>

              <!-- Painter's order: with rotateZ(-45deg) the far corner is the
                   one with the smallest (left + top), so racks are listed
                   back-to-front. Reordering these breaks the occlusion. -->
              <div class="rack" style="--h:76px; width:100px; height:100px; left:0;    top:0;"   title="A-01 充填率 62%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">A-01</span>
              </div>
              <div class="rack warn" style="--h:112px; width:100px; height:100px; left:120px; top:0;" title="A-02 充填率 91%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">A-02</span>
              </div>
              <div class="rack alert" style="--h:132px; width:100px; height:100px; left:0; top:120px;" title="B-01 充填率 97%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">B-01</span>
              </div>
              <div class="rack" style="--h:54px; width:100px; height:100px; left:240px; top:0;" title="A-03 充填率 44%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">A-03</span>
              </div>
              <div class="rack" style="--h:88px; width:100px; height:100px; left:120px; top:120px;" title="B-02 充填率 70%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">B-02</span>
              </div>
              <div class="rack" style="--h:40px; width:100px; height:100px; left:240px; top:120px;" title="B-03 充填率 31%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">B-03</span>
              </div>
              <div class="rack warn" style="--h:104px; width:100px; height:60px; left:360px; top:0;" title="C-01 充填率 88%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">C-01</span>
              </div>
              <div class="rack" style="--h:64px; width:100px; height:60px; left:360px; top:80px;" title="C-02 充填率 55%">
                <span class="face side-a"></span><span class="face side-b"></span><span class="face top-f"></span>
                <span class="tag">C-02</span>
              </div>
            </div>
          </div>

          <div class="legend">
            <span><i style="background:var(--top)"></i>80%未満(余裕)</span>
            <span><i style="background:var(--warn)"></i>80%以上95%未満(逼迫)</span>
            <span><i style="background:var(--alert)"></i>95%以上(要対応)</span>
          </div>
        </section>

        <section class="panel">
          <h2>ゾーン別の充填率</h2>
          <p class="cap">全8ゾーンを高い順に表示。95%以上のゾーンは混雑・受入余力を確認する想定です。</p>

          <div class="rows">
            <div class="row">
              <span class="zone">B-01</span>
              <span class="name">冷蔵・日配</span>
              <span class="pct" style="color:var(--alert)">97%</span>
              <span class="track"><i style="width:97%; background:var(--alert)"></i></span>
            </div>
            <div class="row">
              <span class="zone">A-02</span>
              <span class="name">飲料ケース</span>
              <span class="pct" style="color:var(--warn)">91%</span>
              <span class="track"><i style="width:91%; background:var(--warn)"></i></span>
            </div>
            <div class="row">
              <span class="zone">C-01</span>
              <span class="name">季節商品</span>
              <span class="pct" style="color:var(--warn)">88%</span>
              <span class="track"><i style="width:88%; background:var(--warn)"></i></span>
            </div>
            <div class="row">
              <span class="zone">B-02</span>
              <span class="name">日用雑貨</span>
              <span class="pct">70%</span>
              <span class="track"><i style="width:70%; background:var(--top)"></i></span>
            </div>
            <div class="row">
              <span class="zone">A-01</span>
              <span class="name">保存食</span>
              <span class="pct">62%</span>
              <span class="track"><i style="width:62%; background:var(--top)"></i></span>
            </div>
            <div class="row"><span class="zone">C-02</span><span class="name">保管エリア</span><span class="pct">55%</span><span class="track"><i style="width:55%;background:var(--top)"></i></span></div><div class="row"><span class="zone">A-03</span><span class="name">保管エリア</span><span class="pct">44%</span><span class="track"><i style="width:44%;background:var(--top)"></i></span></div><div class="row">
              <span class="zone">B-03</span>
              <span class="name">返品・検品待ち</span>
              <span class="pct">31%</span>
              <span class="track"><i style="width:31%; background:var(--top)"></i></span>
            </div>
          </div>

          <p class="tip">
            <b>今日の推奨アクション</b><br />
            B-01 の高充填を確認する想定例です。実際の移送には温度帯・品目・受入容量の確認が必要で、この見本では計画や移送は行いません。
          </p>
        </section>
      </div>
<aside class="demo-note"><h2>この見本について</h2><p>架空のサービス・数値・人物を使った表示見本です。外部通信・永続保存は行いません。配布HTMLはCC0・利用料¥0です。</p><p id="demo-warehouse" tabindex="-1"><b>在庫と図の表示</b> — 8ラックの充填率と色を表示します。データ取得・詳細画面・在庫の変更・自動提案・移送処理は実装していません。</p></aside>    </div>
  </body>
</html>

2026年10月14日、Chromiumで320・390・768・1280pxの描画とキーボードのフォーカス表示を確認しました。他のブラウザは未確認です。利用先のブラウザと実データでも確認してください。

概要

等角投影は、遠近をつけずに3方向の軸を同じ縮尺で描く製図法です。19世紀の機械図面から1980年代のシミュレーションゲーム、そして近年のSaaSのイラストまで、繰り返し採用されてきました。理由は単純で、奥行きがあるのに寸法が読める——空間を説明する図としては最も効率がよいからです。

表では「どこ」が分からない

倉庫の在庫管理は、長らく行と列の表で扱われてきました。ゾーンごとの充填率は数値で正確に読めます。しかし現場の人間が本当に知りたいのはどこが詰まっていて、どこに逃がせるかであり、それは位置関係の問題です。B-01が97%だと表で読んでも、隣のC-02が空いていることは頭の中で地図に変換しないと分かりません。フロアマップに立体を与えると、この変換が不要になります。高さで量、色で状態を同時に符号化すれば、視線を走らせるだけで移送計画の候補が浮かびます。

立体と数値を併置する理由

一方で、立体表示には明確な弱点があります。人間は3次元の体積を正確には比較できません。97%と91%の差を高さだけで判定するのは不可能です。だからこの設計では、左に立体マップ、右に数値リストを並べます。立体は「どこ」を、数値は「どれだけ」を担当する——役割を分けることで、どちらの弱点も相手が補います。色だけで状態を示さないのも同じ配慮で、色覚特性の違いに関わらず、高さと数値の二重符号化で情報が届きます。

崩れる形立体だけで量を比べさせる

人間は3次元の体積を正確には比較できません。97%と91%の差を高さだけで判定するのは不可能です。見た目は説得的でも、判断の役には立ちません。

効く形立体と数値を併置する

立体が「どこ」を、数値が「どれだけ」を担当します。役割を分けるとどちらの弱点も相手が補います。高さと数値の二重符号化なら、色覚特性に関わらず届きます。

仕上げの判断軸

実装は CSS だけで完結します。親に rotateX(56deg) rotateZ(-45deg) と preserve-3d を当て、箱は上面と2枚の壁で作る——3Dライブラリを持ち込む必要はありません。100ラック程度なら要素数300でブラウザは平然と描きます。

凡例は必ず添えてください。色と高さが何を意味するかは作った本人にしか自明ではありません。空間が分析軸にならない業務では、この表現はただの装飾になります。

ダッシュボードの構成要素

ダッシュボードの構成要素 ナビ 1,284 96.2% ¥48万 12件 要点の数値 ── 最初に目に入る場所へ 推移 明細 数値は等幅数字で。桁が揃わないと比較にならない 全部を同じ大きさで並べると、どれが重要か分からなくなる
管理画面は何を最初に見せるかで価値が決まります。要点の数値を上に置き、詳細は下へ。並べる順序が優先順位そのものです。

使いどころ

  • 倉庫・物流の在庫管理画面
  • 工場の稼働モニタリング
  • データセンターの設備監視
  • 店舗の売場別実績ダッシュボード
  • 空間そのものが分析軸になる業務

このデザインの分類

カテゴリ
ダッシュボード
スタイル
アイソメトリック / ダーク / SaaS / クール / ボールド

背景と狙いどころ

よくある質問

立体表示は分析に不利では?
数値の精密な比較には不利です。だから左が立体マップ、右が数値リストという併置にしています。立体は位置の把握、数値は比較と役割を分けます。
画像や3Dライブラリは必要ですか?
不要です。CSSの transform と preserve-3d だけで組めます。Three.js を持ち込むと数百KBの追加になります。
ラックが増えると重くなりませんか?
1ラックにつき3要素なので、100ラックで300要素。この規模ならCSSのみで問題なく動きます。それ以上はCanvasを検討してください。
色だけで状態を示して大丈夫ですか?
色覚特性を考えると不十分です。高さという第2の変数と、ホバー時の数値表示、右カラムの数値リストで冗長に伝えてください。

この画面を実装する

動くサンプルとコピペできるコードを、技術別にまとめています。