echartOption.js 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  1. export const getBarOptions = (currentData = []) => {
  2. const xAxis = ["1#好氧池硝酸盐", "2#好氧池硝酸盐", "1#缺氧氨氮", "2#缺氧氨氮", "二沉池正磷酸盐"];
  3. const rangeData = [12, 12, 15, 15, 0.4];
  4. let option = {
  5. tooltip: {
  6. trigger: 'axis',
  7. },
  8. grid: {
  9. bottom: '4%',
  10. top: "6%",
  11. left: "5%",
  12. right: "2%",
  13. containLabel: true,
  14. // bottom: "4%",
  15. // top: "6%",
  16. // left: "10%",
  17. // right: "2%",
  18. },
  19. legend: {
  20. show: false,
  21. },
  22. xAxis: [
  23. {
  24. type: "category",
  25. data: xAxis,
  26. axisLabel: {
  27. interval: 0,
  28. show: true,
  29. fontSize: '12px',
  30. color: "#fff",
  31. },
  32. axisLine: {
  33. show: true,
  34. lineStyle: {
  35. show: true,
  36. color: "#3f4a59",
  37. },
  38. },
  39. axisTick: {
  40. show: false,
  41. },
  42. },
  43. ],
  44. yAxis: [
  45. {
  46. splitNumber: 4,
  47. type: "value",
  48. axisLabel: {
  49. show: true,
  50. fontSize: '12px',
  51. color: "#fff"
  52. },
  53. axisLine: {
  54. show: false,
  55. lineStyle: {
  56. color: "#3f4a59",
  57. },
  58. },
  59. axisTick: {
  60. show: false,
  61. },
  62. splitLine: {
  63. lineStyle: {
  64. color: "#3f4a59",
  65. },
  66. }
  67. },
  68. ],
  69. series: [
  70. {
  71. name: 'maxdata',
  72. type: 'custom',
  73. itemStyle: {
  74. color: 'rgba(216, 230, 255, .1)'
  75. },
  76. renderItem: function (params, api) {
  77. //获取对应类目的axisTick中心点坐标
  78. var start = api.coord([api.value(0)])
  79. //通过坐标系的宽度和类目数,计算单个类目的背景
  80. var width = (params.coordSys.width / 7) * 0.7
  81. return {
  82. type: 'rect',
  83. shape: {
  84. // 相对左上角坐标
  85. x: start[0] - width / 2,
  86. y: params.coordSys.y,
  87. width: width,
  88. height: params.coordSys.height
  89. },
  90. style: api.style()
  91. }
  92. },
  93. data: currentData.map(() => 0)
  94. },
  95. {
  96. name: "当前值",
  97. type: "bar",
  98. itemStyle: {
  99. borderRadius: [2, 2, 0, 0],
  100. color: {
  101. x: 0,
  102. y: 0,
  103. x2: 0,
  104. y2: 1,
  105. colorStops: [
  106. {
  107. offset: 0,
  108. color: "#FBB03B",
  109. },
  110. {
  111. offset: 1,
  112. color: "rgba(246,115,7, 0.1)",
  113. },
  114. ],
  115. },
  116. },
  117. barWidth: 8,
  118. data: currentData,
  119. },
  120. {
  121. name: "标准值",
  122. type: "bar",
  123. itemStyle: {
  124. color: {
  125. x: 0,
  126. y: 0,
  127. x2: 0,
  128. y2: 1,
  129. colorStops: [
  130. {
  131. offset: 0,
  132. color: "#17FFC9",
  133. },
  134. {
  135. offset: 1,
  136. color: "rgba(10,184,4, 0.1)",
  137. },
  138. ],
  139. },
  140. },
  141. barWidth: 8,
  142. // 展示柱图背景
  143. data: rangeData,
  144. },
  145. {
  146. // 柱形顶部色块
  147. name: '',
  148. type: 'pictorialBar',
  149. itemStyle: {
  150. normal: {
  151. color: '#FF6737'
  152. }
  153. },
  154. tooltip: {
  155. show: false
  156. },
  157. symbolRepeat: false,
  158. symbolMargin: 8,
  159. symbol: 'rect',
  160. symbolClip: false,
  161. symbolSize: [7, 2],
  162. symbolPosition: 'end',
  163. symbolOffset: [-5, 0],
  164. data: currentData,
  165. width: 1,
  166. z: 0,
  167. zlevel: 1
  168. },
  169. {
  170. // 柱形顶部色块
  171. name: '',
  172. type: 'pictorialBar',
  173. itemStyle: {
  174. normal: {
  175. color: '#00AB84'
  176. }
  177. },
  178. tooltip: {
  179. show: false
  180. },
  181. symbolRepeat: false,
  182. symbolMargin: 8,
  183. symbol: 'rect',
  184. symbolClip: false,
  185. symbolSize: [7, 2],
  186. symbolPosition: 'end',
  187. symbolOffset: [5, 0],
  188. data: rangeData,
  189. width: 1,
  190. z: 0,
  191. zlevel: 1
  192. },
  193. ],
  194. };
  195. return option;
  196. }
  197. export const getPieOptions = (optionsData) => {
  198. let colors = ['#00A0E9', '#00AB84', '#C6A3FF', '#E9D0A1', '#45D3F2']
  199. function getParametricEquation(
  200. startRatio,
  201. endRatio,
  202. isSelected,
  203. isHovered,
  204. k,
  205. height,
  206. i
  207. ) {
  208. // 计算
  209. let midRatio = (startRatio + endRatio) / 2;
  210. let startRadian = startRatio * Math.PI * 2;
  211. let endRadian = endRatio * Math.PI * 2;
  212. let midRadian = midRatio * Math.PI * 2;
  213. // 如果只有一个扇形,则不实现选中效果。
  214. if (startRatio === 0 && endRatio === 1) {
  215. isSelected = false;
  216. }
  217. // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
  218. k = typeof k !== "undefined" ? k : 1 / 3;
  219. // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
  220. let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
  221. let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
  222. let offsetZ = i == 1 ? 2 : 0;
  223. // 计算高亮效果的放大比例(未高亮,则比例为 1)
  224. let hoverRate = isHovered ? 1.05 : 1;
  225. // 返回曲面参数方程
  226. return {
  227. u: {
  228. min: -Math.PI,
  229. max: Math.PI * 3,
  230. step: Math.PI / 32,
  231. },
  232. v: {
  233. min: 0,
  234. max: Math.PI * 2,
  235. step: Math.PI / 20,
  236. },
  237. x: function (u, v) {
  238. if (u < startRadian) {
  239. return (
  240. offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
  241. );
  242. }
  243. if (u > endRadian) {
  244. return (
  245. offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
  246. );
  247. }
  248. return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
  249. },
  250. y: function (u, v) {
  251. if (u < startRadian) {
  252. return (
  253. offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
  254. );
  255. }
  256. if (u > endRadian) {
  257. return (
  258. offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
  259. );
  260. }
  261. return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
  262. },
  263. z: function (u, v) {
  264. if (u < -Math.PI * 0.5) {
  265. return Math.sin(u);
  266. }
  267. if (u > Math.PI * 2.5) {
  268. return Math.sin(u);
  269. }
  270. return Math.sin(v) > 0 ? 1 * height : -1;
  271. },
  272. };
  273. }
  274. // 生成模拟 3D 饼图的配置项
  275. function getPie3D(pieData, internalDiameterRatio) {
  276. let series = [];
  277. let sumValue = 0;
  278. let startValue = 0;
  279. let endValue = 0;
  280. let legendData = [];
  281. let k =
  282. typeof internalDiameterRatio !== "undefined"
  283. ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
  284. : 1 / 3;
  285. // 为每一个饼图数据,生成一个 series-surface 配置
  286. for (let i = 0; i < pieData.length - 1; i++) {
  287. sumValue += pieData[i].value;
  288. let seriesItem = {
  289. name:
  290. typeof pieData[i].name === "undefined"
  291. ? `series${i}`
  292. : pieData[i].name,
  293. type: "surface",
  294. parametric: true,
  295. wireframe: {
  296. show: false,
  297. },
  298. pieData: pieData[i],
  299. itemStyle: {
  300. color: pieData[i].color, // 自定义颜色
  301. opacity: '0.7'
  302. },
  303. pieStatus: {
  304. selected: false,
  305. hovered: false,
  306. k: k,
  307. },
  308. };
  309. if (typeof pieData[i].itemStyle != "undefined") {
  310. let itemStyle = {};
  311. typeof pieData[i].itemStyle.color != "undefined"
  312. ? (itemStyle.color = pieData[i].itemStyle.color)
  313. : null;
  314. typeof pieData[i].itemStyle.opacity != "undefined"
  315. ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
  316. : null;
  317. seriesItem.itemStyle = itemStyle;
  318. }
  319. series.push(seriesItem);
  320. }
  321. for (let i = 0; i < series.length; i++) {
  322. endValue = startValue + series[i].pieData.value;
  323. series[i].pieData.startRatio = startValue / sumValue;
  324. series[i].pieData.endRatio = endValue / sumValue;
  325. series[i].parametricEquation = getParametricEquation(
  326. series[i].pieData.startRatio,
  327. series[i].pieData.endRatio,
  328. false,
  329. false,
  330. k,
  331. // 调整扇形高度
  332. i === 0 ? 10 : 10,
  333. i,
  334. series[i].pieData.value
  335. );
  336. startValue = endValue;
  337. legendData.push(series[i].name);
  338. }
  339. return series;
  340. }
  341. const series = getPie3D(optionsData, 0.6); // 可做为调整内环大小 0为实心圆饼图,大于0 小于1 为圆环
  342. series.push({
  343. name: "pie2d",
  344. type: "pie",
  345. startAngle: 2, //起始角度,支持范围[0, 360]。
  346. clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
  347. // radius: ["50%", "60%"],
  348. // center: ["62%", "50%"],
  349. data: optionsData,
  350. itemStyle: {
  351. opacity: 0,
  352. },
  353. labelLine: {
  354. show: false
  355. },
  356. label: {
  357. show: false,
  358. position: 'center'
  359. },
  360. });
  361. // 准备待返回的配置项,把准备好的 legendData、series 传入。
  362. let option = {
  363. animation: true,
  364. tooltip: {
  365. formatter: (params) => {
  366. if (params.seriesName !== 'mouseoutSeries') {
  367. const { name, value, color} = optionsData[params.seriesIndex] ?? {};
  368. return `${name
  369. }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${color
  370. };"></span>${value}` ;
  371. }
  372. },
  373. },
  374. title: {
  375. x: "center",
  376. top: "20",
  377. textStyle: {
  378. color: "#fff",
  379. fontSize: 22,
  380. },
  381. },
  382. xAxis3D: {
  383. min: -1,
  384. max: 1,
  385. },
  386. yAxis3D: {
  387. min: -1,
  388. max: 1,
  389. },
  390. zAxis3D: {
  391. min: -1,
  392. max: 1,
  393. },
  394. grid3D: {
  395. show: false,
  396. boxHeight: 2.5,
  397. top: '-10%',
  398. // left: "8%",
  399. // bottom: "50%",
  400. viewControl: {
  401. // alpha: 38,
  402. // beta: 70,
  403. enabled: true,
  404. alpha: 30,
  405. beta: 55,
  406. distance: 150,
  407. rotateSensitivity: 0, //设置为0无法旋转
  408. zoomSensitivity: 0, //设置为0无法缩放
  409. panSensitivity: 0, //设置为0无法平移
  410. autoRotate: false, //自动旋转
  411. // beta: 325,
  412. // autoRotate: false, // 自动旋转
  413. },
  414. },
  415. series: series,
  416. };
  417. // return option
  418. // let colors = ['#16d0ff', '#664bff', '#37a2da', '#ffdb5c', '#ff9f7f', '#9fe6b8', '#67e0e3', '#32c5e9', '#fb7293', "#9A60B4", "#ea7ccc"]
  419. // // 传入数据生成 option
  420. // const optionsData = [
  421. // {
  422. // name: "第一科室",
  423. // value: 68,
  424. // },
  425. // {
  426. // name: "第二科室",
  427. // value: 52,
  428. // },
  429. // {
  430. // name: "第三科室",
  431. // value: 37,
  432. // },
  433. // {
  434. // name: "第四科室",
  435. // value: 58,
  436. // },
  437. // ];
  438. // function getParametricEquation(
  439. // startRatio,
  440. // endRatio,
  441. // isSelected,
  442. // isHovered,
  443. // k,
  444. // height,
  445. // i
  446. // ) {
  447. // // 计算
  448. // let midRatio = (startRatio + endRatio) / 2;
  449. // let startRadian = startRatio * Math.PI * 2;
  450. // let endRadian = endRatio * Math.PI * 2;
  451. // let midRadian = midRatio * Math.PI * 2;
  452. // // 如果只有一个扇形,则不实现选中效果。
  453. // if (startRatio === 0 && endRatio === 1) {
  454. // isSelected = false;
  455. // }
  456. // // 通过扇形内径/外径的值,换算出辅助参数 k(默认值 1/3)
  457. // k = typeof k !== "undefined" ? k : 1 / 3;
  458. // // 计算选中效果分别在 x 轴、y 轴方向上的位移(未选中,则位移均为 0)
  459. // let offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0;
  460. // let offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0;
  461. // let offsetZ = i == 1 ? 2 : 0;
  462. // // 计算高亮效果的放大比例(未高亮,则比例为 1)
  463. // let hoverRate = isHovered ? 1.05 : 1;
  464. // // 返回曲面参数方程
  465. // return {
  466. // u: {
  467. // min: -Math.PI,
  468. // max: Math.PI * 3,
  469. // step: Math.PI / 32,
  470. // },
  471. // v: {
  472. // min: 0,
  473. // max: Math.PI * 2,
  474. // step: Math.PI / 20,
  475. // },
  476. // x: function (u, v) {
  477. // if (u < startRadian) {
  478. // return (
  479. // offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
  480. // );
  481. // }
  482. // if (u > endRadian) {
  483. // return (
  484. // offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
  485. // );
  486. // }
  487. // return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate;
  488. // },
  489. // y: function (u, v) {
  490. // if (u < startRadian) {
  491. // return (
  492. // offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
  493. // );
  494. // }
  495. // if (u > endRadian) {
  496. // return (
  497. // offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
  498. // );
  499. // }
  500. // return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate;
  501. // },
  502. // z: function (u, v) {
  503. // if (u < -Math.PI * 0.5) {
  504. // return Math.sin(u);
  505. // }
  506. // if (u > Math.PI * 2.5) {
  507. // return Math.sin(u);
  508. // }
  509. // return Math.sin(v) > 0 ? 1 * height : -1;
  510. // },
  511. // };
  512. // }
  513. // // 生成模拟 3D 饼图的配置项
  514. // function getPie3D(pieData, internalDiameterRatio) {
  515. // let series = [];
  516. // let sumValue = 0;
  517. // let startValue = 0;
  518. // let endValue = 0;
  519. // let legendData = [];
  520. // let k =
  521. // typeof internalDiameterRatio !== "undefined"
  522. // ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio)
  523. // : 1 / 3;
  524. // // 为每一个饼图数据,生成一个 series-surface 配置
  525. // for (let i = 0; i < pieData.length; i++) {
  526. // sumValue += pieData[i].value;
  527. // let seriesItem = {
  528. // name:
  529. // typeof pieData[i].name === "undefined"
  530. // ? `series${i}`
  531. // : pieData[i].name,
  532. // type: "surface",
  533. // parametric: true,
  534. // wireframe: {
  535. // show: false,
  536. // },
  537. // pieData: pieData[i],
  538. // itemStyle: {
  539. // color: colors[i], // 自定义颜色
  540. // opacity: '0.7'
  541. // },
  542. // pieStatus: {
  543. // selected: false,
  544. // hovered: false,
  545. // k: k,
  546. // },
  547. // };
  548. // if (typeof pieData[i].itemStyle != "undefined") {
  549. // let itemStyle = {};
  550. // typeof pieData[i].itemStyle.color != "undefined"
  551. // ? (itemStyle.color = pieData[i].itemStyle.color)
  552. // : null;
  553. // typeof pieData[i].itemStyle.opacity != "undefined"
  554. // ? (itemStyle.opacity = pieData[i].itemStyle.opacity)
  555. // : null;
  556. // seriesItem.itemStyle = itemStyle;
  557. // }
  558. // series.push(seriesItem);
  559. // }
  560. // // 使用上一次遍历时,计算出的数据和 sumValue,调用 getParametricEquation 函数,
  561. // // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation,也就是实现每一个扇形。
  562. // for (let i = 0; i < series.length; i++) {
  563. // endValue = startValue + series[i].pieData.value;
  564. // console.log(series[i]);
  565. // series[i].pieData.startRatio = startValue / sumValue;
  566. // series[i].pieData.endRatio = endValue / sumValue;
  567. // series[i].parametricEquation = getParametricEquation(
  568. // series[i].pieData.startRatio,
  569. // series[i].pieData.endRatio,
  570. // false,
  571. // false,
  572. // k,
  573. // // 调整扇形高度
  574. // i === 0 ? 10 : 10,
  575. // i,
  576. // series[i].pieData.value
  577. // );
  578. // startValue = endValue;
  579. // legendData.push(series[i].name);
  580. // }
  581. // return series;
  582. // }
  583. // const series = getPie3D(optionsData, 0.6); // 可做为调整内环大小 0为实心圆饼图,大于0 小于1 为圆环
  584. // series.push({
  585. // name: "pie2d",
  586. // type: "pie",
  587. // label: {
  588. // opacity: 1,
  589. // fontSize: 14,
  590. // lineHeight: 20,
  591. // textStyle: {
  592. // fontSize: 14,
  593. // color: "#fff",
  594. // },
  595. // },
  596. // labelLine: {
  597. // length: 10,
  598. // length2: 10,
  599. // },
  600. // startAngle: 2, //起始角度,支持范围[0, 360]。
  601. // clockwise: false, //饼图的扇区是否是顺时针排布。上述这两项配置主要是为了对齐3d的样式
  602. // radius: ["50%", "60%"],
  603. // center: ["62%", "50%"],
  604. // data: optionsData,
  605. // itemStyle: {
  606. // opacity: 0,
  607. // },
  608. // labelLine: {
  609. // show: false
  610. // },
  611. // label: {
  612. // show: false,
  613. // position: 'center'
  614. // },
  615. // });
  616. // // 准备待返回的配置项,把准备好的 legendData、series 传入。
  617. // let option = {
  618. // animation: true,
  619. // tooltip: {
  620. // show: false,
  621. // textStyle: {
  622. // fontSize: 14,
  623. // },
  624. // },
  625. // title: {
  626. // x: "center",
  627. // top: "20",
  628. // textStyle: {
  629. // color: "#fff",
  630. // fontSize: 22,
  631. // },
  632. // },
  633. // labelLine: {
  634. // show: true,
  635. // lineStyle: {
  636. // color: "#7BC0CB",
  637. // },
  638. // normal: {
  639. // show: false,
  640. // length: 10,
  641. // length2: 10,
  642. // },
  643. // },
  644. // label: {
  645. // show: true,
  646. // position: "outside",
  647. // // formatter: "{b} {d}%",
  648. // formatter: function (optionsData) {
  649. // console.log('optionsData', optionsData)
  650. // return (
  651. // "{name|" +
  652. // optionsData.name +
  653. // "}" +
  654. // " {value|" +
  655. // optionsData.percent.toFixed(0) +
  656. // "%}"
  657. // );
  658. // },
  659. // rich: {
  660. // name: {
  661. // fontSize: 14,
  662. // color: "#ffffff",
  663. // },
  664. // value: {
  665. // fontSize: 14,
  666. // color: "#ffffff",
  667. // },
  668. // },
  669. // textStyle: {
  670. // color: "#fff",
  671. // fontSize: "14px",
  672. // },
  673. // },
  674. // xAxis3D: {
  675. // min: -1,
  676. // max: 1,
  677. // },
  678. // yAxis3D: {
  679. // min: -1,
  680. // max: 1,
  681. // },
  682. // zAxis3D: {
  683. // min: -1,
  684. // max: 1,
  685. // },
  686. // grid3D: {
  687. // show: false,
  688. // boxHeight: 2,
  689. // top: '-10%',
  690. // // left: "8%",
  691. // // bottom: "50%",
  692. // // environment: "rgba(255,255,255,0)",
  693. // viewControl: {
  694. // alpha: 30,
  695. // distance: 150,
  696. // beta: 15,
  697. // autoRotate: false, // 自动旋转
  698. // // // alpha: 38,
  699. // // // beta: 70,
  700. // // enabled: true,
  701. // // alpha: 30,
  702. // // beta: 30,
  703. // // distance: 150,
  704. // // rotateSensitivity: 0, //设置为0无法旋转
  705. // // zoomSensitivity: 0, //设置为0无法缩放
  706. // // panSensitivity: 0, //设置为0无法平移
  707. // // autoRotate: false, //自动旋转
  708. // },
  709. // },
  710. // series: series,
  711. // };
  712. return option;
  713. }