微信小程序实现折线面积图-玫瑰图-立体柱状图
2022-07-19 本文已影响0人
苏苏哇哈哈
1.实现效果
图表echarts.gif2.实现原理
官网:https://echarts.apache.org/zh/index.html
echarts社区:http://www.ppchart.com/#/
一些图表类型:
series-line
折线图是用折线将各个数据点标志连接起来的图表,用于展现数据的变化趋势。可用于直角坐标系和极坐标系上。
Tip: 设置 areaStyle 后可以绘制面积图。
Tip: 配合分段型 visualMap 组件可以将折线/面积图通过不同颜色分区间。
series-bar
柱状图(或称条形图)是一种通过柱形的高度(横向的情况下则是宽度)来表现数据大小的一种常用图表类型。
series-pictorialBar
象形柱图是可以设置各种具象图形元素(如图片、SVG PathData 等)的柱状图。往往用在信息图中。用于有至少一个类目轴或时间轴的直角坐标系上。
series-pie
饼图主要用于表现不同类目的数据在总和中的占比。每个的弧度表示数据数量的比例。
对于一个图表中有多个饼图的场景,可以使用 left、right、top、bottom、width、height 配置每个饼图系列的位置和视口大小。radius、label.edgeDistance 等支持百分比的配置项,是相对于该配置项决定的矩形的大小而言的。
Tip: 饼图更适合表现数据相对于总数的百分比等关系。如果只是表示不同类目数据间的大小,建议使用 柱状图,人们对于微小的弧度差别相比于微小的长度差别更不敏感,或者也可以通过配置 roseType 显示成南丁格尔图,通过半径大小区分数据的大小。
一些参数意义:
grid:
直角坐标系内绘图网格,单个 grid 内最多可以放置上下两个 X 轴,左右两个 Y 轴。可以在网格上绘制折线图,柱状图,散点图(气泡图)。
如:
grid: { //图表距边框的距离
left: 10,
right:20,
top: 40,
bottom: 10,
containLabel: true,
},
animation
是否开启动画。
animationDuration
初始动画的时长,支持回调函数,可以通过每个数据返回不同的时长实现更戏剧的初始动画效果:
showSymbol
折线中:是否显示 symbol, 如果 false 则只有在 tooltip hover 的时候显示。
symbol
标记的图形。
ECharts 提供的标记类型包括'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'。
可以通过 'image://url' 设置为图片,其中 URL 为图片的链接,或者 dataURI。
eg:
showSymbol: true, //是否默认展示圆点
symbol: "circle", // 默认是空心圆(中间是白色的),改成实心圆
graphic
graphic 是原生图形元素组件。可以支持的图形元素包括:image, text, circle, sector, ring, polygon, polyline, rect, line, bezierCurve, arc, group。
3.实现代码
<view class="box">
<ec-canvas id="mychart-dom-bar" ec="{{ ec }}"></ec-canvas>
</view>
<view class="box">
<ec-canvas id="mychart-dom-line" ec="{{ ec }}"></ec-canvas>
</view>
<view class="box">
<ec-canvas id="mychart-dom-line1" ec="{{ ec }}"></ec-canvas>
</view>
<view class="box">
<ec-canvas id="mychart-dom-pie" ec="{{ ec }}"></ec-canvas>
</view>
page {
background: linear-gradient(90deg, #03224e 0%, #011030 100%);
}
.box {
width: 100%;
height: 550rpx;
}
import * as echarts from '../../components/ec-canvas/echarts';
Page({
data: {
ec: {
lazyLoad: true // 延迟加载
}
},
onLoad: function (options) {
this.echartsComponnet = this.selectComponent('#mychart-dom-bar');
this.getData('echartsComponnet', 0); //获取数据
this.echartsComponnetLine = this.selectComponent('#mychart-dom-line');
this.getData('echartsComponnetLine', 1); //获取数据
this.echartsComponnetLine1 = this.selectComponent('#mychart-dom-line1');
this.getData('echartsComponnetLine1', 2); //获取数据
this.echartsComponnetpie = this.selectComponent('#mychart-dom-pie');
this.getData('echartsComponnetpie', 3); //获取数据
},
/**
* 获取图表数据
*/
getData(type, action) {
this[type].init((canvas, width, height, dpr) => {
const Chart = echarts.init(canvas, null, {
width: width,
height: height,
devicePixelRatio: dpr
});
Chart.setOption(this.getOption(action));
return Chart;
});
},
/**
* 图表init
*/
getOption(e) {
if (e == 0) {
return this.getBar(["服务1", "服务2", "服务3", "服务4", "服务5"], [2, 5, 1, 8, 1])
}
if (e == 1) {
return this.getLine(["服务1", "服务2", "服务3", "服务4", "服务5"], [2, 5, 1, 8, 1], 1)
}
if (e == 2) {
return this.getLine(["服务1", "服务2", "服务3", "服务4", "服务5"], [2, 22, 55, 22, 44], 2)
}
if (e == 3) {
return this.getPie()
}
},
/**
* 获取数据
*/
getBar(xData, yData) {
let colorArr = ["#2886c6", "#50bfda", "#89e3ec"],
color = {
type: "linear",
x: 0,
x2: 1,
y: 0,
y2: 0,
colorStops: [{
offset: 0,
color: colorArr[0],
},
{
offset: 0.5,
color: colorArr[0],
},
{
offset: 0.5,
color: colorArr[1],
},
{
offset: 1,
color: colorArr[1],
},
],
},
barWidth = 20,
bottomData = [],
topData = [];
yData.filter((item) => {
if (item) {
bottomData.push(1);
topData.push(item);
} else {
bottomData.push(0);
topData.push({
value: 1,
itemStyle: {
normal: {
borderColor: "rgba(0,0,0,0)",
borderWidth: 2,
color: "rgba(0,0,0,0)",
},
},
});
}
});
let option = {
animation: true, //控制动画示否开启
animationDuration: 5000, // 动画的时长,它是以毫秒为单位
tooltip: {
trigger: "axis",
backgroundColor: "rgba(0,0,0,.5)",
axisPointer: {
type: "cross",
label: {
backgroundColor: "rgba(0,0,0,.5)",
},
},
textStyle: {
color: "#fff",
fontSize: 14,
},
},
grid: { //图表距边框的距离
left: 10,
right:20,
top: 40,
bottom: 10,
containLabel: true,
},
xAxis: {
data: xData,
axisTick: {
show: false,
},
axisLabel: {
color: "rgba(255,255,255,.8)", //坐标的字体颜色
fontSize: 12,
},
},
yAxis: {
axisLine: {
show: true,
},
axisLabel: {
show: true,
color: "rgba(255,255,255,.8)", //坐标的字体颜色
fontSize: 12,
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,.25)",
type: "dashed",
},
//网格线颜色
},
},
series: [{
z: 1,
name: "数据",
type: "bar",
barWidth: barWidth,
barGap: "0%",
data: yData,
itemStyle: {
normal: {
color: color,
},
},
},
{
z: 2,
name: "数据",
type: "pictorialBar",
data: bottomData,
symbol: "diamond",
symbolOffset: ["0%", "50%"],
symbolSize: [barWidth, 10],
itemStyle: {
normal: {
color: color,
},
},
tooltip: {
show: false,
},
},
{
z: 3,
name: "数据",
type: "pictorialBar",
symbolPosition: "end",
data: topData,
symbol: "diamond",
symbolOffset: ["0%", "-50%"],
symbolSize: [barWidth - 4, (10 * (barWidth - 4)) / barWidth],
itemStyle: {
normal: {
borderColor: colorArr[2],
borderWidth: 2,
color: colorArr[2],
},
},
tooltip: {
show: false,
},
},
],
};
return option;
},
getLine(xData, yData, type) {
let datacoords = [{
coords: [],
}, ];
for (let i = 0; i < xData.length; i++) {
datacoords[0].coords.push([xData[i], yData[i]]);
}
console.log(datacoords)
let s1 = [{
name: "苏苏小苏苏",
type: "line",
smooth: type == 2,
smoothMonotone: "x",
lineStyle: {
width: 1.5,
type: "solid",
shadowOffsetX: 0, // 折线的X偏移
shadowOffsetY: 3, // 折线的Y偏移
shadowBlur: 4, // 折线模糊
opcity: 1,
shadowColor: "rgba(220,120,40,0.95)", //折线颜色
},
showSymbol: false,
itemStyle: {
color: "#DC7828",
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{
offset: 1,
color: "rgba(220,120,40,0.3)",
},
{
offset: 0.74,
color: "rgba(220,120,40,0.26)",
},
{
offset: 0,
color: "rgba(220,120,40,0)",
},
]),
},
emphasis: {
focus: "series",
},
data: yData,
}],
s2 = [{
name: "苏苏小苏苏222",
type: "line",
smooth: type == 2,
lineStyle: {
color: "#00CCA9",
width: 1.5,
type: "solid",
shadowOffsetX: 0, // 折线的X偏移
shadowOffsetY: 3, // 折线的Y偏移
shadowBlur: 4, // 折线模糊
shadowColor: "rgba(0,204,169,0.95)", //折线颜色
},
showSymbol: true, //是否默认展示圆点
symbol: "circle", // 默认是空心圆(中间是白色的),改成实心圆
symbolSize: 7, //设定实心点的大小
itemStyle: {
color: "#021E47", //实心的圆点的背景颜色-----圆透明!!!!!!!
borderWidth: 1, //圆点边框大小
borderColor: "#00CCA9", //实心的圆点边框颜色
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{
offset: 1,
color: "rgba(0,204,169,0.3)",
},
{
offset: 0,
color: "rgba(0,204,169,0)",
},
]),
},
emphasis: {
focus: "series",
},
data: yData,
},
];
let option = {
animation: true, //控制动画示否开启
animationDuration: 3000, // 动画的时长,它是以毫秒为单位
backgroundColor: "transparent",
color: ["#ec5d5f", "#f2cb58", "#64a0c8"],
tooltip: {
trigger: "axis",
backgroundColor: "rgba(0,0,0,.5)",
axisPointer: {
type: "cross",
label: {
backgroundColor: "rgba(0,0,0,.5)",
},
},
textStyle: {
color: "#fff",
fontSize: 14,
},
},
grid: {
left: 10,
top: 40,
bottom: 10,
right:20,
containLabel: true,
},
xAxis: [{
nameGap: 3,
nameTextStyle: {
//坐标轴单位
color: "rgba(255,255,255,.8)",
fontSize: 12,
},
type: "category",
data: xData,
boundaryGap: false, //从0开始
axisLine: {
rotate: 30, //坐标轴内容过长旋转
interval: 0,
lineStyle: {
color: "#636E7C",
},
},
axisLabel: {
color: "rgba(255,255,255,.8)", //坐标的字体颜色
fontSize: 12,
},
axisTick: {
//坐标轴刻度颜色 x和y不交叉
show: false,
},
}, ],
yAxis: [{
name: "人",
min: 0,
max: function (value) {
return Math.ceil(value.max / 5) * 5;
},
splitNumber: 5,
type: "value",
nameTextStyle: {
//坐标轴单位
color: "rgba(255,255,255,.89)",
fontSize: 12,
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255,255,255,.25)",
type: "dashed",
},
//网格线颜色
},
axisTick: {
//坐标轴刻度颜色
show: false,
},
axisLine: {
//坐标轴线颜色
show: true,
lineStyle: {
color: "#636E7C",
},
},
axisLabel: {
color: "rgba(255,255,255,.8)", //坐标的字体颜色
fontSize: 12,
},
}, ],
series: type == 1 ? s2 : s1
}
return option;
},
getPie() {
let option = {
color: [
"#3D75FC",
"#3E46CE",
"#E45C7E",
"#2DB4D1",
"#CBAE2E",
"#5ECAB9",
"#D36640",
],
animation: true, //控制动画示否开启
animationDuration: 5000, // 动画的时长,它是以毫秒为单位
animationEasing: "bounceOut", //缓动动画
animationThreshold: 8, //动画元素的阈值
tooltip: {
trigger: "item",
formatter: "苏苏{b} : {c} ({d}%",
position: function (point, params, dom, rect, size) {
let x = 0;
let y = 0;
let pointX = point[0];
let pointY = point[1];
let boxWidth = size.contentSize[0];
let boxHeight = size.contentSize[1];
if (boxWidth > pointX) {
x = 5;
} else {
x = pointX - boxWidth;
}
if (boxHeight > pointY) {
y = 5;
} else {
y = pointY - boxHeight;
}
return [x, y];
},
},
legend: {
type: "scroll",
orient: "vertical",
right: '10%',
top: "center",
icon: "rect",
itemWidth: 10, // 设置宽度
itemHeight: 10, // 设置高度
selectedMode: true,
textStyle: {
color: "#fff",
fontSize: 12,
},
formatter: function (name) {
return name.length > 5 ? name.substr(0, 5) + "..." : name;
},
tooltip: {
show: true,
},
},
series: [{
minAngle: 5, //最小的扇区角度(0 ~ 360),用于防止某个值过小导致扇区太小影响交互
avoidLabelOverlap: true, //是否启用防止标签重叠策略
labelLine: {
minTurnAngle: 0,
},
type: "pie",
radius: [20, 120],
center: ["30%", "50%"],
roseType: "area",
itemStyle: {
borderRadius: 0,
},
label: {
show: false,
},
data: [{
value: 88,
name: "rose 1"
},
],
}, ],
};
return option
}
})