# graph-svg-js

> 一个基于 TypeScript 的 SVG 图形绘制库，提供面向对象的 API 和命令式 DSL 两种使用方式。

## 简介

`graph-svg-js` 是一个轻量级的 SVG 图形绘制工具库，支持在浏览器或 Node.js 环境中创建和操作 SVG 图形。提供了丰富的基本图形元素（圆、椭圆、矩形、多边形、三角形、星星等）、高级图表组件（饼图、环形图、雷达图、柱状图）、文本处理、路径操作、动画效果以及命令式 DSL 系统。

## 特性

- **完整的图形支持**：圆形、椭圆、矩形、多边形、三角形、星星、扇形、圆环等
- **图表组件**：饼图、环形图、坐标系、柱状图、雷达图
- **文本处理**：普通文本、路径文本、垂直文本、超链接文本
- **高级功能**：渐变、遮罩、标记、图案填充、Symbol 引用、裁剪路径
- **动画系统**：基础动画、颜色动画、路径动画、变换动画
- **命令 DSL**：支持字符串命令解析，快速创建图形
- **画笔模式**：支持链式调用的画笔操作
- **环境兼容**：同时支持浏览器环境和 Node.js 环境

## 安装

```bash
npm install graph-svg-js
```

## 快速开始

### 基础用法

```typescript
import Svg from 'graph-svg-js';

// 创建 SVG 画布
const svg = new Svg({ width: 900, height: 900 });

// 绘制直线
svg.line({ x: 10, y: 10 }, { x: 30, y: 10 }, { width: 1, color: '#000000' });

// 绘制圆形
svg.circle({ x: 100, y: 100 }, 50, { color: '#446688' });

// 绘制矩形
svg.rect({ x: 200, y: 200 }, 100, 80, { color: '#EEE', border: { width: 2, color: '#333' } });

// 绘制扇形
svg.sector({ x: 300, y: 300 }, 80, { start: 0, end: 120, color: '#446688' });

// 绘制文本
svg.text({ x: 100, y: 50 }, 'Hello SVG', { size: 16, color: '#333' });

// 渲染到页面
document.body.append(svg.draw());
```

### 命令 DSL 模式

```typescript
import Svg from 'graph-svg-js';

const svg = new Svg({ width: 900, height: 900 });

// 使用命令绘制
svg.exec('line 10,10 30,10 --border 1 #000000');
svg.exec('sector 100,450 50 0 360 #EEEEEE 20');
svg.exec('circle 300,600 100 --fill #FFF --border 20 #000');
svg.exec('triangle 400,200 200,400 500,500 --fill red');
svg.exec("text '文本内容' 100,50 #000000 --offset 10 15");

// 批量执行命令
svg.commands(
  'sector 200,200 100 0 120 #446688 20 --attr id id1',
  'sector 200,200 100 120 240 #887731 20 --attr id id2',
  'sector 200,200 100 240 360 #431a88 20 --attr id id3'
);

// 查看命令帮助
svg.commandHelp();
```

### 画笔模式

```typescript
import Svg from 'graph-svg-js';

const svg = new Svg({ width: 800, height: 600 });
const painter = svg.painter({ x: 50, y: 50 });

// 链式调用绘制
painter
  .circle(30, { color: 'red' })
  .move({ x: 100, y: 50 })
  .rect(60, 40, { color: 'blue' })
  .move({ x: 200, y: 50 })
  .text('画笔模式', { size: 14, color: '#333' });
```

## API 文档

### Svg 主类

创建 SVG 画布的统一入口。

#### 构造函数

```typescript
new Svg(options?: SvgOptions)
```

**SvgOptions 配置项：**

| 属性 | 类型 | 说明 |
|------|------|------|
| viewBox | ViewBox \| string | 视图盒模型 |
| preserveAspectRatio | string | 元素缩放属性 |
| width | string \| number | 画布宽度 |
| height | string \| number | 画布高度 |
| style | string \| Style | 样式定义 |
| desc | string | SVG 描述文本 |

#### 主要方法

