PythonIDE Docs
中文
简体中文

图表与画布 API

Chart、Canvas、DrawingContext 和 Path。

本页覆盖 ChartCanvasDrawingContextPathChart 用系统图表展示结构化数据;CanvasDrawingContext 用命令列表画 2D 图形;Path 用矢量路径命令画自定义形状。

#什么时候用

目标首选 API说明
柱状、折线、面积、散点图Chart数据是字典列表,字段由 xyseries 指定。
简单 2D 绘图Canvas + DrawingContext矩形、圆、线、文本、渐变、路径等命令。
自定义矢量形状Path三角形、曲线、弧线、可填充或描边的路径。
实时高频绘制Canvas + 稳定命令列表避免每次 body() 重建大量命令。

#Chart

Chart(data=None, x='x', y='y', type='bar', color=None, series=None)

API签名分类
ChartChart(data: Optional[Sequence[Dict[str, Any]]] = None, x: str = 'x', y: str = 'y', type: str = 'bar', color: Optional[ColorLike] = None, series: Optional[str] = None)media
python
import appui


def body():
    rows = [
        {"day": "Mon", "value": 3},
        {"day": "Tue", "value": 7},
        {"day": "Wed", "value": 5},
        {"day": "Thu", "value": 9},
    ]

    return appui.NavigationStack(
        appui.Chart(
            data=rows,
            x="day",
            y="value",
            type="bar",
            color="systemBlue",
        )
        .frame(height=240)
        .padding()
        .navigation_title("Chart")
    )


appui.run(body)

#多序列示例

python
import appui


def body():
    data = [
        {"month": "Jan", "value": 10, "category": "A"},
        {"month": "Jan", "value": 20, "category": "B"},
        {"month": "Feb", "value": 14, "category": "A"},
        {"month": "Feb", "value": 18, "category": "B"},
        {"month": "Mar", "value": 22, "category": "A"},
        {"month": "Mar", "value": 16, "category": "B"},
    ]

    return appui.NavigationStack(
        appui.Chart(
            data=data,
            x="month",
            y="value",
            series="category",
            type="line",
        )
        .frame(height=240)
        .padding()
        .navigation_title("Series")
    )


appui.run(body)

#Canvas

Canvas(width=300, height=300, commands=None, context=None)

API签名分类
CanvasCanvas(width: float = 300, height: float = 300, commands: Optional[Sequence[Dict[str, Any]]] = None, context: Optional[DrawingContext] = None)drawing
python
import appui


def make_context():
    ctx = appui.DrawingContext()
    ctx.gradient_rect(0, 0, 240, 140, colors=["systemBlue", "systemTeal"])
    ctx.rounded_rect(20, 20, 200, 100, corner_radius=16, color="systemBackground", fill=True)
    ctx.fill_text("Canvas", 72, 76, color="label", font_size=22)
    ctx.line(40, 98, 200, 98, color="separator", line_width=2)
    return ctx


def body():
    return appui.NavigationStack(
        appui.Canvas(width=240, height=140, context=make_context())
        .frame(width=240, height=140)
        .padding()
        .navigation_title("Canvas")
    )


appui.run(body)

#DrawingContext 方法

DrawingContext 的每个方法都会向 commands 追加一个公开命令字典,并返回自身,方便链式调用。

API签名所属类型
fill_rectfill_rect(x: float, y: float, width: float, height: float, color: ColorLike = 'black') -> SelfDrawingContext
stroke_rectstroke_rect(x: float, y: float, width: float, height: float, color: ColorLike = 'black', line_width: float = 1, **kwargs: Any) -> SelfDrawingContext
fill_circlefill_circle(cx: float, cy: float, radius: float, color: ColorLike = 'black') -> SelfDrawingContext
stroke_circlestroke_circle(cx: float, cy: float, radius: float, color: ColorLike = 'black', line_width: float = 1, **kwargs: Any) -> SelfDrawingContext
fill_ellipsefill_ellipse(x: float, y: float, width: float, height: float, color: ColorLike = 'black') -> SelfDrawingContext
stroke_ellipsestroke_ellipse(x: float, y: float, width: float, height: float, color: ColorLike = 'black', line_width: float = 1, **kwargs: Any) -> SelfDrawingContext
lineline(x1: float, y1: float, x2: float, y2: float, color: ColorLike = 'black', line_width: float = 1, **kwargs: Any) -> SelfDrawingContext
fill_textfill_text(text: str, x: float, y: float, color: ColorLike = 'black', font_size: float = 16, **kwargs: Any) -> SelfDrawingContext
fill_pathfill_path(points: Sequence[Tuple[float, float]], color: ColorLike = 'black', close: bool = True) -> SelfDrawingContext
stroke_pathstroke_path(points: Sequence[Tuple[float, float]], color: ColorLike = 'black', line_width: float = 1, close: bool = False, **kwargs: Any) -> SelfDrawingContext
arcarc(cx: float, cy: float, radius: float, start_angle: float = 0, end_angle: float = 360, color: ColorLike = 'black', line_width: float = 1, fill: bool = False, **kwargs: Any) -> SelfDrawingContext
rounded_rectrounded_rect(x: float, y: float, width: float, height: float, corner_radius: float = 8, color: ColorLike = 'black', line_width: float = 1, fill: bool = True, **kwargs: Any) -> SelfDrawingContext
gradient_rectgradient_rect(x: float, y: float, width: float, height: float, colors: Optional[Sequence[ColorLike]] = None, vertical: bool = True) -> SelfDrawingContext

