npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cardenelabs/cdl

v0.141.0

Published

CDL (Chainome Diagram Language). Mermaid-like declarative DSL that compiles to animated SVG diagrams. Built for blockchain / Solidity flows, generic enough for sequence / flow / state / ER / topology diagrams.

Readme

@cardenelabs/cdl

Declarative TypeScript DSL for animated React + SVG diagrams. UML / ER / state machine / topology / sequence / flow を 1 行で書く OSS library。

npm license

Documentation

| 目的 | リンク | |---|---| | repo root | github.com/cardene777/cdl | | 5 分で動かす | README quickstart (本 file 下部) | | playground demo | pnpm dev → http://localhost:4321 (apps/playground) | | 全 API + preset 一覧 | playground /docs/reference | | Text DSL spec | apps/playground/src/content/cdl-docs/text-dsl-spec.md | | LLM prompt guide | apps/playground/src/content/cdl-docs/text-dsl-llm-guide.md | | contribute | CONTRIBUTING.md |

なぜ cdl

mermaid / PlantUML はテキストから静止画像を生成する。 cdl は TypeScript → animated React + SVG component で、 phase / state / tween / progress glow 等の動きを宣言的に書ける。

| 形式 | mermaid | cdl | |---|---|---| | sequence | 静止 | animated + phase 切替 | | ER 図 | 静止 | animated + cardinality + sub label | | state diagram | 静止 | animated + initial/final marker + guard | | flow | 静止 | animated + dotted-flow 進行点 glow | | 構成図 / deployment | 限定的 | animated + container group + connection | | 自由レイアウト | 限定的 | lane + node + edge で自由構成 |

Quickstart

pnpm add @cardenelabs/cdl react react-dom

diagram declare

import { sequence } from "@cardenelabs/cdl";

export const authSeq = sequence({
  id: "auth",
  topic: "User Login",
  actors: ["User", "API", "DB"],
})
  .step({ from: "User", to: "API", label: "POST /login", sub: "email + password" })
  .step({ from: "API", to: "DB", label: "SELECT credentials" })
  .step({ from: "DB", to: "API", label: "rows", tone: "success", style: "dotted-flow" })
  .step({ from: "API", to: "User", label: "200 OK", sub: "JWT token", tone: "success" })
  .build();

React で render

import { CdlDiagramView } from "@cardenelabs/cdl";
import { authSeq } from "./auth-seq";

export function AuthSequenceDemo() {
  return <CdlDiagramView diagram={authSeq} />;
}

これで UML sequence diagram が phase 切替 + state diff + 進行点 glow で animated に表示。

等幅書体で描く図の字幅

textMetrics は proportional (既定) または monospace を取る。 消費側が図全体を等幅書体で描く場合は monospace を指定すると、配置計算と描画の字幅を揃えられる。

monospace は fontFamily: "mono" と同じ JetBrains Mono の実測で、ASCII・半角カナ・記号を 0.63 em、 和字と全角 (CJK) を 1.08 em、絵文字を 1.16 em として書記素ごとに加算する。 図表の字、マインドマップの名前、絵の中の字も同じ測り方になる。

preset では options に指定する。

const terminalFlow = sequence({
  id: "terminal-flow",
  topic: "Terminal flow",
  actors: ["CLI", "Worker"],
  textMetrics: "monospace",
});

CdlDiagram を直接組み立てる場合は field に指定する。

import type { CdlDiagram } from "@cardenelabs/cdl";

const terminalDiagram: CdlDiagram = {
  id: "terminal",
  topic: "Terminal",
  textMetrics: "monospace",
  lanes: [],
  nodes: [],
  edges: [],
  states: [],
  phases: [],
};

線の札の位置と寸法

labelCollision は線の札を自動で逃がす既定の auto と、作者が置いた位置を保つ author を取る。 author は引き直した線から求める基準位置へ labelOffsetX / labelOffsetY を一度だけ足し、 札だけを動かす衝突回避・平行線の散開・線上の移動を行わない。重なりやはみ出しは隠さず visualValidate が知らせる。

labelSize.width / labelSize.height / labelSize.fontSize は有限の正の数で、札の幅・高さ・主文の字を 部分指定する。明示した寸法は縮めず、配置・衝突判定・SVG 描画が同じ解決値を使う。省略した欄は 従来の自動計算を使う。一般の1行札は幅を字から求め、高さ36・字22が既定で、既存の metro と段の箱の 札は高さ40・字21を保つ。このため labelCollision と labelSize を書かない図の出力は変わらない。

見本値は、時間軸の「いいえ」が幅96・高さ40・字21・線との下間20、「翌日もう一度」が 幅162・高さ40・字21・「持ち戻る」の右端から中心まで70、段の箱の「いいえ」が線との上間24。

6 つの preset

低位 API (lane / node / edge 個別宣言) + 高位 preset (1 行で典型図生成)。

swimlane

横並び 3 lane 自動配置 + slug 自動。

swimlane({ id, topic, lanes: ["送信元", "Contract", "出力"] })
  .node("alice", { lane: "送信元", stack: 0, kind: "actor", title: "Alice" })
  .node("fn", { lane: "Contract", stack: 0, kind: "function", title: "transfer(...)" })
  .edge("alice", "fn", { id: "call", label: "call", tone: "accent", style: "dotted-flow" })
  .build()

flow

1 lane 縦 stack、 前 step → 次 step 自動 edge。

flow({ id, topic, laneLabel: "Auth Flow", defaultTone: "teal" })
  .step({ id: "user", kind: "person", title: "User" })
  .step({ id: "api", kind: "api", title: "POST /login" }, "ログイン要求")
  .step({ id: "db", kind: "database", title: "users 表" }, "credential 検証")
  .build()

sequence

UML sequence diagram (actor lifeline + 時系列 message)。

sequence({ id, topic, actors: ["User", "API", "DB"] })
  .step({ from: "User", to: "API", label: "POST /login" })
  .step({ from: "API", to: "DB", label: "SELECT" })
  .step({ from: "API", to: "User", label: "200 OK", tone: "success" })
  .build()

sequenceActorForm: "box" は参加者を幅 236・高さ 89・角 12 の sequence-actor-box で囲み、 sequenceLabelForm: "kind" は一辺 9 の sequence-label-mark と sequence-label-kind を段へ足す。 sequenceReturnHead: "solid" は返す矢じりも 17×19 の三角にし、sequenceKindLabels で種類名だけを言い換えられる。 枠・印・種類名は --cdl-sequence-actor-box / --cdl-sequence-actor-box-fill / --cdl-sequence-label-mark / --cdl-sequence-label-kind で装飾でき、3 つの表示欄を書かなければ出力は変わらない。

sequenceRowGap は言づての段の間を数で指定し、既定値は 64。sequenceSelfLoop は { form: "orthogonal", width, drop } で、自分へ戻る線を H / V だけの角形にして、糸から右端までの 張り出しと縦の落ちを指定する。width の既定値は 52、drop は 32 で、欄を書かなければ従来の 幅 52・上下 16 の丸い鉤を保つ。

sequenceGutter は左の札の列の幅を正の有限数で指定する。未指定では札の字幅から求める。 sequenceBandWidth は動いている間の帯の幅を正の有限数で指定し、帯の x、言づての線の端、 矢じりの先、源の点を帯の縁へ揃える。未指定では帯幅 52 と従来の線・矢じりの座標を保つ。

表の箱 (kind: "storage") の rowDividerForm: "full" は、node-row-divider を箱の左端 0 から 右端 w まで引く。未指定では、足や入れ子を持たない箱の線を従来どおり左右 26 内側に引く。

topology

構成図 / deployment diagram (group + container + connection)。

topology({ id, topic })
  .group("aws", { label: "AWS" })
    .add({ id: "alb", kind: "service", title: "ALB" })
    .add({ id: "ecs", kind: "service", title: "ECS Task" })
    .add({ id: "rds", kind: "database", title: "RDS" })
  .group("client", { label: "Client" })
    .add({ id: "browser", kind: "frontend", title: "Browser" })
  .connect("browser", "alb", { label: "HTTPS" })
  .connect("ecs", "rds", { label: "TCP 5432", tone: "success" })
  .build()

er

ER 図 (entity + cardinality)。

er({ id, topic })
  .entity({ id: "user", title: "User", rows: ["id: PK", "email: string", "createdAt: timestamp"] })
  .entity({ id: "order", title: "Order", rows: ["id: PK", "userId: FK", "total: number"] })
  .relation({ from: "user", to: "order", cardinality: "1:N", label: "places" })
  .build()

cardinality 6 種 ... "1:1" | "1:N" | "N:1" | "N:M" | "0..1" | "1..*"。

stateMachine

FSM / workflow (state + transition trigger + guard)。

stateMachine({ id, topic })
  .state({ id: "idle", title: "Idle", initial: true })
  .state({ id: "loading", title: "Loading" })
  .state({ id: "done", title: "Done", final: true })
  .state({ id: "error", title: "Error" })
  .transition({ from: "idle", to: "loading", trigger: "submit" })
  .transition({ from: "loading", to: "done", trigger: "success", tone: "success" })
  .transition({ from: "loading", to: "error", trigger: "fail", tone: "error" })
  .transition({ from: "error", to: "idle", trigger: "retry", guard: "if attempts < 3" })
  .build()

低位 API

preset で表現しきれない自由レイアウトは低位 API で。

import { diagram } from "@cardenelabs/cdl";

export const custom = diagram("custom", { topic: "Custom" })
  .lane("left", { x: 0, width: 400 })
  .lane("right", { x: 500, width: 400 })
  .node("a", { lane: "left", stack: 0, kind: "actor", title: "Alice" })
  .node("b", { lane: "right", stack: 0, kind: "function", title: "Bob" })
  .edge("a", "b", { id: "e", label: "msg", tone: "accent", style: "solid" })
  .state("counter", { initial: 0 })
  .phase("p1", { duration: 1500, title: "Phase 1", body: "tween counter" },
    (p) => p.activate("a", "b", "e").tween("counter", 0, 100).badge("running"))
  .build();

表示域の中身を横へ動かす

contentOffsetX (viewport.contentOffsetX) は有限の数で、自動計算した viewBox.x を起点に中身を横へ動かす。 正の値は viewBox.x から引いて中身を右へ動かし、負の値は左へ動かす。書かない時の既定値は 0。 node・lane・edge の world 座標や viewBox.y・幅・高さは変えない。

viewport: { width: 1800, contentOffsetX: 250 }

この例では自動の viewBox.x が 100 なら解決後は -150 になり、world 座標 x=650 の縦の時間軸は 表示域内の x=800 に見える。

NodeKind 29 種

| 系統 | kinds | |---|---| | 基本 5 | actor / function / storage / event / card | | 人系 5 | person / user-group / admin / developer / external-user | | インフラ 6 | database / cache / queue / message-bus / cloud / cdn | | アプリ系 6 | service / api / frontend / backend / webhook / microservice | | blockchain 8 | wallet / validator / miner / blockchain-node / mempool / block / bridge-node / relayer | | 暗号 / データ 4 | signer / oracle / merkle-tree / decision |

各 kind は shape / color / icon が異なる。 基本 5 は専用 component、 残り 24 種は GenericNode で汎用描画。

GenericNode の箱に kindForm: "icon" と icon を書くと、kind の意味を保ったまま角12・太さ1・面なしの共通枠と6種の40×40線画で描く。 線画は person / box / database / lightning / cloud / terminal から明示して選び、kindから既定値は補わない。 大きさ・線幅・色は --cdl-component-icon-size / --cdl-component-icon-stroke-width / --cdl-component-icon-color で変えられる。 kindForm を書かない箱の外形・面・既存24×24 iconの出力は変わらない。

札と線上の名札の角

矩形札に cornerForm: "theme-variants" を書くと、1 つの data-cdl-role="node-body" の直下へ、同じ外接を持つ uniform の rect と handdraw の path を描く。 CSS の display で片方だけを選び、uniform は rx / ry、handdraw は cdl が組んだ 左上 / 右上 / 右下 / 左下 16 / 22 / 15 / 24 の円弧を使う。

図面 / 活版 / 図録 / 端末 / 電飾 / 浮彫の一様な札の角は 12 / 12 / 12 / 6 / 16 / 22、図面 / 活版 / 図録 / 端末 / 手描き / 電飾 / 浮彫の 線上の名札は edge-label-bg の rect へ CSS の rx / ry を 9 / 9 / 9 / 4 / 9 / 9 / 20 の順で当てる。路線の名札は同じ値を --cdl-metro-label-radius で決め、変数を指定しない時は既存値を fallback に使う。欄を書かない札、棒、円・菱形・雲・円柱などの 非矩形は従来の出力を保ち、棒と線上の名札を四隅別の path にはしない。