| 方法 | 说明 |
|------|------|
| `circle(o, r, options?)` | 绘制圆形 |
| `ellipse(o, rx, ry, color?)` | 绘制椭圆 |
| `sector(o, r, options?)` | 绘制扇形或圆环 |
| `line(start, end, border?)` | 绘制直线 |
| `rect(point, width, height, options?)` | 绘制矩形 |
| `text(point, content, options?)` | 添加文本 |
| `polygon(points?)` | 绘制多边形 |
| `triangle(p1, p2, p3?)` | 绘制三角形 |
| `star(o, minR, maxR, size?)` | 绘制星星 |
| `pie(o, r, ratios, optional?)` | 绘制饼图 |
| `image(point, src, options?)` | 添加图片 |
| `path(point, commands, attrs?)` | 绘制路径 |
| `use(href, point, options?)` | 引用 Symbol |
| `symbol(id, options)` | 定义 Symbol |
| `coordinate(o, width, height, color?)` | 绘制坐标系 |
| `lineto(points, options?)` | 绘制连续线段 |
| `html(html, options?)` | 嵌入 HTML 片段 |
| `def(def?)` | 创建 Defs 容器 |
| `painter(point?)` | 创建画笔 |
| `command(command)` | 执行单个命令 |
| `commands(...commands)` | 批量执行命令 |
| `commandHelp()` | 查看命令帮助 |
| `append(...graphs)` | 添加图形元素 |
| `css(css, cssValue?)` | 设置样式 |
| `attr(name, value)` | 设置属性 |
| `draw()` | 渲染 SVG 元素 |
| `toString()` | 输出 SVG 字符串 |
| `clear()` | 清空画布 |

### 图形元素详细 API

所有图形元素均继承自 `Graph` 基类，提供通用的操作方法。

#### Graph 基类方法

| 方法 | 说明 |
|------|------|
| `fill(color, opacity?)` | 设置填充色 |
| `border(border)` | 设置边框 |
| `transparent()` | 设置为透明 |
| `font(options)` | 设置字体样式 |
| `attr(name, value)` | 设置属性 |
| `translate(x, y?)` | 平移变换 |
| `rotate(angle, point?)` | 旋转变换 |
| `scale(x, y?)` | 缩放变换 |
| `skewX(angle)` / `skewY(angle)` | 斜切变换 |
| `matrix(a, b, c, d, e, f)` | 变换矩阵 |
| `clipPath(id)` | 引用裁剪路径 |
| `setClass(className)` | 设置 CSS 类 |
| `setId(id)` | 设置 ID |
| `style(css)` | 设置内联样式 |
| `addEventListener(type, listener)` | 添加事件监听 |
| `removeEventListener(type, listener)` | 移除事件监听 |

#### Circle - 圆形

```typescript
import { Circle } from 'graph-svg-js';

const circle = new Circle({ x: 100, y: 100 }, 50);

// 获取圆上某点的坐标（以垂直方向为0°，顺时针）
const point = circle.getPoint(45);

// 批量绘制圆（工厂方法）
const paintFn = Circle.paint(50, { x: 100, y: 100 }, { x: 200, y: 100 });
const elements = paintFn({ fill: 'red' });
```

#### Sector - 扇形/圆环

```typescript
import { Sector } from 'graph-svg-js';

// 绘制扇形
const sector = Sector.sector(
  { x: 100, y: 100 },  // 圆心
  80,                   // 半径
  0,                    // 起始角度
  120,                  // 终止角度
  '#446688',            // 填充色
  0.8                   // 透明度（可选）
);

// 绘制圆环
const annulus = Sector.annulus(
  { x: 100, y: 100 },  // 圆心
  80,                   // 外半径
  20,                   // 环宽度
  '#446688',            // 填充色
  0,                    // 起始角度
  360,                  // 终止角度
  0.8                   // 透明度（可选）
);

// 绘制实心圆
const circle = Sector.circle(
  { x: 100, y: 100 },
  50,
  'red',
  0.5
);
```

#### Ellipse - 椭圆

```typescript
import { Ellipse } from 'graph-svg-js';

const ellipse = new Ellipse(
  { x: 100, y: 100 },  // 中心点
  80,                   // 横向半径
  50                    // 纵向半径（不设置则为正圆）
);
```

#### Polygon - 多边形

