transone-chart 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/README.md +181 -0
  2. package/dist/adapters/index.d.ts +7 -0
  3. package/dist/adapters/miniprogram.d.ts +44 -0
  4. package/dist/adapters/native.d.ts +28 -0
  5. package/dist/adapters/types.d.ts +27 -0
  6. package/dist/adapters/web.d.ts +13 -0
  7. package/dist/charts/bar.d.ts +25 -0
  8. package/dist/charts/index.d.ts +4 -0
  9. package/dist/charts/line.d.ts +20 -0
  10. package/dist/charts/pie.d.ts +14 -0
  11. package/dist/charts/radar.d.ts +16 -0
  12. package/dist/component.d.ts +41 -0
  13. package/dist/core/axis.d.ts +47 -0
  14. package/dist/core/canvas.d.ts +61 -0
  15. package/dist/core/chart.d.ts +69 -0
  16. package/dist/core/layout.d.ts +58 -0
  17. package/dist/core/legend.d.ts +26 -0
  18. package/dist/core/scale.d.ts +67 -0
  19. package/dist/core/text.d.ts +20 -0
  20. package/dist/factory.d.ts +22 -0
  21. package/dist/index.d.ts +29 -0
  22. package/dist/index.js +17 -0
  23. package/dist/index.js.map +49 -0
  24. package/dist/types.d.ts +180 -0
  25. package/lib/adapters/index.ts +18 -0
  26. package/lib/adapters/miniprogram.ts +146 -0
  27. package/lib/adapters/native.ts +39 -0
  28. package/lib/adapters/types.ts +44 -0
  29. package/lib/adapters/web.ts +41 -0
  30. package/lib/charts/bar.ts +270 -0
  31. package/lib/charts/index.ts +4 -0
  32. package/lib/charts/line.ts +153 -0
  33. package/lib/charts/pie.ts +110 -0
  34. package/lib/charts/radar.ts +166 -0
  35. package/lib/component.ts +149 -0
  36. package/lib/core/axis.ts +174 -0
  37. package/lib/core/canvas.ts +130 -0
  38. package/lib/core/chart.ts +322 -0
  39. package/lib/core/layout.ts +221 -0
  40. package/lib/core/legend.ts +94 -0
  41. package/lib/core/scale.ts +183 -0
  42. package/lib/core/text.ts +70 -0
  43. package/lib/factory.ts +62 -0
  44. package/lib/index.ts +69 -0
  45. package/lib/types.ts +218 -0
  46. package/package.json +55 -0
