npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

graph-svg-js

v1.1.39

Published

> 一个基于 TypeScript 的 SVG 图形绘制库,提供面向对象的 API 和命令式 DSL 两种使用方式。

Readme

graph-svg-js

一个基于 TypeScript 的 SVG 图形绘制库,提供面向对象的 API 和命令式 DSL 两种使用方式。

简介

graph-svg-js 是一个轻量级的 SVG 图形绘制工具库,支持在浏览器或 Node.js 环境中创建和操作 SVG 图形。提供了丰富的基本图形元素(圆、椭圆、矩形、多边形、三角形、星星等)、高级图表组件(饼图、环形图、雷达图、柱状图)、文本处理、路径操作、动画效果以及命令式 DSL 系统。

特性

  • 完整的图形支持:圆形、椭圆、矩形、多边形、三角形、星星、扇形、圆环等
  • 图表组件:饼图、环形图、坐标系、柱状图、雷达图
  • 文本处理:普通文本、路径文本、垂直文本、超链接文本
  • 高级功能:渐变、遮罩、标记、图案填充、Symbol 引用、裁剪路径
  • 动画系统:基础动画、颜色动画、路径动画、变换动画
  • 命令 DSL:支持字符串命令解析,快速创建图形
  • 画笔模式:支持链式调用的画笔操作
  • 环境兼容:同时支持浏览器环境和 Node.js 环境

安装

npm install graph-svg-js

快速开始

基础用法

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 模式

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();

画笔模式

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 画布的统一入口。

构造函数

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 - 圆形

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 - 扇形/圆环

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 - 椭圆

import { Ellipse } from 'graph-svg-js';

const ellipse = new Ellipse(
  { x: 100, y: 100 },  // 中心点
  80,                   // 横向半径
  50                    // 纵向半径(不设置则为正圆)
);

Polygon - 多边形

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 - 三角形

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 - 矩形

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 - 星星

import { Star } from 'graph-svg-js';

const star = new Star({
  size: 5,        // 几角星(至少3角)
  minR: 30,       // 内角半径(内角到圆心距离)
  maxR: 60,       // 顶角半径(顶角到圆心距离)
  o: { x: 100, y: 100 }  // 圆心坐标
});

Line - 直线

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 路径命令的完整支持,支持绝对定位(大写)和相对定位(小写)。

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 - 文本

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 - 图片

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 - 饼图

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 - 环形图

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 - 坐标系

import Coordinate from 'graph-svg-js';

const coordinate = new Coordinate({
  o: { x: 100, y: 300 },   // 坐标系原点
  width: 400,               // 宽度(x轴)
  height: -250,             // 高度(y轴,负数表示向上)
  color: '#333333'          // 轴线颜色
});

Radar - 雷达图

雷达图(蛛网图)用于显示多变量数据的可视化图表。维度数量和最大值会自动从数据中推导。

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);

多数据集对比示例:

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);

动态操作数据集:

// 添加新数据集
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 - 定义容器

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 - 基础动画

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)

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)

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

// 定义 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');

渐变

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)');

动画

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 颜色类

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 颜色类

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       # 图片命令

构建

# TypeScript 编译
npm run build

# Babel 转换
npm run build-babel

# Webpack 打包
npm run build-webpack

# 生成文档
npm run typedoc

技术栈

  • TypeScript - 类型安全的 JavaScript 超集
  • Babel - JavaScript 编译器
  • Webpack - 模块打包工具
  • TypeDoc - 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());

绘制星星图案

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