npx -y @larksuite/whiteboard-cli@^0.2.0 渲染height = (value / maxValue) * chartHeighty = originY - height白板坐标系中,X 轴向右为正,Y 轴向下为正。因此图表的"底部原点"实际上拥有最大的 Y 坐标,图形向上生长时 Y 坐标在不断减小。
chartHeight 和宽度 chartWidth(originX, originY)maxValueheight = (value / maxValue) * chartHeighty = originY - heightslotWidth = chartWidth / barCountbarGap(推荐 slotWidth 的 25%-30%)barWidth = slotWidth - barGapx = originX + i * slotWidth + barGap / 2gridY = originY - (tickValue / maxValue) * chartHeight以下示例:3 根柱子,数据 [120, 200, 150],maxValue=200,originX=80, originY=480, chartWidth=900, chartHeight=400。
刻度:0, 50, 100, 150, 200(每 50 一格,gridInterval = 80px)
{
"version": 2,
"nodes": [
{ "type": "rect", "x": 0, "y": 0, "width": 1100, "height": 580 },
{ "type": "text", "x": 80, "y": 10, "width": 900, "height": "fit-content",
"text": "季度销售额对比", "fontSize": 24, "textAlign": "center" },
{ "type": "text", "x": 10, "y": 40, "width": 60, "height": "fit-content",
"text": "万元", "fontSize": 12, "textAlign": "center" },
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 480 }, "to": { "x": 80, "y": 55 },
"lineShape": "straight", "lineWidth": 2, "endArrow": "arrow"
}},
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 480 }, "to": { "x": 1000, "y": 480 },
"lineShape": "straight", "lineWidth": 2, "endArrow": "arrow"
}},
{ "type": "connector", "connector": {
"from": { "x": 70, "y": 480 }, "to": { "x": 80, "y": 480 },
"lineShape": "straight", "lineWidth": 1,
"startArrow": "none", "endArrow": "none"
}},
{ "type": "text", "x": 20, "y": 470, "width": 50, "height": 20,
"text": "0", "fontSize": 12, "textAlign": "right" },
{ "type": "connector", "connector": {
"from": { "x": 70, "y": 400 }, "to": { "x": 80, "y": 400 },
"lineShape": "straight", "lineWidth": 1,
"startArrow": "none", "endArrow": "none"
}},
{ "type": "text", "x": 20, "y": 390, "width": 50, "height": 20,
"text": "50", "fontSize": 12, "textAlign": "right" },
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 400 }, "to": { "x": 980, "y": 400 },
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
"startArrow": "none", "endArrow": "none"
}},
{ "type": "connector", "connector": {
"from": { "x": 70, "y": 320 }, "to": { "x": 80, "y": 320 },
"lineShape": "straight", "lineWidth": 1,
"startArrow": "none", "endArrow": "none"
}},
{ "type": "text", "x": 20, "y": 310, "width": 50, "height": 20,
"text": "100", "fontSize": 12, "textAlign": "right" },
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 320 }, "to": { "x": 980, "y": 320 },
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
"startArrow": "none", "endArrow": "none"
}},
{ "type": "connector", "connector": {
"from": { "x": 70, "y": 240 }, "to": { "x": 80, "y": 240 },
"lineShape": "straight", "lineWidth": 1,
"startArrow": "none", "endArrow": "none"
}},
{ "type": "text", "x": 20, "y": 230, "width": 50, "height": 20,
"text": "150", "fontSize": 12, "textAlign": "right" },
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 240 }, "to": { "x": 980, "y": 240 },
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
"startArrow": "none", "endArrow": "none"
}},
{ "type": "connector", "connector": {
"from": { "x": 70, "y": 160 }, "to": { "x": 80, "y": 160 },
"lineShape": "straight", "lineWidth": 1,
"startArrow": "none", "endArrow": "none"
}},
{ "type": "text", "x": 20, "y": 150, "width": 50, "height": 20,
"text": "200", "fontSize": 12, "textAlign": "right" },
{ "type": "connector", "connector": {
"from": { "x": 80, "y": 160 }, "to": { "x": 980, "y": 160 },
"lineShape": "straight", "lineWidth": 1, "lineStyle": "dashed",
"startArrow": "none", "endArrow": "none"
}},
{ "type": "rect", "id": "bar-0", "x": 120, "y": 240,
"width": 220, "height": 240, "borderRadius": 4 },
{ "type": "text", "x": 120, "y": 215,
"width": 220, "height": 20,
"text": "120", "fontSize": 14, "textAlign": "center" },
{ "type": "text", "x": 120, "y": 490,
"width": 220, "height": 30,
"text": "Q1", "fontSize": 14, "textAlign": "center" },
{ "type": "rect", "id": "bar-1", "x": 420, "y": 80,
"width": 220, "height": 400, "borderRadius": 4 },
{ "type": "text", "x": 420, "y": 55,
"width": 220, "height": 20,
"text": "200", "fontSize": 14, "textAlign": "center" },
{ "type": "text", "x": 420, "y": 490,
"width": 220, "height": 30,
"text": "Q2", "fontSize": 14, "textAlign": "center" },
{ "type": "rect", "id": "bar-2", "x": 720, "y": 180,
"width": 220, "height": 300, "borderRadius": 4 },
{ "type": "text", "x": 720, "y": 155,
"width": 220, "height": 20,
"text": "150", "fontSize": 14, "textAlign": "center" },
{ "type": "text", "x": 720, "y": 490,
"width": 220, "height": 30,
"text": "Q3", "fontSize": 14, "textAlign": "center" }
]
}
坐标推导验证:
此场景必须用 .cjs 脚本生成。Agent 使用时只需修改 data 数组,其余坐标与柱体高度全自动计算。
const { writeFileSync } = require('fs');