npx -y @larksuite/whiteboard-cli@^0.2.0 渲染width * height 必须与数值成比例height 和 y 坐标传给所有子节点(扣除标签预留空间后)width:子width = 父width * (子数值 / 父总数值)x 坐标依次向右累加width 和 x 坐标传给所有子节点height:子height = 父height * (子数值 / 父总数值)y 坐标依次向下累加每个非叶子节点的矩形,顶部必须预留 30-40px 放置分类标签。子矩形从父矩形的 y + 35 开始放置,可用高度为 父height - 35。
示例:父矩形 { x: 40, y: 40, height: 700 },则:
y: 46(留 6px 上边距)y: 75 开始放置(40 + 35)700 - 35 = 6652 层 treemap:3 个分类(硬件 40、软件 35、服务 25),各含 2 个子项。
根矩形 1100x700,第一层水平切分 width,第二层垂直切分 height。
{
"version": 2,
"nodes": [
{
"type": "rect",
"id": "root",
"x": 40, "y": 40,
"width": 1100, "height": 700,
"borderWidth": 2, "borderRadius": 6
},
{
"type": "text",
"x": 48, "y": 46,
"width": 1084, "height": 24,
"text": "{{ROOT_TITLE}}",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-A",
"x": 40, "y": 75,
"width": 440, "height": 665,
"borderWidth": 2, "borderRadius": 6
},
{
"type": "text",
"x": 48, "y": 81,
"width": 424, "height": 24,
"text": "{{CAT_A}}",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-A-item-1",
"x": 40, "y": 110,
"width": 440, "height": 380,
"borderRadius": 4
},
{
"type": "text",
"x": 48, "y": 116,
"width": 424, "height": 24,
"text": "{{ITEM_A1}} (24)",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-A-item-2",
"x": 40, "y": 490,
"width": 440, "height": 250,
"borderRadius": 4
},
{
"type": "text",
"x": 48, "y": 496,
"width": 424, "height": 24,
"text": "{{ITEM_A2}} (16)",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-B",
"x": 480, "y": 75,
"width": 385, "height": 665,
"borderWidth": 2, "borderRadius": 6
},
{
"type": "text",
"x": 488, "y": 81,
"width": 369, "height": 24,
"text": "{{CAT_B}}",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-B-item-1",
"x": 480, "y": 110,
"width": 385, "height": 380,
"borderRadius": 4
},
{
"type": "text",
"x": 488, "y": 116,
"width": 369, "height": 24,
"text": "{{ITEM_B1}} (20)",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-B-item-2",
"x": 480, "y": 490,
"width": 385, "height": 285,
"borderRadius": 4
},
{
"type": "text",
"x": 488, "y": 496,
"width": 369, "height": 24,
"text": "{{ITEM_B2}} (15)",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-C",
"x": 865, "y": 75,
"width": 275, "height": 665,
"borderWidth": 2, "borderRadius": 6
},
{
"type": "text",
"x": 873, "y": 81,
"width": 259, "height": 24,
"text": "{{CAT_C}}",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-C-item-1",
"x": 865, "y": 110,
"width": 275, "height": 399,
"borderRadius": 4
},
{
"type": "text",
"x": 873, "y": 116,
"width": 259, "height": 24,
"text": "{{ITEM_C1}} (15)",
"fontSize": 14
},
{
"type": "rect",
"id": "cat-C-item-2",
"x": 865, "y": 509,
"width": 275, "height": 231,
"borderRadius": 4
},
{
"type": "text",
"x": 873, "y": 515,
"width": 259, "height": 24,
"text": "{{ITEM_C2}} (10)",
"fontSize": 14
}
]
}
面积比例验证(第一层水平切分 width):
此场景必须用 .cjs 脚本生成。Agent 使用时只需修改 data 树,其余坐标与矩形面积自动递归计算。
const { writeFileSync } = require('fs');