```typescript
import Polygon from 'graph-svg-js';

// 基于顶点坐标创建
const polygon = new Polygon([
  { x: 100, y: 100 },
  { x: 200, y: 150 },
  { x: 150, y: 250 }
]);

// 创建正多边形
const hexagon = new Polygon().equilateral(
  { x: 150, y: 150 },  // 中心点
  80,                   // 半径（中心到顶点距离）
  6,                    // 边数（至少为3）
  0                     // 起始偏移角度（可选，默认0）
);

// 基于分值创建（用于雷达图等）
const radar = new Polygon().score(
  { x: 150, y: 150 },  // 中心点
  100,                  // 满分对应的半径
  100,                  // 满分分值
  [80, 60, 90, 70, 85], // 各维度分值（从垂直方向顺时针）
  0                     // 起始偏移角度（可选）
);

// 设置顶点连接样式
polygon.linejoin('round');  // 'miter' | 'round' | 'bevel'

// 设置圆角半径
polygon.radius(5);
```

#### Triangle - 三角形

```typescript
import { Triangle } from 'graph-svg-js';

// 基于三个顶点创建
const triangle = new Triangle(
  { x: 100, y: 50 },
  { x: 50, y: 150 },
  { x: 150, y: 150 }
);

// 创建正等边三角形
const equilateral = Triangle.equilateral(
  { x: 100, y: 100 },  // 中心位置
  60,                   // 中心到顶点距离
  0                     // 偏移角度（可选）
);

// 创建等腰三角形（已知顶点和夹角）
const isosceles = Triangle.isosceles(
  { x: 100, y: 50 },   // 顶点坐标
  100,                  // 顶点到对边中心点的距离
  60,                   // 顶点两条边的夹角（度）
  false                 // 是否反向（可选）
);

// 创建特殊的正三角形（基于原点到顶点的距离）
const regular = Triangle.regular({
  o: { x: 100, y: 100 },  // 圆心坐标
  vr: 60,                  // 圆心到上顶点距离
  lr: 50,                  // 圆心到左下顶点距离
  rr: 50                   // 圆心到右下顶点距离
});
```

#### Rectangle - 矩形

```typescript
import { Rectangle } from 'graph-svg-js';

const rect = new Rectangle(
  { x: 50, y: 50 },  // 左上角坐标
  200,                // 宽度
  100                 // 高度（不设置则为正方形）
);

// 设置圆角
rect.radius(10);           // 统一圆角
rect.radius(10, 20);       // rx=10, ry=20

// 获取中心点
const center = rect.getCenter();

// 获取四个顶点
const points = rect.getPoints();
// 返回: { lt, rt, lb, rb } 分别代表左上、右上、左下、右下
```

#### Star - 星星

```typescript
import { Star } from 'graph-svg-js';

const star = new Star({
  size: 5,        // 几角星（至少3角）
  minR: 30,       // 内角半径（内角到圆心距离）
  maxR: 60,       // 顶角半径（顶角到圆心距离）
  o: { x: 100, y: 100 }  // 圆心坐标
});
```

#### Line - 直线

```typescript
import { Line, Polyline } from 'graph-svg-js';

// 两点创建直线
const line = Line.build(
  { x: 10, y: 10 },
  { x: 200, y: 200 }
);

// 水平线
const horizontal = Line.horizontal(
  { x: 10, y: 50 },
  200  // 长度
);

// 垂直线
const vertical = Line.vertical(
  { x: 100, y: 10 },
  150  // 长度
);

// 斜线（已知起点、长度、角度）
const slash = Line.slash(
  { x: 50, y: 50 },
  100,  // 长度
  45    // 角度（度）
);

// 设置虚线
line.dash('5,5');           // 虚线模式
line.dash('10,5,2,5', 3);   // 虚线模式+偏移量

// 多段线
const polyline = new Polyline([
  { x: 10, y: 10 },
  { x: 100, y: 50 },
  { x: 200, y: 100 }
]);

// 添加点
polyline.point({ x: 300, y: 150 });
polyline.point(400, 200);

// 在顶点处绘制圆
const circles = polyline.acme(
  5,                  // 圆半径
  'red',              // 圆填充色
  { stroke: '#000' }  // 圆属性（可选）
);
```

#### Path - 路径

Path 提供 SVG 路径命令的完整支持，支持绝对定位（大写）和相对定位（小写）。