@@ -0,0 +1,183 @@
1
+ /**
2
+ * 比例尺:把数据域(domain)映射到像素范围(range)。
3
+ *
4
+ * - LinearScale:数值 → 像素,自动 nice 刻度(0.5 / 1 / 2 / 5 步进)
5
+ * - CategoryScale:类目索引 → 像素带(band),供柱状图计算柱宽
6
+ *
7
+ * 纯函数与轻量类实现,零平台依赖,便于单元测试。
8
+ */
9
+
10
+ /** 数值域映射接口。 */
11
+ export interface LinearScaleOptions {
12
+ /** 数据最小值(未指定则按数据自动 nice)。 */
13
+ min?: number;
14
+ /** 数据最大值(未指定则按数据自动 nice)。 */
15
+ max?: number;
16
+ /** 期望刻度分段数,默认 5。 */
17
+ splitCount?: number;
18
+ }
19
+
20
+ export interface ScaleResult {
21
+ /** 映射后的像素坐标(已夹取到 range 内)。 */
22
+ scale(value: number): number;
23
+ /** nice 后的实际最小值。 */
24
+ min: number;
25
+ /** nice 后的实际最大值。 */
26
+ max: number;
27
+ /** 刻度值数组(含 min/max)。 */
28
+ ticks: number[];
29
+ }
30
+
31
+ /**
32
+ * 计算 nice 刻度:把任意 [min, max] 数据范围规整为"美观"范围与刻度。
33
+ * 步进从 1 / 2 / 5 × 10^n 中选择,保证刻度间距整齐。
34
+ */
35
+ export function niceTicks(
36
+ rawMin: number,
37
+ rawMax: number,
38
+ splitCount = 5
39
+ ): { min: number; max: number; step: number; ticks: number[] } {
40
+ let min = rawMin;
41
+ let max = rawMax;
42
+
43
+ if (!Number.isFinite(min) || !Number.isFinite(max)) {
44
+ throw new Error('niceTicks: domain must be finite numbers');
45
+ }
46
+ if (min === max) {
47
+ // 常量数据:人为撑开一个单位区间,避免除以零
48
+ const pad = Math.abs(min) > 1 ? Math.abs(min) * 0.1 : 1;
49
+ min -= pad;
50
+ max += pad;
51
+ }
52
+ if (min > max) {
53
+ [min, max] = [max, min];
54
+ }
55
+
56
+ const span = max - min;
57
+ const roughStep = span / Math.max(1, splitCount);
58
+ const step = niceStep(roughStep);
59
+
60
+ const niceMin = Math.floor(min / step) * step;
61
+ const niceMax = Math.ceil(max / step) * step;
62
+
63
+ const ticks: number[] = [];
64
+ for (let v = niceMin; v <= niceMax + step * 1e-9; v += step) {
65
+ // 浮点误差收敛:四舍五入到 step 的小数位数
66
+ ticks.push(roundToStep(v, step));
67
+ }
68
+
69
+ return { min: niceMin, max: niceMax, step, ticks };
70
+ }
71
+
72
+ function niceStep(rough: number): number {
73
+ const power = Math.pow(10, Math.floor(Math.log10(rough)));
74
+ const fraction = rough / power;
75
+ let niceFraction: number;
76
+ if (fraction <= 1) {
77
+ niceFraction = 1;
78
+ } else if (fraction <= 2) {
79
+ niceFraction = 2;
80
+ } else if (fraction <= 5) {
81
+ niceFraction = 5;
82
+ } else {
83
+ niceFraction = 10;
84
+ }
85
+ return niceFraction * power;
86
+ }
87
+
88
+ function roundToStep(value: number, step: number): number {
89
+ const decimals = Math.max(0, -Math.floor(Math.log10(step)) + 1);
90
+ return Number(value.toFixed(decimals));
91
+ }
92
+
93
+ /** 线性比例尺:domain → [rangeStart, rangeEnd],自动 nice。 */
94
+ export class LinearScale {
95
+ public readonly min: number;
96
+ public readonly max: number;
97
+ public readonly ticks: number[];
98
+ public readonly step: number;
99
+
100
+ private readonly rangeStart: number;
101
+ private readonly rangeEnd: number;
102
+
103
+ public constructor(
104
+ dataMin: number,
105
+ dataMax: number,
106
+ rangeStart: number,
107
+ rangeEnd: number,
108
+ options: LinearScaleOptions = {}
109
+ ) {
110
+ const { min: explicitMin, max: explicitMax, splitCount = 5 } = options;
111
+
112
+ let min = explicitMin;
113
+ let max = explicitMax;
114
+
115
+ if (min === undefined || max === undefined) {
116
+ const auto = niceTicks(dataMin, dataMax, splitCount);
117
+ min = min ?? auto.min;
118
+ max = max ?? auto.max;
119
+ this.ticks = auto.ticks;
120
+ this.step = auto.step;
121
+ } else {
122
+ this.step = (max - min) / Math.max(1, splitCount);
123
+ this.ticks = [];
124
+ for (let i = 0; i <= splitCount; i += 1) {
125
+ this.ticks.push(min + i * this.step);
126
+ }
127
+ }
128
+
129
+ this.min = min;
130
+ this.max = max;
131
+ this.rangeStart = rangeStart;
132
+ this.rangeEnd = rangeEnd;
133
+ }
134
+
135
+ /** 数值 → 像素坐标(反向轴传 rangeEnd > rangeStart 即自然反转)。 */
136
+ public scale(value: number): number {
137
+ const ratio = (value - this.min) / (this.max - this.min);
138
+ return this.rangeStart + ratio * (this.rangeEnd - this.rangeStart);
139
+ }
140
+ }
141
+
142
+ /** 类目比例尺:N 个类目 → range 内均分带(band)。 */
143
+ export class CategoryScale {
144
+ /** 每个类目带的像素宽度。 */
145
+ public readonly bandWidth: number;
146
+ /** 类目带之间的间距占比(0~1),默认 0.35。 */
147
+ public readonly innerGapRatio: number;
148
+
149
+ private readonly rangeStart: number;
150
+
151
+ public constructor(
152
+ public readonly categories: readonly unknown[],
153
+ rangeStart: number,
154
+ rangeEnd: number,
155
+ innerGapRatio = 0.35
156
+ ) {
157
+ this.innerGapRatio = innerGapRatio;
158
+ this.rangeStart = rangeStart;
159
+ const count = Math.max(1, categories.length);
160
+ this.bandWidth = (rangeEnd - rangeStart) / count;
161
+ }
162
+
163
+ /** 第 index 个类目的带起始(绝对像素坐标)。 */
164
+ public bandStart(index: number): number {
165
+ return this.rangeStart + this.bandWidth * index;
166
+ }
167
+
168
+ /** 第 index 个类目的带中心(绝对像素坐标)。 */
169
+ public center(index: number): number {
170
+ return this.bandStart(index) + this.bandWidth / 2;
171
+ }
172
+
173
+ /** 可用绘图宽度 = 带宽 × (1 - innerGapRatio)。 */
174
+ public innerWidth(): number {
175
+ return this.bandWidth * (1 - this.innerGapRatio);
176
+ }
177
+
178
+ /** 每组(多系列)子柱宽度:按系列数均分可用宽度,并预留 20% 间隙。 */
179
+ public groupInnerWidth(groupCount: number): number {
180
+ const usable = this.innerWidth();
181
+ return usable / Math.max(1, groupCount) * 0.8;
182
+ }
183
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * 文字辅助:统一的 font 字符串拼接与文本测量。
3
+ * 所有测量都走 ICanvas2D.measureText,保证跨端一致。
4
+ */
5
+
6
+ import type { ICanvas2D } from './canvas';
7
+ import { DEFAULT_FONT_FAMILY } from '../types';
8
+
9
+ export interface TextStyle {
10
+ fontSize?: number;
11
+ family?: string;
12
+ }
13
+
14
+ /** 构造 canvas font 字符串(小程序与 Web 语义一致)。 */
15
+ export function toFont(size: number, family = DEFAULT_FONT_FAMILY): string {
16
+ return `${size}px ${family}`;
17
+ }
18
+
19
+ /** 设置当前文字样式并返回 font 字符串。 */
20
+ export function applyFont(
21
+ ctx: ICanvas2D,
22
+ size: number,
23
+ family = DEFAULT_FONT_FAMILY
24
+ ): string {
25
+ const font = toFont(size, family);
26
+ ctx.font = font;
27
+ return font;
28
+ }
29
+
30
+ /** 测量文本宽度(自动设置 font)。 */
31
+ export function measureWidth(
32
+ ctx: ICanvas2D,
33
+ text: string,
34
+ fontSize: number,
35
+ family = DEFAULT_FONT_FAMILY
36
+ ): number {
37
+ applyFont(ctx, fontSize, family);
38
+ return ctx.measureText(text).width;
39
+ }
40
+
41
+ /**
42
+ * 截断文本到指定像素宽度(超宽加省略号)。
43
+ * 用于类目轴标签过长时避免溢出绘图区。
44
+ */
45
+ export function truncate(
46
+ ctx: ICanvas2D,
47
+ text: string,
48
+ maxWidth: number,
49
+ fontSize: number,
50
+ family = DEFAULT_FONT_FAMILY
51
+ ): string {
52
+ if (maxWidth <= 0 || measureWidth(ctx, text, fontSize, family) <= maxWidth) {
53
+ return text;
54
+ }
55
+ const ellipsis = '…';
56
+ let lo = 0;
57
+ let hi = text.length;
58
+ let result = text;
59
+ while (lo < hi) {
60
+ const mid = Math.ceil((lo + hi) / 2);
61
+ const candidate = text.slice(0, mid) + ellipsis;
62
+ if (measureWidth(ctx, candidate, fontSize, family) <= maxWidth) {
63
+ result = candidate;
64
+ lo = mid;
65
+ } else {
66
+ hi = mid - 1;
67
+ }
68
+ }
69
+ return result;
70
+ }
package/lib/factory.ts ADDED
@@ -0,0 +1,62 @@
1
+ /**
2
+ * 图表工厂:按 option.type 分发到具体图表策略类(策略模式入口)。
3
+ *
4
+ * 用法(Web):
5
+ * const chart = createWebChart(canvasEl, { type: 'line', ... });
6
+ * chart.render();
7
+ *
8
+ * 用法(小程序,页面 onReady 后):
9
+ * const node = await getMiniProgramCanvasNode({ selector: '#chart' });
10
+ * const chart = createMiniProgramChart(node, option);
11
+ * chart.render();
12
+ */
13
+
14
+ import type { ChartOption, ChartRenderContext } from './types';
15
+ import type { ChartBase } from './core/chart';
16
+ import { LineChart } from './charts/line';
17
+ import { BarChart } from './charts/bar';
18
+ import { PieChart } from './charts/pie';
19
+ import { RadarChart } from './charts/radar';
20
+ import { resolveMiniProgramCanvas } from './adapters/miniprogram';
21
+ import type { MiniProgramCanvasNode } from './adapters/miniprogram';
22
+ import { resolveWebCanvas } from './adapters/web';
23
+ import type { ResolveCanvasOptions } from './adapters/types';
24
+
25
+ /** 按类型创建图表实例(引擎核心入口)。 */
26
+ export function createChart<T extends ChartOption>(
27
+ context: ChartRenderContext,
28
+ option: T
29
+ ): ChartBase<T> {
30
+ switch (option.type) {
31
+ case 'line':
32
+ return new LineChart(context, option) as unknown as ChartBase<T>;
33
+ case 'bar':
34
+ return new BarChart(context, option) as unknown as ChartBase<T>;
35
+ case 'pie':
36
+ return new PieChart(context, option) as unknown as ChartBase<T>;
37
+ case 'radar':
38
+ return new RadarChart(context, option) as unknown as ChartBase<T>;
39
+ default:
40
+ throw new Error(
41
+ `createChart: unsupported chart type "${(option as ChartOption).type}"`
42
+ );
43
+ }
44
+ }
45
+
46
+ /** Web 便捷入口:从 HTMLCanvasElement 直接创建并渲染。 */
47
+ export function createWebChart<T extends ChartOption>(
48
+ canvas: HTMLCanvasElement,
49
+ option: T,
50
+ resolveOptions: ResolveCanvasOptions = {}
51
+ ): ChartBase<T> {
52
+ return createChart(resolveWebCanvas(canvas, resolveOptions), option);
53
+ }
54
+
55
+ /** 小程序便捷入口:从 Canvas 2D 节点直接创建并渲染。 */
56
+ export function createMiniProgramChart<T extends ChartOption>(
57
+ node: MiniProgramCanvasNode,
58
+ option: T,
59
+ resolveOptions: ResolveCanvasOptions = {}
60
+ ): ChartBase<T> {
61
+ return createChart(resolveMiniProgramCanvas(node, resolveOptions), option);
62
+ }
package/lib/index.ts ADDED
@@ -0,0 +1,69 @@
1
+ /**
2
+ * transone-chart:TransOne 跨端图表库。
3
+ *
4
+ * 一份 TypeScript 源码,基于 Canvas 2D 渲染:
5
+ * - Web:HTMLCanvasElement 直接可用
6
+ * - 小程序:微信 / 阿里 / 字节 Canvas 2D 节点
7
+ * - 未来原生 App:实现 ICanvas2D 契约即可接入(见 adapters/native.ts)
8
+ *
9
+ * 一期图表:折线 / 柱状 / 饼图 / 雷达。
10
+ */
11
+
12
+ // 公共类型与默认主题
13
+ export * from './types';
14
+
15
+ // 核心:跨端 Canvas 契约
16
+ export type { ICanvas2D, IGradient } from './core/canvas';
17
+ export { isCanvas2DLike } from './core/canvas';
18
+ export type {
19
+ CanvasLineCap,
20
+ CanvasLineJoin,
21
+ CanvasTextAlign,
22
+ CanvasTextBaseline,
23
+ } from './core/canvas';
24
+
25
+ // 比例尺
26
+ export { LinearScale, CategoryScale, niceTicks } from './core/scale';
27
+ export type { LinearScaleOptions, ScaleResult } from './core/scale';
28
+
29
+ // 布局
30
+ export { computeLayout } from './core/layout';
31
+ export type { Box, LayoutInput, LayoutResult, Padding } from './core/layout';
32
+
33
+ // 图表基类
34
+ export { ChartBase } from './core/chart';
35
+ export type { CartesianScales } from './core/chart';
36
+
37
+ // 四种图表
38
+ export { LineChart } from './charts/line';
39
+ export { BarChart } from './charts/bar';
40
+ export { PieChart } from './charts/pie';
41
+ export { RadarChart } from './charts/radar';
42
+
43
+ // 工厂入口
44
+ export {
45
+ createChart,
46
+ createWebChart,
47
+ createMiniProgramChart,
48
+ } from './factory';
49
+
50
+ // 适配器
51
+ export {
52
+ resolveWebCanvas,
53
+ resolveMiniProgramCanvas,
54
+ getMiniProgramCanvasNode,
55
+ getMiniProgramGlobal,
56
+ detectMiniProgramPixelRatio,
57
+ detectPixelRatio,
58
+ resolveNativeCanvas,
59
+ } from './adapters';
60
+ export type {
61
+ MiniProgramCanvasNode,
62
+ MiniProgramGlobal,
63
+ NativeCanvasHost,
64
+ ResolveCanvasOptions,
65
+ } from './adapters';
66
+
67
+ // 可选组件集成(依赖 transone)
68
+ export { TcChart } from './component';
69
+ export type { TcChartProps } from './component';
package/lib/types.ts ADDED
@@ -0,0 +1,218 @@
1
+ /**
2
+ * transone-chart 公共类型定义。
3
+ *
4
+ * 所有图表共用一份 Option 风格配置(对齐 ECharts 心智:xAxis / yAxis /
5
+ * series / legend / title),但实现零依赖、纯 Canvas 2D 绘制。
6
+ */
7
+
8
+ /** 一期支持的图表类型。 */
9
+ export type ChartType = 'line' | 'bar' | 'pie' | 'radar';
10
+
11
+ /** 默认主题色板(与 transone-ui 主色一致,可按需覆盖)。 */
12
+ export const DEFAULT_PALETTE: readonly string[] = [
13
+ '#1677ff',
14
+ '#00b578',
15
+ '#ff8f1f',
16
+ '#ff3141',
17
+ '#eb2f96',
18
+ '#722ed1',
19
+ '#13c2c2',
20
+ '#faad14',
21
+ '#2f54eb',
22
+ '#a0d911',
23
+ ];
24
+
25
+ export const DEFAULT_TEXT_COLOR = '#323233';
26
+ export const DEFAULT_AXIS_COLOR = '#c8c9cc';
27
+ export const DEFAULT_GRID_COLOR = '#ebedf0';
28
+ export const DEFAULT_FONT_FAMILY =
29
+ "-apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'PingFang SC', 'Microsoft YaHei', sans-serif";
30
+
31
+ /** 标题配置。 */
32
+ export interface TitleOption {
33
+ text: string;
34
+ fontSize?: number;
35
+ color?: string;
36
+ /** 标题与绘图区之间的留白,默认 16。 */
37
+ padding?: number;
38
+ }
39
+
40
+ /** 图例配置。 */
41
+ export interface LegendOption {
42
+ show?: boolean;
43
+ /** 图例位置:顶部横向 / 底部横向 / 右侧纵向。 */
44
+ position?: 'top' | 'bottom' | 'right';
45
+ fontSize?: number;
46
+ color?: string;
47
+ /** 图例色块边长(正方形),默认 12。 */
48
+ markerSize?: number;
49
+ /** 图例项之间的水平间距,默认 16。 */
50
+ itemGap?: number;
51
+ }
52
+
53
+ /** 数值轴(y 轴/雷达数值)配置。 */
54
+ export interface ValueAxisOption {
55
+ /** 显式最小值;缺省自动 nice。 */
56
+ min?: number;
57
+ /** 显式最大值;缺省自动 nice。 */
58
+ max?: number;
59
+ /** 刻度分段数,默认 5。 */
60
+ splitCount?: number;
61
+ labelFontSize?: number;
62
+ labelColor?: string;
63
+ gridColor?: string;
64
+ gridLineWidth?: number;
65
+ /** 网格虚线,如 [4, 4];默认实线。 */
66
+ gridLineDash?: number[];
67
+ /** 是否显示网格,默认 true。 */
68
+ showGrid?: boolean;
69
+ /** 刻度标签格式化。 */
70
+ format?: (value: number) => string;
71
+ }
72
+
73
+ /** 类目轴(x 轴/雷达指标)配置。 */
74
+ export interface CategoryAxisOption {
75
+ labels: readonly string[];
76
+ labelFontSize?: number;
77
+ labelColor?: string;
78
+ gridColor?: string;
79
+ gridLineWidth?: number;
80
+ /** 是否显示类目网格竖线,默认 false。 */
81
+ showGrid?: boolean;
82
+ }
83
+
84
+ /** —— 折线图 —— */
85
+
86
+ export interface LineSeries {
87
+ name?: string;
88
+ data: readonly number[];
89
+ color?: string;
90
+ /** 平滑曲线(三次贝塞尔插值),默认 false。 */
91
+ smooth?: boolean;
92
+ /** 是否填充系列与数值轴之间的面积,默认 false。 */
93
+ area?: boolean;
94
+ /** 是否绘制数据点标记,默认 true。 */
95
+ showSymbol?: boolean;
96
+ lineWidth?: number;
97
+ }
98
+
99
+ export interface LineChartOption {
100
+ type: 'line';
101
+ title?: TitleOption;
102
+ legend?: LegendOption;
103
+ xAxis: CategoryAxisOption;
104
+ yAxis?: ValueAxisOption;
105
+ series: readonly LineSeries[];
106
+ /** 数值轴是否从 0 开始(数据全为正时强制含 0),默认 false(按数据范围紧凑显示)。 */
107
+ startFromZero?: boolean;
108
+ /** 背景色(如 'rgba(22,119,255,0.06)'),默认无。 */
109
+ backgroundColor?: string;
110
+ }
111
+
112
+ /** —— 柱状图 —— */
113
+
114
+ export interface BarSeries {
115
+ name?: string;
116
+ data: readonly number[];
117
+ color?: string;
118
+ /** 堆叠组名;同名系列纵向堆叠。 */
119
+ stack?: string;
120
+ /** 柱体宽度(px),缺省按类目带自动计算。 */
121
+ barWidth?: number;
122
+ /** 柱体圆角,默认 0。 */
123
+ borderRadius?: number;
124
+ }
125
+
126
+ export interface BarChartOption {
127
+ type: 'bar';
128
+ title?: TitleOption;
129
+ legend?: LegendOption;
130
+ xAxis: CategoryAxisOption;
131
+ yAxis?: ValueAxisOption;
132
+ series: readonly BarSeries[];
133
+ /** 横向柱状图(类目轴转纵向、数值轴转横向),默认 false。 */
134
+ horizontal?: boolean;
135
+ backgroundColor?: string;
136
+ }
137
+
138
+ /** —— 饼图 —— */
139
+
140
+ export interface PieDatum {
141
+ name: string;
142
+ value: number;
143
+ color?: string;
144
+ }
145
+
146
+ export interface PieChartOption {
147
+ type: 'pie';
148
+ data: readonly PieDatum[];
149
+ title?: TitleOption;
150
+ legend?: LegendOption;
151
+ /** 外半径:数字(px)或百分比字符串(相对 min(width, height) / 2),默认 '60%'。 */
152
+ radius?: number | string;
153
+ /** 内半径:0 为饼图;>0 为环形图,默认 0。 */
154
+ innerRadius?: number | string;
155
+ /** 是否显示扇区标签(名称 + 百分比),默认 true。 */
156
+ showLabel?: boolean;
157
+ labelFontSize?: number;
158
+ labelColor?: string;
159
+ /** 起始角(弧度),默认 -Math.PI / 2(12 点方向),顺时针。 */
160
+ startAngle?: number;
161
+ backgroundColor?: string;
162
+ }
163
+
164
+ /** —— 雷达图 —— */
165
+
166
+ export interface RadarIndicator {
167
+ name: string;
168
+ /** 指标最大值;缺省取所有系列该指标的最大值。 */
169
+ max?: number;
170
+ }
171
+
172
+ export interface RadarSeries {
173
+ name?: string;
174
+ data: readonly number[];
175
+ color?: string;
176
+ /** 是否填充多边形区域,默认 true。 */
177
+ area?: boolean;
178
+ lineWidth?: number;
179
+ }
180
+
181
+ export interface RadarChartOption {
182
+ type: 'radar';
183
+ indicators: readonly RadarIndicator[];
184
+ series: readonly RadarSeries[];
185
+ title?: TitleOption;
186
+ legend?: LegendOption;
187
+ /** 网格层数,默认 5。 */
188
+ splitCount?: number;
189
+ gridColor?: string;
190
+ gridLineWidth?: number;
191
+ labelFontSize?: number;
192
+ labelColor?: string;
193
+ /** 雷达中心半径(px),缺省取 min(width, height) / 2 的 60%。 */
194
+ radius?: number;
195
+ /** 起始角(弧度),默认 -Math.PI / 2(12 点方向),顺时针。 */
196
+ startAngle?: number;
197
+ backgroundColor?: string;
198
+ }
199
+
200
+ export type ChartOption =
201
+ | LineChartOption
202
+ | BarChartOption
203
+ | PieChartOption
204
+ | RadarChartOption;
205
+
206
+ /** 图表渲染上下文(适配器解析后的产物)。 */
207
+ export interface ChartRenderContext {
208
+ /** 跨端 Canvas 2D 上下文。 */
209
+ ctx: import('./core/canvas').ICanvas2D;
210
+ /** 逻辑宽度(CSS px)。 */
211
+ width: number;
212
+ /** 逻辑高度(CSS px)。 */
213
+ height: number;
214
+ /** 设备像素比。 */
215
+ dpr: number;
216
+ /** 自定义色板,缺省使用 DEFAULT_PALETTE。 */
217
+ palette?: readonly string[];
218
+ }
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "transone-chart",
3
+ "version": "0.1.2",
4
+ "description": "TransOne 跨端图表库:一份 TypeScript 源码,基于 Canvas 2D 渲染,兼容 Web 与多端小程序,预留原生 App(iOS/Android/鸿蒙)扩展",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "source": "./lib/index.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./dist/index.js",
13
+ "types": "./dist/index.d.ts"
14
+ },
15
+ "./adapters": {
16
+ "import": "./dist/adapters/index.js",
17
+ "types": "./dist/adapters/index.d.ts"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "bun scripts/build.ts",
22
+ "build:types": "bunx tsc --project tsconfig.build.json",
23
+ "test": "bun test"
24
+ },
25
+ "peerDependencies": {
26
+ "transone": ">=0.3.0"
27
+ },
28
+ "devDependencies": {
29
+ "transone": "0.3.0"
30
+ },
31
+ "keywords": [
32
+ "transone",
33
+ "chart",
34
+ "canvas",
35
+ "cross-platform",
36
+ "miniprogram",
37
+ "web",
38
+ "typescript"
39
+ ],
40
+ "homepage": "https://geektech-team.github.io/transone/chart/",
41
+ "license": "MIT",
42
+ "engines": {
43
+ "bun": ">=1.3.0"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "lib",
48
+ "README.md",
49
+ "LICENSE"
50
+ ],
51
+ "publishConfig": {
52
+ "access": "public",
53
+ "registry": "https://registry.npmjs.org/"
54
+ }
55
+ }