#命令字段

如果直接传 commands,使用下面的公开字段:

op主要字段
fill_rect / stroke_rectxywhclw
fill_circle / stroke_circlecxcyrclw
fill_ellipse / stroke_ellipsexywhclw
linex1y1x2y2clw
fill_texttxycfs
fill_path / stroke_pathptsccloselw
arccxcyrsaeaclwfill
rounded_rectxywhcrclwfill
gradient_rectxywhcolorsvertical
python
import appui

ctx = appui.DrawingContext()
ctx.fill_rect(0, 0, 10, 10, color="systemRed")
ctx.stroke_rect(10, 0, 10, 10, color="systemBlue", line_width=2)
ctx.fill_circle(50, 50, 20, color="systemGreen")
ctx.line(0, 100, 100, 100, color="systemOrange", line_width=3)
ctx.fill_text("Hi", 5, 105, color="label", font_size=14)
assert len(ctx.commands) == 5

#Path

Path(commands=None, fill=None, stroke=None, line_width=None)

API签名分类
PathPath(commands: Optional[Sequence[Dict[str, Any]]] = None, fill: Optional[ColorLike] = None, stroke: Optional[ColorLike] = None, line_width: Optional[float] = None)drawing

Path 命令结构:

命令键结构行为
move[x, y]移动当前点。
line[x, y]添加直线。
curve{"to": [x, y], "control1": [x, y], "control2": [x, y]?}二次或三次贝塞尔曲线。
arc{"cx": x, "cy": y, "r": r, "start": deg, "end": deg, "clockwise": bool}弧线。
close任意真值闭合路径。
python
import appui


def body():
    commands = [
        {"move": [40, 10]},
        {"line": [80, 70]},
        {"line": [0, 70]},
        {"close": True},
    ]

    return appui.NavigationStack(
        appui.Path(
            commands=commands,
            fill="systemOrange",
            stroke="label",
            line_width=2,
        )
        .frame(width=100, height=90)
        .padding()
        .navigation_title("Path")
    )


appui.run(body)

#与相邻 API 的区别

API不同点
Chart vs CanvasChart 负责数据可视化和坐标轴;Canvas 只画你给的图形命令。
Canvas vs PathCanvas 可以混合矩形、圆、文字、渐变;Path 专注一个可填充/描边的矢量形状。
Path vs Rectangle / Circle常见形状用形状 API;不规则图形才用 Path
Canvas 命令 vs DrawingContext直接命令适合从数据生成;DrawingContext 适合手写绘图逻辑。

#常见错误

错误正确做法
每次 body() 都重新生成大量静态命令。静态命令放到模块级常量或函数缓存,状态变化只更新必要数据。
Chartx / y 字段名和数据字典不匹配。统一字段名,缺失值先清洗再传入。
Chart 展示非数值 y 值。y 对应字段应是数值。
Canvas(width,height) 和外层 .frame(...) 尺寸冲突。两者保持一致,或明确只让外层控制显示尺寸。
Canvas 手写原生控件。表单、按钮、列表、进度优先用 AppUI 原生控件。

#相关文档

文档用途
形状 APIRectangle、RoundedRectangle、Circle、Capsule、Ellipse、Color。
性能指南大数据图表和高频绘制的刷新边界。
UI 模式图表和媒体在 MiniApp 页面中的布局选择。