```typescript
import Path from 'graph-svg-js';

const path = new Path({ x: 10, y: 10 });

// M/m - 移动到指定点
path.moveto({ x: 50, y: 50 });
path.moveto({ x: 10, y: 10 }, true);  // 相对定位

// L/l - 连线到指定点
path.lineto({ x: 100, y: 100 });
path.lineto({ x: 20, y: 20 }, true);  // 相对定位

// H/h - 水平移动
path.horizontal(150);
path.horizontal(-30, true);  // 相对定位

// V/v - 垂直移动
path.vertical(200);
path.vertical(50, true);  // 相对定位

// A/a - 圆弧
path.arc({
  rx: 50,                  // 椭圆x轴半径
  ry: 50,                  // 椭圆y轴半径
  xr: 0,                   // 椭圆长轴角度
  laf: 0,                  // 是否选择长弧 (0或1)
  sf: 0,                   // 是否逆时针 (0或1)
  point: { x: 150, y: 50 } // 终止点
});

// C/c - 三次贝塞尔曲线
// 当前点为起点，end为终点，point1和point2为控制点
path.curveto(
  { x: 50, y: 0 },     // 控制点1
  { x: 100, y: 100 },  // 控制点2
  { x: 150, y: 50 }    // 终点
);

// S/s - 简化贝塞尔曲线（C的简化版）
// 第一个控制点自动计算为前一个控制点的对称点
path.smoothCurveto(
  { x: 100, y: 100 },  // 控制点
  { x: 150, y: 50 }    // 终点
);

// Q/q - 二次贝塞尔曲线
// 只需要一个控制点
path.quadratic(
  { x: 75, y: 0 },     // 控制点
  { x: 150, y: 50 }    // 终点
);

// T/t - 简化二次贝塞尔（Q的简写）
// 自动推断控制点
path.smoothQuadratic(
  { x: 100, y: 100 },  // 推断的控制点
  { x: 150, y: 50 }    // 终点
);

// 设置虚线
path.dash('5,5');              // 虚线模式
path.dash('10,5,2,5', 3);      // 虚线模式+偏移

// 手动添加路径命令字符串
path.push('M 10 10 L 100 100 Z');

// 注意：Path 最终会自动添加 'Z' 命令闭合路径
```

#### Text - 文本

```typescript
import { Text, Tspan } from 'graph-svg-js';

// 基础文本
const text = new Text({
  content: 'Hello SVG',
  point: { x: 100, y: 100 }
});

// 设置字体样式
text.font({
  size: 16,
  weight: 'bold',
  family: 'Arial',
  color: '#333333'
});

// 设置文本偏移
text.offset(10, 5);       // dx=10, dy=5
text.offsetX(15);         // 仅x偏移
text.offsetY(10);         // 仅y偏移

// 文本对齐
text.anchor('middle');    // 'start' | 'middle' | 'end'
text.middle();            // 快捷方法，等同于 anchor('middle')

// 垂直显示文字
text.vertical(1);         // 每行1个字符
text.vertical(2, 3);      // 每行2个字符，行间距3px

// 添加 Tspan
text.tspan('高亮文字', { fill: 'red', fontWeight: 'bold' });
text.tspan(new Tspan('自定义Tspan'));

// 添加多行文本
text.text(['第一行', '第二行', '第三行']);
text.text('追加内容');

// 路径文本（文字沿着路径显示）
// 首先需要定义一个 path 并设置 id
const textPath = new Text({
  content: '沿着曲线显示的文字',
  point: { x: 0, y: 0 }
});
textPath.href('pathId');  // 引用 path 的 id

// 或者使用 href 参数一步到位
const text2 = new Text({
  content: '路径文本',
  point: { x: 0, y: 0 },
  href: 'pathId'  // 直接关联到 path
});
```

#### Image - 图片

```typescript
import { Image } from 'graph-svg-js';

const image = new Image({
  src: '/path/to/image.png',
  point: { x: 100, y: 100 },
  width: 200,
  height: 150
});
```

#### Pie - 饼图

