useEcharts.tsx 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827
  1. import React, { useEffect, useRef, useState } from 'react'
  2. import * as echarts from 'echarts'
  3. import { EChartsOption, init, dispose, registerMap } from 'echarts'
  4. import { Empty } from 'antd'
  5. import { china } from '@/utils/dictionary'
  6. /**通用直接传入原始配置EChartsOption*/
  7. function Echarts(props: { children: EChartsOption | null, style?: { width: number | string, height: number | string } }) {
  8. const { style } = props
  9. const ref: { current: HTMLDivElement | null } = useRef(null)
  10. const [myChart, setMyChart] = useState<any>()
  11. /**创建myChart实例 */
  12. useEffect(() => {
  13. if (ref?.current && props?.children) {
  14. let myChart = init(ref.current)
  15. setMyChart(myChart)
  16. myChart.setOption(props.children);
  17. myChart.resize()
  18. }
  19. }, [ref?.current, props?.children])
  20. /**卸载myChart */
  21. useEffect(() => {
  22. return () => {
  23. if (myChart?.id) {
  24. dispose(myChart.id)
  25. }
  26. }
  27. }, [myChart?.id])
  28. return <>
  29. {
  30. props.children
  31. ?
  32. <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  33. :
  34. <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  35. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  36. </div>
  37. }
  38. </>
  39. }
  40. /**
  41. * Map粉丝统计
  42. * @param data name省名称 vlaue值
  43. * @param style width ,height
  44. */
  45. function Map(props: { data: { name: string, value: number }[], style?: { width: number | string, height: number | string } }) {
  46. const { data, style } = props
  47. const ref: { current: HTMLDivElement | null } = useRef(null)
  48. const [myChart, setMyChart] = useState<any>()
  49. /**创建myChart实例 */
  50. useEffect(() => {
  51. if (ref?.current && data.length > 0) {
  52. let myChart = init(ref.current)//初始化chart
  53. registerMap('China', require('../../public/map.json'))//获取地图数据
  54. let num: number[] = []//获取所有值方便取最大最小值
  55. let newData: any = china//处理匹配接口返回数据和地图数据的映射避免名字不同
  56. data.forEach((item: { name: string, value: number }) => {
  57. newData.forEach((data: { name: string, value: number }) => {
  58. if (item.name && data.name.indexOf(item.name) !== -1) {
  59. data.value = item.value
  60. num.push(item.value)
  61. }
  62. })
  63. })
  64. setMyChart(myChart)//存放Chart实例以备卸载
  65. myChart.setOption({//设置Chart配置
  66. /**悬浮提示 */
  67. tooltip: {
  68. trigger: 'item',
  69. formatter: '{b}:{c}'
  70. },
  71. /**右侧操作工具 */
  72. toolbox: {
  73. show: true,
  74. orient: 'vertical',
  75. right: 50,
  76. top: 'center',
  77. feature: {
  78. dataView: {
  79. readOnly: false,
  80. title: '查看详情'
  81. },
  82. restore: {
  83. title: '刷新'
  84. },
  85. saveAsImage: {
  86. title: '保存为图片'
  87. }
  88. }
  89. },
  90. /**左侧操作工具 */
  91. visualMap: {
  92. min: 0,
  93. max: Math.max(...num),
  94. text: ['High', 'Low'],
  95. realtime: false,
  96. calculable: true,
  97. top: 'middle',
  98. inRange: {
  99. color: ['lightskyblue', 'yellow', 'orangered']
  100. }
  101. },
  102. /**地图参数设置 */
  103. series: [
  104. {
  105. name: '粉丝统计',
  106. type: 'map',
  107. map: 'China', // 自定义扩展图表类型
  108. zoom: 1.2,
  109. scaleLimit: { min: 1, max: 10 },
  110. roam: true,
  111. nameProperty: 'name',
  112. data: newData,
  113. }
  114. ],
  115. });
  116. }
  117. }, [ref?.current, data])
  118. /**卸载myChart */
  119. useEffect(() => {
  120. if (data.length === 0) {
  121. if (myChart?.id) {
  122. dispose(myChart.id)
  123. }
  124. }
  125. return () => {
  126. if (myChart?.id) {
  127. dispose(myChart.id)
  128. }
  129. }
  130. }, [myChart?.id, data])
  131. return <>
  132. {
  133. data.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  134. }
  135. {
  136. data.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  137. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  138. </div>
  139. }
  140. </>
  141. }
  142. /**
  143. * 饼图总关注
  144. * @param data name 名称 value 值
  145. * @param style width,height
  146. * @param name tooltip上的名字即饼图的名字
  147. * @param centerName 饼图中心统计的名称
  148. */
  149. function PieFocus(props: {
  150. /**
  151. * @param data name 名称 value 值
  152. */
  153. data: { name: string, value: number }[],
  154. /**
  155. * @param name tooltip上的名字即饼图的名字
  156. */
  157. name: string,
  158. /**
  159. * @param centerName 饼图中心统计的名称
  160. */
  161. centerName: string,
  162. /**
  163. * @param style width,height
  164. */
  165. style?: { width: number | string, height: number | string },
  166. }) {
  167. const { data, style, name, centerName } = props
  168. const ref: { current: HTMLDivElement | null } = useRef(null)
  169. const [myChart, setMyChart] = useState<any>()
  170. /**创建myChart实例 */
  171. useEffect(() => {
  172. if (ref?.current && data.length > 0) {
  173. let myChart = init(ref.current)
  174. setMyChart(myChart)
  175. myChart.setOption({
  176. /**鼠标悬浮 */
  177. tooltip: {
  178. // trigger: 'item',
  179. // formatter: '{a} <br />{b}: {c} ({d}%)'
  180. },
  181. /**图列 */
  182. legend: {
  183. left: 'center',
  184. bottom: 0,
  185. data: data?.map((item: { name: string }) => item.name)
  186. },
  187. /**工具保存为图片 */
  188. toolbox: {
  189. right: 50,
  190. feature: {
  191. saveAsImage: {
  192. title: '保存为图片'
  193. }
  194. }
  195. },
  196. /**饼图参数 */
  197. series: [
  198. {
  199. name,
  200. type: 'pie',
  201. radius: ['50%', '70%'],
  202. // avoidLabelOverlap: false,
  203. label: {
  204. show: true,
  205. // position: 'center',
  206. // fontSize: '30',
  207. // fontWeight: 'bold',
  208. formatter: `{b}:{c} ({d}%)`,
  209. },
  210. data
  211. },
  212. {
  213. name,
  214. type: 'pie',
  215. radius: ['50%', '70%'],
  216. label: {
  217. show: true,
  218. position: 'center',
  219. fontSize: '30',
  220. fontWeight: 'bold',
  221. formatter: `${data.length > 1 ? data?.reduce((a: any, b: { value: number }) => {
  222. return (a?.value || a) + (b?.value || 0)
  223. }) : data[0].value}\n${centerName}`,
  224. },
  225. data
  226. }
  227. ]
  228. });
  229. }
  230. }, [ref?.current, data])
  231. /**卸载myChart */
  232. useEffect(() => {
  233. if (data.length === 0) {
  234. if (myChart?.id) {
  235. dispose(myChart?.id)
  236. }
  237. }
  238. return () => {
  239. if (myChart?.id) {
  240. dispose(myChart?.id)
  241. }
  242. }
  243. }, [myChart?.id, data])
  244. return <>
  245. {
  246. data.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  247. }
  248. {
  249. data.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }} >
  250. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  251. </div>
  252. }
  253. </>
  254. }
  255. /**
  256. * Line 折线图
  257. * @param data legendName 图列名称 y:x(key为Y轴的展示的名称,value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
  258. * @param style width,height
  259. */
  260. function Line(props: {
  261. data?: { legendName: string, [key: string]: any }[],
  262. style?: React.CSSProperties,
  263. areaStyle?: boolean,//线变块颜色
  264. color?: string | string[],//线颜色
  265. markPoint?: any,//浮点
  266. fontColor?: string,//文字颜色
  267. series?: boolean,//堆叠
  268. title?: string,//标题
  269. smooth?: boolean,//true 圆弧线 false 直角
  270. }) {
  271. const { data, style, areaStyle = false, color, markPoint, fontColor, series, title, smooth = false } = props
  272. const ref: { current: HTMLDivElement | null } = useRef(null)
  273. const [myChart, setMyChart] = useState<any>()
  274. let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
  275. /**创建myChart实例 */
  276. useEffect(() => {
  277. if (ref?.current && (data as any[]).length > 0) {
  278. let Xdata: any = []
  279. let Ydatas: any[] = []
  280. data?.forEach((item, index) => {
  281. Ydatas.push([])
  282. Object.keys(item).forEach((key: string) => {
  283. if (index === 0 && key !== 'legendName') {
  284. Xdata.push(key)
  285. }
  286. if (key !== 'legendName') {
  287. Ydatas[index].push(item[key])
  288. }
  289. })
  290. })
  291. let myChart = init(ref.current)
  292. setMyChart(myChart)
  293. myChart.setOption({
  294. /**鼠标悬浮 */
  295. tooltip: {
  296. trigger: 'axis'
  297. },
  298. /**图列 */
  299. legend: {
  300. data: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }) => item.legendName),
  301. bottom: 0,
  302. left: 'center',
  303. ...textStyle
  304. },
  305. xAxis: {
  306. data: Xdata,
  307. boundaryGap: false,//贴边
  308. },
  309. yAxis: [
  310. {
  311. type: 'value',
  312. },
  313. ],
  314. grid: {
  315. left: 100,
  316. right: 50,
  317. },
  318. ...textStyle,
  319. /**工具保存为图片 */
  320. toolbox: {
  321. right: 50,
  322. feature: {
  323. saveAsImage: {
  324. title: '保存为图片'
  325. }
  326. }
  327. },
  328. title: {
  329. text: title || '',
  330. textAlign: 'center',
  331. right: 'center'
  332. },
  333. /**线图参数 */
  334. series: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }, index: number) => {
  335. return {
  336. name: item.legendName,//名称
  337. type: 'line',//图形
  338. data: Ydatas[index],//数据
  339. areaStyle: areaStyle ? {} : undefined,//是否开启块级颜色
  340. color: Array.isArray(color) ? color[index] : color,//颜色
  341. markPoint: {//最大值最小值
  342. data: markPoint ? markPoint : []
  343. },
  344. emphasis: series ? { focus: 'series' } : {}, //堆叠
  345. smooth
  346. }
  347. })
  348. });
  349. }
  350. }, [ref?.current, data])
  351. /**卸载myChart */
  352. useEffect(() => {
  353. if ((data as any[])?.length === 0) {
  354. if (myChart?.id) {
  355. dispose(myChart?.id)
  356. }
  357. }
  358. return () => {
  359. if (myChart?.id) {
  360. dispose(myChart.id)
  361. }
  362. }
  363. }, [myChart?.id, data])
  364. return <>
  365. {
  366. (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  367. }
  368. {
  369. (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  370. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  371. </div>
  372. }
  373. </>
  374. }
  375. /**
  376. * Bar 柱状图
  377. * @param data legendName 图列名称 y:x(key为Y轴的展示的名称,value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
  378. * @param style width,height
  379. */
  380. function Bar(props: {
  381. data?: { legendName: string, [key: string]: any }[],
  382. style?: React.CSSProperties,
  383. fontColor?: string,//文字颜色
  384. title?: string,//标题
  385. }) {
  386. const { data, style, fontColor, title } = props
  387. const ref: { current: HTMLDivElement | null } = useRef(null)
  388. const [myChart, setMyChart] = useState<any>()
  389. let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
  390. /**创建myChart实例 */
  391. useEffect(() => {
  392. if (ref?.current && (data as any[]).length > 0) {
  393. let Xdata: any = [] // name
  394. let Ydatas: any[] = [] // value
  395. data?.forEach((item) => {
  396. Xdata.push(item.name)
  397. Ydatas.push(item.value)
  398. })
  399. let sum = eval(Ydatas.join("+"))
  400. Ydatas = Ydatas.map((item: number) => {
  401. return (item / sum * 100).toFixed(0)
  402. })
  403. let myChart = init(ref.current)
  404. setMyChart(myChart)
  405. myChart.setOption({
  406. /**鼠标悬浮 */
  407. // tooltip: {
  408. // trigger: 'axis',
  409. // },
  410. xAxis: {
  411. max: 'dataMax'
  412. },
  413. yAxis: {
  414. type: 'category',
  415. data: Xdata,
  416. inverse: true
  417. },
  418. grid: {
  419. left: 100,
  420. right: 50,
  421. },
  422. ...textStyle,
  423. title: {
  424. text: title || '',
  425. textAlign: 'center',
  426. right: 'center'
  427. },
  428. /**线图参数 */
  429. series: [
  430. {
  431. type: 'bar',//图形
  432. realtimeSort: true,
  433. data: Ydatas,//数据
  434. name: 'X',
  435. label: {
  436. show: true,
  437. position: 'right',
  438. valueAnimation: true,
  439. }
  440. }
  441. ]
  442. });
  443. }
  444. }, [ref?.current, data])
  445. /**卸载myChart */
  446. useEffect(() => {
  447. if ((data as any[])?.length === 0) {
  448. if (myChart?.id) {
  449. dispose(myChart?.id)
  450. }
  451. }
  452. return () => {
  453. if (myChart?.id) {
  454. dispose(myChart.id)
  455. }
  456. }
  457. }, [myChart?.id, data])
  458. return <>
  459. {
  460. (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  461. }
  462. {
  463. (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  464. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  465. </div>
  466. }
  467. </>
  468. }
  469. /**
  470. * Bar 柱状图
  471. * @param data legendName 图列名称 y:x(key为Y轴的展示的名称,value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
  472. * @param style width,height
  473. */
  474. // [
  475. // { name: '4341556373', value: 300 }, { name: '4341523456', value: 240 },
  476. // ]
  477. function BarMonitor(props: {
  478. data?: { legendName: string, [key: string]: any }[],
  479. style?: React.CSSProperties,
  480. fontColor?: string,//文字颜色
  481. title?: string,//标题
  482. isGraphic?: boolean, // 是否渐变
  483. xName?: string,
  484. yName?: string,
  485. planID?: string,
  486. onChange?: (id: string, accountId: number[]) => void,
  487. }) {
  488. const { data, style, fontColor, title, xName, yName, planID, onChange } = props
  489. const colors = ['#f8128d', '#fa40a3', '#f56db5', '#f58bc4', '#f7a1cf', '#f5b7d8', '#facee5', '#f8c8e2', '#f8d6e8', '#fae8f1']
  490. const ref: { current: HTMLDivElement | null } = useRef(null)
  491. const [myChart, setMyChart] = useState<any>()
  492. let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
  493. /**创建myChart实例 */
  494. useEffect(() => {
  495. if (ref?.current && (data as any[]).length > 0) {
  496. let Xdata: any = [] // name
  497. let Ydatas: any[] = [] // value
  498. data?.forEach((item) => {
  499. Xdata.push(item.adName)
  500. Ydatas.push(item.value)
  501. })
  502. let dataIndex = data?.findIndex((item: any) => item?.name == planID)
  503. Ydatas = Ydatas.map((item: number, index: number) => {
  504. if (dataIndex !== -1 && dataIndex === index) {
  505. return {
  506. value: item,
  507. itemStyle: {
  508. color: '#37A2FF',
  509. shadowColor: 'rgba(0, 0, 0, 0.8)',
  510. shadowBlur: 10,
  511. },
  512. }
  513. } else {
  514. return {
  515. value: item,
  516. itemStyle: {
  517. color: colors[index],
  518. }
  519. }
  520. }
  521. })
  522. let myChart = init(ref.current)
  523. setMyChart(myChart)
  524. myChart?.setOption({
  525. /**鼠标悬浮 */
  526. // tooltip: {
  527. // trigger: 'axis',
  528. // },
  529. xAxis: {
  530. name: xName || '',
  531. max: 'dataMax',
  532. nameTextStyle: { // y轴名字文字样式设置
  533. verticalAlign: "bottom",
  534. lineHeight: 5,
  535. fontWeight: 'bold',
  536. },
  537. axisLine: { // 坐标轴轴线相关设置
  538. show: true // 是否显示坐标轴轴线
  539. },
  540. },
  541. yAxis: {
  542. name: yName || '',
  543. type: 'category',
  544. data: Xdata,
  545. inverse: true,
  546. nameLocation: 'start', // y轴名字显示位置
  547. nameTextStyle: { // y轴名字文字样式设置
  548. verticalAlign: "bottom",
  549. lineHeight: 0,
  550. fontWeight: 'bold',
  551. color: '#000',
  552. padding: [0, 80, 0, 0]
  553. },
  554. nameGap: 20,
  555. triggerEvent: true,
  556. axisLabel: {//名称
  557. margin: 10,
  558. width: 80,
  559. overflow: 'truncate',
  560. ellipsis: '...',
  561. color: (value: any, index: any) => {
  562. if (index === dataIndex) {
  563. return '#f8128d'
  564. }
  565. return '#3946c3'
  566. },
  567. },
  568. },
  569. grid: {
  570. left: 100,
  571. right: 70
  572. },
  573. ...textStyle,
  574. title: {
  575. text: title || '起量广告排行榜',
  576. textStyle: {
  577. color: '#3946c3',
  578. fontSize: 16
  579. },
  580. left: 'center',
  581. bottom: 0,
  582. },
  583. tooltip: {
  584. show: true,
  585. // formatter:'{b0}: {c0}',
  586. formatter: function (a: any) {
  587. return `${a.marker} <strong> ${a.name} : ${a.value}</strong>`
  588. }
  589. },
  590. series: [
  591. {
  592. type: 'bar',//图形
  593. realtimeSort: true,
  594. data: Ydatas,//数据
  595. name: 'X',
  596. showBackground: true,
  597. backgroundStyle: {
  598. color: 'transparent'
  599. },
  600. label: {
  601. show: true,
  602. valueAnimation: true,
  603. position: 'right',
  604. fontSize: 14,
  605. fontWeight: 900
  606. }
  607. }
  608. ]
  609. });
  610. myChart.on('click', (params: any) => {
  611. let v = params.dataIndex
  612. let d: any = (data as any[])[v]
  613. onChange && onChange(d.name, [d.accountId])
  614. });
  615. }
  616. }, [ref?.current, data, planID])
  617. /**卸载myChart */
  618. useEffect(() => {
  619. if ((data as any[])?.length === 0) {
  620. if (myChart?.id) {
  621. dispose(myChart?.id)
  622. }
  623. }
  624. return () => {
  625. if (myChart?.id) {
  626. dispose(myChart.id)
  627. }
  628. }
  629. }, [myChart?.id, data])
  630. return <>
  631. {
  632. (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  633. }
  634. {
  635. (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  636. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  637. </div>
  638. }
  639. </>
  640. }
  641. /**
  642. * Line 折线图
  643. * @param data legendName 图列名称 y:x(key为Y轴的展示的名称,value对应X轴的值。例:{legendName:'取消关注','2020-12-12':10,'2020-12-13':11,'2020-12-14':33}[])
  644. * @param style width,height
  645. */
  646. function LineMonitor(props: {
  647. data?: { legendName: string, [key: string]: any }[],
  648. style?: React.CSSProperties,
  649. areaStyle?: boolean,//线变块颜色
  650. color?: string | string[],//线颜色
  651. markPoint?: any,//浮点
  652. fontColor?: string,//文字颜色
  653. series?: boolean,//堆叠
  654. title?: string,//标题
  655. smooth?: boolean,//true 圆弧线 false 直角
  656. dataZoomInside?: boolean, // 控制是否开启滚轮缩放
  657. dataZoomSlider?: boolean, // 控制是否开启组件缩放
  658. }) {
  659. const { data, style, areaStyle = false, color, markPoint, fontColor, series, title, smooth = false, dataZoomInside, dataZoomSlider } = props
  660. const ref: { current: HTMLDivElement | null } = useRef(null)
  661. const [myChart, setMyChart] = useState<any>()
  662. let textStyle = fontColor ? { textStyle: { color: fontColor } } : {}
  663. /**创建myChart实例 */
  664. useEffect(() => {
  665. if (ref?.current && (data as any[]).length > 0) {
  666. let Xdata: any = []
  667. let Ydatas: any[] = []
  668. data?.forEach((item, index) => {
  669. Ydatas.push([])
  670. Object.keys(item).forEach((key: string) => {
  671. if (index === 0 && key !== 'legendName') {
  672. Xdata.push(key)
  673. }
  674. if (key !== 'legendName') {
  675. Ydatas[index].push(item[key])
  676. }
  677. })
  678. })
  679. let myChart = init(ref.current)
  680. // 设置是否可缩放
  681. let dataZoom = []
  682. if (dataZoomInside) {
  683. dataZoom.push({
  684. type: 'inside'
  685. })
  686. }
  687. if (dataZoomSlider) {
  688. dataZoom.push({
  689. type: 'slider',
  690. width: 200,
  691. height: 20,
  692. top: 0,
  693. left: 140,
  694. disabled: dataZoomSlider
  695. })
  696. }
  697. setMyChart(myChart)
  698. myChart.setOption({
  699. /**鼠标悬浮 */
  700. tooltip: {
  701. trigger: 'axis'
  702. },
  703. /**图列 */
  704. legend: {
  705. data: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }) => item.legendName),
  706. bottom: 0,
  707. left: 'center',
  708. show: data && data?.length > 1 ? true : false,//数据只有一条就隐藏
  709. ...textStyle
  710. },
  711. xAxis: {
  712. data: Xdata,
  713. boundaryGap: false,//贴边
  714. },
  715. yAxis: [
  716. {
  717. type: 'value',
  718. axisLabel: {//名称
  719. fontWeight: 900,
  720. fontSize: 15,
  721. color: '#333333',
  722. textBorderColor: '#dfdfdf',
  723. textBorderWidth: 1
  724. },
  725. },
  726. ],
  727. dataZoom,
  728. grid: {
  729. left: 100,
  730. right: 50,
  731. },
  732. ...textStyle,
  733. /**工具保存为图片 */
  734. toolbox: {
  735. right: 50,
  736. // feature: {
  737. // saveAsImage: {
  738. // title: '保存为图片'
  739. // }
  740. // }
  741. },
  742. title: {
  743. text: title || '',
  744. left: 'center',
  745. bottom: 0,
  746. textStyle: {
  747. color: '#3946c3',
  748. fontSize: 16
  749. },
  750. },
  751. /**线图参数 */
  752. series: (data as { legendName: string, [key: string]: any }[]).map((item: { legendName: string }, index: number) => {
  753. return {
  754. name: item.legendName,//名称
  755. type: 'line',//图形
  756. data: Ydatas[index],//数据
  757. areaStyle: areaStyle ? {} : undefined,//是否开启块级颜色
  758. color: Array.isArray(color) ? color[index] : color,//颜色
  759. markPoint: {//最大值最小值
  760. data: markPoint ? markPoint : []
  761. },
  762. emphasis: series ? { focus: 'series' } : {}, //堆叠
  763. smooth
  764. }
  765. })
  766. });
  767. }
  768. }, [ref?.current, data])
  769. /**卸载myChart */
  770. useEffect(() => {
  771. if ((data as any[])?.length === 0) {
  772. if (myChart?.id) {
  773. dispose(myChart?.id)
  774. }
  775. }
  776. return () => {
  777. if (myChart?.id) {
  778. dispose(myChart.id)
  779. }
  780. }
  781. }, [myChart?.id, data])
  782. return <>
  783. {
  784. (data as any[])?.length > 0 && <div ref={ref} style={style ? style : { width: '100%', height: '100%' }} />
  785. }
  786. {
  787. (data as any[])?.length === 0 && <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
  788. <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
  789. </div>
  790. }
  791. </>
  792. }
  793. /**
  794. * 常用option配置//https://echarts.apache.org/next/zh/option.html#legend
  795. * @param legend 图例组件 用于用户操作筛选图表展示的组件
  796. * @param title 图标标题
  797. * @param grid 网格控制 可在一个渲染框架中渲染多个图表 或单个图表的间距宽高等值的设定
  798. * @param xAxis grid 中的 x 轴的设置
  799. * @param yAxis grid 中的 y 轴的设置
  800. * @param tooltip 鼠标悬浮的提示组件
  801. * @param series 系列数据配置
  802. */
  803. function useEcharts() {
  804. return {
  805. Echarts,
  806. Map,
  807. PieFocus,
  808. Line,
  809. Bar,
  810. BarMonitor,
  811. LineMonitor
  812. }
  813. }
  814. export default useEcharts