美文网首页
微信小程序实现折线面积图-玫瑰图-立体柱状图

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

作者: 苏苏哇哈哈 | 来源:发表于2022-07-19 23:48 被阅读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+订阅!

    相关文章

      网友评论

          本文标题:微信小程序实现折线面积图-玫瑰图-立体柱状图

          本文链接:https://www.haomeiwen.com/subject/wuayirtx.html