```typescript
import { Pie } from 'graph-svg-js';

const pie = new Pie({
  o: { x: 200, y: 200 },  // 饼图中心
  r: 100,                  // 半径
  ratios: [
    { value: 25, color: '#446688', name: 'A' },
    { value: 35, color: '#887731', name: 'B' },
    { value: 40, color: '#431a88', name: 'C' }
  ],
  optional: {
    width: 2,                          // 边框宽度
    attrs: { stroke: '#FFF' },         // 扇形属性
    font: { color: '#333', size: 12 }, // 标签字体
    anchor: 'middle'                   // 标签对齐方式
  }
});

// 快捷创建（自动分配颜色）
const pie2 = Pie.build(
  { x: 200, y: 200 },
  100,
  [25, 35, 40]  // 仅提供数值
);
```

#### Ring - 环形图

```typescript
import { Ring } from 'graph-svg-js';

const ring = new Ring({
  o: { x: 200, y: 200 },  // 中心点
  r: 100,                  // 半径
  width: 30,               // 环宽度
  items: [
    { value: 30, color: '#446688', label: 'A' },
    { value: 70, color: '#887731', label: 'B' }
  ],
  colors: ['#FF0000', '#00FF00', '#0000FF'],  // 自定义颜色序列（可选）
  render: (graph, item, index) => {
    // 自定义渲染回调（可选）
    if (graph instanceof Sector) {
      graph.attr('opacity', 0.8);
    }
  }
});

// 动态添加项
ring.addItem({ value: 50, label: 'C' });
ring.addItem(25);  // 仅数值
```

#### Coordinate - 坐标系

```typescript
import Coordinate from 'graph-svg-js';

const coordinate = new Coordinate({
  o: { x: 100, y: 300 },   // 坐标系原点
  width: 400,               // 宽度（x轴）
  height: -250,             // 高度（y轴，负数表示向上）
  color: '#333333'          // 轴线颜色
});
```

#### Radar - 雷达图

雷达图（蛛网图）用于显示多变量数据的可视化图表。维度数量和最大值会自动从数据中推导。

```typescript
import { Radar } from 'graph-svg-js';

const radar = new Radar({
  center: { x: 300, y: 300 },  // 雷达图中心坐标
  radius: 150,                  // 雷达图半径
  gridLevels: 5,                // 网格层数（可选，默认5）
  style: {                      // 样式配置（可选）
    gridColor: '#CCCCCC',       // 网格线颜色
    gridWidth: 1,               // 网格线宽度
    gridOpacity: 0.5,           // 网格透明度
    axisColor: '#999999',       // 轴线颜色
    axisWidth: 1,               // 轴线宽度
    axisOpacity: 0.5,           // 轴线透明度
    labelOffset: 20,            // 标签距离顶点的偏移量
    labelFont: {                // 标签字体配置
      size: '12',
      color: '#333333',
      family: 'Arial'
    }
  },
  datasets: [
    {
      data: [
        { label: '攻击力', value: 80 },
        { label: '防御力', value: 60 },
        { label: '速度', value: 90 },
        { label: '力量', value: 70 },
        { label: '技巧', value: 85 },
        { label: '耐力', value: 75 }
      ],
      fillColor: '#446688',      // 填充色
      fillOpacity: 0.3,          // 填充透明度
      strokeColor: '#446688',    // 描边颜色
      strokeWidth: 2,            // 描边宽度
      pointStyle: {              // 数据点样式
        r: 4,                    // 点半径
        fill: '#446688',         // 填充色
        stroke: '#FFF',          // 边框色
        strokeWidth: 1           // 边框宽度
      }
    }
  ]
});

svg.append(radar);
```

**多数据集对比示例：**

```typescript
import { Radar } from 'graph-svg-js';

const radar = new Radar({
  center: { x: 300, y: 300 },
  radius: 150,
  datasets: [
    {
      data: [
        { label: '维度A', value: 80 },
        { label: '维度B', value: 60 },
        { label: '维度C', value: 90 },
        { label: '维度D', value: 70 },
        { label: '维度E', value: 85 }
      ],
      fillColor: '#446688',
      fillOpacity: 0.3,
      strokeColor: '#446688'
    },
    {
      data: [
        { label: '维度A', value: 65 },
        { label: '维度B', value: 75 },
        { label: '维度C', value: 70 },
        { label: '维度D', value: 90 },
        { label: '维度E', value: 60 }
      ],
      fillColor: '#FF6666',
      fillOpacity: 0.3,
      strokeColor: '#FF6666'
    }
  ]
});

svg.append(radar);
```

