echarts - 使用echarts过程中遇到的问题(pending...)
1. 配合tab切换时,被display:none的元素init设置echarts失败
2018-11-09 18:09:35
现象描述:有一个tabs选项卡,每个切换项A、B中都有使用echarts,默认展示的A项中的ecarts初始化和绘制都没问题。
而第二个默认隐藏项B就是一片空白。检查B的echarts盒子还在且是css中设置的宽高大小。但是内部canvas为空,即图表没有绘制。
找问题过程:
假如我的echarts图表所在元素为:div#echartsDiv。
并将其父元素设置 display:none
然后我console一下document.getElementById('echartsDiv');
展开抛出的对象会发现:他的clientWidth和Height都是0,甚至scroll和offset系列的宽高皆为0(看图别介意id名对不上)
对比一个父元素没有隐藏的元素,他的宽高就很正常:
这样我们就明白了,echarts绘制之前是要获取要绘制区域的宽高的,如果皆为0那肯定失败的。
找到问题原因,就是解决:
既然根出在初始化时的元素宽高上,那我们开局就设置宽高即可。
我这里的主要问题是场景用在移动端,元素宽度肯定要随着设备的屏幕改变的。
如果直接在style上设置(注意,我尝试在css上设置了,没用),不能设置固定的数值。
所以我利用js的方法在js的开端设置了下:
let echartsW= $('.echarts-box').width();
$('.echarts-cont').css('width',echartsW);
echarts-box是我存放图标的总的父元素,echarts-cont是我所有图标公用的类名。
然后如果在pc端做响应式的页面时,如果遇到需要满足当屏幕大小被用户扯着随机变时图标也要改变的需求时,可以试试下边这个:
$(window).resize(function () {
let echartsW= $('.echarts-box').width();
$('.echarts-cont').css('width',echartsW);
});
(以下问题均已解决,空闲时间过来填充)
2、默认显示的坐标指示器重新填充样式后,变成第一列显示了,希望展示最后一个
长啥样呢?先来个官网demo图:
图片来自:echarts官网示例图
好了,打个照面后来说需求:
坐标指示器重新填充样式:
想要上边那样的效果,就是一条紫线,而且线有渐变:
设置位置为:
找对了人就好改了:
线的样式主要改他的 lineStyle ,
去掉底部手柄的显示:
不想显示直接改成false就行了。不过如果想显示好看点的,挣扎一下的话,就改label下边这些样式。
效果:
默认显示展示最后一个:
我这里封装成了函数,然后把对象return出去,在xAxis里边的axisPointer上调用这个函数,顺便传参(参数为x轴上的数据),
设置成最后一个,默认展示的就是最后一个了!!
3、y轴左对齐+偏移的问题
y轴左边文字要想设置左对齐,可以设置 axisLabel 的 align:
但是,你发现,真实情况是设置了left之后长这倒霉样:
首先能看出来,是以y轴为中心点的。官网一个图很形象:
center : , left : , right :
看出规律了吗?
他是以柱子为中心线进行偏移的。
那回到最初的问题,
为什么y轴左边文字设置left后就和y轴柱子重叠了?
这是因为还有一个默认的margin值:
【见】:http://www.echartsjs.com/option.html#yAxis.axisLabel.margin
把这个margin值设为0即可。
然后就是偏移问题:
怎么偏移他的位置?
开始感觉,好像只能通过margin偏移,但是margin偏移不靠谱的地方在于,文字的宽度是不固定的,没办法知道偏移多少才能让文字和y轴线不重叠。
然后看到一个offset,
y轴偏移还可以使用offset: 20,缺点同样跟margin相似,不能自适应y轴上文字的宽度。
换个思维思考,可以偏移内容区域:
即整个图表内容区域离y轴左边距远点。
怎么实现图表内容区域偏移?
使用boundaryGap留白策略没用,
最终方案是:
使用了offset让 y 轴整体左偏,
然后grid左边距为offset偏移的值,表现上就是让整个图表区域整体右偏,这样就是留出了y轴向左offset值那么大宽度的距离存放y轴的文案数据。
形象点说:
代码:
调整内容区域的左边距整体向右移动点:
1 grid: {
2 left: '11%'
3 },
y轴向左移,偏离内容区域:
1 yAxis: {
2 type: 'value',
3 offset: 50,
4 //向左偏移50px
5 axisLabel: {
6 align: 'left',
7 //设置我们的目的:左对齐
8 margin: -8,
9 //看效果偏移对应数据
10 },
11 splitLine: {
12 show: false //把横线隐藏掉
13 },
14 },
最终效果:
4、【线图】给选中的点显示特殊指定样式 :
就是这些圆圈:
想让其默认不显示,以前都是设置 symbolSize=0;
但是这次的需求还需要点击(移动端)的时候展示特定的symbol样式。
去掉symbolSize=0;转而设置 showSymbol 为false就行了。
官网说如果设置 false, 则只有在 tooltip hover 的时候显示。
然后在线图的series里边设置:
emphasis: {
itemStyle: {
color: 'rgba(55,167,137,1)',
borderWidth: 18,
borderColor: 'rgba(55,138,119,0.42)'
},
},
正好是我们要的样式。
5、自定义样式的tooltip气泡
5-1、tooltip定位层级太高了,其层级是七个9。。。
这一点就需要我们改源码了。去源码里搜索z-index,不出意外就这一个z-index关键词,把9999999改成你想要的第一点的值。
一般改成1就好了。其他想在他上边的改成2即可。
5-2、tooltip气泡样式自定义:
先来看看两个官网默认的tooltip样式:
是不是很局限?如果ui设计了样式后,你该怎么修改呢?分两种情况:
一、设计的样式是在默认样式基础上的颜色值等的修改
二、与默认样式不同的结构,甚至“变态”的样式
那么第一种,就很简单了,根据官网提供您的API接口就可以修改了:
上面这段样式,就是改了背景色和文字的颜色,这么一段代码就行了。
但是第二种情况就难办了,比如说这种:
以后业务中,遇到的样式肯定千变万化,我这里不可能一一举例。但是下边提供一下这种“自定义的太过分的样式”的解决思路:
相信看过我前边的文章,你已经知道又一个API叫formatter了,并且也体会到了他的重要性了。tooltip也不例外,也有这个
http://www.echartsjs.com/option.html#tooltip.formatter
强大之处在于formatter这个函数的一个参数,他能给你返回任何你想要的、关于当前鼠标hover/click等事件触发时图表对应点的数据:
(后边还有,具体看官网)
在他的回调函数里边,你甚至可以return出自己自定义的结构,进而覆盖掉原来的结构,并且通过行间样式拼接到自定义结构上,比如这样,
1 formatter: function (params) {
2 return '<span style="padding: 6px 12px 4px 14px;border-radius: 200px;background: rgba(23,202,184,.1);color: #17cab8;font-size: 18px">' + params[0].value + '</span>';
3 }
你想要什么样式就能拼成什么样式
5-3、自定义样式的label气泡,给气泡添加阴影或其他额外样式
上边说道,修改自定义样式,有很多api给我们用,但是当我想设置盒阴影这个样式的时候,死活找不到对应的接口。1 extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);'
这样上边一段代码,盒阴影就搞定了。怎么样,度娘还是很贴心的吧!
5-4、自定义样式的label控制显示范围
问题描述:我们经过formatter返回的label标签层,其样式范围不再受echats默认的范围限制了,比如没定义之前的,是会距离x轴有一定距离的,但是我们自定义之后,他就可以和x轴的文案在同一位置,这样就会导致一个问题就是tooltip的label层盖住了x轴的文案。
这种情况,我们依旧通过和formatter一样性质的一个position方法来设置:
tooltip: {
position: function (pos, params, dom, rect, size) {
let left1 = pos[0],
top1 = pos[1],
Tleft = size.viewSize[0] - size.contentSize[0],
Ttop = size.viewSize[1] - size.contentSize[1] - 100;
if (left1 > Tleft - 100) {
left1 = Tleft;
} else if (top1 > Ttop) {
top1 = Ttop;
}
return {
left: left1,
top: top1
};
}
},
5-5、自定义样式的label层默认显示
问题描述:
自定义样式的label气泡怎么初始化的时候就显示在固定的点(默认不显示是因为一开始就没有被填充到结构中,想办法填充到结构中,而不是点击的时候填充)可以通过dispatch这个方法设置:
myEcharts.dispatchAction({
type: 'showTip',
seriesIndex: 0,
dataIndex: 1//第一种写法,根据x轴上的索引值指定,数字类型
});
myEcharts.dispatchAction({
type: 'showTip',
seriesIndex:0,
name: '10.12'//第二种写法,根据x轴上的name值执行,字符串类型
});
6、datazoom的问题
6-1、锁定datazoom
zoomLock: true
这样,图标区域就只能左右平移不能双指拉伸缩放了(移动端禁掉双指,pc端禁掉滚轮)
6-2、阻止默认的移动事件
preventDefaultMouseMove:false
这样手势放到图表上边就禁止掉了图标内部的上下拖动事件,也就能在移动端页面上移。(长页面需要上下移动达到向下翻页的情况)
6-3、(未解决)手势冲突
接上一问题、图表上还需要左右平移,当手势不是非常水平的话,会被识别成上移页面,最终用户体验不太好(app里边是用原生代码画的图表,心里一句大佬。)
7、ios和安卓适配问题
7-1、(未解决)rem显示
图表里的字体和位置设置的时候能不能改成rem格式?在安卓里,viewport解析成了1.0的,导致图表特别特别大。
7-2、安卓和ios的适配问题
比如:oppo手机,图例顶部一小部分被超出隐藏:
思路:
准备一个oUa变量,用于判断是否是ios还是安卓环境,
然后设置legend的 padding: oUa.ios()?0:5,
8、echarts 怎么给x轴左边加图标
(未解决)设计稿上的x和y轴交叉处的那个L形状的图标。
9、终极-监听click事件必须点到柱上,点击柱子之间的空白区域没有作用
(在我们后端研发那里学到的~)
比如,我们直接监听echarts的click事件:
myChart.on('click',(params)=>{ console.log(params); })
就会拿到当前点击柱状图的各种信息。这个在echarts下钻文章里就说过了。
但是最近移动端再使用这个工具,我们发现一个问题:必须点击到柱子上,才能出现数据,点击柱子之间的空白区域出现不了。
比如下图中画圆圈的位置,红色箭头是截图时鼠标的位置:
实际上按照默认设置,空白区域被柱子平分了,理论上来说点击空白区域也应该算是点到柱之上的。就像我们hover在空白区域,也能出现对应tooltip的数据一样。
echarts下钻时我还真没注意到这一点,但这次在移动端发现了。然后回过头试了试,还真是在空白区域点击没反应。
然后在网上搜到了解决方法:echarts监听点击(空白处)事件,echarts监听滑动事件
然后把我之前的做法替换掉试了下:
再次点击空白区域,确实拿到了:
不过这次拿到的params参数是一个事件对象,。所以你能得到的也就是当前鼠标的坐标点。
还好,echarts给了我们这样一个方法:
判断给定的点是否在指定的坐标系或者系列上。
就是让你判断当前点击的空白区域属于哪个柱子/线点的,再返回给你对应坐标系或系列上的属性值。
对应的,如果条件成立,鼠标点击的位置在对应柱上,那么使用它上边紧接着的另一个方法:
然后利用这个方法,执行:
myChart.convertFromPixel({ seriesIndex: 0 }, [params.offsetX, params.offsetY])[0]
这样,我们点击对应柱子的空白区域,就可以拿到一个索引值,比如我从第一个柱点到最后一个柱,打印出来的index值如下:
有了索引值,我们再取xData或者series的data数组里边拿对应数据就可以实现了。