当前位置:   article > 正文

Echarts 环形饼图_echart 环形3d饼图

echart 环形3d饼图

 

  1. var myChart = echarts.init(document.getElementById('yt-bar'));
  2. let selectedIndex = '';
  3. let hoveredIndex = '';
  4. const colorList = ['#37FFC9', '#31A1FF', '#FFF777']
  5. const data = {
  6. value: [20, 30, 40, 50],
  7. title: ['11', '22', '33', '44'],
  8. color: ['#37FFC9', '#31A1FF', '#FFF777']
  9. }
  10. const paramsList = data.value.map((item, index) => {
  11. return {
  12. value: item,
  13. name: data.title[index],
  14. shading: 'realistic',
  15. itemStyle: {
  16. color: data.color[index]
  17. },
  18. }
  19. })
  20. option = getPie3D(paramsList, 0.59)
  21. // 生成扇形的曲面参数方程
  22. function getParametricEquation(startRatio, endRatio, isSelected, isHovered, k, h) {
  23. // 计算
  24. const midRatio = (startRatio + endRatio) / 2;
  25. const startRadian = startRatio * Math.PI * 2;
  26. const endRadian = endRatio * Math.PI * 2;
  27. const midRadian = midRatio * Math.PI * 2;
  28. // 如果只有一个扇形,则不实现选中效果。
  29. if (startRatio === 0 && endRatio === 1) {
  30. isSelected = false;
  31. }
  32. // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
  33. k = typeof k !== 'undefined' ? k : 1 / 3;
  34. // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
  35. const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
  36. const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
  37. // 计算高亮效果的放大比例(未高亮,则比例为 1)
  38. const hoverRate = isHovered ? 1 : 1;
  39. // 返回曲面参数方程
  40. return {
  41. u: {
  42. min: -Math.PI,
  43. max: Math.PI * 3,
  44. step: Math.PI / 32,
  45. },
  46. v: {
  47. min: 0,
  48. max: Math.PI * 2,
  49. step: Math.PI / 20,
  50. },
  51. x(u, v) {
  52. if (u < startRadian) {
  53. return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
  54. }
  55. if (u > endRadian) {
  56. return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
  57. }
  58. return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
  59. },
  60. y(u, v) {
  61. if (u < startRadian) {
  62. return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate;
  63. }
  64. if (u > endRadian) {
  65. return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate;
  66. }
  67. return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
  68. },
  69. z(u, v) {
  70. if (u < -Math.PI * 0.5) {
  71. return Math.sin(u);
  72. }
  73. if (u > Math.PI * 2.5) {
  74. return Math.sin(u) * h * 0.1;
  75. }
  76. // 当前图形的高度是Z根据h(每个value的值决定的)
  77. return Math.sin(v) > 0 ? 1 * h * 0.1 : -1;
  78. },
  79. };
  80. }
  81. // 生成模拟 3D 饼图的配置项
  82. function getPie3D(pieData, internalDiameterRatio) {
  83. const series = [];
  84. // 总和
  85. let sumValue = 0;
  86. let startValue = 0;
  87. let endValue = 0;
  88. const legendData = [];
  89. const k =
  90. typeof internalDiameterRatio !== 'undefined'
  91. ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
  92. : 1 / 3;
  93. // 为每一个饼图数据,生成一个 series-surface 配置
  94. for (let i = 0; i < pieData.length; i++) {
  95. sumValue += pieData[i].value;
  96. let seriesItem = {
  97. name:
  98. typeof pieData[i].name === "undefined"
  99. ? `series${i}`
  100. : pieData[i].name,
  101. type: "surface",
  102. parametric: true,
  103. wireframe: {
  104. show: false,
  105. },
  106. pieData: pieData[i],
  107. pieStatus: {
  108. selected: false,
  109. hovered: false,
  110. k
  111. },
  112. };
  113. if (typeof pieData[i].itemStyle != "undefined") {
  114. let itemStyle = {};
  115. if (typeof pieData[i].itemStyle.color != "undefined") {
  116. itemStyle.color = pieData[i].itemStyle.color;
  117. }
  118. if (typeof pieData[i].itemStyle.opacity != "undefined") {
  119. itemStyle.opacity = pieData[i].itemStyle.opacity;
  120. }
  121. seriesItem.itemStyle = itemStyle;
  122. }
  123. series.push(seriesItem);
  124. }
  125. // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
  126. // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
  127. for (let i = 0; i < series.length; i++) {
  128. endValue = startValue + series[i].pieData.value;
  129. series[i].pieData.startRatio = startValue / sumValue;
  130. series[i].pieData.endRatio = endValue / sumValue;
  131. series[i].parametricEquation = getParametricEquation(
  132. series[i].pieData.startRatio,
  133. series[i].pieData.endRatio,
  134. false,
  135. false,
  136. k,
  137. series[i].pieData.value === series[0].pieData.value ? 1 : 1
  138. );
  139. startValue = endValue;
  140. legendData.push(series[i].name);
  141. }
  142. // 准备待返回的配置项,把准备好的 legendData、series 传入。
  143. const option = {
  144. tooltip: {
  145. formatter: (params) => {
  146. if (params.seriesName !== 'mouseoutSeries') {
  147. return `${params.seriesName
  148. }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color
  149. };"></span>${option.series[params.seriesIndex].pieData.value}`;
  150. }
  151. return '';
  152. },
  153. },
  154. xAxis3D: {
  155. min: -1,
  156. max: 1,
  157. },
  158. yAxis3D: {
  159. min: -1,
  160. max: 1,
  161. },
  162. zAxis3D: {
  163. min: -1,
  164. max: 1,
  165. },
  166. grid3D: {
  167. show: false,
  168. boxHeight: 15,
  169. top: '-10%',
  170. viewControl: {
  171. // 3d效果可以放大、旋转等,请自己去查看官方配置
  172. alpha: 25,
  173. rotateSensitivity: 1,
  174. zoomSensitivity: 0,
  175. panSensitivity: 0,
  176. distance: 170,
  177. },
  178. // 后处理特效可以为画面添加高光、景深、环境光遮蔽(SSAO)、调色等效果。可以让整个画面更富有质感。
  179. postEffect: {
  180. // 配置这项会出现锯齿,请自己去查看官方配置有办法解决
  181. enable: false,
  182. bloom: {
  183. enable: true,
  184. bloomIntensity: 0.1,
  185. },
  186. SSAO: {
  187. enable: true,
  188. quality: 'medium',
  189. radius: 2,
  190. },
  191. },
  192. },
  193. series,
  194. };
  195. return option;
  196. }
  197. // 修正取消高亮失败的 bug
  198. // 监听 mouseover,近似实现高亮(放大)效果
  199. // myChart.on('mouseover', function (params) {
  200. // // 准备重新渲染扇形所需的参数
  201. // let isSelected;
  202. // let isHovered;
  203. // let startRatio;
  204. // let endRatio;
  205. // let k;
  206. // let i;
  207. // // 如果触发 mouseover 的扇形当前已高亮,则不做操作
  208. // if (hoveredIndex === params.seriesIndex) {
  209. // return;
  210. // // 否则进行高亮及必要的取消高亮操作
  211. // } else {
  212. // // 如果当前有高亮的扇形,取消其高亮状态(对 option 更新)
  213. // if (hoveredIndex !== '') {
  214. // // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 false。
  215. // isSelected = option.series[hoveredIndex].pieStatus.selected;
  216. // isHovered = false;
  217. // startRatio = option.series[hoveredIndex].pieData.startRatio;
  218. // endRatio = option.series[hoveredIndex].pieData.endRatio;
  219. // k = option.series[hoveredIndex].pieStatus.k;
  220. // i = option.series[hoveredIndex].pieData.value === option.series[0].pieData.value ? 1 : 1;
  221. // // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
  222. // option.series[hoveredIndex].parametricEquation = getParametricEquation(
  223. // startRatio,
  224. // endRatio,
  225. // isSelected,
  226. // isHovered,
  227. // k,
  228. // i
  229. // );
  230. // option.series[hoveredIndex].pieStatus.hovered = isHovered;
  231. // // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
  232. // hoveredIndex = '';
  233. // }
  234. // // 如果触发 mouseover 的扇形不是透明圆环,将其高亮(对 option 更新)
  235. // if (params.seriesName !== 'mouseoutSeries') {
  236. // // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
  237. // isSelected = option.series[params.seriesIndex].pieStatus.selected;
  238. // isHovered = true;
  239. // startRatio = option.series[params.seriesIndex].pieData.startRatio;
  240. // endRatio = option.series[params.seriesIndex].pieData.endRatio;
  241. // k = option.series[params.seriesIndex].pieStatus.k;
  242. // // 对当前点击的扇形,执行高亮操作(对 option 更新)
  243. // option.series[params.seriesIndex].parametricEquation = getParametricEquation(
  244. // startRatio,
  245. // endRatio,
  246. // isSelected,
  247. // isHovered,
  248. // k,
  249. // option.series[params.seriesIndex].pieData.value + 5
  250. // );
  251. // option.series[params.seriesIndex].pieStatus.hovered = isHovered;
  252. // // 记录上次高亮的扇形对应的系列号 seriesIndex
  253. // hoveredIndex = params.seriesIndex;
  254. // }
  255. // // 使用更新后的 option,渲染图表
  256. // myChart.setOption(option);
  257. // }
  258. // });
  259. // // 修正取消高亮失败的 bug
  260. myChart.on('globalout', function () {
  261. if (hoveredIndex !== '') {
  262. // 从 option.series 中读取重新渲染扇形所需的参数,将是否高亮设置为 true。
  263. isSelected = option.series[hoveredIndex].pieStatus.selected;
  264. isHovered = false;
  265. k = option.series[hoveredIndex].pieStatus.k;
  266. startRatio = option.series[hoveredIndex].pieData.startRatio;
  267. endRatio = option.series[hoveredIndex].pieData.endRatio;
  268. // 对当前点击的扇形,执行取消高亮操作(对 option 更新)
  269. i = option.series[hoveredIndex].pieData.value === option.series[0].pieData.value ? 35 : 10;
  270. option.series[hoveredIndex].parametricEquation = getParametricEquation(
  271. startRatio,
  272. endRatio,
  273. isSelected,
  274. isHovered,
  275. k,
  276. i
  277. );
  278. option.series[hoveredIndex].pieStatus.hovered = isHovered;
  279. // 将此前记录的上次选中的扇形对应的系列号 seriesIndex 清空
  280. hoveredIndex = '';
  281. }
  282. // 使用更新后的 option,渲染图表
  283. myChart.setOption(option);
  284. });
  285. myChart.setOption(option);

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/105404
推荐阅读