**动态操作数据集：**

```typescript
// 添加新数据集
radar.addDataset({
  data: [
    { label: '维度A', value: 50 },
    { label: '维度B', value: 80 },
    { label: '维度C', value: 60 },
    { label: '维度D', value: 75 },
    { label: '维度E', value: 90 }
  ],
  fillColor: '#66CC66',
  fillOpacity: 0.3,
  strokeColor: '#66CC66'
});

// 更新数据集
radar.updateDataset(0, {
  data: [
    { label: '维度A', value: 90 },
    // ...
  ],
  fillColor: '#446688'
});

// 清空所有数据集
radar.clearDatasets();
```

### Defs 定义元素

#### Defs - 定义容器

```typescript
import { Defs, LinearGradient, RadialGradient, Pattern, ClipPath, Marker, Mask, Symbol, Use } from 'graph-svg-js';

const defs = new Defs();

// 线性渐变
const linearGrad = new LinearGradient('grad1', {
  start: { x: 0, y: 0 },
  end: { x: 1, y: 0 }
});
linearGrad.stop({ offset: '0%', stopColor: '#8cffa0' });
linearGrad.stop({ offset: '100%', stopColor: '#8ca0ff' });
defs.def(linearGrad);

// 径向渐变
const radialGrad = new RadialGradient('grad2', {
  o: { x: 0.5, y: 0.5 },
  r: '50%',
  focus: { x: 0.3, y: 0.3 }
});
radialGrad.stop({ offset: '0%', stopColor: 'white' });
radialGrad.stop({ offset: '100%', stopColor: 'black' });
defs.def(radialGrad);

// 图案填充
const pattern = new Pattern({
  id: 'pattern1',
  x: 0, y: 0,
  width: 20, height: 20
});
// 可以往 pattern 里添加图形
defs.def(pattern);

// 剪切路径
const clipPath = new ClipPath('myClip');
clipPath.append(new Circle({ x: 30, y: 30 }, 20));
defs.def(clipPath);

// 标记（用于箭头等）
const marker = Marker.build('arrow', {
  viewBox: { point: { x: 0, y: 0 }, width: 10, height: 10 },
  markerWidth: 6,
  markerHeight: 6,
  orient: 'auto',
  refX: 1,
  refY: 5
});
// 往 marker 里添加路径等
defs.def(marker);

// 遮罩
const mask = new Mask({
  id: 'myMask',
  maskUnits: 'objectBoundingBox',
  x: '-10%',
  y: '-10%',
  width: '120%',
  height: '120%'
});
// 往 mask 里添加图形定义遮罩
defs.def(mask);

// Symbol 定义
const symbol = new Symbol({
  id: 'mySymbol',
  viewBox: '0 0 1024 1024'
});
// 往 symbol 里添加内容
defs.def(symbol);

// Use 引用
const use = Use.link('mySymbol', {
  point: { x: 100, y: 100 },
  width: 50,
  height: 50
});
use.mask('myMask');  // 应用遮罩
```

### 动画系统

#### Animate - 基础动画

```typescript
import { Animate, AnimateColor, AnimateMotion, AnimateTransform } from 'graph-svg-js';

// 基础属性动画
const animate = new Animate({
  attributeName: 'opacity',
  from: '0',
  to: '1',
  dur: '2s',
  repeatCount: 'indefinite'
});

// 颜色动画
const animateColor = new AnimateColor({
  attributeName: 'fill',
  from: 'red',
  to: 'blue',
  dur: '3s',
  repeatCount: 3
});

// 路径动画（元素沿路径移动）
const animateMotion = new AnimateMotion({
  dur: '6s',
  repeatCount: 'indefinite',
  path: new Path({ x: 10, y: 110 }),  // 运动路径
  calcMode: 'linear',
  rotate: 'auto'  // 自动旋转朝向路径
});

// 或者引用已有的 path
const animateMotion2 = new AnimateMotion({
  dur: '6s',
  repeatCount: 'indefinite',
  'xlink:href': '#theMotionPath'  // 引用 path 的 id
});

// 变换动画
const animateTransform = new AnimateTransform({
  type: 'rotate',  // 'translate' | 'scale' | 'rotate' | 'skewX' | 'skewY'
  from: '0 100 100',
  to: '360 100 100',
  dur: '10s',
  repeatCount: 'indefinite'
});

// 高级选项
const advancedAnimate = new Animate({
  attributeName: 'x',
  from: '0',
  to: '100',
  dur: '5s',
  repeatCount: 'indefinite',
  values: '0;50;100;50;0',  // 多个变化值
  by: '10',                  // 相对结束值
  begin: '3s',               // 延迟开始
  end: '10s',                // 结束时间
  attributeType: 'XML'       // 'CSS' | 'XML' | 'auto'
});
```