function の箱に titleFontSize を書くと題をその大きさで描き、箱の高さを (値 - 24) * 0.97 だけ伸ばす。 低い箱で題を幅と高さに合わせて縮める計算でも、この値が上限になる。function 以外はこの欄を読まない。 例: .node("label", { kind: "function", title: "送り状を起こす", titleFontSize: 32.93 })

表の箱の見出しと行

storage は emptyRowsNote、emphasis: "primary"、titleAlign: "center"、rowRules: true をそれぞれ独立に受け取る。 空の注記は等幅 19・字間 0.05em・上 20・下 22 で node-row-empty、中央の名前は字 29、小見出しは等幅 16・名前の 9 上で node-eyebrow を持つ。 主の箱は data-cdl-emphasis="primary" と枠 2.25、罫線は node-row-divider / node-row-rule と太さ 1 で描く。 色は --cdl-row-empty / --cdl-node-eyebrow / --cdl-row-divider / --cdl-row-rule、線種と非表示は role の CSS で上書きできる。 4 欄を書かない箱の出力は変わらない。

RowMark.tone は primary / muted、未指定は normal として data-cdl-row-tone に出る。rowMarkForm: "tone" は全印を一辺 9・名前との間 14 の同形印にし、山形だった群の先頭へ太さ 1.5 の node-row-group-divider を描く。 印の色は --cdl-row-mark-primary / --cdl-row-mark-normal / --cdl-row-mark-muted、角丸と回転は --cdl-row-mark-radius / --cdl-row-mark-rotate で変えられる。 群境界と重なる node-row-rule は描かず、rowMarkForm を書かない箱の出力は変わらない。

rowLayout は表の箱ごとに { titleBaseline, rowTop, rowPitch } を部分指定し、題の baseline、 1行目の baseline、行の baseline 間隔を決める。既定は86・152・56である。 見出し下の線、行と群の区切り線、行の受け皿、呼び名、空の注記、自動高さ、視覚検査も同じ値を使う。 titleBaseline と rowTop は0以上、rowPitch は0より大きい有限数とし、rowLayout を書かない箱の出力は変わらない。

rowWell は行のまとまりごとに、行・印・区切り線の後ろへ透明な node-row-well を描く。 { top, right, bottom, left, radius } を部分指定でき、空の object は上2・右16・下4・左16・角15を使う。 行が無く emptyRowsNote を持つ箱では注記を囲む1面を描き、nestIn を持つ子には描かない。 色と影は利用側が role の CSS で当て、rowWell を書かない箱の出力は変わらない。

storage の子に nestIn: "親の id" を書くと、親の見出し下にある node-nest-well の中へ子を縦に積む。 親子はともに storage に限り、1 段だけ入れ子にできる。囲いは親枠から14、内側の余白と子間は12で、子は角8・見出し22・行高40・行名20・型17になる。親の高さは子の合計高から決まり、figureCard の足は囲いの下へ置く。 子は段に数えないが普通の箱として座標を持つため、edge は子の辺へ着く。囲いと子は --cdl-node-nest-well / --cdl-node-nest-child-stroke / --cdl-node-nest-title-size で装飾でき、nestIn を書かない図の出力は変わらない。

流れの始まりと終わりを示す印として mark-start (塗った丸) と mark-end (輪で囲んだ丸) がある。 印そのものが意味を持つので文字は描かない。 印に markGap を書くと段を使わず、矢印 1 本でつながる同じ縦列の箱から、その間だけ離して置かれる。 欄を書かない図は今までどおり段に置く。 例: .node("start", { lane: "荷主", stack: 0, kind: "mark-start", title: "", w: 43, h: 43, markGap: 73.47 })

路線図の駅には station を使う。 駅は小さな丸で、名前を丸の外に描く。 stationNamePosition は "top" / "bottom" を取り、既定の "top" では中心から 34 上、"bottom" では中心から 52 下へ置く。 未指定で線路が真上から入る駅だけは名前を右へ自動配置し、明示した "top" / "bottom" は右配置より優先する。 下へ置く時は .node("visit", { kind: "station", stationNamePosition: "bottom", ... }) のように書く。 説明 (subtitle) は名前が下なら名前の下、それ以外は丸の下に描く。 posX / posY で線路上の点へ置き、既定の大きさは 24×24 になる。 tone を指定すると丸の枠色が変わる。

routing: "metro" の実線が直接つなぐ station と decision / mark-start / mark-end の組だけを、節どうしの近さの判定から外す。重なり (node-overlap) は外さない。 線が無い組、solid でない線、ほかの経路や節種の組は、通常の近さの判定を保つ。

時間軸の番号には timeline-number を使う。 番号は 52×52 の丸の中央に描き、lane の timelineAxis: true で丸の中心を通る実線を引く。 札の leaderTo に番号の node id を書くと、札と丸を矢印なしの点線で結ぶ。 leaderTo を持つ card の subtitle は、札の右側へ担当の字として描く。 補助線を持たない札も subtitlePlacement: "right" を書けば、同じ位置と大きさで担当の字を描く。 例: .node("return", { kind: "card", subtitle: "配送便", subtitlePlacement: "right", ... })

書ける種類の全件は NODE_KINDS を値として公開しているので、記法を書く側は手書きせずに引ける (上の表は代表例で、全件ではない)。

EdgeStyle + EdgeHead + Tone

| EdgeStyle | 動き | |---|---| | solid | 実線 + 矢頭 marker、 progress 連動で path が伸びる | | dotted-flow | 点線 + 進行点 glow (3 重円) が path 上を流れる、 node 貫通自動判定 |

端の形 (head) は線の種類とは 別の軸 で、線の先端に何を置くかを決める。 実線 × 三角 (継承) と破線 × 三角 (実装) は線種で分かれ、 実線 × 三角 (継承) と実線 × 菱 (集約) は端で分かれる。

| EdgeHead | 形 | 表すもの | |---|---|---| | triangle | 塗った三角 (既定) | 書かなければこれになる | | dot | 線幅に比例する塗った丸 | tailHead: "dot" で線の出どころを示す | | diamond | 塗った菱 | 「持っている」 側を指す | | open | 閉じない 2 本の腕 | 向きだけを示し、待たない | | crow | 三又 | 「多」 を示す (ER の鳥の足) |

受理する値は EDGE_HEADS を値として公開しているので、記法を書く側は手書きせずに引ける。 dot は data-cdl-role="edge-arrowhead" と data-cdl-edge-head="dot" を持ち、中心を path の始点へ重ねる。 半径は線幅に比例し、線幅 6 では 5.5。始点も出どころの箱の縁から線幅 6 で 14 離れ、太さに比例する。 色は線と同じ --cdl-tone-* を使い、未知の tone は --cdl-line-mute の受け皿へ落ちる。 tailHead を書かない線と既存の端の形の出力は変わらない。

| Tone | 色 (hex) | 用途 | |---|---|---| | accent | #c17f3e | default | | teal | #4a8b7f | 補助動作 | | success | #6b9e5a | 成功 path | | error | #c15a4a | 失敗 path | | warning | #c9a23e | 警告 | | info | #5a8ec1 | 情報 |

線の道筋 (routing)

| 値 | 道筋 | 向く場面 | |---|---|---| | default | 箱を避け、角を丸めた直角の線 | 箱を避けたい図、直角の線に揃えたい図 | | back-detour | 箱の上を回って戻り、途中の箱と交わる時は外側を回る線 | 前の箱へ戻る関係 | | curve | 両端で水平になる 3 次曲線 | 段や列をまたぐ関係を柔らかくつなぐ図 | | metro | 横線と傾き ±1 の斜線を円弧で結ぶ線 | 路線図の線路と乗り換え |

posX1 / posY1 / posX2 / posY2を全て書いた線は、任意のwaypoints: { x: number; y: number }[]を 始点と終点の間に順に通る。隣り合う点はxまたはyを揃え、斜めの区間はvalidate()が知らせる。 矢じりとheadLabelは最後の区間、tailHeadとtailLabelは最初の区間を使う。中央の札は経路の 合計長の中点へ置き、labelCollision: "author"ではlabelOffsetX / labelOffsetYを一度だけ足す。 waypointsを書かない固定座標線と、4座標が揃わない自動経路は従来の出力を保つ。

.edge("source", "target", {
  id: "fixed-route",
  label: "使う",
  posX1: 1438,
  posY1: 124.95,
  posX2: 1391,
  posY2: 335.27,
  waypoints: [{ x: 1434, y: 124.95 }, { x: 1434, y: 335.27 }],
})

back-detour は辺を書かなければ、今までどおり始点と終点の上辺を結び、両端より 100 上を横に渡る。 途中の箱と交わる時だけ、縦に並ぶ箱を避けた最も近い外側の列を通り、交わる箱が少なく短い方を選ぶ。 side を書くと両端へ同じ辺を使い、fromSide と toSide はそれぞれ出る辺と入る辺だけを上書きする。 左右の辺は箱や段階列の外側の縦列、上辺と下辺は箱や段階列の外側の横行を通る。 札の中心はその縦列または横行の上に置き、外側へ回っても避けられない箱は edge-node-cross として検査結果に残る。 ただし、上辺どうしは従来の道筋と札の位置を保ち、下辺どうしは途中の箱を外側の列で避けずに下の横行を通って札の中心をその横行の上に置く。 左右または上下で向かい合う辺は迂回にならず、default と同じ道筋になる。

.edge("return", "load", {
  label: "翌日もう一度",
  routing: "back-detour",
  fromSide: "right",
  toSide: "top",
})

curve は、行き先が右なら始点の右辺から終点の左辺へ、左なら始点の左辺から終点の右辺へ結ぶ。 2 つの箱の横の範囲が重なる時は、両方の右辺を結ぶ。 2 点の高さが同じなら直線になる。 線が終点へ水平に入るため、終点の矢印も線の向きに沿って水平を向く。 途中の箱は避けない。 箱を避けたい時は routing を書かずに default のままにする。

import { diagram } from "@cardenelabs/cdl";

export const curvedRelation = diagram("curved-relation", { topic: "曲線で結ぶ" })
  .lane("left", { x: 0, width: 300 })
  .lane("right", { x: 600, width: 300 })
  .node("source", { lane: "left", stack: 0, kind: "card", title: "始点" })
  .node("target", { lane: "right", stack: 1, kind: "card", title: "終点" })
  .edge("source", "target", { id: "curve", label: "柔らかくつなぐ", routing: "curve" })
  .build();

metro は、行き先が右なら始点の右辺から終点の左辺へ、左なら始点の左辺から終点の右辺へ結ぶ。 両端の間に高さの差以上の横幅があれば、傾き ±1 の斜線を中央に置く。 横線と斜線は半径 24 を上限とする円弧でつなぎ、横線か斜線が短い時は収まる半径まで縮める。 横の余裕が高さの差に足りない時と、箱の横の範囲が重なる時は、両方の右辺をくの字で結ぶ。 同じ高さなら横の直線になり、途中の箱は避けない。

metro を使う図だけがこの道筋を選ぶ。 default / back-detour / curve の線と、座標を固定した線の出力は変わらない。

図全体の edgeEndGap には0以上の有限の数を指定できる。全ての線について、始点側は線の端または tailHead の先、終点側は線の端または矢じりの先を、発着する箱の縁から指定 px だけ離す。 書かない時と 0 は同じ従来 SVG を出す。流れ図、段の箱、時間軸を含む共通の edge 描画に効く。

sub の無い metro の札は、高さ 40、字の大きさ 21・太さ 700、角丸 9 で描き、幅は字の幅と左右の余白から求める。 角丸は --cdl-metro-label-radius で上書きでき、CSS を読まない SVG には rx 属性の 9 が残る。 札は経路の中点に置かれ、後から逃がす pass では動かさない。 前の駅へ戻る線の札だけは、線が出る駅の中心と角の中点に置く。 縦に長い区間の札は labelOffsetY、横方向は labelOffsetX で動かす。

全ての lane が段の図では、sub の無い curve と back-detour の札を高さ 40・字 21/700・角丸 9・字の基準線を札の上端から 28 で描き、幅は路線図の枝札と同じ式で求める。 角丸は rx 属性にだけ書き、意匠ごとの角は使う側の CSS の rx で当てる。 段の見出しの番号と名前は、列の左端から stage.header.leftPad (既定 20) の所に置く。 段の箱でない図の札は変わらない。

段の箱では、図全体の stageLayout に列の幅と間隔、戻り線の回り道の間を部分指定できる。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | columnWidths | 段名ごとの0以上の列幅。書いた列だけに使う | lane の幅と今までの自動調整 | | columnGap | 隣り合う列面の縁どうしの0以上の間 | 今までの列間計算 | | backDetourTopGap | 全列の上端から戻り線の水平部中心までの0以上の間 | 列上端から50と節から100の外側 | | backDetourSideGap | 最外列の縁から戻り線の垂直部中心までの0以上の間 | 今までの回り道計算 | | backDetourTargetInset | 戻り線が行き先の箱の上辺へ入る位置までの、箱の右端からの0以上の距離 | 24 |

