index.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. <template>
  2. <div class="dataAnalysisSpaceAna" :class="!theme ? 'themeDark' : 'themeLight'">
  3. <div class="dataAnalysisSpaceAnaMain">
  4. <div class="main_top">
  5. <p class="topPsty">毛容量分析</p>
  6. </div>
  7. <div class="main">
  8. <div class="treeDataMain">
  9. <tree-cop :data="treeData" @checkChange="funTreeCheckChange" :show-checkbox="false"
  10. :height="treeHeight" @currentChange="funCurrentChange" @refresh="funGetTree">
  11. </tree-cop>
  12. </div>
  13. <div class="excelDataMain">
  14. <excel-cop :checkIds="excelCheckIds" :showCheckbox="false" :data="excelList" :height="excelHeight"
  15. :theme="theme" @excelChange="funExcelChange" @checkChange="funExcelCheckChange"></excel-cop>
  16. </div>
  17. <div class="tableDataMain">
  18. <div :style="{ height: tableHeight }">
  19. <div style="height: 49%">
  20. <el-icon :style="!theme ? 'color: #fff' : ''" class="chartIcon" size="18"
  21. @click="funActCop({xAxis:barxAxis, yAxis:baryAxis, series: barSeries}, 'barChartCop')">
  22. <ZoomIn />
  23. </el-icon>
  24. <bar-chart-cop width="100%" height="100%" :subtext="`${windName} 平均风速 ${avgSpeed}`"
  25. :theme="theme" :echartsTheme="echartsTheme" :xAxis="barxAxis" :yAxis="baryAxis"
  26. :series="barSeries"></bar-chart-cop>
  27. </div>
  28. <div style="height: 49%">
  29. <el-icon :style="!theme ? 'color: #fff' : ''" class="chartIcon" size="18"
  30. @click="funActCop({xAxis:linexAxis, yAxis:lineyAxis, series: lineSeries}, 'lineChartCop')">
  31. <ZoomIn />
  32. </el-icon>
  33. <bar-chart-cop width="100%" height="100%" :subtext="`${windName} 平均毛容量系数 ${avgMrxs}`"
  34. :theme="theme" :echartsTheme="echartsTheme" :xAxis="linexAxis" :yAxis="lineyAxis"
  35. :series="lineSeries"></bar-chart-cop>
  36. </div>
  37. </div>
  38. </div>
  39. </div>
  40. </div>
  41. <el-dialog custom-class="windLifeDialog" draggable width="80%" v-model="dialog" :title="actDiaTitle">
  42. <el-form class="whitespace-nowrap" :inline="true" :model="queryForm">
  43. <el-form-item label="" class="!mb-0">
  44. <el-select v-model="queryForm.checkIds" clearable @clear="checkAll = false" collapse-tags multiple>
  45. <el-option label="全选" :class="{'selected': checkAll}" @click="funCheckAll"></el-option>
  46. <el-option v-for="item in chartExcelList" :key="item.id" :value="item.id" :label="item.name">
  47. </el-option>
  48. </el-select>
  49. </el-form-item>
  50. <el-form-item class="!mb-0">
  51. <submit-btn desc="查询" @click="funDiaSubmit"></submit-btn>
  52. <submit-btn desc="导出" @click="funDiaExport"></submit-btn>
  53. </el-form-item>
  54. </el-form>
  55. <div v-loading="exportLoading">
  56. <el-row ref="diaPanelRef" style="height: 650px;overflow-y:auto;over-x:hidden">
  57. <el-col :span="actCopList.length > 1 ? 12 : 24" v-for="item in actCopList" :key="item.id"
  58. style="height: 650px">
  59. <component :is="item.actCop" width="100%" height="100%" :xAxis="item.xAxis"
  60. :subtext="item.subtext" :title="item.title" :series="item.series"
  61. :isDiaAlone="(actCopList.length === 1)" @dblclick="funDbClick(item)" :yAxis="item.yAxis"
  62. :dataset="item.dataset" :brush="item.isBrush" :theme="theme" :echartsTheme="echartsTheme"
  63. @getSelected="funChartSelect"></component>
  64. </el-col>
  65. </el-row>
  66. </div>
  67. </el-dialog>
  68. </div>
  69. </template>
  70. <script setup name="rateAnalysis">
  71. import excelCop from '@/components/generatingCapacityComponent/excel.vue'
  72. import treeCop from '@/components/generatingCapacityComponent/tree.vue'
  73. import barChartCop from './components/barChart.vue'
  74. import {
  75. onMounted,
  76. ref,
  77. onActivated,
  78. shallowRef,
  79. reactive,
  80. nextTick,
  81. watch
  82. } from 'vue'
  83. import {
  84. useStore
  85. } from 'vuex';
  86. import httpRequest from '@/utils/request.js'
  87. import tools from '@tools/htmlToPdf.js'
  88. /**配置参数 */
  89. const treeHeight = ref(window.innerHeight - 125 + 'px') //tree高度
  90. const excelHeight = ref(window.innerHeight - 125 + 'px') //excel高度
  91. const tableHeight = ref(window.innerHeight - 125 + 'px')
  92. /**excel 开始 */
  93. const excelCheckIds = ref([])
  94. const excelList = ref([])
  95. /** 额定功率 */
  96. const powerproduction = ref("")
  97. //点击excel项时
  98. const funExcelChange = async (obj) => {
  99. excelCheckIds.value = [obj.id] //当为单选展示风机图表时
  100. chartExcelList.value = excelList.value.map(o => {
  101. return {
  102. ...o,
  103. name: o.windturbine
  104. }
  105. }) // 选中excel当前项时, excel列表赋值给dialog 下拉框
  106. queryForm.checkIds = excelList.value.map(o => o.id)
  107. checkAll.value = true
  108. funSubmit()
  109. }
  110. const funExcelCheckChange = ({
  111. checkArr,
  112. data
  113. }) => {
  114. excelCheckIds.value = checkArr
  115. }
  116. /**tree 开始 */
  117. const treeData = ref([])
  118. const actTreeNode = ref(null)
  119. const funRepeatMap = (arr) => {
  120. return arr.map(o => {
  121. if (o.children) {
  122. const findIndex = o.children.findIndex(p => !!p.type)
  123. if (findIndex !== -1) {
  124. o.childs = o.children
  125. o.children = []
  126. if (!actTreeNode.value) {
  127. actTreeNode.value = o
  128. }
  129. }
  130. }
  131. return {
  132. ...o,
  133. children: o.children.length ? funRepeatMap(o.children) : []
  134. }
  135. })
  136. }
  137. const funGetTree = async () => {
  138. const res = await httpRequest.get("/power/process/tree")
  139. actTreeNode.value = null
  140. excelList.value = []
  141. treeData.value = funRepeatMap(res.data)
  142. if (actTreeNode.value) {
  143. funCurrentChange({
  144. current: actTreeNode.value,
  145. currentNode: null
  146. })
  147. funExcelChange({
  148. id: actTreeNode.value.childs[0].id
  149. })
  150. }
  151. }
  152. const funTreeCheckChange = ({
  153. current,
  154. checkedNodes,
  155. checkedKeys,
  156. halfCheckedNodes,
  157. halfCheckedKeys
  158. }) => { //tree change -> excel change
  159. funCurrentChange({
  160. current,
  161. currentNode: ''
  162. })
  163. const checkIds = []
  164. if (checkedNodes.length) {
  165. for (const node of checkedNodes) {
  166. if (node.childs && node.childs.length) {
  167. for (const child of node.childs) {
  168. checkIds.push(child.id)
  169. }
  170. }
  171. }
  172. }
  173. excelCheckIds.value = checkIds
  174. }
  175. const funCurrentChange = ({
  176. current,
  177. currentNode
  178. }) => {
  179. if (current.childs) {
  180. excelList.value = current.childs.map(o => {
  181. return {
  182. id: o.id,
  183. interval: o.interval,
  184. path: o.path,
  185. prepareid: o.prepareid,
  186. station: o.station,
  187. time: o.time,
  188. type: o.type,
  189. windturbine: o.windturbine,
  190. name: o.path.substring(o.path.indexOf(o.station + '_') + (o.station + '_').length)
  191. }
  192. })
  193. if (excelList.value.length > 0) {
  194. funExcelChange(excelList.value[0])
  195. }
  196. } else {
  197. excelList.value = []
  198. }
  199. }
  200. /**chart */
  201. let chartId = 1
  202. const powerproductionNum = ref(0)
  203. const avgSpeed = ref('')
  204. const avgMrxs = ref('')
  205. const windName = ref('')
  206. /**submit */
  207. const funSubmit = async () => {
  208. const tempRes = await httpRequest.get('/wind/avg/speed', {
  209. params: {
  210. ids: excelCheckIds.value.join(','),
  211. }
  212. })
  213. if (tempRes.code === 200) {
  214. if (tempRes.data.length) {
  215. for (const chart of tempRes.data) {
  216. chart.currentData.sort((a, b) => {
  217. return new Date(a.time).getTime() - new Date(b.time).getTime()
  218. })
  219. chart.preData.sort((a, b) => {
  220. return new Date(a.time).getTime() - new Date(b.time).getTime()
  221. })
  222. let xAxisData = [],
  223. barData1 = [],
  224. barData2 = [],
  225. lineData1 = [],
  226. lineData2 = []
  227. let avgSpeedSum = 0,
  228. avgMrxsSum = 0
  229. chart.currentData.forEach(current => {
  230. xAxisData.push(current.time)
  231. barData1.push(current.avgspeed)
  232. avgSpeedSum += current.avgspeed
  233. avgMrxsSum += current.mrxs
  234. lineData1.push((current.mrxs * 100).toFixed(2))
  235. });
  236. chart.preData.forEach(current => {
  237. xAxisData.push(current.time)
  238. barData2.push(current.avgspeed)
  239. lineData2.push((current.mrxs * 100).toFixed(2))
  240. });
  241. avgSpeed.value = (avgSpeedSum / barData1.length).toFixed(2) + ' m/s'
  242. avgMrxs.value = (avgMrxsSum / lineData1.length * 100).toFixed(2) + ' %'
  243. // windName.value = chart.wtId
  244. windName.value = chart.code
  245. barxAxis.data = xAxisData
  246. linexAxis.data = xAxisData
  247. barSeries[0].data = barData1
  248. barSeries[1].data = barData2
  249. chartId++
  250. lineSeries[0].data = lineData1
  251. lineSeries[1].data = lineData2
  252. chartId++
  253. }
  254. }
  255. }
  256. }
  257. /**lineChart */
  258. const linexAxis = reactive({
  259. type: 'category',
  260. name: '月',
  261. data: [],
  262. splitLine: {
  263. show: false
  264. },
  265. axisTick: {
  266. show: true
  267. },
  268. axisLine: {
  269. onZero: false
  270. }
  271. })
  272. const lineyAxis = reactive({
  273. type: 'value',
  274. name: '%',
  275. splitLine: {
  276. show: false
  277. },
  278. axisTick: {
  279. show: true
  280. },
  281. axisLine: {
  282. onZero: false
  283. }
  284. })
  285. const lineSeries = reactive([{
  286. name: "最新",
  287. type: "line",
  288. data: [],
  289. symbol: "line", //设定为实心点
  290. symbolSize: 0, //设定实心点的大小
  291. markLine: {
  292. symbol: 'none',
  293. label: {
  294. show: true,
  295. },
  296. lineStyle: {
  297. color: '#F72C5B'
  298. },
  299. data: []
  300. }
  301. }, {
  302. name: "历史",
  303. type: "line",
  304. data: [],
  305. symbol: "line", //设定为实心点
  306. symbolSize: 0, //设定实心点的大小
  307. markLine: {
  308. symbol: 'none',
  309. label: {
  310. show: false,
  311. },
  312. lineStyle: {
  313. color: '#F72C5B'
  314. },
  315. data: []
  316. }
  317. }])
  318. // 圈选散点触发函数
  319. const funChartSelect = async (batch) => {
  320. const wDataArr = []
  321. const yDataArr = []
  322. let scatterls = []
  323. let dataSetObj = []
  324. wtData.value = []
  325. if (batch.length && actCopList.value[0].dataset) {
  326. scatterls = batch[0].selected[1].dataIndex
  327. if (scatterls.length) {
  328. dataSetObj = JSON.parse(actCopList.value[0].dataset)
  329. if (scatterls.length) {
  330. for (const scatterIndex of scatterls) {
  331. wDataArr.push(dataSetObj[0].source[scatterIndex].k)
  332. }
  333. }
  334. const wtRes = await httpRequest.get('/power/fitting/filter', {
  335. params: {
  336. yk: yDataArr.join(','),
  337. wk: wDataArr.join(',')
  338. }
  339. })
  340. if (wtRes.code === 200) {
  341. let id = 1
  342. const tempArr = [] //用于以风机id 聚合dataArr
  343. if (wtRes.data.length) {
  344. for (const data of wtRes.data) {
  345. if (tempArr.length) {
  346. const findIndex = tempArr.findIndex(o => o.wtId === data.wtId)
  347. if (findIndex !== -1) {
  348. if (!tempArr[findIndex].children) {
  349. tempArr[findIndex].children = []
  350. }
  351. tempArr[findIndex].children.push({
  352. ...data,
  353. id: id,
  354. filter: data.filter === 0 ? '是' : '否'
  355. })
  356. id++
  357. } else {
  358. tempArr.push({
  359. ...data,
  360. id: id,
  361. filter: data.filter === 0 ? '是' : '否'
  362. })
  363. id++
  364. }
  365. } else {
  366. tempArr.push({
  367. ...data,
  368. id: id,
  369. filter: data.filter === 0 ? '是' : '否'
  370. })
  371. id++
  372. }
  373. }
  374. wtDialog.value = true
  375. nextTick(() => {
  376. wtTab.value = 'table'
  377. wtData.value = tempArr
  378. })
  379. }
  380. }
  381. }
  382. }
  383. }
  384. /**barChart */
  385. const barxAxis = reactive({
  386. type: 'category',
  387. name: '月',
  388. data: [],
  389. splitLine: {
  390. show: false
  391. },
  392. axisTick: {
  393. show: true
  394. },
  395. axisLine: {
  396. onZero: false
  397. }
  398. })
  399. const baryAxis = reactive({
  400. type: 'value',
  401. name: 'm/s',
  402. splitLine: {
  403. show: false
  404. },
  405. axisTick: {
  406. show: true
  407. },
  408. axisLine: {
  409. onZero: false
  410. }
  411. })
  412. const barSeries = reactive([{
  413. name: "机舱风速(最近)",
  414. type: "line",
  415. symbol: "line", //设定为实心点
  416. symbolSize: 0, //设定实心点的大小
  417. data: [],
  418. markLine: {
  419. symbol: 'none',
  420. label: {
  421. show: true,
  422. },
  423. lineStyle: {
  424. color: '#F72C5B'
  425. },
  426. data: []
  427. }
  428. }, {
  429. name: "机舱风速(历史)",
  430. type: "line",
  431. symbol: "line", //设定为实心点
  432. symbolSize: 0, //设定实心点的大小
  433. data: [],
  434. markLine: {
  435. symbol: 'none',
  436. label: {
  437. show: false,
  438. },
  439. lineStyle: {
  440. color: '#F72C5B'
  441. },
  442. data: []
  443. }
  444. }])
  445. /**dialog 数据 */
  446. const wtDialog = ref(false)
  447. const wtData = ref([])
  448. const wtTab = ref('table')
  449. /**dialog */
  450. const dialog = ref(false)
  451. const actChartName = ref('')
  452. const actDiaTitle = ref('')
  453. const diaPanelRef = ref()
  454. const exportLoading = ref(false)
  455. const actCopList = ref([
  456. // {
  457. // xAxis: [],
  458. // subtext: '',
  459. // title: '',
  460. // isRadar: false,
  461. // series: [],
  462. // yAxis: [],
  463. // dataset: []
  464. // }
  465. ])
  466. // 作为actCopList的备份 在actCopList赋值多个时 同时赋值, 在dialog弹出时清空. 作用: 在actCopList变化时, 重新赋值原始数据
  467. const actCopListBak = ref([])
  468. const checkAll = ref(true)
  469. const queryForm = reactive({
  470. checkIds: []
  471. })
  472. const funCheckAll = () => {
  473. checkAll.value = !checkAll.value
  474. if (checkAll.value) {
  475. queryForm.checkIds = chartExcelList.value.map(o => o.id)
  476. } else {
  477. queryForm.checkIds = []
  478. }
  479. }
  480. const chartExcelList = ref([]) //dialog 下拉项
  481. const funActCop = (obj, type) => {
  482. switch (type) {
  483. case 'barChartCop':
  484. actChartName.value = 'barChartCop'
  485. obj.actCop = shallowRef(barChartCop)
  486. actDiaTitle.value = '风速'
  487. break
  488. case 'lineChartCop':
  489. actChartName.value = 'lineChartCop'
  490. obj.actCop = shallowRef(barChartCop)
  491. actDiaTitle.value = '毛容量系数'
  492. break
  493. // case 'CurrentScatterChartCop':
  494. // actChartName.value = 'CurrentScatterChartCop'
  495. // obj.actCop = shallowRef(CurrentScatte // console.log(res)rChartCop)
  496. // actDiaTitle.value = '静态偏航对风分析图'
  497. // break
  498. }
  499. obj.isBrush = false
  500. obj.id = chartId
  501. chartId++
  502. dialog.value = true
  503. actCopListBak.value = []
  504. nextTick(() => {
  505. actCopList.value = [obj]
  506. })
  507. }
  508. const funDiaSubmit = async () => {
  509. let url = ''
  510. switch (actChartName.value) {
  511. case 'barChartCop':
  512. url = '/wind/avg/speed'
  513. break
  514. case 'lineChartCop':
  515. url = '/wind/avg/speed'
  516. break
  517. // case 'CurrentScatterChartCop':
  518. // url = '' //暂无接口
  519. // break
  520. }
  521. if (url) {
  522. const res = await httpRequest.get(url, {
  523. params: {
  524. ids: queryForm.checkIds.join(','),
  525. mode: 0
  526. }
  527. })
  528. if (res.code === 200) {
  529. actCopList.value = []
  530. actCopListBak.value = [] //清空备份
  531. if (res.data.length) {
  532. for (const chart of res.data) {
  533. chart.currentData.sort((a, b) => {
  534. return new Date(a.time).getTime() - new Date(b.time).getTime()
  535. })
  536. chart.preData.sort((a, b) => {
  537. return new Date(a.time).getTime() - new Date(b.time).getTime()
  538. })
  539. const xAxisData = [],
  540. barData1 = [],
  541. barData2 = [],
  542. lineData1 = [],
  543. lineData2 = []
  544. let avgSpeedSum = 0,
  545. avgMrxsSum = 0
  546. let avgSpeedDesc = '',
  547. avgMrxsDesc = ''
  548. for (const current of chart.currentData) {
  549. xAxisData.push(current.time)
  550. barData1.push(current.avgspeed)
  551. avgSpeedSum += current.avgspeed
  552. avgMrxsSum += current.mrxs
  553. lineData1.push((current.mrxs * 100).toFixed(2))
  554. }
  555. for (const current of chart.preData) {
  556. barData2.push(current.avgspeed)
  557. lineData2.push((current.mrxs * 100).toFixed(2))
  558. }
  559. avgSpeedDesc = (avgSpeedSum / barData1.length).toFixed(2) + ' m/s'
  560. avgMrxsDesc = (avgMrxsSum / lineData1.length * 100).toFixed(2) + ' %'
  561. if (actChartName.value === 'barChartCop') {
  562. actCopList.value.push({
  563. id: chartId,
  564. isBrush: false,
  565. actCop: shallowRef(barChartCop),
  566. // title: chart.windturbine,
  567. subtext: `${chart.wtId} 平均风速 ${avgSpeedDesc}`,
  568. xAxis: {
  569. ...barxAxis,
  570. data: xAxisData
  571. },
  572. yAxis: baryAxis,
  573. series: [{
  574. ...barSeries[0],
  575. data: barData1
  576. }, {
  577. ...barSeries[1],
  578. data: barData2
  579. }]
  580. })
  581. chartId++
  582. }
  583. if (actChartName.value === 'lineChartCop') {
  584. actCopList.value.push({
  585. id: chartId,
  586. isBrush: false,
  587. actCop: shallowRef(barChartCop),
  588. // title: chart.windturbine,
  589. subtext: `${chart.wtId} 平均毛容量系数 ${avgMrxsDesc}`,
  590. xAxis: {
  591. ...linexAxis,
  592. data: xAxisData
  593. },
  594. yAxis: lineyAxis,
  595. series: [{
  596. ...lineSeries[0],
  597. data: lineData1
  598. }, {
  599. ...lineSeries[1],
  600. data: lineData2
  601. }]
  602. })
  603. chartId++
  604. }
  605. }
  606. actCopListBak.value = actCopList.value
  607. }
  608. }
  609. }
  610. }
  611. const funDiaExport = () => {
  612. exportLoading.value = true
  613. tools.scrollToPDF(diaPanelRef.value, actDiaTitle.value, () => {
  614. exportLoading.value = false
  615. })
  616. }
  617. const funDbClick = (obj) => {
  618. if (actCopListBak.value.length > 1) { //判断大于1时, 才有双击放大功能
  619. if (actCopList.value.length === 1) {
  620. actCopList.value = actCopListBak.value
  621. } else {
  622. actCopList.value = [obj]
  623. }
  624. }
  625. }
  626. /**created */
  627. // funGetTree()
  628. const theme = ref(null)
  629. const echartsTheme = ref('')
  630. const store = useStore()
  631. watch(() => store.state.theme, (newVal, oldVal) => {
  632. theme.value = newVal
  633. echartsTheme.value = !newVal ? 'dark' : ''
  634. funGetTree()
  635. }, {
  636. deep: true
  637. })
  638. /**activated */
  639. onMounted(() => {
  640. //test
  641. // funSubmit()
  642. //
  643. funGetTree()
  644. theme.value = store.state.theme
  645. echartsTheme.value = !theme.value ? 'dark' : ''
  646. tableHeight.value = window.innerHeight - 125 + 'px'
  647. excelHeight.value = (window.innerHeight - 125) + 'px'
  648. treeHeight.value = (window.innerHeight - 125) + 'px'
  649. window.addEventListener('resize', () => {
  650. tableHeight.value = window.innerHeight - 125 + 'px'
  651. excelHeight.value = (window.innerHeight - 125) + 'px'
  652. treeHeight.value = (window.innerHeight - 125) + 'px'
  653. })
  654. })
  655. onActivated(() => {
  656. // funGetTree()
  657. })
  658. </script>
  659. <style lang="less" scoped>
  660. .dataAnalysisSpaceAna {
  661. height: 100%;
  662. .dataAnalysisSpaceAnaMain {
  663. height: 100%;
  664. .main_top {
  665. height: 40px;
  666. display: flex;
  667. align-items: center;
  668. .topPsty {
  669. position: relative;
  670. top: 5px;
  671. padding: 7px 20px;
  672. font-size: 12px;
  673. font-weight: 600;
  674. margin-left: 10px;
  675. border-radius: 3px;
  676. }
  677. }
  678. .main {
  679. display: flex;
  680. justify-content: space-between;
  681. // width: calc(100% - 40px);
  682. width: 100%;
  683. .treeDataMain,
  684. .excelDataMain,
  685. .tableDataMain {
  686. padding: 10px;
  687. border-radius: 10px;
  688. }
  689. .treeDataMain {
  690. width: calc(20% - 20px);
  691. }
  692. .excelDataMain {
  693. width: calc(13% - 20px);
  694. }
  695. .tableDataMain {
  696. width: calc(66% - 20px);
  697. position: relative;
  698. .chartIcon {
  699. cursor: pointer;
  700. }
  701. .butten_com {
  702. position: absolute;
  703. right: 20px;
  704. z-index: 111111;
  705. }
  706. }
  707. }
  708. }
  709. }
  710. .themeDark {
  711. .dataAnalysisSpaceAnaMain {
  712. .main_top {
  713. .topPsty {
  714. color: #1C99FF;
  715. background: #1E2126;
  716. }
  717. }
  718. .main {
  719. background: #13171e;
  720. .treeDataMain {
  721. background: transparent;
  722. }
  723. .excelDataMain {
  724. background: #313233;
  725. }
  726. .tableDataMain {
  727. margin-top: 5px;
  728. background: #212223;
  729. }
  730. }
  731. }
  732. }
  733. .themeLight {
  734. padding: 0;
  735. .dataAnalysisSpaceAnaMain {
  736. .main_top {
  737. .topPsty {
  738. color: #2778FF;
  739. background: #FFFFFF;
  740. }
  741. }
  742. .main {
  743. background: #E6E8F2;
  744. .treeDataMain {
  745. background: transparent;
  746. }
  747. .excelDataMain {
  748. background: #F4F6FB;
  749. }
  750. .tableDataMain {
  751. background: #fff;
  752. margin-top: 5px;
  753. }
  754. }
  755. }
  756. }
  757. </style>