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

echarts-pie3d-gl

v1.0.2

Published

把 echarts 环形图配置直接渲染成 3D 立体环形图(基于 echarts-gl surface 参数方程)

Readme

echarts-pie3d-gl

当前版本 v1.0.2 · 更新日志 · MIT 许可

3D 环形图效果

把一份普通的 echarts 环形图配置直接渲染成 3D 立体环形图。你基本不用改原来的 echarts pie 配置,createRing3D(el, option) 一包就出 3D。

特性

  • 入参长得像 echarts 环形图:color / tooltip / legend / series[0].data / radius / label / itemStyle / emphasis 都能用
  • 扇区上下四条棱支持圆角(borderRadius);扇区之间是否留缝由 gap 控制
  • hover 时扇区抬升、标签放大,带 220ms 缓动(扇区之间切换时新旧动画同时进行)
  • autoRotate 自动旋转时标签跟着转;鼠标一进扇区就暂停旋转,移开自动恢复
  • 图例、标签用浮层实现(echarts-gl 的 surface 吃不到原生 legend / label)
  • 不打包 echarts / echarts-gl,它们是 peer 依赖

依赖

必须先加载 echarts(>=5)echarts-gl(>=2)。3D 的 surface 系列由 echarts-gl 提供,少了它不出图;npm 场景必须自己 import 'echarts-gl' 一次,否则有图例没环。

安装

npm install echarts-pie3d-gl echarts echarts-gl
# pnpm add echarts-pie3d-gl echarts echarts-gl
# yarn add echarts-pie3d-gl echarts echarts-gl

用法

不用打包工具:CDN

下面这份是完整可运行的例子,存成 .html 双击就能打开,不需要起本地服务:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>echarts-pie3d-gl</title></head>
<body>
  <div id="main" style="width:640px;height:520px"></div>

  <script src="https://unpkg.com/[email protected]/dist/echarts.min.js"></script>
  <script src="https://unpkg.com/[email protected]/dist/echarts-gl.min.js"></script>
  <script src="https://unpkg.com/echarts-pie3d-gl/dist/echarts-pie3d.min.js"></script>
  <script>
    var option = {
      color: ['#4a90d9', '#2dd4bf', '#f59e0b', '#ef4444', '#9a60b4'],
      tooltip: { trigger: 'item', formatter: '{b}: {c} ({d}%)' },
      legend: { show: true, top: '5%', left: 'center', icon: 'circle', showValue: true },
      series: [{
        type: 'pie',
        radius: ['40%', '70%'],
        label: { show: true, position: 'outside', formatter: '{b}: {d}%' },
        emphasis: { label: { show: true, fontSize: 40, fontWeight: 'bold' } },
        data: [
          { value: 1048, name: 'Search Engine' },
          { value: 735, name: 'Direct' },
          { value: 580, name: 'Email' },
          { value: 484, name: 'Union Ads' },
          { value: 300, name: 'Video Ads' }
        ]
      }]
    };

    // 全局名是 EChartsPie3D
    var chart = EChartsPie3D.createRing3D(document.getElementById('main'), option);
    window.addEventListener('resize', function () { chart.resize(); });
  </script>
</body>
</html>

CDN 用法下 echarts 从 window.echarts 取,不会走动态 import。想换源用 jsdelivr:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts-gl.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts-pie3d-gl/dist/echarts-pie3d.min.js"></script>

用打包工具:ESM

import * as echarts from 'echarts';
import 'echarts-gl';                       // 必须引一次,否则有图例没环
import { createRing3D } from 'echarts-pie3d-gl';

const option = { /* 同上 */ };

const chart = createRing3D(document.getElementById('main'), option);
window.addEventListener('resize', () => chart.resize());

<script type="module">file:// 协议下会被浏览器 CORS 策略拦住,必须起本地服务:npx serve .python -m http.server 8080

API

createRing3D(container, option, config?)

函数式入口,内部就是 new Ring3D(container, option, config)

  • container:HTMLElement 或选择器字符串
  • option:见下方参数表
  • config.echarts:手动注入 echarts 实例(模块化环境不想全局引时用)

实例方法:

| 方法 | 说明 | | --- | --- | | setOption(option) | 重新设置配置(会重建) | | resize() | 容器尺寸变化后调用 | | dispose() | 销毁,解绑所有事件与循环 | | chart.chart | 拿到原始 echarts 实例 | | chart.on / off | 转发 echarts 事件 |