stageLayout: {
  columnWidths: { 申し込み: 300, 受付: 360, 配送: 400, 結果: 420 },
  columnGap: 64,
  backDetourTopGap: 34,
  backDetourSideGap: 58,
  backDetourTargetInset: 60,
}

外側の欄を省くと既定値は undefined で、0.131.0までの経路をそのまま使う。一部だけ書いた時も、 残りは同じ自動計算で補う。明示した列幅と間は札の幅や自動拡張では縮めず、配置、描画、戻り線は 同じ解決値を使う。札が狭い列に収まらない時は列を広げず、visualValidate が知らせる。 backDetourTargetInset は行き先が上辺の back-detour だけに効き、箱の幅を超える値は左端で 止める。戻る線の札は、上を通る水平区間の中点へ入口の移動と同じだけ追随する。

lane に metro: { subtitle } を書くと、幅 200・角丸 12 の担当名札へ label と補足を描く。 名前は字の大きさ 29・太さ 700、補足は字の大きさ 19 で、名前と補足の文字境界の間は 10。 名前の字の大きさは --cdl-metro-lane-badge-name-size (既定 29px)、太さは --cdl-metro-lane-badge-name-weight (既定 700) で上書きできる。

lane に flowchart: { subtitle } を書くと、同じ欄を持つ縦列の最大の箱幅を基準に、倍率 k = 幅 / 300 の見出しを描く。高さ 88k、名前 29k / 700、補足 19k で、箱の下端 + 26k に横線、縦列中心の中点に区切り線を置く。 箱・名前・補足・横線・区切り線は flowchart-lane-heading / -name / -subtitle / flowchart-lane-rule / flowchart-lane-divider で選べ、名前は --cdl-flowchart-lane-heading-name-size と --cdl-flowchart-lane-heading-name-weight で変えられる。 FlowchartPreset.lanes には { label, subtitle } も渡せる。flowchart を書かない図の出力は変わらない。

通常の lane に subtitle を書くと、lane-label の右へ14空け、同じ基準線に等幅16の lane-label-subtitle を描く。 間は数値の14に固定し、字の大きさは --cdl-lane-label-subtitle-size で変えられる。 metro.subtitle と flowchart.subtitle は別の形を保ち、subtitle を書かない通常laneの出力は変わらない。

import { diagram } from "@cardenelabs/cdl";

export const metroMap = diagram("metro-map", { topic: "路線図" })
  .lane("upper", { x: 0, width: 700 })
  .lane("lower", { x: 800, width: 700 })
  .node("central", {
    lane: "upper", stack: 0, kind: "station", title: "中央", posX: 100, posY: 200,
  })
  .node("museum", {
    lane: "upper", stack: 1, kind: "station", title: "美術館", posX: 500, posY: 200,
  })
  .node("river", {
    lane: "lower", stack: 0, kind: "station", title: "川辺", posX: 900, posY: 400,
  })
  .node("park", {
    lane: "lower", stack: 1, kind: "station", title: "公園", posX: 1300, posY: 400,
  })
  .edge("central", "museum", { id: "upper-line", label: "", routing: "metro" })
  .edge("river", "park", { id: "lower-line", label: "", routing: "metro" })
  .edge("museum", "river", { id: "transfer", label: "乗り換え", routing: "metro" })
  .build();

phase / state / tween / set / badge

phase 内で state を tween / set し、 badge を出す。

.state("amount", { initial: 0 })
.state("status", { initial: "idle" })
.phase("p1", { duration: 1800, title: "Phase 1", body: "tween + set" },
  (p) => p
    .activate("a", "b")
    .tween("amount", 0, 100)    // 数値の線形補間
    .set("status", "running")    // 文字列の即時切替
    .badge("processing"))         // header に badge 表示

state placeholder は node の title / subtitle / eyebrow / value 内で {stateId} 記法で参照。

.node("a", { lane: "l", stack: 0, kind: "function", title: "Process", subtitle: "status: {status}" })

phase 切替に連動して status: idle → status: running のように描画される。

図表を見出し帯と足のある札にする時は、node に figureCard を書く。 .node("bar", { kind: "chart-bar", title: "営業所ごとの取扱数", figureCard: { label: "棒", note: "今月 / 単位 件" }, chartData: [...] }) 題と足は figure-title / figure-footer-label / figure-footer-note role で選べる。 字・線・横余白は --cdl-figure-card-title-size (既定 29px)、--cdl-figure-card-title-weight (既定 700)、--cdl-figure-card-rule-width (既定 1px)、--cdl-figure-card-inset (既定 22px)、--cdl-figure-card-label-letter-spacing (既定 0.16em)、--cdl-figure-card-note-letter-spacing (既定 0.1em) で上書きできる。

図表札に figureInset を書くと、見出しと足の間へ装飾用の figure-content-inset を描く。 外側の欄の既定値は undefined で要素を描かず、figureInset: {} の既定値は 上 4、右 18、下 8、左 18、角 18 である。top / right / bottom / left / radius は 0以上の有限数で部分指定できる。holdsContent の既定値は false で、true にすると図表の 中身を凹み面の矩形へ収める。面は fill="none"、stroke="none"、filter: none なので、 holdsContent を書かなければ見た目や図表の配置領域を変えない。

同じSVGのfilterは右5・下5・ぼかし11の figure-content-inset-shadow-dark と、左5・上5・ ぼかし11の figure-content-inset-shadow-light を持つ。CSSは figure-content-inset のfilterと、 2つの影roleの flood-color / flood-opacity だけを選ぶ。間の和が外枠を超える時は負の寸法を 描かず、visualValidate が figure-inset-bounds を報告する。

[data-cdl-role="figure-content-inset"] {
  filter: var(--cdl-figure-content-inset-filter);
}
[data-cdl-role="figure-content-inset-shadow-dark"] {
  flood-color: rgb(160 144 120);
  flood-opacity: 0.42;
}
[data-cdl-role="figure-content-inset-shadow-light"] {
  flood-color: white;
  flood-opacity: 0.88;
}

同じ figureCard.label / note を storage と kindForm: "icon" の部品箱に書くと、高さ36・上罫1・上下9・左右22の足を下端へ描く。 部品箱は足より上を90、全体を126とし、足なしの部品箱も名前・説明・40角の絵を収める自動高90にする。著者が90より高い h を書いた部品箱では、90との差を上下へ分けて中身を置く。表箱は見出し61、1行46、空の注記61の見本寸法から足より上を決める。 上罫・左の種別・右の補足は node-footer-divider / node-footer-label / node-footer-note role で個別に選べる。 線は --cdl-node-footer-rule-width / -rule-color、左字は -label-size / -label-weight / -label-letter-spacing / -label-color、右字は -note-size / -note-letter-spacing / -note-color で変えられる。 figureCard を書かない表と既存の図表札の出力は変えず、著者が h を書いた時はその高さを優先する。

折れ線の計画と実績

chart-line の chartLineSeries に系列を並べると、計画と実績のような複数の線を同じ目盛りに描ける。

.node("delivery", {
  lane: "chart",
  stack: 0,
  kind: "chart-line",
  title: "月ごとの配達数",
  chartLineSeries: [
    {
      points: [
        { label: "6月", value: 900 },
        { label: "7月", value: 1180 },
        { label: "8月", value: 1250 },
        { label: "9月", value: 1520 },
        { label: "10月", value: 1750 },
      ],
      marker: "hollow",
      valueIndexes: [0, 4],
    },
    {
      label: "計画",
      points: [
        { label: "6月", value: 1000 },
        { label: "7月", value: 1150 },
        { label: "8月", value: 1300 },
        { label: "9月", value: 1450 },
        { label: "10月", value: 1600 },
      ],
      tone: "muted",
      dash: "dotted",
      marker: "none",
      valueIndexes: [4],
    },
  ],
})

