echarts 示例
Echarts图表效果图(Make A Pie替代)
Make A Pie 是由社区贡献者维护的用于 Apache ECharts 作品分享的第三方非官方社区。平时做Echarts图表经常需要用到,由于官方已经关闭,找到以下几个可替代的网站。(Make A Pie替代网址)
1、http://analysis.datains.cn/finance-admin/#/chartLib/all
2、makeapie 复刻站点1:http://ppchart.com/
3、Make A Pie复刻站点2:http://www.isqqw.com/ 备用地址http://echarts.isqqw.com/
4、Make A Pie复刻站点3: http://pie.antcode.net
作者:轮回千载:https://blog.csdn.net/mengdongdew/article/details/123193551?spm=1001.2014.3001.5502
echart 应用
1、vue中使用echarts-gl(3d环形图):https://blog.csdn.net/weixin_44766633/article/details/111831321
2、echarts3d饼图,环形图(包含透明效果):https://blog.csdn.net/weixin_41326021/article/details/120195920
Echarts 细节设置
1、效果图
(1)设置 lenged 样式:
color: ['#67E5FF', '#FFD153', '#01BAFF', '#FFBB00'],
legend: [
{
left: '10%',
itemWidth: 8,
itemHeight: 8,
data: [
{
name: '进水水量',
icon: 'circle',
textStyle: {
fontSize: 14,
color: 'rgba(255,255,255,0.8)',
},
},
],
},
{
left: '30%',
itemWidth: 8,
itemHeight: 8,
data: [
{
name: '出水水量',
icon: 'circle',
textStyle: {
fontSize: 14,
color: 'rgba(255,255,255,0.8)',
},
},
],
},
{
left: '50%',
itemWidth: 8,
itemHeight: 2,
data: [
{
name: '进水浓度',
icon: 'rect',
textStyle: {
fontSize: 14,
color: 'rgba(255,255,255,0.8)',
},
},
],
},
{
left: '70%',
textStyle: {
color: '#71F003',
fontSize: 15,
fontFamily: '微软雅黑',
},
itemWidth: 8,
itemHeight: 2,
data: [
{
name: '出水浓度',
icon: 'rect',
textStyle: {
fontSize: 14,
color: 'rgba(255,255,255,0.8)',
},
},
],
},
],
(2)设置 Y 轴单位样式 mg/L
和 万m³/d
nameTextStyle: {
color: 'rgba(255,255,255,0.6)',
padding: [0, 15, 0, 0],
},
yAxis: [
{
type: 'value',
name: 'mg/L',
nameTextStyle: {
color: 'rgba(255,255,255,0.6)',
padding: [0, 15, 0, 0],
},
min: 0,
max: 4,
interval: 1,
axisLabel: {
show: true, //这里的show用于设置是否显示y轴下的字体 默认为true
textStyle: {
//textStyle里面写y轴下的字体的样式
color: 'rgba(255,255,255,0.6)',
fontSize: 12,
},
formatter: '{value}',
},
splitLine: {
show: true,
// 背景虚线
lineStyle: {
color: 'rgba(255,255,255,0.2)',
},
},
},
{
type: 'value',
name: '万m³/d',
nameTextStyle: {
color: 'rgba(255,255,255,0.6)',
},
min: 0,
max: 40,
interval: 20,
axisLabel: {
show: true, //这里的show用于设置是否显示y轴下的字体 默认为true
textStyle: {
//textStyle里面写y轴下的字体的样式
color: 'rgba(255,255,255,0.6)',
fontSize: 12,
},
formatter: '{value}',
},
splitLine: {
show: true,
// 背景虚线
lineStyle: {
color: 'rgba(255,255,255,0.2)',
},
},
},
],
2、横向柱状图
参考:https://blog.csdn.net/qq_36157085/article/details/114627259
3、echarts 中 legend 不显示问题
legend 中的data
要跟series
中的data
的name
相等 值一样才能显示;
4、柱状图折线图复合图
注意双Y轴,左侧Y轴和右侧Y轴,通过索引来对应
option = {
color:['#ED7D31','#4472C4','#FFC000','#A5A5A5'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar']},
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['2小时快速修复', '常规施工工程', '准时百分比', '累计准时百分比']
},
xAxis: [
{
type: 'category',
data: [ '3月', '4月', '5月', '6月', '7月'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{ // 对应左侧Y轴
type: 'value',
name: '水量',
min: 0,
max: 250,
interval: 50,
axisLabel: {
formatter: '{value} ml'
}
},
{ // 对应右侧Y轴
type: 'value',
name: '温度',
min: 0,
max: 25,
interval: 5,
axisLabel: {
formatter: '{value} °C'
}
}
],
series: [
{
name: '2小时快速修复',
type: 'bar',
stack: '施工统计',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
yAxisIndex: 0, //对应左侧Y轴
},
{
name: '常规施工工程',
type: 'bar',
stack: '施工统计',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
yAxisIndex: 0, //对应左侧Y轴
},
{
name: '准时百分比',
type: 'line',
yAxisIndex: 1, //对应右侧Y轴
data: [2.0, 2.2, 3.3, 4.5, 6.3]
},
{
name: '累计准时百分比',
type: 'line',
yAxisIndex: 1,
data: [10, 14, 13.3, 14.5,15]
}
]
};
5、动态改变柱状图柱子的颜色
注意:这里的 data 属性值应该为一个对象数组形式:
例如:
data:[
{name:'1', level:'2', value:20},
{name:'2', level:'2', value:20},
]
series: [
{
name: "变化趋势",
type: "bar",
stack: "one",
barWidth: 10, //柱子宽度
data: this.data,
zlevel: 11, // 设置层级
itemStyle: {
color: (params) => {
if (params.value > 0 && params.value <= 50) {
return "#81C124";
} else if (params.value > 50 && params.value <= 100) {
return "#F7C40A";
} else if (params.value > 100 && params.value <= 150) {
return "#F6880D";
} else if (params.value > 150 && params.value <= 200) {
return "#E62753";
} else if (params.value > 200 && params.value <= 300) {
return "#99226C";
} else if (params.value > 300) {
return "#751226";
}
},
barBorderRadius: [1, 1, 1, 1], // 柱状图圆角
},
},
],
6、设置 ECharts 中图表加载动画时间
series:[
{
name:'销量',
type:'bar',
data:[5,20,36,10,10,20],
animationDuration: 2800,
animationEasing: 'cubicInOut',
}
]
参考:https://blog.csdn.net/qyp_1/article/details/107686262
7、设置标准限值线
参考:https://blog.csdn.net/qq_36437172/article/details/105921501
效果:
代码:
series:[
{
name: '',
type: 'line',
yAxisIndex: 0,
showSymbol: false, //默认不显示拐点
data: [],
unit: '单位',
markLine:{
/*以下设置一行后,平均线就没有开始和结束标记了(即看不见箭头了)*/
symbol:"none",
data: [
{
name: '平均线',
// 支持 'average', 'min', 'max'
type: 'average',
lineStyle:{
normal:{
color:"green",
width:2,
type:"solid",
}
}
},
]
}
}
]
8、环形图中间文字设置
效果图:
方法一:设置 title
和 subtext
参考:https://www.cnblogs.com/web520/p/6086038.html
option: {
color: this.color,
legend: {
show: false,
selectedMode: false, //取消图例上的点击事件
},
title: {
show: true,
text: "设备总数",
subtext: "100", //副标题文本,'\n'指定换行
x: "center", //水平安放位置,默认为'left',可选为:'center' | 'left' | 'right' | {number}(x坐标,单位px)
y: "36%", //垂直安放位置,默认为top,可选为:'top' | 'bottom' | 'center' | {number}(y坐标,单位px)
textAlign: null,
itemGap: 8,
textStyle: {
// fontFamily: "Arial, Verdana, sans...",
fontSize: 12,
fontWeight: 400,
color: "#999999",
},
subtextStyle: {
// fontFamily: "Arial, Verdana, sans...",
fontSize: 19,
fontWeight: "bold",
color: "#3EC3AE",
},
},
series: [
{
name: "告警次数统计",
type: "pie",
radius: ["65%", "100%"], //饼图的半径,数组的第一项是内半径,第二项是外半径。支持设置成百分比,相对于容器高宽中较小的一项的一半。可以将内半径设大显示成圆环图, 设置内半径和外半径,形成环状
center: ["50%", "50%"], //饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标。支持设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。这里的center一旦设置, 则 graphic/legend 里的内容位置也要相应进行调整
hoverAnimation: false, //鼠标悬浮是否有区域弹出动画,false:无 true:有
avoidLabelOverlap: false,
itemStyle: {
normal: {
label: {
show: false,
},
labelLine: {
show: true,
},
},
emphasis: {
shadowColor: "rgba(0, 0, 0, 0.1)",
// shadowBlur: 10,
},
},
data: [],
},
],
},
方法二:设置 graphic
option: {
color: this.color,
legend: {
show: false,
selectedMode: false, //取消图例上的点击事件
},
graphic: [
{
type: "group",
left: "center",
top: "44%",
bounding: "raw",
children: [
{
type: "text",
style: {
text: "设备总数",
fontSize: 12,
fill: "#999999", //文字的颜色
textVerticalAlign: "middle",
textAlign: "center",
},
},
],
},
{
type: "group",
left: "center",
top: "60%",
bounding: "raw",
children: [
{
type: "text",
style: {
text: "0",
fontSize: 19,
fill: "#3EC3AE", //文字的颜色
textVerticalAlign: "middle",
textAlign: "center",
},
},
],
},
],
series: [
{
name: "告警次数统计",
type: "pie",
radius: ["65%", "100%"], //饼图的半径,数组的第一项是内半径,第二项是外半径。支持设置成百分比,相对于容器高宽中较小的一项的一半。可以将内半径设大显示成圆环图, 设置内半径和外半径,形成环状
center: ["50%", "50%"], //饼图的中心(圆心)坐标,数组的第一项是横坐标,第二项是纵坐标。支持设置成百分比,设置成百分比时第一项是相对于容器宽度,第二项是相对于容器高度。这里的center一旦设置, 则 graphic/legend 里的内容位置也要相应进行调整
hoverAnimation: false, //鼠标悬浮是否有区域弹出动画,false:无 true:有
avoidLabelOverlap: false,
itemStyle: {
normal: {
label: {
show: false,
},
labelLine: {
show: true,
},
},
emphasis: {
shadowColor: "rgba(0, 0, 0, 0.1)",
// shadowBlur: 10,
},
},
data: [],
},
],
},
9、水球图
echarts-liquidfill
10、报错:vue.esm.js:628 [Vue warn]: You may have an infinite update loop in watcher with expression “rankData”
在给 echarts 图表通过 props 传参数时,出现下面报错:
在带有表达式的观察程序中,可能有无限更新循环
为什么会出现这个bug呢?
分析如下:
错误的模式下:首先 yKeyData 在 created 生命周期中获取数据时也发生了变化,watch 监听到后,就执行 option 操作,结果 option 中的 data 中的数组进行倒置了 this.yKeyData.reverse()
,那么 watch 监听的 yKeyData 又发生变化,陷入了无限死循环中。
正确的模式下:data 就是个纯数组,不可在其上添加函数操作。将倒置操作 reverse() 在传进参数之前就处理好。
总结:
echarts 中 option 的 data 传数组,千万不要对数组进行操作(不要在 watch 中改变所监听的数据)。否则会出 bug。
对该数组的操作在传进这个组件之前就已经处理好
11、echarts x轴文字显示不全
使用 echarts 绘制图表时,当数据量比较多时,我们会发现 x 轴文字显示不全,出现如下图的情况。
echarts 图表中有个 axisLabel 配置项,是坐标轴刻度标签的相关设置。interval
属性是坐标轴刻度标签的显示间隔,默认会采用标签不重叠的策略间隔显示标签。可以设置成 0
强制显示所有标签。还有一个属性:rotate: number
度角是倾斜的控制所在,在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。
解决如下:
<script>
//初始化echarts实例
var myCharts = echarts.init(document.getElementById('main'));
//指定图表的配置项和数据
var option={
title:{
text:'ajax动态获取后台数据绘制echarts图表'
},
color:['#3398db'], //调色盘颜色列表
tooltip:{ //提示框组件
trigger:'axis', //触发类型(坐标轴触发)
axisPointer:{
type:'line' //指示器类型(直线指示器)
}
},
grid:{ //直角坐标系内绘图网格
left:'3%', //grid组件离容器左侧的距离
right:'4%',
bottom:'3%',
containLabel:true //grid 区域是否包含坐标轴的刻度标签。
},
xAxis:[ //x轴
{
type:'category', //坐标轴类型(类目轴)
data:[], //类目数据
axisTick:{ //坐标轴刻度相关配置
alignWithLabel:true //刻度线与标签对齐
}
}
],
yAxis:[
{
type:'value' //数值轴
}
],
series:[ //系列列表
{
name:'直接访问',
type:'bar',
barWidth:'60%',
data:[]
}
]
};
myCharts.setOption(option);
myCharts.showLoading(); //显示加载动画
var x = [];
var y = [];
$.ajax({
type:'get',
url:'./data/obj.txt',
dataType:'JSON',
success:function(data){
// console.log(data.data);
data.data.map((item)=>{
x.push(item.name);
y.push(item.extn);
})
// console.log(x,y)
myCharts.hideLoading(); //隐藏加载效果
myCharts.setOption({
xAxis:{
type:'category', //坐标轴类型(类目轴)
data:x ,
axisLabel:{
interval:0,
rotate:-30
}
},
series:{
data:y
}
})
}
})
</script>
效果如下:
现在 x 轴的文字已经全部显示出来了
备注:参考解决方法:echarts x轴文字显示不全(xAxis文字倾斜比较全面的3种做法值得推荐)
12、Echarts 初始化
- 初始化关键一:对象值必须是重新初始化赋值,如下
(1)可以定义一个全变变量:var myChart = null;
(2)初始化赋值:
myChart = echarts.init(document.getElementById("myID"));
- 当每次数据改变,需要重新初始化时:
mychart.dispose()
之后重新init
就好了
13、echarts 环状图中添加图片
可在环形图里面、外面添加图片
线上调试地址:http://echarts.zhangmuchen.top/#/detail?cid=xDoTDlajsn
代码如下:
option = {
graphic: {
elements: [{
type: "image",
z: 3, //设置图片的层级 例如:-3 0 3等
style: {
image: require("image/abc.png"),//你的图片地址
width: 80,
height: 80,
},
// left: "70",
left: "center",
top: "center",
// position: [100, 100],
}, ],
},
tooltip: {
confine: true,
show: false,
},
}
14、echarts 饼图不显示0的数据
需求:当接口返回数据为0的时候,饼图会出现指示线和0数据,看上去效果并不好,产品提出,将数据为0时不显示。
这个是数据为0时的效果
附上源码:
var option = {
title: {
show: false,
text: "",
},
color: [],
tooltip: {
trigger: "item",
backgroundColor: "rgba(1, 12, 19, 0.9)",
formatter: "{a} <br/>{b} :{d}%",
textStyle: {
fontSize: this.isFullScreen ? 20 : 12 * scale,
},
},
series: [
{
name: this.name,
label: {
formatter: "{b}:{c}个/{d}%",
},
type: "pie",
radius: [],
center: ["50%", "50%"],
data: [
{ name: "第一项", value: 1 },
{ name: "第二项", value: 0 },
{ name: "第三项", value: 0 },
{ name: "第四项", value: 5 },
{ name: "第五项", value: 3 },
],
},
],
};
要实现数据为 0 时不显示的效果,有两种方法:
第一种是:在处理后台接口数据时,就将结果为 0 的过滤掉
第二种是:处理 option
效果如下:
附上代码:
var option = {
title: {
show: false,
text: "",
},
color: [],
tooltip: {
trigger: "item",
backgroundColor: "rgba(1, 12, 19, 0.9)",
formatter: "{a} <br/>{b} :{d}%",
textStyle: {
fontSize: this.isFullScreen ? 20 : 12 * scale,
},
},
series: [
{
label: {
formatter: function (params, ticket, callback) {
var total = 0;
var percent = 0;
newValue.forEach((value, index) => {
total += value.value;
});
percent = ((params.value / total) * 100).toFixed(2);
if (params.value == 0) {
//取消数据为0的指示线
params.data.labelLine.show = false;
params.data.label.show = false;
return null; //取消为0的数据
} else {
return `${params.name}:${params.value}个/${percent}%`;
}
},
fontSize: 14 * scale,
},
type: "pie",
radius: [],
center: ["50%", "50%"],
data: [
{ name: "第一项", value: 1, labelLine:{ show: true }, label: { show: true } },
{ name: "第二项", value: 0, labelLine:{ show: true }, label: { show: true } },
{ name: "第三项", value: 0, labelLine:{ show: true }, label: { show: true } },
{ name: "第四项", value: 5, labelLine:{ show: true }, label: { show: true } },
{ name: "第五项", value: 3, labelLine:{ show: true }, label: { show: true } },
],
},
],
};
参考1:https://blog.csdn.net/li_970408/article/details/120414766
参考2:https://wenku.baidu.com/view/0cae66325c0e7cd184254b35eefdc8d376ee14b5.html
参考3:https://www.freesion.com/article/86881219213/
15、让echarts折线图X轴不从0刻度开始
效果图:
配置代码:
修改 xAxis.boundaryGap:true
let option = {
tooltip: {
trigger: "axis",
axisPointer: {
label: {
backgroundColor: "#6a7985",
},
lineStyle: {
color: "#C1F2FF",
},
},
},
grid: {
top: "10%",
left: "1%",
right: "6%",
bottom: "15%",
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: true, //X轴不从0刻度开始
data: ["2018年", "2019年", "2020年"],
axisLabel: {
show: true,
interval: 0,
margin: 12 ,
textStyle: {
color: "#fff",
fontSize: 12 ,
},
formatter: function (value, index) {
return value;
},
},
axisLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,0.6)",
type: "solid",
},
},
axisTick: {
show: false,
},
},
yAxis: {
type: "value",
scale: true,
name: "数据单位:吨",
nameTextStyle: {
color: "rgba(255,255,255,0.6)",
padding: [0, -20, 0, 0],
},
axisLabel: {
show: true,
interval: 0,
textStyle: {
color: "#fff",
fontSize: 12 ,
},
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,0.3)",
type: "dashed",
width: 0.8 ,
},
},
axisLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,0.6)",
},
},
axisTick: {
show: false,
},
},
series: [
{
// data: [150, 230, 224, 218, 135, 147, 260],
data: [1, 2, 3],
type: "line",
},
],
};
16、echarts 柱形图 x 轴的刻度显示在柱形中间,刻度和标签对齐
关键点:xAixs.axisTick.alignWithLabel:true
xAxis: {
type: "category", //类名轴
data: ["3月1日", "3月2日", "3月3日", "3月4日", "3月5日", "3月6日", "3月7日"],
axisLine: {
//坐标轴轴线相关设置
lineStyle: {
color: "#d7d7d7", //x轴线颜色设置
},
},
axisLabel: {
// 坐标轴刻度标签的相关设置
show: true, //控制显隐
textStyle: {
color: "#d7d7d7", //x轴字体颜色
},
interval: 0,
},
axisTick: {
//x轴刻度相关设置
alignWithLabel: true,
},
},
17、不显示 X 轴坐标轴指示器
xAxis: {
type: "category",
// 坐标轴指示器相关设置
axisPointer: {
type: "none", // 取消当前轴的坐标轴指示器
},
},
18、X 轴数据多时,名称显示。解决 Echarts 柱状图X轴数据隔一个显示、文字显示不全
原始图:
解决 Echarts 柱状图X轴数据隔一个显示:
参考1:https://blog.csdn.net/fufu_good/article/details/106808713
解决 Echarts 柱状图X轴文字显示不全:解决x轴文字显示不全并将文字倾斜
参考2:https://blog.csdn.net/suhui1995/article/details/74231671
效果图:
核心代码:
axisLabel: {
interval: 0, //设置间隔为0
rotate: 40, //文字倾斜
fontSize:12
},
完整代码:
<div id="concentration-container" style="width: 100%; height: 228px"> </div>
initChart() {
var dom = document.getElementById("concentration-container");
var myChart = echarts.init(dom, null, {
renderer: "canvas",
useDirtyRect: false,
});
var option;
let that = this;
let color = ["#3483EA", "#3483EA", "#D14305", "#ffffff"];
option = {
color: color,
tooltip: {
trigger: "axis",
showDelay: 0, // 显示延迟,添加显示延迟可以避免频繁切换,单位ms
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
show: false,
formatter: (params) => {
let newArr = [];
params.forEach((work) => {
newArr.push(work);
});
let dataStr = `<div class="tool-tips">
<div class="name-con">
${newArr[0].name}
</div>
</div>`;
newArr.forEach((item, index) => {
// 获取图标(小圆点)颜色,并且自定义样式为正方形,即要改变小圆点,只需重写marker的html片段,并修改样式即可
dataStr += `<div>
<div class="tool-item">
<span class="len-box" style="background-color:${
color[item.seriesIndex]
};" ></span>
<span>
<span></span>
</span>
<span class="len-name">${item.seriesName}</span>
<span class="len-percent">${item.data}</span>
</div>
</div>`;
});
return dataStr;
},
},
grid: {
top: "15%",
left: "3%",
right: "4%",
bottom: "12%",
containLabel: true,
},
legend: [
{
left: "20%",
y: "bottom", //延Y轴居中
// bottom:"-3%",
itemWidth: 12,
itemHeight: 12,
data: [
{
name: "2014年",
icon: "roundRect",
textStyle: {
fontSize: 14,
color: "#666666",
},
},
],
},
{
left: "40%",
y: "bottom", //延Y轴居中
// bottom: "-3%",
itemWidth: 12,
itemHeight: 12,
data: [
{
name: "2021年",
icon: "roundRect",
textStyle: {
fontSize: 14,
color: "#666666",
},
},
],
},
{
left: "60%",
y: "bottom", //延Y轴居中
// bottom: "-3%",
itemWidth: 20,
itemHeight: 6,
data: [
{
name: "2022年",
textStyle: {
fontSize: 14,
color: "#666666",
},
},
],
},
],
xAxis: {
type: "category",
data: [
"01月",
"02月",
"03月",
"04月",
"05月",
"06月",
"07月",
"08月",
"09月",
"10月",
"11月",
"12月",
],
axisLine: {
lineStyle: {
color: "#CCCCCC",
},
},
axisTick: {
show: false, //不显示刻度
},
axisLabel: {
interval: 0, //设置间隔为0
rotate: 30, //文字倾斜
fontSize: 12,
},
boundaryGap: false, // 不留白,从原点开始 ECharts折线从x轴原点(0点)开始
},
yAxis: [
{
type: "value",
name: "mg/L",
nameTextStyle: {
padding: [0, 0, 0, -30], // y轴的name属性设置位置(上右下左与原位置距离)
},
splitLine: { show: false },
symbol: "none",
axisLine: {
show: true,
lineStyle: {
color: "#CCCCCC",
},
},
},
],
series: [
{
name: "2014年",
data: [150, 155, 150, 175, 170, 162, 180, 150, 168, 188, 200, 240],
type: "line",
areaStyle: {
color: "rgba(27,171,246,0.1)",
},
symbol: "none", //不显示拐点
itemStyle: {
normal: {
lineStyle: {
width: 1, //折线宽度
color: "rgba(27,171,246,1)", //改变折线颜色
},
},
emphasis: {
lineStyle: {
width: 1,
color: "rgba(27,171,246,1)",
},
},
},
},
{
name: "2021年",
data: [80, 90, 85, 95, 95, 90, 100, 85, 100, 110, 140, 160],
type: "line",
areaStyle: {
color: "rgba(255,255,255,1)",
},
symbol: "none", //不显示拐点
itemStyle: {
normal: {
lineStyle: {
width: 1, //折线宽度
color: "rgba(27,171,246,1)", //改变折线颜色
},
},
emphasis: {
lineStyle: {
width: 1,
color: "rgba(27,171,246,1)",
},
},
},
zlevel: 11,
},
{
name: "2022年",
type: "line",
data: [150, 192, 161, 174, 182, 162],
symbolSize: 4, //拐点大小
animation: false,
itemStyle: {
normal: {
lineStyle: {
width: 1, //折线宽度
color: "#D14305", //改变折线颜色
},
},
emphasis: {
lineStyle: {
width: 1,
color: "#D14305",
},
},
},
},
],
};
if (option && typeof option === "object") {
myChart.setOption(option);
}
window.addEventListener("resize", myChart.resize);
},
19、图例换行
参考:https://blog.csdn.net/qq_44271127/article/details/109691992
20、堆叠柱状图 文字显示
const option = {
title: {
subtext: "超标天数",
subtextStyle: {
color: "#999999"
}
},
color: ["#2492FF", "#5DE9B0", "#FEC715"],
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
legend: {
show: true,
bottom: 10,
x: "center",
itemWidth: 12,
itemHeight: 12
},
grid: {
top: "40",
left: "20",
right: "20",
bottom: "40",
containLabel: true
},
xAxis: [
{
type: "category",
data: ["南澳青澳湾", "大梅沙", "小梅沙", "闸坡"],
axisTick: { show: false },
axisLine: {
show: true,
lineStyle: {
color: "#CCCCCC"
}
},
axisLabel: {
show: true,
// interval: 0,
//当x轴名称太长,柱子默认隔一个显示,这里需求是让他全部显示
fontSize: 12,
color: "#333333",
overflow: "break"
}
}
],
yAxis: [
{
type: "value",
axisTick: {
show: true,
inside: true
},
axisLine: {
show: true,
lineStyle: {
color: "#CCCCCC"
}
},
axisLabel: {
show: true,
color: "#999999"
},
splitLine: { show: false }
// interval: 'auto',
}
],
series: [
{
name: "优",
type: "bar",
stack: "total",
data: [60, 70, 50, 60],
barMaxWidth: 24
},
{
name: "良",
type: "bar",
stack: "total",
data: [20, 15, 25, 20],
barMaxWidth: 24
},
{
name: "差",
type: "bar",
stack: "total",
data: [20, 15, 25, 20],
barMaxWidth: 24
}
]
};
处理:
//柱子上显示数值
const seriesFormatter = (params) => {
let value = Number.parseFloat(params.value)
if (value === 0) {
// 如果是0数值,不显示
return ''
}
return value
}
/**
* 这个位置的数据,是否在这一柱子最顶部,并且第一个不是0的数
* @param chartData 二维数组,每行是一个系列的柱子
* @param rowIndex chartData的行
* @param colIndex chartData的列
*/
const isTopLastNotZero = (chartData = [], rowIndex, colIndex) => {
if (!chartData.length) {
return false
}
// 转化 chartData
let testArr = []
chartData.forEach(item => {
testArr.push(item.data)
})
const zip = (...arrays) => {
// 找到最短数组的长度
const shortestLength = Math.min(...arrays.map(arr => arr.length));
// 使用 map 和数组解构来组合元素
return Array.from({ length: shortestLength }, (_, i) => {
return arrays.map(arr => arr[i]);
});
}
let matrix = zip(...testArr)
let viewBarData = matrix[colIndex]
let index = viewBarData.findLastIndex(num => num != 0)
return rowIndex === index
}
const getPosition = (chartData, rowIndex, colIndex) => {
let position = ''
if (chartData.length > 1) {
if (isTopLastNotZero(chartData, rowIndex, colIndex)) {
// 最顶部开始非0的柱子的标签显示在top
position = 'top'
} else {
position = 'inside'
}
} else {
// 只有一个系列label都显示在顶部
position = 'top'
}
return position
}
let resultData = JSON.parse(JSON.stringify(option.series))
resultData = resultData.map((item, rowIndex) => {
item.data = item.data.map((work, colIndex) => {
let position = getPosition(option.series, rowIndex, colIndex)
return {
value: work,
label: {
show: true,
color: '#333333',
fontSize: 12,
formatter: seriesFormatter,
position: position
}
}
})
return item
})
option.series = resultData
效果:
21、折线图:多X轴、双Y轴、翻转x轴
function getInitData() {
//x轴日期(模拟)
function getAll(start, end) {
let dateList = [];
var startTime = getDate(start);
var endTime = getDate(end);
while ((endTime.getTime() - startTime.getTime()) >= 0) {
var year = startTime.getFullYear();
var month = startTime.getMonth() + 1 < 10 ? '0' + (startTime.getMonth() + 1) : startTime.getMonth() + 1;
var day = startTime.getDate().toString().length == 1 ? "0" + startTime.getDate() : startTime.getDate();
// dateList.push(year + "-" + month + "-" + day);
let obj = {
subGroup: `${month}月`,
name: day,
value: ""
}
dateList.push(obj)
startTime.setDate(startTime.getDate() + 1);
}
return dateList;
}
function getDate(datestr) {
var temp = datestr.split("-");
var date = new Date(temp[0], temp[1] - 1, temp[2]);
return date;
}
//日期
var srcData = getAll('2023-10-21', '2023-11-20')
//均值
var meanValue = {
subGroup: '均值',
name: '均值',
value: ""
}
srcData.push(meanValue)
var covertData = function (src) {
var nameList = [];
var valueList = [];
var subGroupLabelList = [''];
var subGroupTickList = [0];
var subGroupTmp = {
name: '',
count: 0
};
for (var i = 0; i < src.length; i++) {
nameList.push(src[i].name);
valueList.push(src[i].value);
subGroupLabelList.push('', '');
if (i === src.length - 1 || subGroupTmp.name !== '' && subGroupTmp.name !== src[i + 1].subGroup) {
subGroupLabelList[i * 2 - subGroupTmp.count + 1] = src[i].subGroup;
subGroupTmp.name = '';
subGroupTmp.count = 0;
subGroupTickList.push(i * 2 + 2);
} else {
subGroupTmp.name = src[i].subGroup;
subGroupTmp.count++;
}
}
return {
nameList: nameList,
valueList: valueList,
subGroupLabelList: subGroupLabelList,
subGroupTickList: subGroupTickList
};
};
//x轴分组显示
dstData = covertData(srcData);
const option = {
color: ['#0FAE59', '#666666', '#3483EB', '#0FAE59', '#666666'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
formatter: function (params) {
// console.log('params12', params)
var str = ""; //声明一个变量用来存储数据
str += `<div style="margin-bottom: 5px; font-weight: 600">${params[0].name}</div>`;
for (var i = 0; i < params.length; i++) {
if (params[i].seriesType === 'bar' && params[i].value === '-') {
continue
} else {
str += `
<div style="display: flex; align-items: center;justify-content: space-between;">
<div style="display: flex; align-items: center;"><span style="display:inline-block;margin-right:5px;margin-bottom:2px;width:10px;height:10px;border-radius:50%;background-color: ${params[i].color}"></span>${params[i].seriesName}</div>
<div style="padding-left: 20px; font-weight: 600">${params[i].value}</div>
</div>
`
}
}
return str;
}
},
legend: {
show: true,
bottom: 10,
x: 'center',
itemWidth: 12,
itemHeight: 8,
data: ["总磷", "总磷-手工", '降雨量']
},
grid: [
{
bottom: '25%'
}
],
xAxis: [
{
//第一级
type: 'category',
data: [dstData.nameList],
axisTick: {
length: 0
},
},
{
//第二级
type: 'category',
data: dstData.subGroupLabelList,
position: 'bottom',
// boundaryGap: false,
axisLine: {
show: true,
lineStyle: {
color: '#CCCCCC',
},
onZero: false
},
axisLabel: {
margin: 40,
interval: 0,
color: '#666666',
},
axisTick: {
length: 60,
interval: (index) => dstData.subGroupTickList.indexOf(index) != -1
},
axisPointer: {
type: 'none'
},
}
],
yAxis: [
{
name: '浓度',
type: 'value',
max: 5,
axisTick: {
show: true,
inside: true,
},
axisLine: {
show: true,
lineStyle: {
color: '#0FAE59',
},
},
axisLabel: {
show: true,
color: '#0FAE59',
},
splitLine: { show: false },
},
{
name: '降雨量',
type: 'value',
axisTick: {
show: true,
inside: true,
},
axisLine: {
show: true,
lineStyle: {
color: '#3483EB',
},
},
max: 200,
axisLabel: {
show: true,
color: '#3483EB',
},
splitLine: { show: false },
nameLocation: 'start',
type: 'value',
inverse: true
}
],
series: [
{
xAxisIndex: 0,
yAxisIndex: 0,
name: '总磷',
type: 'line',
showSymbol: false,
data: [0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18, 0.25, 0.24, 0.15, 0.25, 0.23, 0.14, 0.1, 0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18, 0.25, 0.15, 0.26, 0.15, 0.23, 0.19, 0.17, 0.22, 0.25, 0.18],
label: {
show: true,
color: '#0FAE59'
},
markLine: {
silent: true,
animation: false,
data: [{ yAxis: 0.2, name: '标记线', label: { show: false } }],
symbol: ['none', 'none'],
position: "insideTopCenter",
itemStyle: {
normal: {
lineStyle: {
type: 'dashed',
color: '#CCCCCC'
},
},
}
}
},
{
xAxisIndex: 0,
yAxisIndex: 0,
name: '总磷-手工',
type: 'line',
symbol: 'triangle',
data: ['-', 0.18, '-', '-', '-', '-', 0.13, '-', '-', '-', '-', '-', 0.1, '-', '-', '-', '-', '-', '-', 0.2, '-', '-', '-', '-', 0.12, '-', '-', '-', '-', '-', 0.12],
symbolSize: 10,
itemStyle: {
normal: {
label: {
show: true,
color: '#666666',
position: 'bottom',
},
lineStyle: {
color: "rgba(0,0,0,0)"
}
}
}
},
{
xAxisIndex: 0,
yAxisIndex: 1,
name: '降雨量',
type: 'bar',
data: [10, 20, 30, 25, '-', '-', '-', 18, 20, 26, 28, 10, '-', '-', '-', 12, 13, 25, '-', '-', '-', 28, 32, 23, 34, '-', '-', 15, 50, 28, 6],
symbolSize: 8,
label: {
// position: 'bottom',
// show: true,
color: '#3483EB'
},
markLine: {
silent: true,
animation: false,
data: [{ yAxis: 0, name: '标记线', label: { show: false } }],
symbol: ['none', 'none'],
position: "insideTopCenter",
itemStyle: {
normal: {
lineStyle: {
type: 'solid',
color: '#CCCCCC'
},
},
}
}
},
{
xAxisIndex: 0,
yAxisIndex: 0,
name: '总磷',
type: 'bar',
data: ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', 0.21],
barMaxWidth: 10,
label: {
show: true,
position: 'top',
color: '#0FAE59'
},
symbolSize: 8
},
{
xAxisIndex: 0,
yAxisIndex: 0,
name: '总磷-手工',
type: 'bar',
// yAxisIndex: 1,
data: ['-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', 0.13],
barMaxWidth: 16,
label: {
show: true,
position: 'top',
color: '#666666'
},
symbolSize: 8
},
]
}
return option
}
CSS 样式
1、渐变色文字及边框
效果图:
代码实现:
<template>
<div class="demo-line">
<div class="level-text">优~良</div>
</div>
</template>
<style lang="scss" scoped>
.demo-line {
width: 88px;
height: 24px;
border: 1px solid #28fea7;
text-align: center;
//背景、边框渐变
border: 1px solid transparent;
border-radius: 4px;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(
to right,
rgba(6, 51, 40, 1),
rgba(54, 70, 37, 1)
),
linear-gradient(90deg, rgba(40, 254, 167, 1), rgba(247, 255, 0, 1));
// 文字颜色渐变
.level-text {
-webkit-background-clip: text;
color: transparent;
background-image: linear-gradient(to right, #28fea7, #f7ff00);
}
}
</style>
2、上一页、下一页切换
效果图:
代码实现:
<template>
<div class="myt-panel-con">
<div class="air-forecast">
<!-- 左箭头:上一页 -->
<div class="panel-btn left-btn" @click="prevCard">上</div>
<div ref="forecastWrap" class="forecast-wrap">
<div
class="forecast-item"
v-for="(item, index) in forecastList"
:key="index"
>
{{ item }}
</div>
</div>
<!-- 右箭头:下一页 -->
<div class="panel-btn right-btn" @click="nextCard">下</div>
</div>
</div>
</template>
<script>
export default {
name: "ActualAirQuality",
components: {},
data() {
return {
scrollLeft: 0,
forecastList: ["第一", "第二", "第三", "第四", "第五", "第六", "第七", "第八"],
};
},
methods: {
// 卡片切换
prevCard() {
let forecastWrap = this.$refs.forecastWrap;
let itemWidth = 120;
if (forecastWrap.childNodes && forecastWrap.childNodes.length) {
itemWidth = forecastWrap.childNodes[0].offsetWidth;
}
this.scrollLeft -= itemWidth;
if (this.scrollLeft < 0) {
this.scrollLeft = 0;
}
forecastWrap.scrollTo({ left: this.scrollLeft, behavior: "smooth" });
},
// 卡片切换
nextCard() {
let forecastWrap = this.$refs.forecastWrap;
let itemWidth = 120;
if (forecastWrap.childNodes && forecastWrap.childNodes.length) {
itemWidth = forecastWrap.childNodes[0].offsetWidth;
}
this.scrollLeft += itemWidth;
let maxScrollLeft = forecastWrap.scrollWidth - itemWidth * 3;
if (this.scrollLeft > maxScrollLeft) {
this.scrollLeft = maxScrollLeft;
}
forecastWrap.scrollTo({ left: this.scrollLeft, behavior: "smooth" });
},
},
created() {},
watch: {},
};
</script>
<style lang="scss" scoped>
.myt-panel-con {
width: 743px;
height: 400px;
background: #001339;
padding: 20px;
}
.air-forecast {
display: flex;
margin-bottom: 18px;
height: 177px;
width: 410px;
.forecast-wrap {
flex: 1;
display: inline-flex;
overflow-x: auto;
&::-webkit-scrollbar {
height: 0;
}
}
.panel-btn {
width: 20px;
height: 169px;
border: 1px solid transparent;
font-size: 14px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}
.left-btn,
.right-btn {
color: red;
border: 1px solid rgba(110, 210, 255, 0.05);
// background: #ccc;
background: rgba(10, 34, 69, 0.8);
font-size: 14px;
}
.forecast-item {
flex-shrink: 0;
width: 120px;
height: 169px;
background: linear-gradient(
180deg,
rgba(86, 164, 200, 0.2) 0%,
rgba(43, 82, 100, 0.2) 100%
);
border: 1px solid;
border-image: linear-gradient(to bottom, #00577e, #39cfff) 1;
cursor: pointer;
font-size: 16px;
font-family: MiSans-Regular, MiSans;
font-weight: 400;
color: #8ad9ff;
position: relative;
}
}
</style>