另外还导出这些纯函数,方便二次加工:buildOption / resolveConfig / resolveItems / resolveLegend / normalizeLabel / getParametricEquation / ratioToK / normalizeRadius / radiusToGeometry / radiusToInnerRatio / radiusToOuterScale / normalizeHeight / normalizeHeightPair / normalizeNumber / startAngleToRadian / computeRatios / applyGap / midRadian / outerRadius / clampBorderRadius / resolveBorderRadius / DEFAULTS / DEFAULT_PALETTE,以及各参数的上下界常量(MAX_BORDER_RADIUS / MIN_HEIGHT / MAX_HEIGHT / MIN_HOVER_SCALE / MAX_HOVER_SCALE / MIN_DISTANCE / MAX_DISTANCE / MIN_ALPHA / MAX_ALPHA / MIN_BOX_HEIGHT / MAX_BOX_HEIGHT / MIN_AUTO_ROTATE_SPEED / MAX_AUTO_ROTATE_SPEED)。

参数

顶层

| 参数 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | color | string[] | echarts 默认调色板 | 调色板,数据项没写色时按索引取 | | tooltip | object | { trigger:'item' } | 透传 echarts 原生 tooltip。formatter 支持函数和字符串模板({a}系列名 / {b}数据名 / {c}数值 / {d}百分比);另有 valueFormatterbackgroundColorborderColorborderWidthtextStyleextraCssTextconfinepadding 等样式项。注意 trigger 被强制为 'item' | | legend | object | — | 见「legend」表 | | height | number | 15 | 扇区厚度(同时决定顶面高度)。范围 0 ~ 200,越界/非法自动钳制并 console.warn。series 上写同名参数优先 | | hoverHeight | number | 18 | hover 时的厚度。范围 0 ~ 200,且必须 >= height(写小了会被抬到 height) | | hoverScale | number | 1.05 | hover 时的径向放大倍数。范围 0.5 ~ 1.3 | | alpha | number | 35 | 俯视角,越大越俯视。范围 -90 ~ 90 | | distance | number | 220 | 相机距离,越大环形越小。范围 100 ~ 400box 单位,不是像素) | | boxHeight | number | 6 | grid3D.boxHeight,z 轴盒子尺寸。范围 1 ~ 100 | | autoRotate | boolean | false | 自动旋转。只有字面 true 才生效1 / 'true' 都算关闭)。打开后 hover 扇区会暂停旋转、标签会跟随旋转 | | autoRotateSpeed | number | 10 | 自动旋转速度(度/秒)。范围 -360 ~ 360,保留符号(负值反向旋转) | | light | object | echarts-gl 默认 | 透传 grid3D.light | | viewControl | object | — | 覆盖 grid3D.viewControl(如自定义 rotateSensitivity) |

legend

| 参数 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | show | boolean | true | 关掉后不渲染图例浮层 | | orient | 'horizontal' \| 'vertical' | 'horizontal' | 排布方向 | | left / right / top / bottom | number \| string | — | 数字按 px;'center' / 'middle' 表示该方向居中 | | icon | 'circle' \| 'rect' \| 'roundRect' | 'circle' | 色块形状 | | itemWidth / itemHeight | number | 18 | 色块尺寸 | | itemGap | number | 18 | 项间距 | | formatter | string \| function | — | 名称格式化,'{name}' 模板或 (name, item) => string | | showValue | boolean | true | 图例是否带数值(原生 echarts 不带,本库默认带) | | valueFormatter | function | — | (value, item) => string | | selectedMode | boolean \| 'single' | true | 点击图例切换显示;'single' 单选 | | textStyle | object | {color:'#333',fontSize:14} | 文字样式 |

series[0]

| 参数 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | type | 'pie' | — | 接受 pie,内部转 surface | | name | string | — | 系列名,tooltip 的 params.seriesName 取它 | | data | Array | — | { value, name, itemStyle: { color } } | | radius | array \| string \| number | ['40%','70%'] | [内, 外]画实心饼:给单值('70%')或内径给 0(['0%','70%'])。数字按百分比口径(50'50%' 都是 50%);内外写反会自动交换;越界钳制并 warn | | startAngle | number | 90 | 起始角(度)。方向为逆时针,与 echarts 环形图默认相反 | | itemStyle.opacity | number | 1 | 扇区透明度。建议保持 1:小于 1 时 echarts-gl 对透明网格按距离排序,扇区会出现互相覆盖的渲染错觉 | | itemStyle.borderColor | color | — | 不生效:缝里看到的是扇区自己的端面。想要"缝隙感"用 gap | | gap | number | 0 | 3D 独有:扇区之间的缝隙(占整圈比例,0~0.9)。如 0.01 ≈ 3.6° | | borderRadius | number | 0 | 3D 独有:扇区截面圆角半径,范围 0 ~ 0.5,超出自动钳制,0 = 直角。见下方「圆角」 | | label | object | — | 标签配置,字段见下方「label」 | | labelLine | object | — | 引导线配置,字段见下方「labelLine」 | | emphasis | object | — | hover 态配置,字段见下方「emphasis」 | | height 等所有 3D 参数 | — | — | 同顶层,series 上写优先 |

