架构
分层设计、ICanvas2D 契约、渲染管线与原生 App 扩展指南。
分层设计
| 层 | 职责 | 位置 |
|---|---|---|
| core | 纯引擎:ICanvas2D 契约、比例尺、布局、坐标轴、图例、ChartBase 渲染管线(零平台依赖) | lib/core/ |
| charts | 图表策略类:LineChart / BarChart / PieChart / RadarChart,只依赖 core | lib/charts/ |
| adapters | 平台差异:web / miniprogram(wx·my·tt)/ native(契约占位) | lib/adapters/ |
| factory | createChart 按 option.type 分发到图表策略 | lib/factory.ts |
| component | TcChart 声明式组件(可选,依赖 transone) | lib/component.ts |
上层只依赖下层的公开接口,平台差异被收敛在 adapters——新增一个端只需要实现一个适配器,图表层零改动。
ICanvas2D 契约
跨端解耦的唯一边界是ICanvas2D(lib/core/canvas.ts):图表所需的最小 Canvas 2D 子集,约 20 个方法。刻意不含Path2D;fill / stroke无参调用;包含measureText / createLinearGradient。Web 标准 2D context 天然满足;小程序 Canvas 2D 节点经node.getContext('2d')适配;原生端按契约实现即可。
typescript
// 契约核心形状(精简示意)
interface ICanvas2D {
beginPath(): void;
moveTo(x: number, y: number): void;
lineTo(x: number, y: number): void;
bezierCurveTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): void;
arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;
fill(): void;
stroke(): void;
measureText(text: string): { width: number };
createLinearGradient(x0: number, y0: number, x1: number, y1: number): IGradient;
// ... 见 lib/core/canvas.ts 完整定义
}渲染管线
ChartBase 统一渲染顺序,各图表只实现 drawSeries:
text
save → scale(dpr) → clear → 背景 → 布局(title/legend/轴区逐层扣除)
→ 标题 → 图例 → 坐标轴(仅笛卡尔类) → drawSeries → restore- seriesColor 按索引取 DEFAULT_PALETTE 色板,显式 color 优先。
- 数值轴自动 nice 刻度;类目轴无标签时不预留轴区。
- 图例:series 带 name 且未显式配置时,默认 top 显示。
原生 App 扩展指南
引擎与平台完全解耦:原生端实现ICanvas2D(Skia / ArkUI Canvas / 原生桥),再通过resolveNativeCanvas(host)注入即可,图表层零改动。
typescript
import { createChart } from 'transone-chart';
import { resolveNativeCanvas } from 'transone-chart/adapters';
// 原生桥层:把原生画布上下文包装成 ICanvas2D,并实现 NativeCanvasHost
const host = {
width: 375,
height: 260,
pixelRatio: 2,
getContext(type: '2d') {
return { beginPath() {}, moveTo() {}, /* ...实现 ICanvas2D */ };
},
};
const chart = createChart(resolveNativeCanvas(host), option);
chart.render();快速失败
adapters/native.ts 当前是契约占位:未实现时调用会显式抛错,绝不静默降级,保证原生端不会出现"看起来渲染了其实空白"的隐性故障。