在使用echarts折线图时,设置最大值超出Y轴的数据,会导致看着很别扭,经过长久的百度得出了结果。
//通过这个函数可以算出Y轴的平均值
nice(span, splitNumber, round) {
let val = span / splitNumber;
var exponent = Math.floor(Math.log(val) / Math.LN10);
var exp10 = Math.pow(10, exponent);
var f = val / exp10; // 1 <= f < 10
var nf;
if (round) {
if (f < 1.5) {
nf = 1;
} else if (f < 2.5) {
nf = 2;
} else if (f < 4) {
nf = 3;
} else if (f < 7) {
nf = 5;
} else {
nf = 10;
}
} else {
if (f < 1) {
nf = 1;
} else if (f < 2) {
nf = 2;
} else if (f < 3) {
nf = 3;
} else if (f < 5) {
nf = 5;
} else {
nf = 10;
}
}
val = nf * exp10; // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
// 20 is the uppper bound of toFixed.
const step = exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
let result;
for (let i = splitNumber - 3; i < splitNumber + 3; i++) {
result = step * i;
if (result > span) break;
}
return result.toFixed(1);
},
全部代码
<template>
<view class="myChartBox">
<view class="myChartTitle">
<text></text>
<text>{{ titleObj.明细项目 }}</text>
<text>(单位:{{ titleObj.单位 }})</text>
</view>
<scroll-view :scroll-x="true" class="myChartScroll"><view id="myChart"></view></scroll-view>
</view>
</template>
<script>
import * as echarts from 'echarts';
import { mapState } from 'vuex';
export default {
props: ['curTableData', 'newArr'],
data() {
return {
option: {
tooltip: {
show: true,
trigger: 'axis'
// confine: true, // 该属性可使tooltip一直处于容器中
// transitionDuration: 0,
// position: function(point, params, dom, rect, size) {
// dom.style.transform = 'translateZ(0)';
// }, //该属性解决ios手机滑动出现白条问题
// axisPointer: {
// // 坐标轴指示器,坐标轴触发有效
// type: 'line', // 默认为直线,可选为:'line' | 'shadow'
// shadowStyle: {
// // 阴影指示器样式设置
// width: 'auto', // 阴影大小
// color: 'rgba(150,150,150,0.3)' // 阴影颜色
// }
// },
// formatter: function(params) {
// //对显示数据进行格式化
// let result = `<span style="color:#fff; float: left; ">${params[0].name}</span>`;
// params.forEach(function(item) {
// if (item.data >= 0) {
// result += `
// <br/><span style="background: ${item.color}; width: 5px; height: 5px; border-radius: 50%; float: left; margin: 7px 3px;"></span><span style='color:${
// item.color
// };float: left;'>${item.seriesName}:${item.data}</span>`;
// }
// });
// return result;
// }
},
legend: {
data: ['A设备', 'B设备', 'C设备']
},
grid: {
left: '10%',
right: '15%',
bottom: '0%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: ['2010-11-22 19:30:01', '2010-11-22 19:30:01', '2010-11-22 19:30:01', '2010-11-22 19:30:01', '2010-11-22 19:30:01', '2010-11-22 19:30:01'],
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
color: '#E6E6E6' //Y轴线条颜色
}
},
axisLabel: {
textStyle: {
color: '#999999' //Y轴字体颜色
},
rotate: -40
// formatter: (value, index) => {
// const time = value.split(' ');
// return `${time[0]} \n ${time[1]}`;
// }
}
},
yAxis: {
type: 'value',
axisLine: {
show: true,
lineStyle: {
color: '#E6E6E6' //Y轴线条颜色
}
},
axisLabel: {
textStyle: {
color: '#999999' //Y轴字体颜色
}
}
},
series: [
{
name: 'A设备',
type: 'line',
data: [80, 150, 180, 50, 240, 100],
smooth: true, //平滑
symbolSize: 8,
itemStyle: {
normal: {
lineStyle: {
width: 4
}
}
}
},
{
name: 'B设备',
type: 'line',
data: [130, 60, 60, 220, 99, 55],
smooth: true, //平滑
symbolSize: 8,
itemStyle: {
normal: {
lineStyle: {
width: 4
}
}
}
},
{
name: 'C设备',
type: 'line',
data: [140, 88, 66, 230, 130, 22],
smooth: true, //平滑
symbolSize: 8,
itemStyle: {
normal: {
lineStyle: {
width: 4
}
}
}
}
]
},
mychar: null,
titleObj: {}
};
},
computed: {
...mapState(['mycharData'])
},
mounted() {
this.$nextTick(() => {});
},
watch: {
newArr: {
handler(val) {
this.init();
},
deep: true
}
},
methods: {
// 初始化数据
init() {
// 如果不为1 就不画
if (this.newArr.是否数字 != 1) return;
if (!this.mychar) {
this.mychar = echarts.init(document.querySelector('#myChart'));
}
const series = [];
const date = [];
const legend = [];
const arr = this.newArr.data;
const obj = {};
this.titleObj = arr[0];
arr.forEach(item => {
// date.push({
// key: item.仪器,
// time: item.检查日期
// });
date.push(item.检查日期);
if (!obj[item['仪器']]) {
obj[item['仪器']] = {
key: item.仪器,
children: []
};
legend.push(item.仪器);
}
obj[item['仪器']].children.push({
num: item.检验结果,
time: item.检查日期
});
});
const arr2 = Object.values(obj);
arr2.forEach(item => {
series.push({
name: item.key,
type: 'line',
data: this.update(item.children, date),
smooth: true, //平滑
symbolSize: 8,
itemStyle: {
normal: {
lineStyle: {
width: 4
}
}
},
markLine: {
// symbol: ['none', 'none'], //去掉箭头
symbol: 'none',
data: [
{
name: '最小值',
type: 'min',
yAxis: this.titleObj.参考区间最小值,
label: {
position: 'middle',
color: 'red',
formatter: () => {
return `最小值(${this.titleObj.参考区间最小值})`;
}
},
lineStyle: {
color: 'red'
}
},
{
name: '最小值',
type: 'max',
yAxis: this.titleObj.参考区间最大值,
label: {
position: 'middle',
color: 'red',
formatter: () => {
return `最大值(${this.titleObj.参考区间最大值})`;
}
},
lineStyle: {
color: 'red'
}
}
]
}
});
});
this.option.xAxis.data = date;
this.option.series = series;
this.option.legend.data = legend;
this.option.yAxis = {
type: 'value',
axisLine: {
show: true,
lineStyle: {
color: '#E6E6E6' //Y轴线条颜色
}
},
axisLabel: {
textStyle: {
color: '#999999' //Y轴字体颜色
}
},
max: extent => {
const max = extent.max > arr[0].参考区间最大值 ? extent.max : arr[0].参考区间最大值;
return this.nice(max, 5, true);
}
};
this.mychar.setOption(this.option, true);
},
/**
* @param span series 中最大值与最小值的差值
* @param splitNumber 坐标轴分割段数
* @param round 折线图中需要传 true
* @returns {number} 处理后 max 的最后结果
*/
nice(span, splitNumber, round) {
let val = span / splitNumber;
var exponent = Math.floor(Math.log(val) / Math.LN10);
var exp10 = Math.pow(10, exponent);
var f = val / exp10; // 1 <= f < 10
var nf;
if (round) {
if (f < 1.5) {
nf = 1;
} else if (f < 2.5) {
nf = 2;
} else if (f < 4) {
nf = 3;
} else if (f < 7) {
nf = 5;
} else {
nf = 10;
}
} else {
if (f < 1) {
nf = 1;
} else if (f < 2) {
nf = 2;
} else if (f < 3) {
nf = 3;
} else if (f < 5) {
nf = 5;
} else {
nf = 10;
}
}
val = nf * exp10; // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
// 20 is the uppper bound of toFixed.
const step = exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
let result;
for (let i = splitNumber - 3; i < splitNumber + 3; i++) {
result = step * i;
if (result > span) break;
}
return result.toFixed(1);
},
/**
* @param {Array} arr 每个仪器的数据
* @param {Array} nArr 时间
* @returns {Array} 每个仪器处理过后的数据
*/
update(arr, nArr) {
const arrs = [...arr];
nArr.forEach(time => {
arrs.push({ num: null, time });
});
const obj = {};
arrs.forEach(item => {
if (!obj[item['time']]) {
obj[item['time']] = {
time: item.time,
num: item.num
};
}
});
const newARR = Object.values(obj)
.sort((a, b) => a.time.localeCompare(b.time))
.map(item => item.num);
return newARR;
}
}
};
</script>
<style scoped lang="scss">
.myChartBox {
width: 100%;
height: 100%;
background-color: white;
overflow: hidden;
.myChartTitle {
width: 750rpx;
height: 80rpx;
display: flex;
align-items: center;
font-size: 34rpx;
color: #333;
font-weight: bold;
text:nth-child(1) {
width: 8rpx;
height: 28rpx;
background-color: #3c74f6;
margin: 0 10rpx 0 32rpx;
}
text:nth-child(3) {
font-size: 24rpx;
font-weight: 500;
color: #999999;
}
}
#myChart {
width: 800rpx;
// height: calc(100% - 80rpx);
height: 100%;
}
.myChartScroll {
width: 100%;
height: calc(100% - 80rpx);
}
}
</style>
很久之前百度到的,忘记出处了,怕忘记故此记录下