### 支持的 DSL 命令

| 命令 | 说明 | 示例 |
|------|------|------|
| `circle` | 绘制圆形 | `circle 100,100 50 --border 2 #333` |
| `ellipse` | 绘制椭圆 | `ellipse 100,100 50 30` |
| `sector` | 绘制扇形/圆环 | `sector 100,100 50 0 180 red` |
| `line` | 绘制直线 | `line 10,10 100,100 --border 2 blue` |
| `polyline` | 绘制多段线 | `polyline 10,10 50,50 100,10` |
| `rectangle` | 绘制矩形 | `rectangle 10,10 100,80 --fill #EEE` |
| `triangle` | 绘制三角形 | `triangle 10,10 100,100 50,200` |
| `polygon` | 绘制多边形 | `polygon 10,10 50,50 100,10` |
| `text` | 添加文本 | `text '内容' 100,100 #333` |
| `coordinate` | 绘制坐标系 | `coordinate 100,100 200 200 red` |
| `defs` | 定义容器 | `defs` |
| `symbol` | 定义符号 | `symbol id1 --viewBox 0 0 100 100` |
| `use` | 引用符号 | `use #id1 50,50 --width 32 --height 32` |

### 高级组件

#### 饼图 (Pie)

```typescript
svg.pie(
  { x: 200, y: 200 },  // 中心点
  80,                   // 半径
  [
    { color: 'gray', value: 10, name: 'p1' },
    { color: 'green', value: 30, name: 'p2' },
    { color: 'orange', value: 60, name: 'p3' }
  ],
  {
    width: 2,            // 边框宽度
    attrs: { stroke: '#FFF', 'stroke-width': 2 },
    font: { color: '#333' }
  }
);
```

#### 环形图 (Ring)

```typescript
import { Ring } from 'graph-svg-js';

const ring = new Ring({
  o: { x: 200, y: 200 },
  r: 80,
  width: 30,
  items: [
    { value: 30, color: '#446688', label: 'A' },
    { value: 70, color: '#887731', label: 'B' }
  ]
});
svg.append(ring);
```

#### Symbol 与 Use

```typescript
// 定义 Symbol（可用于 iconfont 图形）
svg.symbol('heart', {
  viewBox: '0 0 1024 1024',
  content: `<path d="M32 407.584a279.584 279.584 0 0 1 480-194.944..."></path>`
});

// 引用 Symbol
svg.use('heart', { x: 100, y: 100 }, { width: 32, height: 32 })
  .attr('fill', 'red');
```

#### 渐变

```typescript
import { Defs, LinearGradient, GradientStop } from 'graph-svg-js';

const defs = svg.def();
const gradient = new LinearGradient({
  id: 'gradient',
  x1: '0%', y1: '0%', x2: '100%', y2: '0%'
});
gradient.stop(new GradientStop('0%', '#8cffa0'));
gradient.stop(new GradientStop('100%', '#8ca0ff'));
defs.def(gradient);

svg.circle({ x: 100, y: 100 }, 50).attr('fill', 'url(#gradient)');
```

#### 动画

```typescript
import { Animate, AnimateColor, AnimateTransform } from 'graph-svg-js';

// 基础动画
const animate = new Animate({
  attributeName: 'opacity',
  from: '0',
  to: '1',
  dur: '2s',
  repeatCount: 'indefinite'
});

// 颜色动画
const animateColor = new AnimateColor({
  attributeName: 'fill',
  from: 'red',
  to: 'blue',
  dur: '3s'
});

// 变换动画
const animateTransform = new AnimateTransform({
  type: 'rotate',
  from: '0 100 100',
  to: '360 100 100',
  dur: '5s',
  repeatCount: 'indefinite'
});
```

