vue踩坑記錄之echarts動(dòng)態(tài)數(shù)據(jù)刷新問題
vue echarts動(dòng)態(tài)數(shù)據(jù)刷新
需求是數(shù)據(jù)發(fā)生變化echarts會(huì)立即刷新,我將data設(shè)置未動(dòng)態(tài)的
請求數(shù)據(jù)成功之后,將數(shù)據(jù)插入到investmentnum里面,但是后來發(fā)現(xiàn)數(shù)據(jù)雖然插入成功,但是echarts圖卻沒有變化,所以我猜想是echarts沒有刷新
接下來進(jìn)行填坑
用watch 監(jiān)聽data的變化,數(shù)據(jù)發(fā)生變化時(shí)重新初始化echarts圖
watch: { //觀察data的變化 investmentnum: { handler (newVal, oldVal) { if (this.chart) { for (let i = 0; i < this.investmentnum.length; i++) { if (oldVal[i] != newVal[i]) { this.option = { //echarts tooltip: { trigger: 'item', formatter: '{a} <br/> : {c}' }, legend: { right: 'right', // data: ['金額'], data: [{name:'金額',textStyle:{color:'#4a78e8'}} ] }, xAxis: { type: 'category', name: 'x', splitLine: {show: false}, data : this.weektime, //設(shè)置坐標(biāo)軸字體顏色 axisLine: { lineStyle: { color: '#4a78e8', width: 1,//這里是為了突出顯示加上的 }} }, grid: { left: '1%', right: '1%', bottom: '3%', containLabel: true }, yAxis: { type: 'value', name: ' 金額 (萬元)', splitLine: { lineStyle: { // 使用深淺的間隔色 color: ['#60bee9'] } }, nameTextStyle: { color: ['#4a78e8'] }, axisLine: { lineStyle: { color: '#4a78e8', width: 1,//這里是為了突出顯示加上的 } }, axisLabel: { color: "#7e8c8d" //刻度線標(biāo)簽顏色 }, min: 0 }, series: [ { name: '金額', type: 'line', smooth: true, data: this.investmentnum, itemStyle : { normal : { color:'#4a78e8', lineStyle: { color:'#4a78e8' }, label: { show: true } } } } ] } this.chart.setOption(this.option) } } } else { this.init() } }, deep: true //對象內(nèi)部屬性的監(jiān)聽,關(guān)鍵。 }
以下是我自己渲染出來的圖
vue echarts動(dòng)態(tài)刷新數(shù)據(jù)(x軸y軸和title)
最近需求做一個(gè)數(shù)據(jù)表,根據(jù)篩選條件不一樣,渲染不同的內(nèi)容。
主要如下圖
如圖,一開始什么都沒有的時(shí)候默認(rèn)顯示title,當(dāng)進(jìn)行篩選的時(shí)候橫軸和縱軸都顯示相應(yīng)的數(shù)據(jù)。
問題就是,我按照其他百度問題說的做,直接賦值語句上this.chart.setOption(newVal);
然而并沒有什么用。。。。。
因?yàn)樾枨笫怯袛?shù)據(jù)時(shí)改變x軸和y軸數(shù)據(jù),隱藏標(biāo)題的渲染,百度到幾乎都是差不多一樣的解法之后,,,,我放棄了百度,自己上,因?yàn)橹坝凶鰁charts的經(jīng)驗(yàn),所以摸索起來花了一個(gè)多小時(shí)把它整出來了,最關(guān)鍵代碼先貼出來,心急的小伙伴看完就差不多可以自己擼起袖子干了。
axiasy: function(newVal, oldVal) { console.log(newVal, oldVal) this.chart.clear() // 清空echarts之前渲染的數(shù)據(jù) this.lineOption.series[0].data = this.axiasy //賦值y軸 this.lineOption.xAxis[0].data = this.axiasx //賦值x軸 this.lineOption.title.show = this.emptyshow //標(biāo)題的展示和隱藏 this.chart.setOption(this.lineOption, true) //賦值好之后將數(shù)據(jù)set進(jìn)去完事 }
上面就是我研究出來的,哈哈,滿足需求就很爽!
人狠話不多,上代碼(由于某種原因,echarts的線圖是直接抽出來的插件,so我把它展示一下,覺得難以理解可以看別人的渲染,只是修改的時(shí)候渲染的時(shí)候看這個(gè)就行)
<template> <div :id="id" :class="className" :axiasx="axiasx" :axiasy="axiasy" :style="{height:height,width:width}" /> </template> <script> import echarts from 'echarts' import resize from './mixins/resize' export default { mixins: [resize], props: { className: { type: String, default: 'chart' }, id: { type: String, default: 'chart' }, width: { type: String, default: '200px' }, height: { type: String, default: '200px' }, axiasx: { type: Array, default: () => [] }, axiasy: { type: Array, default: () => [] }, emptyshow: {//展示標(biāo)題與否 type: Boolean, default: true }, titles: {//是否輸入不同的標(biāo)題提示 type: String, default: '' } }, data() { return { chart: null, lineOption: { backgroundColor: '#394056', tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: '#57617B' } }, formatter: '時(shí)間: \n 使用率:{c}%' }, title: { text: '暫無數(shù)據(jù),選擇醫(yī)院及日期后將自動(dòng)渲染', show: this.emptyshow, textStyle: { color: '#fff', fontSize: 16 }, textAlign: 'middle', top: '50%', left: '45%' }, grid: { top: 100, left: '5%', right: '5%', bottom: '3%', containLabel: true }, xAxis: [{ type: 'category', boundaryGap: false, name: '時(shí)間', nameTextStyle: { color: 'rgb(0,253,255,0.6)', fontSize: 16 }, axisLine: { lineStyle: { color: 'rgb(23,255,243,0.3)' } }, axisLabel: { margin: 10, textStyle: { fontSize: 14, color: '#fff' } }, data: this.axiasx }], yAxis: [{ type: 'value', name: '使用率(%)', nameTextStyle: { color: 'rgb(0,253,255,0.6)', fontSize: 16 }, max: 100, axisTick: { show: false }, axisLine: { lineStyle: { color: 'rgb(23,255,243,0.3)' } }, axisLabel: { margin: 10, textStyle: { fontSize: 14, color: '#fff' } }, splitLine: { lineStyle: { color: 'rgb(23,255,243,0.3)' } } }], series: [{ name: '使用率', type: 'line', // smooth: true,//是否需要曲線平滑 symbol: 'circle', symbolSize: 5, lineStyle: { normal: { width: 1 } }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: 'rgba(23, 255, 243, 0.5)' }, { offset: 0.8, color: 'rgba(23, 255, 243, 0)' }], false), shadowColor: 'rgba(0, 0, 0, 0.1)', shadowBlur: 10 } }, itemStyle: { normal: { color: 'rgba(23, 255, 243)', borderWidth: 12, label: { show: true, position: 'top', textStyle: { color: '#fff', fontSize: 14 }, formatter: '{c}%' } } }, data: this.axiasy }] } } }, watch: { axiasy: function(newVal, oldVal) { console.log(newVal, oldVal) this.chart.clear() this.lineOption.series[0].data = this.axiasy this.lineOption.xAxis[0].data = this.axiasx this.lineOption.title.show = this.emptyshow this.chart.setOption(this.lineOption, true) }, titles: function(newVal, oldVal) { console.log(newVal, oldVal) this.chart.clear() this.lineOption.title.text = this.titles this.chart.setOption(this.lineOption, true) } }, mounted() { this.initChart() }, beforeDestroy() { if (!this.chart) { return } this.chart.dispose() this.chart = null }, methods: { initChart() { this.chart = echarts.init(document.getElementById(this.id)) this.chart.setOption(this.lineOption) } } } </script>
由于引入了mixins/resize,所以也把它貼出來
export default { data() { return { $_sidebarElm: null } }, mounted() { this.__resizeHandler = this.debounce(() => { if (this.chart) { this.chart.resize() } }, 100) window.addEventListener('resize', this.__resizeHandler) this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) }, beforeDestroy() { window.removeEventListener('resize', this.__resizeHandler) this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) }, methods: { // use $_ for mixins properties // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential $_sidebarResizeHandler(e) { if (e.propertyName === 'width') { this.__resizeHandler() } }, debounce(func, wait, immediate) { let timeout, args, context, timestamp, result const later = function() { // 據(jù)上一次觸發(fā)時(shí)間間隔 const last = +new Date() - timestamp // 上次被包裝函數(shù)被調(diào)用時(shí)間間隔 last 小于設(shè)定時(shí)間間隔 wait if (last < wait && last > 0) { timeout = setTimeout(later, wait - last) } else { timeout = null // 如果設(shè)定為immediate===true,因?yàn)殚_始邊界已經(jīng)調(diào)用過了此處無需調(diào)用 if (!immediate) { result = func.apply(context, args) if (!timeout) context = args = null } } } } }
主組件就根據(jù)條件傳參進(jìn)來即可
<div class="chart-container"> <chart height="92%" width="100%" :axiasx="axiasx" :axiasy="axiasy" :emptyshow="emptyShow" :titles="noneTitle" /> </div> <script> import Chart from '@/components/Charts/LineMarker' import { Message } from 'element-ui' import { fetchEcharts, fetchClassTable, fetchhospitalList } from '@/api/api-request' export default { name: 'TabPane', components: { Pagination, Chart }, props: { type: { type: String, default: 'et' } }, data() { return { selectValue: null, // 選擇的醫(yī)院 options: [], axiasx: [], axiasy: [], // 畫圖的y軸 emptyShow: true, // 定義是否已經(jīng)可以渲染 sortValue: '', // 排序條件選擇 noneTitle: '', // 選擇查看的圖表沒有數(shù)據(jù) dateValue: [new Date(new Date().getTime() - 3600 * 1000 * 24), new Date()], listLoading: false, // 加載數(shù)據(jù)回來后變?yōu)閒alse listQuery: { page: 1, limit: 20, total: 12 }, tableData: [] } }, created() { this.getHospital() }, methods: { getHospital() { fetchhospitalList().then(res => { console.log(res) if (res.errcode === 0) { this.options = res.hospital_list const list = getHosMessage(res) this.$store.commit('hospital/SET_HOSPITAL_LIST', list[0]) this.$store.commit('hospital/SET_DEPARTMENT_LIST', list[1]) this.$store.commit('hospital/SET_ORGINHOSPITAL_LIST', res.hospital_list) } this.loading = false }) }, getList() { // 只是折線圖 const params = { 'page': this.listQuery.page, 'hospital_id': this.selectValue, 'start_date': this.dateValue[0], 'end_date': this.dateValue[1] } fetchEcharts(params).then(res => { console.log(res) if (res.errcode === 0) { const arrx = [] const arry = [] const item = res.use_rate_list if (item.length > 0) { for (let i = 0; i < item.length; i++) { arrx.push(item[i].day) arry.push(parseFloat(item[i].use_rate) * 100) } this.axiasx = arrx this.axiasy = arry this.emptyShow = false } else { console.log('我是沒有數(shù)據(jù)的顯示') this.noneTitle = '抱歉!您選擇的醫(yī)院在本時(shí)間段并沒有數(shù)據(jù)~' this.emptyShow = true } } }) console.log(this.dateValue)// 篩選的日期 }, handleFilter() { if (!this.selectValue) { Message({ message: '請選擇需要查看的醫(yī)院!', type: 'error', duration: 2 * 1000 }) return } else if (!this.dateValue) { Message({ message: '請選擇需要查看的時(shí)間段!', type: 'error', duration: 2 * 1000 }) return } this.getList() } } } </script>
最終經(jīng)過篩選條件出來后,顯示如下:
有數(shù)據(jù)時(shí)顯示
沒有數(shù)據(jù)時(shí)顯示
最后,不要問我為什么不直接調(diào)用init函數(shù),因?yàn)橹匦落秩綿om節(jié)點(diǎn)是需要付出代價(jià)的?。。?!
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue下載excel的實(shí)現(xiàn)代碼后臺用post方法
這篇文章主要介紹了vue下載excel的實(shí)現(xiàn)代碼,后臺用post方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05vite.config.js或者vue.config.js配置方式
這篇文章主要介紹了vite.config.js或者vue.config.js配置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10解決VUE項(xiàng)目localhost端口服務(wù)器拒絕連接,只能用127.0.0.1的問題
這篇文章主要介紹了解決VUE項(xiàng)目localhost端口服務(wù)器拒絕連接,只能用127.0.0.1的問題2020-08-08利用Vue3和element-plus實(shí)現(xiàn)圖片上傳組件
element-plus提供了uploader組件,但是不好定制化。所以本文將利用Vue3和element-plus實(shí)現(xiàn)一個(gè)圖片上傳的組件,感興趣的可以了解一下2022-03-03Vue使用Echarts實(shí)現(xiàn)數(shù)據(jù)可視化的方法詳解
這篇文章主要為大家詳細(xì)介紹了Vue使用Echarts實(shí)現(xiàn)數(shù)據(jù)可視化的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03vue + el-form 實(shí)現(xiàn)的多層循環(huán)表單驗(yàn)證
這篇文章主要介紹了vue + el-form 實(shí)現(xiàn)的多層循環(huán)表單驗(yàn)證,幫助大家更好的理解和使用vue框架,感興趣的朋友可以了解下。2020-11-11vue報(bào)錯(cuò)Not?allowed?to?load?local?resource的解決辦法
這篇文章主要給大家介紹了關(guān)于vue報(bào)錯(cuò)Not?allowed?to?load?local?resource的解決辦法,這個(gè)錯(cuò)誤是因?yàn)閂ue不能加載本地資源的原因,需要的朋友可以參考下2023-07-07