这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
前言
本集锦在前后端分离的架构下,webpack打包、vue.js框架的技术下遇到的问题集锦。
在 webpack 中使用 ECharts 详见官方文档:
echarts.baidu.com/tutorial.ht…
一、JSON.parse对象转换问题
obj = JSON.parse(data)时候报错:
SyntaxError: Unexpected token . in JSON at position 0
原因:
- data已经是对象了。
- JSON.parse():将JSON字符串转换成JSON对象
- JSON.stringify():将JSON对象转换成JSON字符串
二、echarts的div高度一定要定义
高度不定义可能会导致加载了但没显示出来!
eecharts的div高度一定要定义!!
当然了宽度最好也定义!!
三、elementUI的tab页中画echarts图形问题
elementUI的tab页通过v-show控制tab页存在但不展示(v-if不存在v-show存在),但是非当前tab的高宽没有!
导致不能够一次性把所有tab页的图画上,会提示dom高宽未定义!!!
所以可通过切换tab页时将当前数值传递给echarts进行绘制。
四、主题json引入问题
1、json引入和import导入
obj = JSON.parse('/static/***.json')
parse不能这么引入json,于是我import一下吧
import from '/static/***.json'
并没有用啊,谁告诉你import这么用的!!!
2、那试试jquery读json文件咯
jQuery.getJSON("/static/***.json", "", function(response) {
obj = JSON.parse(response)
})
复制代码
还是报错,因为response已经是对象了!不需要再JSON.parse!
3、于是直接注册主题吧
jQuery.getJSON("/static/***.json", "", function(response) {
echarts.registerTheme('themeName', response)
})
let myChart = echarts.init(document.getElementById('test'), 'themeName')
复制代码
还是没用啊,不对是页面闪现了一下,因为jquery异步,又回到默认了。
4、所以将init放到jQuery处理后
如下总算能引入自定义的主题色了
jQuery.getJSON("/static/***.json", "", function(response) {
echarts.registerTheme('themeName', response)
echarts.init(document.getElementById('test'), 'themeName')
})
复制代码
5、最后其实import很好用啊,这里有了import还要什么jquery。
import chartOpt from './***.json'
let self = this
echarts.registerTheme('themeName', chartOpt)
self.initChart()
复制代码
呵呵呵,其实这样就好了。
五、echarts3D图引入需要额外下载安装echarts-gl
package.json中的dependencies,添加”echarts-gl”: “^1.1.1″,会有提示尚未安装
去项目所在根目录执行命令npm install echarts-gl –save
webpack会去下载包save指令会将下载的详情保存至package-lock.json文件中
"echarts-gl": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/echarts-gl/-/echarts-gl-1.1.1.tgz",
"integrity": "sha512-cRSTU9H+Ay+qCUFowm+2XcxYqCfi/OLK805NISeJunKgJa5p+7p7tnHZoI0qKebjtHu8VbFSOBk9UvWZ01adng==",
"requires": {
"claygl": "1.2.3",
"zrender": "4.0.4"
}
},
复制代码
在使用echarts的时候import ‘echarts-gl’即可。
六、echarts缓存问题
当series[]中包含多个对象多组data[]时:
以折线图为例,能实现一条折线到两条的增加,但是当series[]中data[]减少为一条折线数据时,仍然会显示之前的两条折线。
思考过程:
找到this.myChart.setOption(this.currentData)处,打印this.currentData
其中series[]明明只有一个,但是会画出两条甚至多条折线图!!!
猜想是不是有缓存,百度echarts缓存清理得知,需要在setOption之前调用clear方法,即:
this.myChart.clear()
this.myChart.setOption(this.currentData)
复制代码
果然问题解决。
七、echarts宽度变化后重绘的问题
window.onresize监听宽度变化毛线用没有
定时器定时查询echarts外层div的宽度不建议使用
addEventListener加载监听事件到echarts外层div总是失效
所以,可以在最外层加addEventListener宽度,变化了存起来,然后computed属性读取vuex里面存的宽度,然后watch全局宽度变量变化了就重新绘制echarts。
但是我还是喜欢定时器哈哈哈哈哈
定时器:
- 用完一定要记得关闭,用之前最好先clearTimeout!!!
- 用完一定要记得关闭,用之前最好先clearTimeout!!!
- 用完一定要记得关闭,用之前最好先clearTimeout!!!
记住这样:
somefuntion () {
// 需要定时执行的方法
clearTimeout(this.timer)
this.timer = setTimeout(somefuntion, 30000)
}
destroyed () {
clearTimeout(this.timer)
}
复制代码
解释:
写在setTimeout()之前的清除,只是为了保证当前定时器只开启了一个。
先清除缓存中的定时器,然后开启一个30s后执行一次的定时器,30s后先清除还有没有定时器(一般没有),新建一个定时器,以此循环。
比起setInterval建议使用setTimeout只是延迟执行一次
八、myChart对象定义位置的区别
自己定义的echarts组件,通常把myChart = echarts.init(document.getElementById(this.id), ‘theme-mychart’)挂在
data () {
return {
myChart: null
}
}
复制代码
同事说这样导致vue对象太大??不太理解
但是经同事建议将myChart定义在外部,如下:
let myChart = []
export default {
methods: {
echartsShow () {
echarts.registerTheme('theme-mychart', chartTheme)
myChart = echarts.init(document.getElementById(this.id), 'theme-mychart')
},
echartsResize () {
// 重绘图像
myChart.resize()
}
}
}
复制代码
这有个问题,同一路由下多个echarts组件引入,后面的myChart会覆盖前面的,导致重绘图像只能操作最后一个myChart!
最后借鉴隔壁项目组将同一路由下的myChart放到数组中定义在外部,myChart是临时变量,重绘时遍历数组如下即可:
let myChartArr = []
methods: {
echartsShow () {
echarts.registerTheme('theme-mychart', chartTheme)
let myChart = echarts.init(document.getElementById(this.id), 'theme-mychart')
// 清理echarts缓存
myChart.clear()
// 绘制图像
myChart.setOption(this.currentData)
// 判断是否需要往数组里添加myChart对象
let replace = null
for (let i = 0; i < myChartArr.length; i++) {
if (myChartArr[i]._dom.id === this.id) {
replace = i
break
}
}
if (replace !== null) {
myChartArr.splice(replace, 1, myChart)
} else {
myChartArr.push(myChart)
}
},
echartsResize () {
// 重绘图表
for (let i = 0; i < myChartArr.length; i++) {
if (this.id === myChartArr[i]._dom.id) {
myChartArr[i].resize()
break
}
}
}
}
复制代码
九、echarts3使用字符云wordCloud的方法
报错:Component series.wordCloud not exists. Load it first.
因为echarts3不再支持字符云wordCloud,需要额外引入echarts-wordcloud.js。
在webpack中引入wordCloud方法:
- 1、进入项目根目录,运行cmd,执行命令npm install echarts-wordcloud –save
- 2、需要使用wordCloud的地方import ‘echarts-wordcloud’即可
同时,将官网的例子复制下来,发现字符云的颜色根本没法随机变化!!
官网例子:
echarts.baidu.com/echarts2/do…
注意点:
series: [{
......
data: [{
name: "Macys",
value: 6181,
itemStyle: createRandomItemStyle()
},
......
]
......
}]
复制代码
将option打印出来发现itemStyle设置的颜色确实没问题各有不同,在官网看配置没找到怎么设置颜色。
后面发现git上有个例子
注意点:
data: [{
name: 'Farrah Abraham',
value: 366,
// Style of single text
textStyle: {
normal: {},
emphasis: {}
}
}]
复制代码
于是将原本的itemStyle改为textStyle就OK了。。。
十、折线图的动画效果问题
option.animation = true 可以控制折线图加载时候的动画效果,默认为true;
但是当数据量太大时,即便设置为true,动画效果也没了。
十一、动态追加数据效果
修改series中的data再重新绘制echarts会导致动画从头到尾重新绘制。
比如说随着时间推移数据追加,如果重新绘制echarts会导致动画从第一个数值开始刷新到最后一个,体验很不好。
参考官方案例:
echarts.apache.org/examples/zh…
关键点在:
不要重新创建echarts对象,只需对原来的echarts对象.setOption(newOption)即可。
十二、echarts里面的悬浮框前面的图标怎么改变大小
关键代码:
formatter: function (params) {
var result = ''
var dotHtml = '<span style="display:inline-block;margin-right:5px;border-radius:44px;width:44px;height:44px;background-color:#1ddae4"></span>'
var dotHtml2 = '<span style="display:inline-block;margin-right:5px;border-radius:44px;width:44px;height:44px;background-color:#b9c6e6"></span>'
result += params[0].axisValue + '</br>' + dotHtml + 'COD:' + params[0].data + '</br>' + dotHtml2 + 'NH3:' + arams[1].data
return result
}
复制代码
效果如下:
参考文档: