1 叙述问题
产品和UI出了一个平滑的曲线图,如下图:
看起来并不复杂,但想要实现还是有一些细节需要注意的。
通过我的努力改造,把这个图做到了下面的效果:
现在问题来了,x轴的第一个数据和最后一个数据无法放在折线图的区域内,这个问题太让你头疼了。
2 问题详解
x轴的所展示的肯定是一些数据,我在想有没有可能在x轴的第一个数据的前面加等宽的空格去占位,这样可不可以把1时挤进来,同理,在24时后面也加空格。最终解决了这个问题。但又出现了一个新的问题,我们如何去知道等宽的空格到底是几个空格呢? 我先手动给1时前加了6个空格和24时后面加了8个空格,效果如下:
果然是解决了。
3 解决第二步中所述的问题
我们可以通过canvas去获取一个字符串的宽度和一个空格的宽度,因为大家都知道,echarts所绘制的图表就是通过canvas实现的。于是,我写了一个工具方法:
const getStr = (str, addStr, direction) => {
if (!str) return "";
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const strWidth = context.measureText(str).width; // 测量字符串的宽度
const addStrWidth = context.measureText(addStr).width; // 测量一个空格的宽度
const num = Math.ceil(strWidth / addStrWidth); // 计算字符串需要添加空格的个数
if (direction === "left") {
return " ".repeat(num) + str;
} else {
return str + " ".repeat(num);
}
};
console.log(getStr("1时", " ", "left").length); // 8
console.log(getStr("24时", " ", "right").length); // 11
这个方法可以帮助我添加空格,并且可以根据传入的字符串的宽度,最终返回的数据就是我所需要的数据,有需要的朋友,拿去,不谢。。。
4 最终实现代码
<script>
const getStr = (str, addStr, direction) => {
if (!str) return "";
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
const strWidth = context.measureText(str).width; // 测量字符串的宽度
const addStrWidth = context.measureText(addStr).width; // 测量一个空格的宽度
const num = Math.ceil(strWidth / addStrWidth); // 计算字符串需要添加空格的个数
if (direction === "left") {
return " ".repeat(num) + str;
} else {
return str + " ".repeat(num);
}
};
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
var chartData = {
xData: ['1时', '3时', '6时', '9时', '12时', '15时', '18时', '21时', '24时'],
yData: [10, 22, 5, 15, 19, 10, 17, 16, 22]
}
chartData.xData[0] = getStr(chartData.xData[0], " ", "left");
chartData.xData[chartData.xData.length - 1] = getStr(chartData.xData[chartData.xData.length - 1], " ", "right");
// 指定图表的配置项和数据
var option = {
xAxis: {
axisTick: {
show: false, //不显示坐标轴刻度线
},
axisLine: {
show: false, //不显示坐标轴线
},
boundaryGap: false, // x轴两边不留空白
offset: -22, // x轴偏移量
axisLabel: {
padding: [0, 0, 0, 0], //文字左右定位
},
data: chartData.xData
},
yAxis: {
axisTick: {
show: false //不显示坐标轴刻度线
},
axisLine: {
show: false, //不显示坐标轴线
},
axisLabel: {
show: false, //不显示坐标轴上的文字
},
splitLine: { // 背景线的更改
show: true,
lineStyle: {
color: ['#F5F6FA'],
type: 'dashed', // 虚线
},
},
},
tooltip: {
trigger: 'axis',
},
series: [
{
data: chartData.yData,
type: 'line',
areaStyle: { // 折线填充样式
color: new echarts.graphic.LinearGradient(
0, 1, 0, 0,
[
{ offset: 0, color: '#fff' },
{ offset: 1, color: '#6F98F4' },
]
),
},
lineStyle: { // 系列级个性化折线样式
width: 2,
type: 'solid',
color: new echarts.graphic.LinearGradient(
0, 0, 1, 0,
[
{ offset: 0, color: '#fff' },
{ offset: 0.1, color: '#6F98F4' },
{ offset: 0.5, color: '#6F98F4' },
{ offset: 0.9, color: '#6F98F4' },
{ offset: 1, color: '#fff' }
]
),//线条渐变色
},
symbol: 'none', //取消折点圆圈
smooth: true
}
]
};
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>