通过切换头部tab,控制主体内容的显示与隐藏。如下图所示,图标除了第一个tab分页,其他分页的图表没有占满一行,蜷缩在页面左边。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-frgKM3Ui-1638624897975)(D:\home\笔记\工作相关\图片\tab切换echarts显示不全.png)]
Echarts展示一张图表时,承载其的html容器一定要设置好宽度,所以想着是不是页面结构问题,Echarts图表容器的宽度设置出错。检查发现,肯定是设置了宽高的。
查看图表容器,发现容器元素宽度被设置为100px了;说明是Echart源码进行了某些处理。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbAmkPt1-1638624897976)(D:\home\笔记\工作相关\图片\图标样式.webp)]
echarts3源码中获取容器的宽高的代码
_getSize: function (whIdx) {
var opts = this._opts;
var wh = ['width', 'height'][whIdx];
var cwh = ['clientWidth', 'clientHeight'][whIdx];
var plt = ['paddingLeft', 'paddingTop'][whIdx];
var prb = ['paddingRight', 'paddingBottom'][whIdx];
if (opts[wh] != null && opts[wh] !== 'auto') {
return parseFloat(opts[wh]);
}
var root = this.root; // IE8 does not support getComputedStyle, but it use VML.
var stl = document.defaultView.getComputedStyle(root);
return (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh])) - (parseInt10(stl[plt]) || 0) - (parseInt10(stl[prb]) || 0) | 0;
},
这才发现问题所在,获取图表宽度时,由于图表所在的分页display:none,所以root.clientWidth获取失败;
这样也就解释为什么我们的图表宽度都是100px了。
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="新增用户" name="first" lazy>
<new-users></new-users>
</el-tab-pane>
<el-tab-pane label="累计用户" name="second" lazy>
<total-users></total-users>
</el-tab-pane>
<el-tab-pane label="用户占比" name="third" lazy>
<percentage-users></percentage-users>
</el-tab-pane>
</el-tabs>
代码中加入elementUI标签tabs中的lazy属性就可以实现这个功能。
但是经测试发现有时候,还是会出现突然闪现左移的问题。
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="新增用户" name="first">
<new-users v-if="'first' === activeName"></new-users>
</el-tab-pane>
<el-tab-pane label="累计用户" name="second">
<total-users v-if="'second' === activeName"></total-users>
</el-tab-pane>
<el-tab-pane label="用户占比" name="third">
<percentage-users v-if="'third' === activeName"></percentage-users>
</el-tab-pane>
</el-tabs>
data() {
return {
//默认展示的页面
activeName: "first",
};
},
方案二:完全没有问题,但是每一次切换的时候,echarts图就要重新进行渲染。
到这里这个问题已经完美的解决啦啦啦啦啦。。。。写一个问题。
1.echarts在vue项目中一般是全局引用的。
npm install echarts -S
2.在main.js中引入
// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts
3.在项目中使用时
<div id="myChart" :style="{width: '300px', height: '300px'}"></div>
export default {
name: 'hello',
data () {
return {
msg: 'Welcome to Your Vue.js App'
}
},
mounted(){
this.drawLine();
},
methods: {
drawLine(){
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(document.getElementById('myChart'))
// 绘制图表
myChart.setOption({
title: { text: '在Vue中使用echarts' },
tooltip: {},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
});
}
}
}
1.echarts在vue项目中一般是全局引用的。
npm install echarts -S
2.在main.js中引入
import myCharts from './utils/myCharts.js'
Vue.use(myCharts)
3.utils/myCharts.js中定义方法
//引入echarts
import echarts from 'echarts'
//方法挂载
const install = function (Vue) {
Object.defineProperties(Vue.prototype, {
$chart: {
get() {
return {
// 折线图
userLine: function (id, lineObj) {
this.chart = echarts.init(document.getElementById(id));
this.chart.clear();
this.chart.xAxis = [];
this.chart.yAxis = [];
const userData = {
//设置折线的颜色
// color: ["#60d1de", "#abeca3", "#f78181", "#8ce7ca","#fee78b","#a2cdfc"],
title: {
// text: '折线图堆叠'
},
tooltip: {
// trigger: 'axis',
formatter:null
},
legend: {
data: lineObj.legendData,
selected: lineObj.selectedData
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
// xAxis: {
// type: 'category',
// boundaryGap: false,
// data: lineObj.xData
// },
xAxis: {
type: 'category',
boundaryGap: false,
data: lineObj.xData
},
yAxis: {
type: 'value',
minInterval: lineObj.yAxis.minInterval,
axisLabel: {
formatter: null
},
},
series: lineObj.seriesData
};
//当折线图是使用的坐标轴需要用不同的形式表现时
//百分比的表示dataFormat进行判断是使用百分比还是正常
userData.xAxis.data = lineObj.xData;
userData.legend.data = lineObj.legendData;
userData.series = lineObj.seriesData;
var dataFormat = lineObj.dataFormats;
if (dataFormat == 'normal') {
userData.yAxis.axisLabel.formatter = null;
userData.tooltip.formatter = null;
} else if (dataFormat == 'percentage') {
userData.yAxis.axisLabel.formatter = function (value, index) {
return (value * 100) + '%';
};
//鼠标经过对应图标时,显示seriesName,marker(颜色),value(值)。
userData.tooltip.formatter = function (params) {
if(params.seriesName.indexOf("series") == -1) {
return params.seriesName + '
' +params.marker+ params.name + ' '+ (params.value * 100).toFixed(2) + '%'
} else{
return params.marker+ params.name + ' '+ (params.value * 100).toFixed(2) + '%'
}
};
}
this.chart.setOption(userData, true);
},
// 柱状图
userBar: function (id, barObj) {
this.chart = echarts.init(document.getElementById(id));
this.chart.clear();
this.chart.xAxis = [];
this.chart.yAxis = [];
const actionUserData = {
title: {
text: barObj.title,
textStyle: {
fontSize: 16,
fontStyle: "normal"
},
left: 10,
top: 0,
},
tooltip: {
trigger: 'axis',
// axisPointer: { // 坐标轴指示器,坐标轴触发有效
// type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
// }
formatter: function (barObj) {
var res;
var resList = [];
//当tip需要使用不同格式表现时。
for (let i in barObj) {
if (barObj[i].seriesName == "活跃用户" || barObj[i].seriesName == "非活跃用户") {
resList.push(''+ barObj[i].marker + barObj[i].seriesName +' ' +barObj[i].name+' ' + barObj[i].value+'
')
}
else if (barObj[i].seriesName == "活跃用户占比" || barObj[i].seriesName == "非活跃用户占比") {
resList.push(''+ barObj[i].marker + barObj[i].seriesName + ' ' +barObj[i].name+' '+ (barObj[i].value * 100).toFixed(2) + '%' + '
')
} else {
res = '' + barObj[i].name + ':' + barObj[i].value + '
'
}
}
if (resList.length == 0) {
return res
} else {
let sum = resList.reduce((accumulator, currentValue) => {
return accumulator + currentValue
})
return sum
}
},
},
legend: {
data: barObj.legendData,
selected: barObj.selectedData
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: barObj.xData,
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value'
}],
series: barObj.seriesData
};
this.chart.setOption(actionUserData);
},
// 饼图
userPie: function (id, pieObj) {
this.chart = echarts.init(document.getElementById(id));
this.chart.clear();
this.chart.xAxis = [];
this.chart.yAxis = [];
const industryData = {
color: ["#5470c6", "#9fe080", "#ffdc60", "#ff7070", "#7ed3f4", "#40b27d", "#a969c6", "#ff915a"],
title: {
// text: '占比图',
},
tooltip: {
trigger: 'item',
formatter: '{b} : {d}% ({c})'
},
legend: {
top: 'bottom',
orient: 'horizontal',
},
series: [{
name: '暂无数据',
type: 'pie',
radius: [0, 200],
center: ['50%', '50%'],
data: pieObj.data
}]
}
this.chart.setOption(industryData);
},
}
}
}
})
}
export default {
install
}
4.按需引入的对应的图标,比如bar图
<div id="newUserLine"></div>
data(){
return{
lineObj: {
legendData: [
"新增注册用户",
"新增试用用户",
"新增正式用户",
"新增使用用户",
],
xData: [],
yAxis: {
minInterval: 1,
},
seriesData: [
{
name: "新增注册用户",
type: "line",
data: [],
},
{
name: "新增试用用户",
type: "line",
data: [],
},
{
name: "新增正式用户",
type: "line",
data: [],
},
{
name: "新增使用用户",
type: "line",
data: [],
},
],
selectedData: {
新增试用用户: false,
新增正式用户: false,
新增使用用户: false,
},
},
}
},
created(){
this.getUserLine();
},
methods:{
getUserLine(val) {
//请求对应的数据
getNewAccountSerial(val).then((res) => {
this.lineObj.seriesData[0].data = res.data.newAccountSerial.data;
this.lineObj.seriesData[1].data = res.data.newTrailAccountSerial.data;
this.lineObj.seriesData[2].data = res.data.newFormalAccountSerial.data;
this.lineObj.seriesData[3].data = res.data.newUseAccountSerial.data;
this.lineObj.xData = res.data.newTrailAccountSerial.time;
//实例化echarts对象,将dom元素挂载到页面中
this.$chart.userLine("newUserLine", this.lineObj);
});
},
}
这是最近数据统计中一些比较重要的问题记录。这次需求中,自己做的不够的地方,就是完成之后进行测试了,但是没有进行系统的测试,而且不够细心。主要就是占比需要用百分比显示的问题,没有注意过。
还有一些细节性的问题,希望下次能够注意一点,加油奥利给!!!!!
this.lineObj.seriesData[3].data = res.data.newUseAccountSerial.data;
this.lineObj.xData = res.data.newTrailAccountSerial.time;
//实例化echarts对象,将dom元素挂载到页面中
this.$chart.userLine(“newUserLine”, this.lineObj);
});
},
}
这是最近数据统计中一些比较重要的问题记录。这次需求中,自己做的不够的地方,就是完成之后进行测试了,但是没有进行系统的测试,而且不够细心。主要就是占比需要用百分比显示的问题,没有注意过。
还有一些细节性的问题,希望下次能够注意一点,加油奥利给!!!!!