微信小程序实现折线面积图-玫瑰图-立体柱状图

2022-07-19  本文已影响0人  苏苏哇哈哈

1.实现效果

图表echarts.gif

2.实现原理

官网: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
  }
})

4.更多小程序相关,关注公众号 苏苏的bug,更多小程序demo,尽在苏苏的码云如果对你有帮助,欢迎你的star+订阅!

上一篇下一篇

猜你喜欢

热点阅读