| 欄 | 値 | 書かない時 | |---|---|---| | label | 値の札の前に付ける系列名 | 数だけを描く | | points | { label, value } の並び | 必須 | | tone | accent / muted などの意味色 | 系列の添字に対応する --cdl-chart-N | | dash | solid / dotted | solid | | marker | dot / hollow / none | dot | | valueIndexes | 札を付ける点の添字 | 全点 |

  • 全系列が同じ目盛りと横の位置を使う。点数の短い系列は途中で終わる。
  • 横軸の名前は、添字ごとにその点を持つ最初の系列から取る。
  • tone を書かない系列は系列色を並び順に受けるため、主役を先頭に書く。tone を書いた系列も添字を 1 つ使う。node に chartSeriesSkipMuted: true を書いた図では、muted の系列だけが添字を使わない (## 沈めた項目を飛ばして系列の色を配る)。
  • 点線は実線の下に重なり、点と値の札は全ての線より上に重なる。
  • 値の札は同じ添字の全系列より大きければ上、小さければ下、それ以外は 1 本の折れ線と同じ谷の決まりで置く。
  • chartFillUnder と chartTrace は系列を書いた図では描かない。chartValueRise は系列にも効く。
  • chartLineSeries を書かない図は、今までどおり chartData を 1 本の線として描く。

折れ線の寸法

chart-line の任意の object 欄 chartLineSize で、値札の間、軸の字、点、格子と点の左右余白、 月名の基線を SVG 座標の数で部分指定できる。外側の欄、空の object、各要素の省略はいずれも 従来の値を使う。

| 要素 | 明示する値 | 書かない時 | |---|---|---:| | valueLabelOffset.above | 点の中心から上側の値札の基線までの 0 以上の間 | 12 | | valueLabelOffset.below | 点の中心から下側の値札の基線までの 0 以上の間 | 18 | | tickFontSize | 縦軸の目盛りの正の字の大きさ | 11 | | periodFontSize | 横軸の月名の正の字の大きさ | 11 | | pointRadius | 点の正の半径 | 5 | | plotPadding.top | 図の上端から値を置く描画面までの 0 以上の間 | 56 | | plotPadding.right | 格子の右端から図の右端までの 0 以上の間 | 40 | | plotPadding.bottom | 値を置く描画面から図の下端までの 0 以上の間 | 76 | | plotPadding.left | 図の左端から格子の左端までの 0 以上の間 | 72 | | tickGap | 格子の左端から目盛りの基準 x までの左向きの 0 以上の間 | 8 | | pointPadding.left | 格子の左端から最初の点と月名までの 0 以上の間 | 24 | | pointPadding.right | 最後の点と月名から格子の右端までの 0 以上の間 | 24 | | periodY | 図の上端から月名の基線までの 0 以上の y 座標 | 図の高さ - 36 |

見本帳の寸法は次の形で書く。

chartLineSize: {
  valueLabelOffset: { above: 20, below: 34 },
  tickFontSize: 17,
  periodFontSize: 19,
  pointRadius: 7.5,
  plotPadding: { top: 106.891, right: 60, bottom: 82, left: 92 },
  tickGap: 12,
  pointPadding: { left: 46, right: 0 },
  periodY: 416,
}

単系列と chartLineSeries は同じ解決値を使い、山・谷・系列間から値札の上下を選ぶ規則は 変えない。上の横寸法では格子が 92..708、目盛りの基準 x が 80、点と月名が 138..708、 月名の基線が 416 になる。明示値は figureSize への収まりを理由に縮めず、値札、格子、目盛り、 点、月名が外へ出る場合は visualValidate が知らせる。0 以下の字と点の半径、負の間と余白、有限でない数は validate() が欄名と入力値を付けて拒む。値札の字、線の太さ、札を出す点、色、線種は含めない。

升目の一覧の位置

chartWaffleLegendPosition で、升目の一覧を左または右から選べる。

.node("size", {
  lane: "l",
  stack: 0,
  kind: "chart-waffle",
  chartWaffleLegendPosition: "right",
  chartData: [
    { label: "小さい", value: 52 },
    { label: "ふつう", value: 31 },
    { label: "大きい", value: 17 },
  ],
})

| 値 | 形 | |---|---| | left (既定) | 一覧が左。色の縦棒と名前と数の 2 段 | | right | 一覧が右。印・名前・割合の 1 行で、実数は描かない |

型の外の値は left として描く。

| data-cdl-role | 部品 | |---|---| | chart-waffle-item-mark | 印の rect | | chart-waffle-item-label | 名前 | | chart-waffle-item-share | 割合 | | chart-waffle-item-rule | 区切り線 |

4 つとも right だけに付く。left の一覧は今までどおり chart-waffle-count を持つ。 right の字と間はマスの送りに対する見本の比で決まり、名前は var(--cdl-text, #1a1f2a) の太さ 500、割合は #1081 の円の表の値と同じ var(--cdl-text-mute, #8a8678) と 'JetBrains Mono' で描く。

right では任意 object 欄 chartWaffleSize で升目の横位置と送りを部分指定できる。

| 要素 | 制約と意味 | 書かない時の既定値 | |---|---|---| | gridLeft | 0 以上。図の左端から升目の左端まで | 従来の中身幅から求める自動値 | | cellPitch | 正の数。隣り合うマスの左端どうしの間 | 従来の幅と高さから求める自動値 |

chartWaffleSize: { gridLeft: 42.5, cellPitch: 30 }

1 マスの幅と右一覧の寸法は送りに連動し、見本比は 25 / 30 である。明示値は縮めず、升目や 一覧が figureSize から出る時は visualValidate が知らせる。負の位置、0 以下の送り、 有限でない数は validate() が欄名と入力値を付けて拒む。

使う側の CSS から、たとえば印を菱形、区切り線を破線にできる。

[data-cdl-role="chart-waffle-item-mark"] {
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(45deg);
}

[data-cdl-role="chart-waffle-item-rule"] {
  stroke-dasharray: 3 3;
}

2 時点の構成比

chart-pie と chart-stacked-bar と chart-slope は datum の previous で前の時点を受け取る。 previous を 1 件でも書くと、書かない datum も前の時点では 0 として扱うため、系列の色と 並びが時点間で対応する。

.node("share", {
  lane: "l",
  stack: 0,
  kind: "chart-pie",
  chartData: [
    { label: "Web", previous: 45, value: 30 },
    { label: "Mobile", previous: 35, value: 45 },
    { label: "API", value: 25 },
  ],
})

chart-pie は前を内側、今を外側の輪で描き、名札には 45 → 30 30% の形で今の割合を添える。 chart-stacked-bar は前から今の順に帯を並べる。previous を書かない図は、どちらも今だけを描く。 3 時点以上は chart-stacked-bar だけが chartStackedPeriods で受け取る (次の節)。

内訳の帯の期間と率

chart-stacked-bar は chartStackedPeriods で 3 期間以上の帯を描ける。 chartStackedRateId で指した系列の割合を帯の右へ置き、chartStackedLegendPosition: "top" で 凡例を帯の上へ置く。

.node("delivery", {
  lane: "l",
  stack: 0,
  kind: "chart-stacked-bar",
  title: "配達の結果",
  chartData: [
    { id: "once", label: "一度で届いた", value: 85, tone: "muted" },
    { id: "again", label: "再配達", value: 13, emphasis: "primary" },
    { id: "returned", label: "戻った", value: 2 },
  ],
  chartStackedPeriods: [
    { label: "6月", values: [78, 19, 3] },
    { label: "7月", values: [80, 17, 3] },
    { label: "8月", values: [76, 21, 3] },
    { label: "9月", values: [82, 16, 2] },
    { label: "10月", values: [85, 13, 2] },
  ],
  chartStackedRateId: "again",
  chartStackedLegendPosition: "top",
})

values[i] は chartData[i] の値で、足りない添字は 0、余った添字は読まない。 期間を書いた図では datum の value と previous を読まない。 value には最後の期間の値を書いておくと、chartStackedPeriods を外した時も今の帯 1 本になる。

配列でない値、空の配列、values を配列で持つ期間が 1 つもない配列は、期間を書かなかった ものとして扱う。 有効な配列の中で values を持たない期間は全て 0 の帯、文字列でない label は空の字になる。

率は空でない chartStackedRateId が datum の id に当たる時だけ描き、合計 0 の帯では描かない。 率の色は指した区画と同じだが、tone: "muted" の系列だけは字の対比を保つため本文色を使う。 率の <text> は data-cdl-role="chart-stacked-bar-rate" で選べる。

凡例の位置は top と bottom で、書かない時と型の外の値は今までどおり下になる。 期間の帯が枠に入らない時は高さと間を 44:20 の比のまま縮める。 縮めた図と率を描く図は、数を率と凡例から読むため区画の中の割合と実数を描かない。

内訳の帯の寸法

任意の object 欄 chartStackedLayout で、凡例、区画、帯、字の寸法を部分指定できる。 外側の欄または要素を書かない時は、今までの自動計算を使う。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | legendColumns | 1 行に置く凡例の正の整数の列数 | 名前の幅と描画域から折り返す | | legendColumnGap | 隣り合う列の起点どうしの 0 以上の横の間 | 印、名前の字幅、件の間 10 から出す | | legendOffsetY | 自動配置から凡例の全行を下へ動かす有限の量。負は上 | 0 | | segmentGap | 隣り合う区画の縁どうしの 0 以上の間 | 0 | | barThickness | 全ての帯の正の太さ | 44 を上限に描画高と帯の数から出す | | barWidth | 区画の間を含む帯全体の正の幅 | 時点名、率、描画幅から出す | | legendMarkSize | 凡例の印の正の幅と高さ | 10 | | legendFontSize | 凡例の名前の正の字 | 13 | | periodFontSize | 時点名の正の字 | 13 | | rateFontSize | 率の正の字 | 13 |

chartStackedLayout: {
  legendColumns: 3,
  legendColumnGap: 170,
  legendOffsetY: -20.609375,
  segmentGap: 3,
  barThickness: 32,
  barWidth: 365,
  legendMarkSize: 16,
  legendFontSize: 17,
  periodFontSize: 19,
  rateFontSize: 19,
}

legendOffsetY の既定値は 0 で、書かない時の自動配置を変えない。 見本帳では7意匠に同じ -20.609375 を使い、見出し線から先頭の凡例印の中心までを 27.390625 にする。明示した差分は収まりのために縮めず、図外へ出た凡例は visualValidate が知らせる。

区画の間は帯の幅へ足さず、割合から決めた内部境界の両側から半分ずつ引く。 このため合計 100% の帯の左右端は barWidth のままになる。 見本 7 意匠の共通幅は 365 で、図面・活版・図録・手描きとの差は 0、端末は -2、電飾は -4、 浮彫は -36 である。幅は CSS の拡縮で変えず、この共通幅を記法で渡す。

帯のまとまりは chart-stacked-bar-plot、各行は chart-stacked-bar-row と data-cdl-row で選べる。意匠ごとの左端と縦の間は行単位の CSS transform で変え、 同じ行に入る区画、時点名、率を同量動かす。凡例は行の外にあり動かない。 明示した帯と字は figureSize へ収めるために縮めず、配置、描画、draw の切り抜き、 visualValidate が同じ解決値を使う。収まらない時は visualValidate がはみ出しや重なりを 知らせる。

2 時点の増減と順位

chart-slope は同じ previous を読むが、構成比ではなく 値そのもの を左右に打ち、系列ごとに 直線で結ぶ。 線の向きが増減、傾きが動いた量、線の交差が順位の入れ替わりを表す。

.node("trend", {
  lane: "l",
  stack: 0,
  kind: "chart-slope",
  chartData: [
    { label: "Web", previous: 45, value: 30 },
    { label: "Mobile", previous: 35, value: 45 },
    { label: "API", previous: 20, value: 25 },
  ],
})

尺は 0 に固定せず、両時点の最小と最大から取る。 近い値どうしの差を傾きで読ませる図なので、 0 まで伸ばすと線が全部水平に潰れるため。

previous を 1 件も書かない図は線を引かず、軸 1 本に点を並べる。 2 点が無いと傾きが定義できず、 水平線を引くと「動かなかった」 という別の意味になる。

段の draw にこの node を載せると、線が左の軸から右の軸へ伸びる。

名札の字は値と名前で role が分かれる (chart-slope-value / chart-slope-name)。 値だけに字体を当てられるようにするため。 系列の名前はその線と同じ色で描く。 線を目で辿らずに名前と線の対応が取れる。

傾き図の見せ方

chart-slope は chartSlopeForm で見せ方を選ぶ。 欄を書かない図は values と同じ。

| 値 | 縦の位置 | 右の列 | 向くもの | |---|---|---|---| | values (既定) | 値 | 今の値 | 2 時点の水準をそれぞれ読ませたい図 | | delta | 値 | 増減 (+40 / -90) | どれがどれだけ動いたかを読ませたい図 | | rank | 順位の段 (等間隔) | 今の値 | 順位の入れ替わりを読ませたい図 |

.node("move", { lane: "l", stack: 0, kind: "chart-slope", chartSlopeForm: "delta", chartData: [...] })

傾き図の時点名と主役

chartSlopePeriods で左右の時点名を、chartSlopeEmphasisIds で色を残す主役を指定できる。 主役は名札の字ではなく、各 datum の id で指す。

.node("delivery-rate", {
  lane: "l",
  stack: 0,
  kind: "chart-slope",
  chartSlopePeriods: ["先月", "今月"],
  chartSlopeEmphasisIds: ["osaka", "nagoya"],
  chartData: [
    { id: "nagoya", label: "名古屋", previous: 79, value: 85 },
    { id: "tokyo", label: "東京", previous: 84, value: 88 },
    { id: "osaka", label: "大阪", previous: 86, value: 80 },
    { id: "fukuoka", label: "福岡", previous: 82, value: 83 },
  ],
})

時点名を書かなければ 前 / 今。2 つ以外の配列、文字列以外、空白だけの名前が片方でも 含まれる値は、欄全体を書かなかったものとして扱う。前の値が 1 件も無い図では時点名を描かない。

主役の id が 1 件以上当たる時だけ、tone を書いていない残りの線と点を muted にする。 残りの名前は、沈んだ色では字の対比が足りないため var(--cdl-text, #1a1f2a) で描く。 空の配列、存在しない id だけの配列、id を持たない datum では従来の色のまま。 主役の色は主役だけで数え直さず、datum の並びで決まるため、指定を外しても同じ系列の色は変わらない。

左の列はどれでも前の値。

delta は右の列だけを変える

前 + 増減 = 今 なので delta でも今の値は足せば戻る。 3 つ目の数を足さないので、 名札の高さも線を引く幅も変わらない。

増減は chart-slope-delta で出す。 今の値とは意味が違い、 消費側が増減だけに色を 当てられるようにするため。 engine 側では色を分けない = 系列の色を名前に当てているので、 増減にも色を当てると 1 つの図に 2 つの色の体系が混ざる。 向きは符号が持つ。

rank は縦の位置を変える

段を等間隔に置くので、 線の交差が順位の入れ替わりと 1 対 1 になり、 水平線が 「順位が動かなかった」 を意味する。 既定 (値の尺) では交差点の位置が順位と噛み合わず、 どの交差が本当に順位を変えた交差なのかは値を読み比べないと決まらない。

軸の脇の字は値のまま。 字も順位にすると 380 → 420 と 60 → 90 がどちらも同じ水平線に なり、 量が図から完全に消える。 位置が順位を、 字が量を担う。

rank では「線の傾きが動いた量」 が成立しない。 +40 と +30 がどちらも水平線に なるので、 量は字を読む。

同じ値の系列は同じ段に重なる = 無理に 1 つずつずらすと、 書いていない差を絵が主張する。 系列が 1 本の図は段が 1 つしか無いので縦の中央に置く。

どの形でも同じ扱い

型の外の値を書いた図は values として描く。 前の時点を持たない図も values として描く = delta は引く相手がいないため、 rank は軸が 1 本で並べ替える相手がいないため。

傾き図の値の単位

chartSlopeUnit で、左右の値の字の後ろに付ける単位を指定できる。

.node("delivery-rate", {
  lane: "l",
  stack: 0,
  kind: "chart-slope",
  chartSlopePeriods: ["先月", "今月"],
  chartSlopeUnit: "%",
  chartData: [
    { id: "nagoya", label: "名古屋", previous: 79, value: 85 },
    { id: "tokyo", label: "東京", previous: 84, value: 88 },
    { id: "osaka", label: "大阪", previous: 86, value: 80 },
    { id: "fukuoka", label: "福岡", previous: 82, value: 83 },
  ],
})

| 形 | 単位が付く列 | |---|---| | values | 左右 | | rank | 左右 | | delta | 左だけ | | 前の時点を持たない図 | 右だけ |

delta の右の列は値ではなく差なので単位を付けない。たとえば 86% から 80% への変化を -6% と書くと、「86 の 6% 減」と読め、百分率の目盛りの差とは違う量になるため。

単位の前後の空白は削らない。chartSlopeUnit: " 件" なら 84 件 と描く。空の文字列、 空白だけの文字列、文字列以外は、欄を書かなかったものとして扱う。

傾き図の名札と寸法

chartSlopeLabelTemplate は左右の名前と値を 1 つの text に組む。 left と right の両方が有効な時だけ使い、使える占位子は {name}・{value}・{unit} である。 見本帳では左を "{name} {value}{unit}"、右を "{value}{unit} {name}" とする。 主役の名札全体は線と同じ色・太さ700、非主役は本文色・太さ400で描く。 空、未知の占位子、左右の片方が無いひな形は欄ごと無効になり、従来の名前と値の2要素へ戻る。

chartSlopeSize は部分指定でき、要素を書かない時は次の値または従来の自動計算を使う。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | pointRadius | 点の正の半径 | 4 | | periodFontSize | 時点名の正の字の大きさ | 12 | | labelFontSize | 1要素の名札の正の字の大きさ | 従来の名前の字の自動計算(上限13・下限9) | | leftAxisX | 図の左端から左軸までの0以上の間 | 従来の描画面と名札幅から出す | | axisGap | 左右の軸の中心線どうしの正の間 | 従来の左右軸から出す | | labelAxisGap | 軸から名札の文字箱までの0以上の間 | 10 | | plotPadding.top | 図の上端から見える軸線の上端までの0以上の間 | 従来式(前の値があり時点名19なら55) | | plotPadding.bottom | 見える軸線の下端から図の下端までの0以上の間 | 24 | | pointPadding.top | 軸線の上端から最大値の点までの0以上の間 | 6 | | pointPadding.bottom | 最小値の点から軸線の下端までの0以上の間 | 6 |

chartSlopeLabelTemplate: {
  left: "{name} {value}{unit}",
  right: "{value}{unit} {name}",
},
chartSlopeSize: {
  pointRadius: 7,
  periodFontSize: 19,
  labelFontSize: 19,
  leftAxisX: 150,
  axisGap: 250,
  labelAxisGap: 18,
  plotPadding: { top: 109.891, bottom: 59 },
  pointPadding: { top: 44.464, bottom: 44.464 },
}

外側の chartSlopeLabelTemplate と chartSlopeSize を書かない時の既定値は undefined で、 名前と値の分離、色、太さ、点、軸、座標を0.131.0までの出力から変えない。 明示した字と点は名前の長さや figureSize への収まりを理由に縮めず、収まらない時は visualValidate がはみ出しと名札の重なりを知らせる。 軸と点の上下余白は1つの解決値を配置と描画で共有する。余白の合計で軸または点の高さが 0以下になる場合も明示値を縮めず、visualValidate が知らせる。 plotPadding と pointPadding を書かない時と空objectでは、0.132.0の従来式を保つ。 0以下の正寸法、負の leftAxisX / labelAxisGap / 上下余白、非有限数、空または未知の占位子を持つひな形は validate() が欄名と入力値を付けて拒む。

7意匠の順は図面・活版・図録・端末・手描き・電飾・浮彫である。 共通値を左軸150・軸間250とした時、左軸の残差は 0 / 0 / 0 / +1 / 0 / +2 / +18、 軸間の残差は 0 / 0 / 0 / -2 / 0 / -4 / -36 になる。

円グラフの見せ方

chart-pie は chartPieForm で見せ方を選ぶ。 欄を書かない図は ring と同じ。

| 値 | 形 | 向くもの | |---|---|---| | ring (既定) | 輪を扇に切り分け、外へ引き出し線を伸ばして名札を置く | 内訳の割合をひとめで見せる | | arcs | 系列ごとに 1 本の弧を置き、割合を角度ではなく弧の長さで読む | 合計が 100 にならない図 (系列ごとの達成率など) | | table | 輪を左に寄せ、右に 名前 / 割合 / 実数 の 3 列の表を組む | 割合と実数の両方を読ませたい図 |

.node("share", { lane: "l", stack: 0, kind: "chart-pie", chartPieForm: "arcs", chartData: [...] })

型の外の値を書いた図は ring として描く。 previous が効くのは ring だけで、 他の形では内側の輪を描かない。

区画の間

chartPieSliceGap に0以上の有限の数を書くと、隣り合う区画を輪の中ほどの半径上でその長さだけ 離す。内半径と外半径の平均を中ほどの半径とし、内半径が0なら外半径の半分になる。各区画は 両端を間の半分ずつ内側へ寄せたdで描き、地の色の区切り線を持たない。

ringとtableで効き、系列ごとに独立した弧を描くarcsは読まない。区画が1つだけなら形を 離さず、正の値では区切り線だけを外す。区画の角より寄せる角が大きい時はpathを消さず、その 区画の角を0にする。欄を書かない時と0は、従来の全区画のdと地の色の太さ3の線を保つ。

中心の合計の下の字

chartPieCenterLabel で、中心の合計の下に単位や補足を 1 つだけ置ける。

.node("status", {
  lane: "l",
  stack: 0,
  kind: "chart-pie",
  chartPieForm: "table",
  chartPieCenterLabel: "件",
  chartData: [...],
})

欄を書かない図は 合計 を描く。空の文字列と空白だけの文字列は 2 行目を描かず、 文字列以外は欄を書かなかったものとして 合計 を描く。ring と table で効き、 中心に字を置かない arcs はこの欄を読まない。

2 行目は var(--cdl-text-dim, #5a6270) で描き、字の大きさと位置は 合計 と同じ。 長い字は穴に収まるまで縮む。図に 1 つだけ置く字で、扇ごとの凡例を兼ねない。

表の列

chartPieTableColumns で、table の表を 3 列または 2 列から選べる。

.node("status", {
  lane: "l",
  stack: 0,
  kind: "chart-pie",
  chartPieForm: "table",
  chartPieTableColumns: "value",
  chartPieCenterLabel: "件",
  chartData: [
    { label: "配達中", value: 270 },
    { label: "集荷済", value: 141 },
    { label: "受付済", value: 77 },
    { label: "完了", value: 796 },
  ],
})

| 値 | 列 | 見出しの行 | |---|---|---| | share-value (既定) | 名前 / 割合 / 実数 | あり | | value | 名前 / 実数 | なし |

value で省いた幅は輪へ回る。chartPieForm: "table" の時だけ読み、型の外の値は share-value として描く。

| data-cdl-role | 部品 | |---|---| | chart-pie-table-mark | 印の rect | | chart-pie-table-label | 名前 | | chart-pie-table-value | 値 | | chart-pie-table-rule | 区切り線 |

4 つとも両方の列で付く。share-value では見出しの罫も chart-pie-table-rule を持つ。 value の名前は var(--cdl-text, #1a1f2a) の太さ 500、値は札の足の右の文と同じ var(--cdl-text-mute, #8a8678) と 'JetBrains Mono' で描く。

使う側の CSS から、たとえば印を菱形、区切り線を破線にできる。

[data-cdl-role="chart-pie-table-mark"] {
  transform-box: fill-box;
  transform-origin: center;
  transform: rotate(45deg);
}

[data-cdl-role="chart-pie-table-rule"] {
  stroke-dasharray: 3 3;
}

円の 2 列表と輪の寸法

chartPieForm: "table" と chartPieTableColumns: "value" の組では、任意の object 欄 chartPieSize で一覧と輪の寸法を SVG 座標の数として部分指定できる。外側の欄を書かない時と 空の object は既存の自動計算を使い、share-value の 3 列表、ring、arcs はこの欄を読まない。

| 要素 | 制約と意味 | 書かない時の既定値 | |---|---|---| | tableWidth | 正の数。一覧が使う幅 | 印、名前、値の実測幅と列の間から出す | | tableLabelFontSize | 正の数。名前の字 | 15 | | tableValueFontSize | 正の数。値の字 | 名前の字 × 19 / 22 | | tableRowGap | 0 以上。隣り合う行の中心間隔 | 名前の字 × 46 / 22 を上限に、図の高さから出す | | tablePaddingInline | 0 以上。一覧の左右それぞれの余白 | 0 | | outerRadius | 正の数。輪の中心から外周までの半径 | 一覧を除いた幅と図の高さから出す | | centerX | 0 以上。図の左端から輪の中心まで | 20 + outerRadius |

見本帳の円は次の形で書く。

chartPieSize: {
  tableWidth: 310,
  tableLabelFontSize: 22,
  tableValueFontSize: 19,
  tableRowGap: 46,
  tablePaddingInline: 24,
  outerRadius: 171.055,
  centerX: 227,
}

明示した一覧幅は名前や値の長さで広げたり縮めたりせず、明示した外半径も一覧幅や figureSize から再計算しない。明示した centerX は外半径と独立して輪、中央の字、扇へ使う。 配置と描画は同じ解決済み寸法を使う。字が一覧へ収まらない時、 または輪と一覧がはみ出す・重なる時は、値を縮めず visualValidate が知らせる。 0 以下の幅・字・外半径、負の中心・行間・余白、有限でない数は validate() が欄名と入力値を 付けて拒む。

輪の太さ

chartPieRingWidth で、輪の太さを選べる。

.node("status", {
  lane: "l",
  stack: 0,
  kind: "chart-pie",
  chartPieForm: "table",
  chartPieTableColumns: "value",
  chartPieCenterLabel: "件",
  chartPieRingWidth: "thin",
  chartData: [
    { label: "配達中", value: 270 },
    { label: "集荷済", value: 141 },
    { label: "受付済", value: 77 },
    { label: "完了", value: 796 },
  ],
})

| 値 | 内半径 | |---|---| | thick (既定) | 外半径の 0.58 倍 | | thin | 外半径の 0.75 倍 |

前の時点を持たない ring と table で読む。前の時点を持つ ring は外の輪が既に 0.75、 arcs は別の形なので、この欄を読まない。型の外の値は thick として描く。

外半径・表・引き出し線の位置は変わらず、中心の合計の字は穴に入る範囲で外半径の 0.26 倍まで 戻る。扇の間を地の色の線 (太さ 3) で区切るため、見える輪の内外の比は 0.75 より少し大きく、 外半径 99.79 では 0.777 になる。

漏斗の見せ方

funnel-stages は funnelForm で形、funnelRate で率の見せ方を選ぶ。

| funnelForm | 形 | |---|---| | trapezoid (既定) | 上から下へ狭まる台形を積む | | proportional-bars | 最大の件数を基準に、件数に比例した幅の棒を中央寄せで積む |

| funnelRate | 率 | |---|---| | drop (既定) | 離脱率を今までどおり ↓ x.x% で描く | | conversion | 前の段からの通過率を四捨五入した整数で描く | | none | 率を描かない |

.node("funnel", {
  lane: "l",
  stack: 0,
  kind: "funnel-stages",
  funnelForm: "proportional-bars",
  funnelRate: "conversion",
  funnelData: [
    { id: "seen", title: "見た", count: 12000, tone: "muted" },
    { id: "apply", title: "申し込んだ", count: 3400, tone: "muted" },
    { id: "arrive", title: "届いた", count: 2750, tone: "accent" },
  ],
})

段の tone で段ごとの塗りを選べる。書かない段は今までどおり段の順の色になる。 通過率は前の段の件数を分母にして四捨五入し、前の段が 0 件なら描かない。 比例の棒の幅は 1 段目ではなく全段の最大の件数を基準にする。 funnelForm と funnelRate を書かない図は trapezoid / drop と同じで、型の外の値も 見せ方が決まらないまま消すのではなく、この既定で描く。

ガントの目盛りの名前

欄を書かないガントは、目盛りの名前を工程の startLabel と endLabel から集める。そのため、 どの工程の端も指さない目盛りは空になる。ganttTickLabels を書くと、i 番目の名前を位置 i の 目盛りの線と i+1 の線の間の中央に描き、工程の名前は目盛りに使わない。

.node("shelf-plan", {
  lane: "l",
  stack: 0,
  kind: "gantt-timeline",
  title: "仕分け棚を入れ替える工程",
  ganttAxisMax: 5,
  ganttTickLabels: ["6月", "7月", "8月", "9月", "10月"],
  ganttData: [
    { id: "survey", title: "調べる", startIdx: 0, endIdx: 0, startLabel: "6月", endLabel: "6月" },
    { id: "build", title: "棚を作る", startIdx: 2, endIdx: 2.2, startLabel: "8月", endLabel: "8月" },
  ],
})

| 書いた値 | 目盛りの名前 | |---|---| | 欄なし、または型の外の値 | 今までどおり工程の端から集める | | 1 個以上の文字列の配列 | i 番目を描く。空の文字列と空白だけの位置は名前を描かず、線を残す |

| 尺 | 扱い | |---|---| | ganttAxisMax を書いた | その値を使う。並びの数と違えば validate() が警告し、尺の外の名前は描かない | | ganttAxisMax を書かない | 工程から決めた尺と並びの数の大きい方を使う |

節目の札と今日の札は、今までどおり工程の startLabel と ganttToday.label から描く。

ガントの帯の終わりと厚み

欄を書かないガントの帯は終わりの目盛りの右端まで伸びるため、1 目盛りより短く描けない。 ganttBarEnd: "position" を書くと startIdx の位置から endIdx の位置までを描き、 ganttBarThickness: "thin" で帯を行の名前の字に対する見本の比の厚みにする。

.node("shelf-plan", {
  lane: "l",
  stack: 0,
  kind: "gantt-timeline",
  title: "仕分け棚を入れ替える工程",
  ganttAxisMax: 5,
  ganttTickLabels: ["6月", "7月", "8月", "9月", "10月"],
  ganttBarEnd: "position",
  ganttBarThickness: "thin",
  ganttData: [
    { id: "survey", title: "調べる", startIdx: 0, endIdx: 0.75, startLabel: "6月", endLabel: "6月" },
    { id: "trial", title: "試す", startIdx: 3.6, endIdx: 4.2, startLabel: "9月", endLabel: "10月" },
  ],
})

| ganttBarEnd | 帯の終わり | |---|---| | cell (既定、型の外の値も) | 終わりの目盛りの右端まで。左右に余白を置く | | position | endIdx の位置まで。余白を置かず、厚みより短い帯は厚みと同じ幅にする。自動の尺は始まりと終わりの位置から決め、ganttAxisMax の外の帯は軸の右端へ寄せる |

| ganttBarThickness | 帯の厚み | |---|---| | thick (既定、型の外の値も) | 行の高さと 30 の小さい方 | | thin | 行の高さと 15.65 (行の名前の字 12 × 30 / 23) の小さい方 |

2 つの欄は別々に書ける。長さは値の意味、厚みは見た目なので分けている。 thin では担当者の字を描かない。帯の角の丸みは使う側の CSS (rx) で当てる。

ガントの寸法

任意の object 欄 ganttSize で、行名、目盛り、帯、節目、通常の依存線を SVG 座標の数で 部分指定できる。欄なしと空の object、部分指定で書かなかった要素は従来の計算を使う。

| 要素 | 制約と意味 | 書かない時の既定値 | |---|---|---| | taskLabelFontSize | 正の数。行名の字 | 12 | | taskLabelAlign | start / end。行名を揃える側 | end | | taskLabelX | 0 以上。図の左端から行名の揃え位置まで | 140 | | taskColumnWidth | 0 以上。図の左端から棒の描画面の左端まで | 156 | | timelinePaddingRight | 0 以上。棒の描画面の右端から図の右端まで | 48 | | tickFontSize | 正の数。目盛りの字 | 11 | | tickCount | 2 以上の整数。左右端を含む縦線の本数 | 尺と目盛り名から自動計算 | | barThickness | 正の数。帯の厚み | ganttBarThickness と行高から計算 | | milestoneFontSize | 正の数。節目と今日の札の字 | 11 | | milestoneRadius | 正の数。菱形の中心から頂点まで | 帯の厚み × 0.6 | | dependencyStrokeWidth | 正の数。上から下へ進む通常の依存線 | 帯の厚み × 3.5 / 30 |

ganttSize: {
  taskLabelFontSize: 23,
  taskLabelAlign: "start",
  taskLabelX: 36,
  taskColumnWidth: 330,
  timelinePaddingRight: 64,
  tickFontSize: 20,
  tickCount: 6,
  barThickness: 30,
  milestoneFontSize: 19,
  milestoneRadius: 18,
  dependencyStrokeWidth: 3.5,
}

taskColumnWidth と timelinePaddingRight の既定値は156と48である。 見本帳では taskColumnWidth: 330 と timelinePaddingRight: 64 を使う。 taskLabelX は行名の基準 x だけを表し、作業名列の幅を変えない。

数値の barThickness を書いた時は ganttBarThickness より優先する。どちらも書かない時は 従来の thick、ganttBarThickness: "thin" だけなら従来の 15.65 を使う。戻る依存線は dependencyStrokeWidth を読まず 2.4 のままである。

tickCount の線は描画面へ等間隔に置き、ganttTickLabels は左から各線間へ順に割り当てる。 名前が少ない残りは空、名前が多い末尾は描かない。縦線は既存の上限を保って最大 200 本にする。 明示寸法は figureSize への収まりを理由に縮めない。左右余白を引いた棒の描画幅が正でない時と、 収まらない字、帯、菱形、通常の依存線は visualValidate が知らせる。

主役の段と帯の斜線

漏斗の段 (funnelData)・ガントの帯 (ganttData)・内訳の帯の区分 (chartData) は、 emphasis: "primary" を書いた項目を主役として描く。主役の本体は tone の塗りを変えず、 同じ形の重ねに斜線を描く。重ねの role は漏斗が funnel-stage-hatch、ガントが gantt-bar-hatch、内訳の帯が chart-stacked-bar-slice-hatch で、本体には data-cdl-emphasis="primary" が付く。

ganttData: [
  {
    id: "design",
    title: "設計する",
    startIdx: 0,
    endIdx: 1,
    startLabel: "6月",
    endLabel: "7月",
    emphasis: "primary",
  },
]

内訳の帯は主役の系列の全時点の区画に重ねを描き、一覧の色見本には描かない。 chartData の emphasis を読むのは内訳の帯だけで、組み立て器 chart() はこの欄を渡さない。 ガントの節目も emphasis を読まない。"primary" 以外の値と欄を書かない項目は今までどおりで、 欄を書かない図の出力も変わらない。

既定の斜線は 45 度・線の幅 1.5・間隔 8 で、線色は --cdl-node-fill、未定義なら #ffffff。意匠ごとに変える時は画面に模様を 1 つ置いて重ねの fill を CSS で差し替える。 斜線を描かない意匠は重ねを消し、本体を data-cdl-emphasis で選ぶ。

/* 斜線を描く意匠は、画面に置いた模様へ差し替える */
[data-cdl-role="gantt-bar-hatch"],
[data-cdl-role="funnel-stage-hatch"],
[data-cdl-role="chart-stacked-bar-slice-hatch"] {
  fill: url(#my-hatch);
}

/* 斜線を描かない意匠は、重ねを消して本体を塗る */
.no-hatch :is([data-cdl-role="gantt-bar-hatch"], [data-cdl-role="funnel-stage-hatch"], [data-cdl-role="chart-stacked-bar-slice-hatch"]) {
  display: none;
}
.no-hatch [data-cdl-role="gantt-bar"][data-cdl-emphasis="primary"] {
  fill: #c8431f;
}

沈めた項目を飛ばして系列の色を配る

図表の項目は tone を書かない限り、並びの番号の系列色 (--cdl-chart-N、漏斗は段の順の --cdl-tone-*) で塗る。tone: "muted" の項目も番号を 1 つ使うため、沈めた項目の後ろの色は 1 つずつずれる。node に chartSeriesSkipMuted: true を書くと、muted の項目が番号を使わず、 後ろの項目が詰めて数えられる。

.node("delivery", {
  lane: "l",
  stack: 0,
  kind: "chart-stacked-bar",
  title: "配達の結果",
  chartData: [
    { id: "once", label: "一度で届いた", value: 85, tone: "muted" },
    { id: "again", label: "再配達", value: 13, emphasis: "primary" },
    { id: "returned", label: "戻った", value: 2 },
  ],
  chartStackedPeriods: [
    { label: "6月", values: [78, 19, 3] },
    { label: "7月", values: [80, 17, 3] },
    { label: "8月", values: [76, 21, 3] },
    { label: "9月", values: [82, 16, 2] },
    { label: "10月", values: [85, 13, 2] },
  ],
  chartStackedRateId: "again",
  chartStackedLegendPosition: "top",
  chartSeriesSkipMuted: true,
})

| 項目 | 欄なし | chartSeriesSkipMuted: true | |---|---|---| | 一度で届いた (muted) | --cdl-tone-muted | --cdl-tone-muted | | 再配達 | --cdl-chart-2 | --cdl-chart-1 | | 戻った | --cdl-chart-3 | --cdl-chart-2 |

  • 読む図種は chart-stacked-bar・funnel-stages・chart-line (chartLineSeries)・chart-pie・chart-waffle・chart-gauge (内訳の形)・chart-radial・chart-stat・chart-slope。
  • 傾き図は chartSlopeEmphasisIds に当たらず沈めた系列も番号を使わない。
  • muted 以外の tone を書いた項目は番号を 1 つ使う。
  • 1 つの図の中で、区画・前の帯・一覧・率の字、円と半円の今の輪と前の輪は同じ番号で塗る。
  • 系列色の 6 色を超えると先頭へ戻る。飛ばした後の 7 つ目は --cdl-chart-1 になる。
  • 書かない図と true 以外の値は今までどおり。既定を変えないのは、沈めた項目が番号を使う前提で並べた図の色が変わるため。
  • chart-bar・gantt-timeline・quadrant-matrix・tree-hierarchy は位置の番号で塗らないので読まない。

放射の図の見せ方

mind-map は mindForm で中心・枝・葉をまとめた見せ方を選べる。

| 値 | 描き方 | |---|---| | filled (既定) | 中心を tone の面と白の字、枝を外へ細くなる線、葉を字だけで描く | | outline | 中心を塗りなしの枠と墨の字、枝を一定の太さ、葉を枝と同じ色の下線付きで描く |

.node("redelivery", {
  lane: "l",
  stack: 0,
  kind: "mind-map",
  title: "再配達を減らす",
  w: 720,
  h: 480,
  mindForm: "outline",
  mindData: {
    rootId: "root",
    rootTitle: "再配達を減らす",
    branches: [
      { id: "place", title: "置き場所", parent: "root" },
      { id: "drop", title: "置き配", parent: "place" },
      { id: "locker", title: "宅配ロッカー", parent: "place" },
    ],
  },
})

outline の大きさは宅配の見本帳で共通だった比から決める。枝の太さは葉の字の大きさの 4.5/23、曲線と字および字と下線の外端の間は 6/23、字の基線から下線までは 12/23。 子を持つ箱の幅は名前の字の大きさの 220/29、中心の幅はその箱の 330/220 (= 1.5) 倍になる。 中心と子を持つ箱の rect は rx="12" と主線色を属性に持ち、stroke-width は中心 2.25、枝 1。 属性値を入口として使う側の CSS の rx・stroke-width・stroke が優先されるため、意匠ごとの 6・16・22 または角ごとの丸みと、中心の強調を含む枠の太さ・色へ上書きできる。

使う側の CSS は次の属性で意匠を当てられる。

| 属性 / role | 部品 | |---|---| | [data-cdl-mind-form="outline"] | 放射の図全体の g | | mind-root | 中心の rect | | mind-box | 子を持つ箱の rect | | mind-root-title / mind-box-title / mind-leaf-title | 中心・箱・葉の名前の text | | mind-node-subtitle | 補足の text | | mind-edge | 枝の path | | mind-leaf-underline | 葉の下線の line |

中心の枠の太さと面、中心と箱の角の丸み (rx は CSS で指定できる)、字の色は使う側の CSS の 役目になる。たとえば図面の意匠は次のように当てられる。

[data-cdl-mind-form="outline"] [data-cdl-role="mind-root"] {
  fill: rgba(227, 233, 234, 0.82);
  stroke-width: 2.25px;
  rx: 12px;
  ry: 12px;
}

枝の濃さを変える時は mind-edge と mind-leaf-underline の両方へ同じ値を当てる。下線は枝の 続きとして読むため、片方だけを変えない。欄を書かない図、"filled"、型の外の値は今までと 同じ出力になる。

ジャーニーの見せ方

journey-map は journeyForm で段、journeyLineForm で線、段の opportunityPosition で注記の置き場所を選ぶ。

| journeyForm | 段の見せ方 | | -------------- | ---------------------------------------------------------------------------------- | | bands (既定) | 色の帯、絵文字付きの段の名、番号付きの横の名前 | | rules | 段ごとの横の点線、字だけの段の名、番号なしの横の名前、段の名の字幅で決まる左の余白 |

| journeyLineForm | 線の形 | | ----------------- | ---------------- | | curve (既定) | 3 次ベジエの曲線 | | straight | 点を順に結ぶ直線 |

| opportunityPosition | 注記の置き場所 | | --------------------- | ------------------------------ | | below-chart (既定) | 図の下へ幅 110 の札で置く | | below-point | 点の真下へ枠の無い字だけで置く |

journeyLabels は気持ちの値を鍵にして、5 段の名前をまとめて書く。

任意の object 欄 journeySize は罫と点の左右余白を SVG 座標で部分指定する。罫、点、線、 横の名前、点の下の注記は合成後の同じ横座標を使う。明示値は狭い figureSize でも縮めず、 罫または点の範囲が収まらない時は visualValidate が知らせる。

| 要素 | 明示する値の意味 | 書かない時の既定値 | | --- | --- | --- | | plotPadding.left | 図の左端から罫の左端までの 0 以上の間 | 段名の字幅から求める従来式 | | plotPadding.right | 罫の右端から図の右端までの 0 以上の間 | 32 | | pointPadding.left | 罫の左端から最初の点までの 0 以上の間 | 従来の1列幅の半分 | | pointPadding.right | 最後の点から罫の右端までの 0 以上の間 | 従来の1列幅の半分 |

見本帳の値は左から 120 / 44 / 100 / 70 である。点が1件なら点の範囲の中央、2件以上なら 両端を含む等間隔へ置く。

.node("journey", {
  lane: "l",
  stack: 0,
  kind: "journey-map",
  journeyForm: "rules",
  journeyLineForm: "straight",
  journeySize: {
    plotPadding: { left: 120, right: 44 },
    pointPadding: { left: 100, right: 70 },
  },
  journeyLabels: {
    delighted: "最高",
    happy: "満足",
    neutral: "普通",
    frustrated: "不満",
    angry: "怒り",
  },
  journeyData: [
    { id: "apply", title: "申し込む", emotion: "happy" },
    { id: "wait", title: "集荷を待つ", emotion: "neutral" },
    { id: "carry", title: "運ばれる", emotion: "happy" },
    {
      id: "absent",
      title: "不在だった",
      emotion: "angry",
      opportunity: "不在票に気づかなかった",
      opportunityPosition: "below-point",
    },
    { id: "redeliver", title: "再配達を頼む", emotion: "frustrated" },
    { id: "receive", title: "受け取る", emotion: "delighted" },
  ],
})

rules の 4 つは 1 つの見せ方として配置が互いに依存するため、別々の欄にせずまとめて選ぶ。 rules は段名 19、横名 20、注記 18、段間 40、点半径 9、注記の下げ 34、主線 5、点輪郭 3.5 で描き、journey-line-glow は描かない。描画域の高さが 287 未満なら、これらと罫 1.25、 段名の左 36、最下段から横名基線 64 を 1 つの比で縮める。 罫の色は --cdl-row-divider、段の名の色は --cdl-text-dim で当てる。 主線・点輪郭・注記は同じ --cdl-tone-accent を使う。 欄を書かない図と型の外の値は、各表の既定で描く。 journeyLabels は 5 つの鍵が全て空白以外の文字列でなければ欄ごと使わない。

半円の固定の尺と目標と差

chart-gauge に chartGaugeValue を書くと、0 から max の固定の尺に今の値、 目標の印、前の値からの差を描ける。

.node("rate", {
  lane: "l",
  stack: 0,
  kind: "chart-gauge",
  title: "定時に届いた割合",
  chartGaugeValue: {
    max: 100,
    current: "{rate}",
    target: "{target}",
    previous: "{previous}",
    previousLabel: "先月",
  },
})

current、target、previous は数のほかに {名前} を受け、段の状態と tween に追随する。 状態参照の current が解けない時は固定の尺を保って 0 として描き、半円に data-cdl-unresolved="true" を付ける。 状態参照の target または previous が解けない時は対応する印または差の字だけを描かず、同じ未解決印を付ける。 数を直接書いた時の扱いと、max・previousLabel が状態を読まないことは変わらない。

| 書いた値 | 描く形 | |---|---| | 欄なし | 今までどおり chartData の内訳と合計を描く | | null、配列、文字、数 | 欄を書かなかったものとして内訳の形で描く | | max が有限の正の数でない、または current が有限の数でない | 欄ごと書かなかったものとして内訳の形で描く | | 上のどれにも当たらない | 固定の尺の形で描く |

| 欄 | 表示 | |---|---| | current | 中央に current / max の割合、弧に 0 から 1 の範囲へ収めた位置を使う | | max | 尺の端を 0 と max の実値で描く | | target | 0 以上 max 以下の有限の数だけ印を描く | | previous | (current - previous) / max の割合から % を外し、正の差に + を付ける | | previousLabel | 前後の空白を除いて {previousLabel}より +6 と描く。空・空白だけ・文字列でない値なら 前 |

| role | 既定の色 | |---|---| | chart-gauge-fixed-scale | --cdl-tone-muted を不透明度 0.35 で使う | | chart-gauge-arc | --cdl-chart-1 | | chart-gauge-target | --cdl-text | | chart-gauge-value | --cdl-text | | chart-gauge-delta | --cdl-chart-2 | | chart-gauge-scale-endpoint | --cdl-text-dim |

段の draw では今の値の弧だけが 9 時から伸び、尺・目標の印・字は最初から出る。 chartGaugeValue の図は chartData と datum の previous を読まない。

半円の寸法

chartGaugeSize は固定尺の半円の寸法を部分指定する任意 object で、外側の欄そのものを 書かない時の既定値は undefined である。空の object も欄なしと同じ自動計算を使う。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | arcThickness | 背景の尺と今の値の弧に共通する正の太さ | 外半径と内半径の従来の比から出す | | outerRadius | 弧の外側までの正の半径 | figureSize から出す | | plotTop | node の上端から弧の外周上端までの 0 以上の間 | 従来の配置から出す | | valueFontSize | 中央の割合の正の字 | 外半径から出す |

chartGaugeSize: {
  arcThickness: 34,
  outerRadius: 222,
  plotTop: 165,
  valueFontSize: 66,
}

見本帳の共通値は外半径 222、太さ 34、上位置 165、中央の字 66 である。 chartGaugeValue は尺・割合・目標・差の値を担い、chartGaugeSize はその固定尺の寸法だけを担う。 内訳の半円は chartGaugeSize を読まず、欄を書かない固定尺とともに従来の出力を保つ。 配置、描画、draw、visualValidate は同じ解決済みの中心・半径・太さを使う。 明示値は最後の一様縮小で変えず、収まらない時は visualValidate が知らせる。 0 以下の正寸法、負の plotTop、有限でない数は validate() が欄名と入力値を付けて拒む。 色、線端、filter、字の太さは CSS が担い、座標と path の d は CSS で作り直さない。 外半径の残差は図面 0、活版 0、図録 0、端末 -1、手描き 0、電飾 -2、浮彫 -18 である。 上位置の残差は図面 +2、活版 -1、図録 -2、端末 0、手描き -1、電飾 0、浮彫 +3 である。

木の箱と枝の見せ方

tree-hierarchy は、箱の形、枝の色、枝の先の印を独立した欄で選べる。

| 欄 | 値 | 描き方 | |---|---|---| | treeNodeForm | accent (既定) / frame | accent は根を色の面、他を段の色の枠と左の帯で描く。frame は根を含む全ての箱を同じ枠で描く | | treeEdgeTone | accent (既定) / depth | accent は全ての枝を 1 色、depth は段 d を系列色 d (--cdl-chart-d) で描き、6 段を超えると先頭へ戻る | | treeEdgeHead | none (既定) / triangle | none は印なし、triangle は子の箱へ下向きに入る枝の先へ塗った三角を置く |

.node("org", {
  lane: "l",
  stack: 0,
  kind: "tree-hierarchy",
  treeNodeForm: "frame",
  treeEdgeTone: "depth",
  treeEdgeHead: "triangle",
  treeData: [
    { id: "hq", title: "本社", subtitle: "全国 12 営業所" },
    { id: "east", title: "東日本", subtitle: "7 営業所", parent: "hq" },
  ],
})

frame は、名前の級を箱の基準の幅の 29/220、補足を名前の 19/29、基線の間を名前の 1.1 倍、箱の高さを名前の 3.1 倍にする。枠の太さ・角・影・字の色は使う側の CSS の役目である。 使う側は [data-cdl-tree-form="frame"] の箱と、tree-node-title、tree-node-subtitle、 tree-edge、tree-edge-head の各 data-cdl-role を選べる。

3 つの欄を書かない図と型の外の値を書いた図は、今までと同じ accent / accent / none で描く。

棒の寸法と上下の角

chart-bar の任意の object 欄 chartBarSize では、字、描画面の余白、全ての棒に使う幅を SVG 座標の数で部分指定できる。欄全体、plotPadding、各要素はいずれも省略でき、省略した値は 0.131.0 までの計算を使う。

外側の chartBarShape は、従来の上下2枚を重ねる split と、上2角だけを丸めた単一pathの top-rounded を選ぶ。書かない時の既定値は split である。

全て必須の object 欄 barCornerRadii は、棒の4隅を topLeft、topRight、 bottomRight、bottomLeft(左上・右上・右下・左下)の順で別々に指定する。各値は0以上の 有限の数で、4値の不足、負の数、数でない値、有限でない値は validate() が拒む。

barCornerRadii: {
  topLeft: 0,
  topRight: 8,
  bottomRight: 8,
  bottomLeft: 0,
}

この欄が効く図表は、chart-bar、funnel-stages の funnelForm: "proportional-bars"、 gantt-timeline の工程の帯、chart-stacked-bar の内訳の帯である。漏斗の既定の台形は棒では ないため、この欄を読まない。内訳の帯では最初の区画が左2隅、最後の区画が右2隅を受け持つ。 chart-bar で chartBarShape と両方を書いた時は barCornerRadii が chartBarShape より優先 される。欄を書かない4図表は従来の要素とSVG文字列を保つ。

大きすぎる4隅の値は、CSS の border-radius と同じ割合で縮める。上・右・下・左の各辺について、 辺の長さを隣り合う2隅の和で割り、最小の比が1未満なら4隅全てへその比を掛ける。和が0の辺は 比を求めず、全ての比が1以上なら入力値を保つ。幅か高さが0の棒は4隅を全て0にする。内訳の帯は 最初と最後の区画それぞれの幅と高さで同じ計算を行う。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | tickFontSize | 縦軸の目盛りの正の字の大きさ | 11 | | valueFontSize | 棒の上に置く値の正の字の大きさ | 12 | | labelFontSize | 横軸に置く名前の正の字の大きさ | 11 | | plotPadding.top | 図の上端から描画面までの 0 以上の間 | 34 | | plotPadding.right | 図の右端から描画面までの 0 以上の間 | 24 | | plotPadding.bottom | 図の下端から描画面までの 0 以上の間 | 44 | | plotPadding.left | 図の左端から描画面までの 0 以上の間 | 60 | | barWidth | 全ての棒に使う正の幅 | 本数、描画面の幅、棒と隙間の比 2.2 から出し、上限 96 | | cornerRadius | 棒の上角へ使う0以上の半径 | min(barWidth * 0.06, 8) |

字の既定値は 11 / 12 / 11、余白の既定値は上・右・下・左の順で 34 / 24 / 44 / 60、 自動の棒幅の上限は 96 である。見本の寸法は次のように書く。

chartBarShape: "top-rounded",
chartBarSize: {
  tickFontSize: 19,
  valueFontSize: 25,
  labelFontSize: 22,
  plotPadding: { top: 136.891, right: 32, bottom: 100, left: 82 },
  barWidth: 82.944,
  cornerRadius: 4,
}

明示した barWidth は本数や隙間の都合で縮めず、収まらない時は visualValidate が知らせる。 0 以下の字と棒幅、負の余白、有限でない数は validate() が欄名と入力値を付けて拒む。

1 本の棒は chart-bar role の組で、split では 同じ外接の chart-bar-top と chart-bar-bottom を別のclipで上半分と下半分に分ける。 top-rounded は chart-bar roleの 閉じたpath 1要素で、上2角だけに弧を置き、下2角を直角にする。両方が同じ cornerRadius の 解決値を使うため、欄を書かない時は棒幅の6%と8の小さい方になる。 barCornerRadii を書いた時は4隅の弧を持つ chart-bar roleのpath 1要素になる。

[data-cdl-role="chart-bar-top"] { rx: 10px; ry: 10px; }
[data-cdl-role="chart-bar-bottom"] { rx: 3px; ry: 3px; }

木と放射の寸法

tree-hierarchy の treeSize と mind-map の mindSize では、箱、字、間隔を SVG 座標の数で 部分指定できる。外側の欄を書かない時と空の object を書いた時は、0.130.0 までと同じ自動計算を 使う。要素を一部だけ書いた時も、残りは同じ自動計算で補う。

treeSize の形と既定値は次のとおり。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | nodeWidths | 根を 0 とした深さごとの正の幅。深い段では最後の値を繰り返す | 基準幅 140、字幅、区画の 92% から出す | | nodeHeight | 全段の札の正の高さ | frame は題の字の 3.1 倍、その他は 38 と段高の 70% の小さい方 | | titleFontSize | 題の字の正の大きさ | frame は基準幅の 29/220 倍、その他は根 13・子 12 | | subtitleFontSize | 副題の字の正の大きさ | frame は題の 19/29 倍、その他は 9 | | siblingGap | 同じ段の札の縁どうしの 0 以上の横の間 | 札の基準幅と段の隙間から出す | | levelGap | 隣り合う段の札の縁どうしの 0 以上の縦の間 | 描画高を段数で割り、札の高さを引く |

treeSize: {
  nodeWidths: [260, 240, 220],
  nodeHeight: 89.891,
  titleFontSize: 29,
  subtitleFontSize: 19,
  siblingGap: 180,
  levelGap: 60.109,
}

mindSize の形と既定値は次のとおり。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | contentOffset | 中心、全ての枝、全ての葉をまとめて動かす有限の { x, y }。正の x は右、正の y は下、負の x は左、負の y は上 | { x: 0, y: 0 } | | root.width | 中心の箱の正の幅 | outline は枝の幅の 1.5 倍、その他は 120 | | root.height | 中心の箱の正の高さ | 52 | | root.fontSize | 中心の字の正の大きさ | 15 | | branch.width | 子を持つ枝の箱の正の幅 | outline は枝の字 13 の 220/29 倍、その他は 130 | | branch.height | 子を持つ枝の箱の正の高さ | 枝の行間隔の 70% と 48 の小さい方 | | branch.fontSize | 子を持つ枝の字の正の大きさ | 13 | | leaf.fontSize | 葉の字の正の大きさ | 13 | | rootBranchGap | 中心と第 1 階層の枝の箱の縁どうしの 0 以上の横の間 | 24 を下限に、描画幅と子の深さから出す | | branchLeafGap | 枝の箱の縁と葉の下線の起点の 0 以上の横の間 | 24 を望ましい値に、描画幅と子の深さから出す | | branchRowGap | 同じ側の第 1 階層の枝の 0 以上の行間 | 描画高と、中心から枝までの横の伸びから出す | | branchRowOffset | 枝の行全体を中心から下へ動かす有限の量。負なら上 | 0 | | leafRowGap | 同じ枝に属する葉の 0 以上の行間 | 枝全体の行間隔 | | leafRowOffset | 葉の行全体を親の枝から下へ動かす有限の量。負なら上 | 0 |

mindSize: {
  contentOffset: { x: 20, y: 22 },
  root: { width: 330, height: 60.891, fontSize: 29 },
  branch: { width: 220, height: 60.891, fontSize: 29 },
  leaf: { fontSize: 23 },
  rootBranchGap: 155,
  branchLeafGap: 70,
  branchRowGap: 290,
  branchRowOffset: 10,
  leafRowGap: 92,
  leafRowOffset: 6,
}

左または上へ動かす時は contentOffset: { x: -20, y: -22 } のように負の数を書く。 contentOffset は中心、枝の線と箱、葉の字と下線を同じ量だけ動かす。 図の左上に置く種別の字 figureKindLabel は動かさない。

figureSize は図全体の描画領域を決め、treeSize と mindSize はその内側の部品を決める。 明示した寸法は名前の幅、区画の割付、最後の一様縮小では変えない。描画領域へ収まらない場合も 縮めず、contentOffset でも viewBox を広げない。visualValidate がはみ出しや重なりを知らせる。 0 以下の正寸法、負の間隔、有限でない数、 空の nodeWidths は validate() が理由と欄名を付けて拒む。色、影、角、枠と枝の太さ、書体は この 2 欄の役目に含めない。

階層図とマインドマップの種類札

tree-hierarchy と mind-map は、任意の object 欄 figureKindLabel で図の内側左上に種類札を 描ける。外側の欄を書かない時の既定値は undefined で、要素を描かず従来の出力を保つ。 text は必須で、空または空白だけなら描かない。text では {名前} の値を差し込める。

| 要素 | 明示する値 | 書かない時 | |---|---|---| | text | 種類札に描く空でない文字列 | 必須 | | x | 図の左端から札の左端までの有限の距離 | 0 | | y | 図の上端から字の基線までの有限の距離 | 34 | | fontSize | 正の有限数 | 17 | | fontWeight | 正の有限数 | 500 | | letterSpacing | 0 以上の有限数 | 2 |

figureKindLabel: { text: "tree · 階層図" }
figureKindLabel: { text: "mind · マインドマップ" }

札は JetBrains Mono で描き、role figure-kind-label (data-cdl-role="figure-kind-label") を持つ。 色は座標を変えず、使う側が --cdl-figure-kind-label へ意匠ごとの値を当てる。未指定時は --cdl-text-dim、さらにその未指定時は #5a6270 を使う。

[data-cdl-role="figure-kind-label"] {
  --cdl-figure-kind-label: #4d7187;
}

明示した位置と字の寸法は figureSize への収まりを理由に縮めたり移動したりしない。 描画と visualValidate は同じ解決値を使い、札の外接が描画領域から出る時は node-inside-viewbox の error を返す。非有限の位置、0 以下の字の大きさと太さ、負の字間は、 validate() が欄名と入力値を付けて拒む。他の図の種類へ札を自動生成しない。

端末風の役割要素

任意 object の terminalDecoration は、色や意匠名を持たず、利用側の CSS が選ぶ役割要素だけを 出す。外側の欄を書かない時は undefined、各要素を書かない時は false と同じで、既存 SVG を 変えない。

| 要素 | 対応する図 | true の時 | |---|---|---| | windowControls | mind-map の主役 | 半径5・中心間20の3個を幅52・高さ12へ置き、terminal-window-control と close / minimize / maximize の属性を付ける | | cursor | mind-map の主役 | 描画済みの題の後ろ6へ太さ400の ▋ を terminal-cursor として置く | | rowOrdinal | chart-pie の table + value、chart-waffle の右一覧 | 1からの番号を15・太さ400・幅16の右寄せで terminal-row-ordinal として置く |

番号を出す行では、既存の印・名前・値を terminal-row-content の1組へまとめる。端末 CSS は 番号を表示してこの組を30右へ動かす。窓の丸を出す主役では、題と字送りを terminal-title-content の1組へまとめ、CSS で68右へ動かす。他の意匠は3種類の飾りを隠し、 2つの組を動かさないため、欄を書く前の座標を保てる。

terminalDecoration: {
  windowControls: true,
  cursor: true,
  rowOrdinal: true,
}
[data-cdl-role="terminal-window-control"],
[data-cdl-role="terminal-cursor"],
[data-cdl-role="terminal-row-ordinal"] { display: none; }

.terminal [data-cdl-role="terminal-window-control"],
.terminal [data-cdl-role="terminal-cursor"],
.terminal [data-cdl-role="terminal-row-ordinal"] { display: initial; }
.terminal [data-cdl-terminal-control="close"] { fill: #ff5f57; }
.terminal [data-cdl-terminal-control="minimize"] { fill: #febc2e; }
.terminal [data-cdl-terminal-control="maximize"] { fill: #28c840; }
.terminal [data-cdl-role="terminal-cursor"] { fill: #4ade80; }
.terminal [data-cdl-role="terminal-row-ordinal"] { fill: #3f5a49; }
.terminal [data-cdl-role="terminal-title-content"] { transform: translateX(68px); }
.terminal [data-cdl-role="terminal-row-content"] { transform: translateX(30px); }

visualValidate は上の移動量を描画と同じ解決値へ当て、表示時の見出しと一覧の外接が箱や figureSize を越える場合に知らせる。背景格子、書体、線種、配色はこの欄の対象外である。

四象限の区画名と寸法

四象限の四隅の区画名は、それぞれの <text> に付く data-cdl-role="quadrant-label" で選べる。点の札の quadrant-item、補足の quadrant-item-subtitle、省略表示の quadrant-more とは別の role である。

quadrantLabelPosition: "outside-corners" は、左の区画名を面の左辺から12の左寄せ、右を 右辺から12の右寄せ、上の基線を上辺から28、下を下辺から14に置く。欄を書かない時は、 今までどおり各半区画の中央へ置く。

quadrantSize は次の要素を部分指定できる。書かない要素は0.131.0までの自動計算を使い、 明示値は figureSize に収まらなくても縮めない。その場合は visualValidate がはみ出しを知らせる。

| 要素 | 条件 | 書かない時 | |---|---|---| | plotOffset.x / plotOffset.y | 0以上の有限数 | 軸名から出す左右余白 / 上40 | | plotSize | 正の有限数 | 左右余白を引いた幅 / 上下余白を引いた高さ | | pointRadius | 正の有限数 | 5 | | pointFontSize | 正の有限数 | 13 | | pointLabelGap | 0以上の有限数 | 6 | | quadrantFontSize | 正の有限数 | 13 | | axisFontSize | 正の有限数 | 12 |

見本帳で使う共通値は、左 / 上 / 一辺が 70 / 80.891 / 325.109、点の半径11、点名19、 点との間9、区画名17、軸名18である。左・上・一辺は7意匠の中央値で、意匠別の残差は次のとおり。

| 意匠 | 左位置 | 共通70との差 | 上位置 | 共通80.891との差 | 面の大きさ | 共通325.109との差 | |---|---:|---:|---:|---:|---:|---:| | 図面 | 70 | 0 | 76.891 | -4 | 332.109 | +7 | | 活版 | 70 | 0 | 79.891 | -1 | 326.109 | +1 | | 図録 | 70 | 0 | 81.891 | +1 | 323.109 | -2 | | 端末 | 71 | +1 | 73.5 | -7.391 | 332.5 | +7.391 | | 手描き | 70 | 0 | 80.891 | 0 | 325.109 | 0 | | 電飾 | 72 | +2 | 80.891 | 0 | 324.109 | -1 | | 浮彫 | 88 | +18 | 83.891 | +3 | 308.109 | -17 |

quadrantLabelPosition: "outside-corners",
quadrantSize: {
  plotOffset: { x: 70, y: 80.891 },
  plotSize: 325.109,
  pointRadius: 11,
  pointFontSize: 19,
  pointLabelGap: 9,
  quadrantFontSize: 17,
  axisFontSize: 18,
}

面、十字軸、区画名、点、点名、軸名と visualValidate は同じ解決済み寸法を読む。 CSSは面や点を transform で拡縮せず、色、線、字形など座標を変えない意匠だけを担う。

四象限の点の名前の向き

quadrantPointLabelSide: "right" を書くと、座標で置いた点の名前と補足を見本と同じく点の右に置ける。

.node("delivery-quadrant", {
  lane: "all",
  stack: 0,
  kind: "quadrant-matrix",
  title: "打ち手の手間と効き目",
  posX: 320,
  posY: 240,
  posW: 640,
  posH: 480,
  quadrantPointLabelSide: "right",
  quadrantData: {
    xAxis: { left: "手間 小", right: "手間 大" },
    yAxis: { bottom: "効き目 小", top: "効き目 大" },
    quadrantLabels: {
      topLeft: "先にやる",
      topRight: "計画してやる",
      bottomLeft: "ついでにやる",
      bottomRight: "やらない",
    },
    items: [
      { id: "okihai", title: "置き配", at: { x: 0.2, y: 0.82 } },
      { id: "notice", title: "前日に知らせる", at: { x: 0.3, y: 0.62 } },
      { id: "locker", title: "宅配ロッカー", at: { x: 0.7, y: 0.7 } },
      { id: "slip", title: "不在票を電子に", at: { x: 0.22, y: 0.32 } },
      { id: "night", title: "夜の便", at: { x: 0.76, y: 0.2 } },
    ],
  },
})

| 値 | 点の名前と補足の置き方 | |---|---| | auto、欄なし、型の外の値 | at.x が 0.5 以上なら点の左、0.5 未満なら点の右 | | right | 点の右。ただし、下の2条件のどちらかに当たる点だけ左 |

right でも、名前と補足の広い方が札の右端を越える時と、名前と補足を合わせた外接が端点形の横軸の右の名前に重なる時は左に置く。 描画域の右端は越えてよいので、札に収まる範囲では右側の点も見本と同じ向きになる。

この欄はatを書いた項目だけが読み、象限に積む項目は読まない。 同じ座標に置いた点どうしの名前は重なったまま描き、名前どうしの重なりはほどかないため、書き手が座標を少しずらして置くことを勧める。

凡例の項目

legend の項目は tone で --cdl-tone-* の色を選び、lineStyle で端を持つ線を実線または丸い点の並びにできる。 線端は18×22の白抜き三角と30×18の白抜き・塗った菱、rounded-box は46×32・角6・太さ2の実線で描く。 mark を省いた項目は文字だけになり、lead は先頭語を太字、align: "end" は凡例行の右端へ揃える。 legend-item・legend-mark・legend-text roleとdata-cdl-legend-markで選べ、これらの欄を書かない凡例の出力は変わらない。

図全体の任意object欄legendOffsetは、自動配置した凡例全体へ差分を1度だけ足す。 xは正で右・負で左、yは正で下・負で上へ動かし、どちらも有限の数を受ける。 各軸の既定値は0