label

| 字段 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | show | boolean | true | 是否显示标签 | | position | 'outside' \| 'inside' \| 'center' | 'outside' | 标签位置。'inside' / 'center' / 'inner' 都按环中线处理;'left' / 'right' / 'top' / 'bottom' 按普通 outside 处理 | | formatter | string \| function | {name}: {percent}% | 字符串模板或函数。模板可用 {a}=系列名(没给则回退数据名)、{b}=数据名、{c}=数值、{d}=百分比,另有具名写法 {name} / {value} / {percent} / {seriesName};函数形式入参为 { name, value, percent, seriesName, color, dataIndex, data } | | color | color | 该扇区的颜色 | 文字颜色 | | fontSize | number | 12 | 字号 | | fontWeight | string \| number | 'normal' | 字重 | | distance | number | 5 | 标签末端与引导线终点的间距(px) |

labelLine

| 字段 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | show | boolean | true | 是否显示引导线 | | length | number | 15 | 第一段长度(px) | | length2 | number | 15 | 第二段长度(px) | | lineStyle.color | color | '#999' | 引导线颜色 | | lineStyle.width | number | 1 | 引导线粗细 |

emphasis

| 字段 | 类型 | 默认 | 说明 | | --- | --- | --- | --- | | disabled | boolean | false | 为 true 时该系列不参与 hover(不抬升、不套 emphasis 样式) | | label | object | — | hover 时的标签配置,字段同「label」,差别见下方 | | itemStyle | object | — | hover 时盖在扇区上的样式(3D 里没有原生 emphasis.itemStyle,由本库手动盖上) |

emphasis.label 的字段与「label」完全相同,差别在两点:

  1. show三态语义(这是最容易搞混的地方):

    | emphasis.label.show | 行为 | | --- | --- | | 显式 true | hover 时套 emphasis 样式。即使 label.show: false 也能把标签"救"回来 | | 显式 false | 完全不套 emphasis 样式,hover 时退回普通标签(注意:这不是"hover 隐藏标签") | | 不给 | 不干预显隐,只提供 hover 的样式放大;显隐继承 label.show |

  2. 没写的字段继承 labelfontSize 没写时继承 label.fontSize(不会把 20px 的标签缩回默认 12px),position / formatter / color 同理。只有你显式写了的项才在 hover 时生效。

圆角(borderRadius

圆角效果

  • 只作用在上/下表面的四条棱(截面圆角),不作用于扇区两侧的切片端面。周向倒角会让扇区在角方向上收缩或外扩、有互相重叠/露缝的风险,所以不做;想要"缝隙感"用 gap
  • 圆角只削掉角上的材料、绝不外扩:外沿最大半径仍等于外径、内沿仍等于内径,相邻扇区不会互相重叠。
  • hover 时 hoverScale 是在截面算完之后才乘上去的,圆角会被同比放大(视觉上跟着扇区一起放大)。

已知限制

  • 必须在支持 WebGL 的环境跑,纯 Canvas 或老浏览器不行。
  • center 不生效,环形在 3D 盒子里固定居中。
  • label.position'left' / 'right' / 'top' / 'bottom' 按普通 outside 处理(沿扇区中角向外)。
  • 标签和图例是叠在图表上的浮层。标签位置优先用 grid3D 坐标系 + 相机矩阵投影,不可用时降级为正交投影;越界的标签会夹回容器边缘。
  • itemStyle.opacity < 1 会有渲染错觉(见参数表);itemStyle.borderColor 不生效;开了 gap > 0 才会补端面。
  • 图例浮层依赖父容器有定位(库会自动把 position: static 的容器设成 relative)。
  • 开了 autoRotate 时,鼠标在容器内但没压着扇区(环外空白、甜甜圈中间的洞)时 hover 的收尾可能有 1~2 帧延迟;扇区边缘 1~2px 的过渡带在极端视角(alpha 接近 ±90)下理论上可能有一次误判。

开发

npm install
npm run build   # 产出 dist 三形态
npm test        # 279 条
  • src/ 7 个模块:index.js 入口、geometry.js 参数方程、option.js option 构建、chart.js 主类、overlay.js 浮层、defaults.js 默认值、util.js 工具
  • ⚠️ demo/ 只在 GitHub 仓库里有,npm 包不含 demo/files 只发布 dist / src / README.md / CHANGELOG.md / LICENSE

从 0.2.x 升级

1.0.0 是第一个稳定版本。从 0.2.x 升级有若干行为变更(如 emphasis.label.fontSize 改为继承 label.fontSizeautoRotate 打开后 hover 会暂停旋转),完整清单见 CHANGELOG.md