### 颜色工具

#### Rgb 颜色类

```typescript
import { Rgb } from 'graph-svg-js';

const color = new Rgb(255, 0, 0);        // RGB 构造
const color2 = new Rgb('#FF0000');       // Hex 字符串构造
const color3 = new Rgb('#FF000080');     // 带透明度

color.setAlpha(0.5);                     // 调整透明度
color.toHex();                           // 转为 Hex 格式
color.toString();                        // 输出 rgb(255, 0, 0)
```

#### Hex 颜色类

```typescript
import { Hex } from 'graph-svg-js';

const hex = new Hex('#FF0000');
hex.setAlpha(0.8);
hex.toRgb();                             // 转为 Rgb 格式
Hex.toRgbString('#FF0000');             // 直接转换
```

## 项目结构

```
src/
├── index.ts           # 主入口，导出所有模块
├── core.ts            # 核心基础类 (Graph, Point, Border 等)
├── circle.ts          # 圆形、扇形、椭圆
├── polygon.ts         # 多边形、三角形、矩形、星星
├── line.ts            # 直线、多段线
├── text.ts            # 文本、路径文本、超链接
├── path.ts            # SVG 路径操作
├── pie.ts             # 饼图
├── ring.ts            # 环形图
├── bar.ts             # 柱状图
├── radar.ts           # 雷达图
├── coordinate.ts      # 坐标系
├── defs.ts            # SVG 定义元素 (渐变、遮罩、标记等)
├── image.ts           # 图片
├── animate.ts         # 动画系统
├── style.ts           # CSS 样式类型定义
└── command/           # 命令 DSL 系统
    ├── core.ts        # 命令解析与执行基础
    ├── index.ts       # 命令入口
    ├── circle.ts      # 圆形命令
    ├── line.ts        # 线段命令
    ├── polygon.ts     # 多边形命令
    ├── text.ts        # 文本命令
    ├── defs.ts        # 定义命令
    ├── coordinate.ts  # 坐标系命令
    └── image.ts       # 图片命令
```

## 构建

```bash
# TypeScript 编译
npm run build

# Babel 转换
npm run build-babel

# Webpack 打包
npm run build-webpack

# 生成文档
npm run typedoc
```

## 技术栈

- **TypeScript** - 类型安全的 JavaScript 超集
- **Babel** - JavaScript 编译器
- **Webpack** - 模块打包工具
- **TypeDoc** - TypeScript 文档生成器

## 使用示例

### 绘制组合图形

```typescript
import Svg from 'graph-svg-js';

const svg = new Svg({ width: 600, height: 400 });

// 绘制圆环
svg.exec('circle 300,200 100 --fill #FFF --border 20 #333');

// 绘制坐标系
svg.coordinate({ x: 50, y: 350 }, 500, -300, '#666');

// 绘制饼图
svg.pie(
  { x: 450, y: 200 }, 60,
  [
    { color: '#446688', value: 25, name: 'A' },
    { color: '#887731', value: 35, name: 'B' },
    { color: '#431a88', value: 40, name: 'C' }
  ]
);

// 垂直文本
svg.text({ x: 100, y: 50 }, '垂直文本示例', { size: 14, color: '#333' })
  .vertical(2);

// 渲染
document.body.append(svg.draw());
```

### 绘制星星图案

```typescript
import Svg from 'graph-svg-js';

const svg = new Svg({ width: 400, height: 300 });

// 直接绘制星星
svg.star({ x: 100, y: 150 }, 20, 50);

// 使用 Symbol 复用
svg.symbol('star', {
  viewBox: '0 0 256 256',
  content: new Star({
    size: 5,
    minR: 31,
    maxR: 80,
    o: { x: 128, y: 128 }
  })
});

// 多次引用
svg.use('star', { x: 200, y: 100 }, { width: 32, height: 32 }).fill('gold');
svg.use('star', { x: 250, y: 150 }, { width: 32, height: 32 }).fill('gold');
svg.use('star', { x: 300, y: 200 }, { width: 32, height: 32 }).fill('gold');

document.body.append(svg.draw());
```

## License

ISC
