You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

800 lines
22 KiB

2 months ago
2 months ago
  1. <template>
  2. <div ref="bottomRadarRef" class="bottomRadarChart"></div>
  3. </template>
  4. <script setup>
  5. import { ref, onBeforeUnmount } from 'vue'
  6. import { createChartResizeHandler, applyResponsiveStyles } from '@/utils/chartResize.js'
  7. import * as echarts from 'echarts'
  8. const bottomRadarRef = ref(null)
  9. let bottomRadarChart = null
  10. let resizeHandler = null
  11. function initEmotionalBottomRadar(KlineData, barAndLineData) {
  12. // 如果已存在图表实例,先销毁
  13. if (bottomRadarChart) {
  14. bottomRadarChart.dispose()
  15. bottomRadarChart = null
  16. }
  17. if (!bottomRadarRef.value) {
  18. console.error('bottomRadarRef not found');
  19. return;
  20. }
  21. bottomRadarChart = echarts.init(bottomRadarRef.value)
  22. // 日期-作为x轴
  23. let dateArray = barAndLineData.map(subArray => subArray[0])
  24. // k线数据格式:['2025/04/24', 250.5, 259.51, 249.2, 259.54, 274.899, 0.685, 258.354]
  25. // 原始数据:索引1=开盘价, 索引2=收盘价, 索引3=最低价, 索引4=最高价
  26. // ECharts candlestick需要:[开盘, 收盘, 最低, 最高]
  27. let kLineDataArray = KlineData.map(subArray => [
  28. subArray[1], // 开盘价
  29. subArray[2], // 收盘价
  30. subArray[3], // 最低价
  31. subArray[4] // 最高价
  32. ])
  33. // 计算K线数据的最小值,用于设置y轴起始值
  34. let allKlineValues = []
  35. kLineDataArray.forEach(item => {
  36. if (Array.isArray(item) && item.length >= 4) {
  37. // K线数据格式:[开盘价, 收盘价, 最低价, 最高价]
  38. allKlineValues.push(item[0], item[1], item[2], item[3])
  39. }
  40. })
  41. // 找到最小值和最大值
  42. let validValues = allKlineValues.filter(val => typeof val === 'number' && !isNaN(val))
  43. let minValue = Math.min(...validValues)
  44. let maxValue = Math.max(...validValues)
  45. // 最小值向下取整,最大值向上取整
  46. let yAxisMin = Math.floor(minValue)
  47. let yAxisMax = Math.ceil(maxValue)
  48. // 红线,取第二个值
  49. let redLineDataArray = barAndLineData.map(subArray => subArray[1])
  50. // 色块数据格式化
  51. let barTotalDataArray = barAndLineData.map(subArray => subArray.slice(2, 6))
  52. // 删掉
  53. // barTotalDataArray[0] = [0, 0, 0, 0]
  54. // barTotalDataArray[8] = [1, 1, 1, 1]
  55. // barTotalDataArray[9] = [0, 0, 1, 1]
  56. // barTotalDataArray[13] = [1, 0, 1, 0]
  57. // barTotalDataArray[16] = [0, 0, 1, 0]
  58. // 黄色块、黄色加仓资金、紫色柱子、蓝色柱子
  59. let yellowBlockDataArray = []
  60. let yellowLineDataArray = []
  61. let purpleLineDataArray = []
  62. let blueLineDataArray = []
  63. let transparentFillingDataArray = []
  64. // 黄色块:为1 0-4显示柱体
  65. // 黄色加仓资金文字:为1 在4的位置展示文字
  66. // 紫色柱子:为1 1-80显示柱体
  67. // 蓝色柱子:为1 0-40显示柱体
  68. // 因数据要互相叠加展示,所以需要数据处理。base适用于 ECharts 4.x 及以上版本
  69. barTotalDataArray.forEach((item) => {
  70. if (item[0]) {
  71. yellowBlockDataArray.push(4)
  72. if (item[3]) {
  73. // 40-4
  74. blueLineDataArray.push(36)
  75. if (item[2]) {
  76. // 80-40
  77. purpleLineDataArray.push(40)
  78. transparentFillingDataArray.push(0)
  79. } else {
  80. purpleLineDataArray.push(0)
  81. transparentFillingDataArray.push(0)
  82. }
  83. } else {
  84. blueLineDataArray.push(0)
  85. if (item[2]) {
  86. // 80-4
  87. purpleLineDataArray.push(76)
  88. transparentFillingDataArray.push(0)
  89. } else {
  90. purpleLineDataArray.push(0)
  91. transparentFillingDataArray.push(0)
  92. }
  93. }
  94. } else if (!item[0]) {
  95. yellowBlockDataArray.push(0)
  96. if (item[3]) {
  97. blueLineDataArray.push(40)
  98. if (item[2]) {
  99. // 80-40
  100. purpleLineDataArray.push(40)
  101. transparentFillingDataArray.push(0)
  102. } else {
  103. purpleLineDataArray.push(0)
  104. transparentFillingDataArray.push(0)
  105. }
  106. } else {
  107. blueLineDataArray.push(0)
  108. if (item[2]) {
  109. // 80-1,base为1
  110. purpleLineDataArray.push(79)
  111. transparentFillingDataArray.push(1)
  112. } else {
  113. purpleLineDataArray.push(0)
  114. transparentFillingDataArray.push(0)
  115. }
  116. }
  117. }
  118. // 加仓资金
  119. if (item[1]) {
  120. yellowLineDataArray.push(1)
  121. } else if (!item[1]) {
  122. yellowLineDataArray.push(0)
  123. }
  124. })
  125. // 配置图表选项,很多操作和展示已限制,如果需要需放开
  126. let option = {
  127. // backgroundColor: '#000046', // 设置整个图表的背景色
  128. axisPointer: {
  129. link: {
  130. xAxisIndex: 'all' // 全局设置所有x轴联动
  131. }
  132. },
  133. tooltip: {
  134. show: true, // 启用tooltip显示
  135. trigger: 'axis',
  136. triggerOn: 'mousemove',
  137. confine: true,
  138. axisPointer: {
  139. type: 'cross',
  140. crossStyle: {
  141. color: 'grey',
  142. width: 1,
  143. type: 'dashed'
  144. },
  145. lineStyle: {
  146. color: 'grey',
  147. width: 1,
  148. type: 'dashed'
  149. },
  150. label: {
  151. backgroundColor: 'rgba(0, 0, 0, 0.8)',
  152. color: '#fff',
  153. borderColor: '#fff',
  154. borderWidth: 1
  155. }
  156. },
  157. // backgroundColor: 'rgba(0, 0, 0, 0.8)',
  158. backgroundColor: 'rgba(232, 232, 242, 0.87)',
  159. borderColor: '#fff',
  160. borderWidth: 1,
  161. padding: 10,
  162. textStyle: {
  163. color: '#fff',
  164. fontSize: 12
  165. },
  166. formatter: function (params) {
  167. if (!params || params.length === 0) return ''
  168. // 检查是否有第二个或第三个网格的数据,如果有则不显示tooltip
  169. let hasSecondOrThirdGrid = params.some(param => {
  170. return (param.seriesName === '红线' && param.axisIndex === 1) ||
  171. (param.axisIndex === 2) ||
  172. (param.seriesName !== 'K线' && param.seriesName !== '基础base')
  173. })
  174. // 如果鼠标悬浮在第二个或第三个网格上,不显示tooltip
  175. if (hasSecondOrThirdGrid && !params.some(param => param.seriesType === 'candlestick')) {
  176. return ''
  177. }
  178. let result = `<div style="font-weight: bold; color: black; margin-bottom: 8px;">${params[0].name}</div>`
  179. // 对params进行排序,确保K线数据优先显示
  180. const sortedParams = params.sort((a, b) => {
  181. if (a.seriesType === 'candlestick') return -1;
  182. if (b.seriesType === 'candlestick') return 1;
  183. if (a.seriesName === '红线') return -1;
  184. if (b.seriesName === '红线') return 1;
  185. return 0;
  186. });
  187. sortedParams.forEach(param => {
  188. let value = param.value
  189. let color = param.color
  190. if (param.seriesType === 'candlestick') {
  191. // ECharts candlestick的value格式:[开盘, 收盘, 最低, 最高]
  192. let candlestickData = param.value
  193. // 确保数据有效性
  194. if (!Array.isArray(candlestickData) || candlestickData.length < 4) {
  195. return ''
  196. }
  197. let openPrice = candlestickData[1] // 开盘价
  198. let closePrice = candlestickData[2] // 收盘价
  199. let lowPrice = candlestickData[3] // 最低价
  200. let highPrice = candlestickData[4] // 最高价
  201. // 确保所有价格都是有效数字
  202. if (typeof openPrice !== 'number' || typeof closePrice !== 'number' ||
  203. typeof lowPrice !== 'number' || typeof highPrice !== 'number') {
  204. return ''
  205. }
  206. // 获取前一日收盘价
  207. let previousClosePrice = null;
  208. const currentIndex = param.dataIndex;
  209. if (currentIndex > 0 && kLineDataArray && kLineDataArray[currentIndex - 1]) {
  210. // 从原始K线数据中获取前一日收盘价
  211. const previousData = kLineDataArray[currentIndex - 1];
  212. if (previousData && Array.isArray(previousData) && previousData.length >= 2) {
  213. previousClosePrice = previousData[1]; // 前一日收盘价(ECharts格式:[开盘, 收盘, 最低, 最高])
  214. }
  215. }
  216. result += `<div style="margin-bottom: 6px;">`
  217. result += `<div style="color: black; font-weight: bold;">${param.seriesName}</div>`
  218. result += `<div style="color: black;">开盘价: ${openPrice}</div>`
  219. result += `<div style="color: black;">收盘价: ${closePrice}</div>`
  220. result += `<div style="color: black;">最低价: ${lowPrice}</div>`
  221. result += `<div style="color: black;">最高价: ${highPrice}</div>`
  222. // 只有当存在前一日收盘价时才显示涨跌幅
  223. if (previousClosePrice !== null && typeof previousClosePrice === 'number') {
  224. let priceChange = closePrice - previousClosePrice;
  225. let changePercent = ((priceChange / previousClosePrice) * 100).toFixed(2);
  226. let changeColor = priceChange >= 0 ? '#14b143' : '#ef232a'; // 互换颜色:上涨红色,下跌绿色
  227. result += `<div style="color: ${changeColor};">涨跌: ${priceChange >= 0 ? '+' : ''}${priceChange.toFixed(2)} (${changePercent}%)</div>`;
  228. }
  229. result += `</div>`
  230. } else if (param.seriesName === '红线') {
  231. result += `<div style="color: #ef232a; margin-bottom: 4px;">${param.seriesName}: ${value}</div>`
  232. } else if (param.seriesName !== '基础base' && value > 0) {
  233. result += `<div style="color: ${color}; margin-bottom: 4px;">${param.seriesName}: ${value}</div>`
  234. }
  235. })
  236. return result
  237. }
  238. },
  239. legend: {
  240. // data: ['K线', '红线', '色块'], 不要展示图例
  241. type: 'scroll',
  242. pageButtonItemGap: 2,
  243. pageButtonPosition: 'end',
  244. textStyle: {
  245. color: '#666'
  246. }
  247. },
  248. grid: [
  249. {
  250. left: '10%',
  251. right: '3%',
  252. top: '20px',
  253. bottom: '50%',
  254. height: '150px',
  255. width: '85%'
  256. // containLabel: true
  257. },
  258. {
  259. left: '10%',
  260. right: '3%',
  261. top: '170px',
  262. bottom: '25%',
  263. height: '150px',
  264. width: '85%'
  265. // containLabel: true
  266. },
  267. {
  268. left: '10%',
  269. right: '3%',
  270. top: '320px',
  271. bottom: '50px',
  272. height: '150px',
  273. width: '85%'
  274. // containLabel: true
  275. }
  276. ],
  277. xAxis: [
  278. {
  279. type: 'category',
  280. data: dateArray,
  281. gridIndex: 0,
  282. boundaryGap: true, // 保持间距,不要离y轴太近,不然重叠了
  283. axisLine: {
  284. // show: false,
  285. lineStyle: {
  286. color: 'white', // x轴线颜色
  287. }
  288. },
  289. axisTick: {
  290. show: false,
  291. alignWithLabel: true, // 刻度线与标签对齐
  292. lineStyle: {
  293. color: "#999", // 与十字线颜色保持一致
  294. width: 1,
  295. type: "dashed" // 与十字线样式保持一致
  296. }
  297. },
  298. axisLabel: {
  299. show: false
  300. },
  301. splitLine: {
  302. show: false // 不要x轴的分割线
  303. },
  304. axisPointer: {
  305. link: {
  306. xAxisIndex: 'all'
  307. },
  308. label: {
  309. show: false // 不显示标签
  310. }
  311. }
  312. },
  313. {
  314. type: 'category',
  315. data: dateArray,
  316. gridIndex: 1,
  317. boundaryGap: true,
  318. axisLine: {
  319. // show: false,
  320. lineStyle: {
  321. // color: '#008000'
  322. color: 'white'
  323. }
  324. },
  325. axisTick: {
  326. show: false
  327. },
  328. axisLabel: {
  329. show: false
  330. },
  331. splitLine: {
  332. show: false
  333. },
  334. axisPointer: {
  335. link: {
  336. xAxisIndex: 'all'
  337. },
  338. label: {
  339. show: false // 不显示标签
  340. }
  341. }
  342. },
  343. {
  344. type: 'category',
  345. data: dateArray,
  346. gridIndex: 2,
  347. axisLine: {
  348. lineStyle: {
  349. color: 'white'
  350. }
  351. },
  352. axisTick: {
  353. show: true, // 显示刻度线
  354. alignWithLabel: true,
  355. lineStyle: {
  356. color: '#999', // 颜色
  357. width: 1, // 宽度
  358. type: 'solid' // 线样式(solid/dashed/dotted)
  359. }
  360. },
  361. axisLabel: {
  362. color: 'white',
  363. interval: 'auto', // 自动计算显示间隔,只显示部分日期但覆盖所有范围
  364. rotate: 0 // 取消倾斜角度
  365. },
  366. splitLine: {
  367. show: false
  368. },
  369. axisPointer: {
  370. link: {
  371. xAxisIndex: 'all'
  372. }
  373. }
  374. }
  375. ],
  376. yAxis: [
  377. {
  378. type: 'value',
  379. gridIndex: 0,
  380. splitNumber: 4,
  381. min: yAxisMin, // 设置y轴最小值为数据最小值向下取整
  382. max: yAxisMax, // 设置y轴最大值为数据最大值向上取整
  383. interval: (yAxisMax - yAxisMin) / 4, // 设置固定间隔,避免重复值
  384. axisLine: {
  385. lineStyle: {
  386. color: 'white' // y轴坐标轴颜色
  387. }
  388. },
  389. axisTick: {
  390. show: true
  391. },
  392. axisLabel: {
  393. width: 50, // 宽度限制
  394. color: 'white',
  395. formatter: function (value, index) {
  396. // 显示一位小数
  397. return value.toFixed(1);
  398. }
  399. },
  400. splitLine: {
  401. show: false,
  402. lineStyle: {
  403. color: '#837b7b',
  404. type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线
  405. }
  406. },
  407. scale: true, // 不强制包含0,不然k线图底部空余太多
  408. },
  409. {
  410. type: 'value',
  411. gridIndex: 1,
  412. splitNumber: 3,
  413. axisLine: {
  414. lineStyle: {
  415. color: 'white'
  416. }
  417. },
  418. axisTick: {
  419. show: true
  420. },
  421. splitNumber: 5, // 刻度数量
  422. axisLabel: {
  423. width: 50, // 宽度限制
  424. color: 'white',
  425. formatter: function (value, index) {
  426. // 如果没有刻度数量,其他方法获取不到y轴刻度总长
  427. if (index === 0) {
  428. return '0'
  429. } else if (index === 5) {
  430. return ''
  431. }
  432. return value
  433. }
  434. },
  435. splitLine: {
  436. show: false,
  437. lineStyle: {
  438. color: '#837b7b',
  439. type: 'dotted'
  440. }
  441. },
  442. },
  443. {
  444. type: 'value',
  445. gridIndex: 2,
  446. splitNumber: 2,
  447. axisLine: {
  448. lineStyle: {
  449. color: 'white'
  450. }
  451. },
  452. axisTick: {
  453. show: true
  454. },
  455. splitNumber: 5, // 刻度数量
  456. axisLabel: {
  457. width: 50, // 宽度限制
  458. color: 'white',
  459. formatter: function (value, index) {
  460. if (index === 5) {
  461. return ''
  462. }
  463. return value
  464. }
  465. },
  466. splitLine: {
  467. show: false,
  468. lineStyle: {
  469. color: '#837b7b',
  470. type: 'dotted' // 设置网格线类型 dotted:虚线 solid:实线
  471. }
  472. },
  473. splitNumber: 5,
  474. min: function (value) {
  475. return 0 // 最小值
  476. },
  477. max: function (value) {
  478. return value.max + 10 // 比最大值高10, 避免最高点和上一个图表x轴重合
  479. }
  480. }
  481. ],
  482. dataZoom: [
  483. {
  484. type: 'slider',
  485. xAxisIndex: [0, 1, 2],
  486. start: 50,
  487. end: 100,
  488. show: true,
  489. bottom: window.innerWidth > 768 ? 30 : 50,
  490. height: 20,
  491. borderColor: '#CFD6E3',
  492. fillerColor: 'rgba(135, 175, 274, 0.2)',
  493. handleStyle: {
  494. color: '#CFD6E3'
  495. },
  496. textStyle: {
  497. color: '#fff'
  498. },
  499. dataBackground: {
  500. lineStyle: {
  501. color: '#CFD6E3'
  502. },
  503. areaStyle: {
  504. color: 'rgba(241,243,247,0.5)'
  505. }
  506. }
  507. },
  508. {
  509. type: 'inside',
  510. xAxisIndex: [0, 1, 2],
  511. start: 50,
  512. end: 100,
  513. zoomOnMouseWheel: true,
  514. moveOnMouseMove: true,
  515. moveOnMouseWheel: false
  516. }
  517. ],
  518. series: [
  519. {
  520. name: 'K线',
  521. type: 'candlestick',
  522. data: kLineDataArray,
  523. xAxisIndex: 0,
  524. yAxisIndex: 0,
  525. itemStyle: {
  526. color: '#14b143', // 开盘价 > 收盘价时为绿色
  527. color0: '#ef232a', // 开盘价 < 收盘价时为红色
  528. borderColor: '#14b143',
  529. borderColor0: '#ef232a',
  530. normal: {
  531. color: '#14b143', // 开盘价 > 收盘价时为绿色
  532. color0: '#ef232a', // 开盘价 < 收盘价时为红色
  533. borderColor: '#14b143',
  534. borderColor0: '#ef232a',
  535. opacity: function (params) {
  536. // K线数据格式:[开,收,低,高] 收盘价 > 开盘价时为阳线,设置边框不透明、填充透明
  537. return params.data[1] > params.data[0] ? 0 : 1
  538. }
  539. }
  540. }
  541. },
  542. {
  543. name: '红线',
  544. type: 'line',
  545. data: redLineDataArray,
  546. xAxisIndex: 1,
  547. yAxisIndex: 1,
  548. symbol: 'none',
  549. sampling: 'average',
  550. itemStyle: {
  551. normal: {
  552. color: '#ef232a'
  553. }
  554. },
  555. areaStyle: {
  556. color: {
  557. type: 'linear',
  558. x: 0,
  559. y: 0,
  560. x2: 0,
  561. y2: 1,
  562. colorStops: [
  563. { offset: 0, color: 'rgba(33, 150, 243, 0.4)' },
  564. { offset: 1, color: 'rgba(33, 150, 243, 0)' }
  565. ]
  566. }
  567. }
  568. },
  569. {
  570. name: '基础base',
  571. type: 'bar',
  572. stack: 'total',
  573. // barGap: '-100%', // 重叠
  574. xAxisIndex: 2,
  575. yAxisIndex: 2,
  576. barCategoryGap: '0%',
  577. itemStyle: {
  578. normal: {
  579. color: '#ffffff',
  580. borderWidth: 0,
  581. }
  582. },
  583. data: transparentFillingDataArray,
  584. },
  585. {
  586. name: '黄色',
  587. type: 'bar',
  588. stack: 'total',
  589. // barGap: '-100%', // 重叠
  590. xAxisIndex: 2,
  591. yAxisIndex: 2,
  592. barCategoryGap: '0%', // 类目间柱条间距为0
  593. itemStyle: {
  594. normal: {
  595. color: 'rgba(255, 255, 0, 1)',
  596. borderWidth: 0,
  597. // 加仓资金的文字显示
  598. label: {
  599. show: (params) => {
  600. return yellowLineDataArray[params.dataIndex] > 0
  601. },
  602. position: 'top',
  603. textStyle: {
  604. color: 'rgba(255, 255, 0, 1)'
  605. },
  606. formatter: (params) => {
  607. return yellowLineDataArray[params.dataIndex] > 0 ? '加仓资金' : ''
  608. }
  609. }
  610. }
  611. },
  612. data: yellowBlockDataArray,
  613. },
  614. {
  615. name: '蓝色',
  616. type: 'bar',
  617. stack: 'total',
  618. xAxisIndex: 2,
  619. yAxisIndex: 2,
  620. barCategoryGap: '0%', // 类目间柱条间距为0
  621. label: {
  622. show: true,
  623. position: 'inside'
  624. },
  625. itemStyle: {
  626. normal: {
  627. color: 'rgba(34, 196, 190, 1)',
  628. borderWidth: 0
  629. }
  630. },
  631. data: blueLineDataArray
  632. },
  633. {
  634. name: '紫色',
  635. type: 'bar',
  636. stack: 'total',
  637. xAxisIndex: 2,
  638. yAxisIndex: 2,
  639. barCategoryGap: '0%', // 类目间柱条间距为0
  640. label: {
  641. show: true,
  642. position: 'inside'
  643. },
  644. itemStyle: {
  645. normal: {
  646. color: 'rgba(191, 87, 222, 1)',
  647. borderWidth: 0
  648. }
  649. },
  650. data: purpleLineDataArray
  651. },
  652. ]
  653. }
  654. // 使用配置项显示图表
  655. bottomRadarChart.setOption(option)
  656. // 添加图表交互事件监听器
  657. if (bottomRadarChart) {
  658. // 监听数据缩放事件
  659. bottomRadarChart.on('dataZoom', () => {
  660. if (window.handleChartInteractionStart) {
  661. window.handleChartInteractionStart();
  662. }
  663. });
  664. // 监听鼠标滚轮事件(缩放)
  665. bottomRadarChart.on('mousewheel', () => {
  666. if (window.handleChartInteractionStart) {
  667. window.handleChartInteractionStart();
  668. }
  669. });
  670. // 监听鼠标按下事件(拖拽开始)
  671. bottomRadarChart.on('mousedown', () => {
  672. if (window.handleChartInteractionStart) {
  673. window.handleChartInteractionStart();
  674. }
  675. });
  676. // 监听鼠标释放事件(拖拽结束)
  677. bottomRadarChart.on('mouseup', () => {
  678. if (window.handleChartInteractionEnd) {
  679. window.handleChartInteractionEnd();
  680. }
  681. });
  682. // 监听图表点击事件
  683. bottomRadarChart.on('click', () => {
  684. if (window.handleChartInteractionStart) {
  685. window.handleChartInteractionStart();
  686. }
  687. });
  688. }
  689. // 应用响应式样式
  690. if (bottomRadarRef.value) {
  691. applyResponsiveStyles(bottomRadarRef.value);
  692. }
  693. // 创建响应式处理器
  694. if (resizeHandler) {
  695. resizeHandler.cleanup();
  696. }
  697. resizeHandler = createChartResizeHandler({
  698. chart: bottomRadarChart,
  699. container: bottomRadarRef.value,
  700. option: option,
  701. beforeResize: adjustGridHeight,
  702. name: '情绪探底雷达图表'
  703. });
  704. // 立即触发一次resize以确保初始布局正确
  705. setTimeout(() => {
  706. if (resizeHandler) {
  707. resizeHandler.triggerResize();
  708. }
  709. }, 100);
  710. function adjustGridHeight() {
  711. if (window.innerWidth <= 768) {
  712. option.grid[0].height = '150px'
  713. option.grid[1].height = '150px'
  714. option.grid[2].height = '150px'
  715. option.grid[0].left = '15%'
  716. option.grid[1].left = '15%'
  717. option.grid[2].left = '15%'
  718. option.grid[1].top = '170px'
  719. option.grid[2].top = '320px'
  720. option.grid[0].width = '80%'
  721. option.grid[1].width = '80%'
  722. option.grid[2].width = '80%'
  723. }
  724. bottomRadarChart.setOption(option)
  725. }
  726. // 初始化时调整高度
  727. adjustGridHeight()
  728. }
  729. // 暴露给父级
  730. defineExpose({
  731. initEmotionalBottomRadar
  732. })
  733. onBeforeUnmount(() => {
  734. // 清理响应式处理器
  735. if (resizeHandler) {
  736. resizeHandler.cleanup();
  737. resizeHandler = null;
  738. }
  739. // 组件卸载时销毁图表
  740. if (bottomRadarChart) {
  741. bottomRadarChart.dispose();
  742. bottomRadarChart = null;
  743. }
  744. })
  745. </script>
  746. <style>
  747. .bottomRadarChart {
  748. width: 100%;
  749. height: 542px;
  750. box-sizing: border-box;
  751. overflow: hidden;
  752. margin: 0px auto !important;
  753. padding: 0;
  754. }
  755. /* 手机端适配样式 */
  756. @media only screen and (max-width: 768px) {
  757. .bottomRadarChart {
  758. width: 90% !important;
  759. height: 560px;
  760. padding: 0;
  761. }
  762. }
  763. </style>