美文网首页echart收藏Angular框架专题
angular中对echarts图表进行封装(环形进度条、双Y轴

angular中对echarts图表进行封装(环形进度条、双Y轴

作者: 听书先生 | 来源:发表于2022-02-09 16:32 被阅读0次

    在大屏的开发过程中,需要大量的使用echarts图表,我们可以腾出时间将echarts图表进行二次封装,以便后期循环使用。

    1、二次封装echarts:

    封装为公共组件,在使用的时候只需要传入option项即可

    import { AfterViewInit, Component, ElementRef, Input, OnDestroy } from "@angular/core";
    import * as echarts from 'echarts';
    
    @Component({
      selector: 'my-charts',
      template: ``,
      styles: [`
        :host {
          display: inline-block;
          height: 100%;
          width: 100%;
          padding: 0;
          margin: 0;
          border: none;
          cursor: pointer;
          overflow: hidden;
        }
      `]
    
    })
    export class MYChartsComponent implements AfterViewInit, OnDestroy {
    
      chart;
      _option;
    
      constructor(private el: ElementRef) {
      }
    
      @Input()
      set option(option) {
        this._option = option
        if (this.chart) {
          this.chart.setOption(option, true);
        }
      }
    
      ngAfterViewInit() {
        this.chart = echarts.init(this.el.nativeElement);
        this.chart.setOption(this._option, true);
        window.addEventListener('resize', this.onWindowResize)
      }
    
      onWindowResize = () => {
        this.chart.resize()
      }
    
      ngOnDestroy() {
        window.removeEventListener('resize', this.onWindowResize)
      }
    
    }
    
    2、将不同的echarts图表封装到一个charts.options.ts文件中:

    这个文件将你所有图表的配置项写成key-value的形式存入进去,这样可以在你使用到某个相同的echarts图表时,只需要在外部动态的修改data数据即可。

    import * as echarts from "echarts";
    
    const CHARTS_OPTION = {
       progressAllotment: {
         // 环形进度条的代码部分 
       },
       taskNumByMonth: {
          // 双Y轴折线区域图
       }
    };
    
    export { CHARTS_OPTION };
    
    
    

    环形进度条说明:
    环形进度条有一些地方需要记录一下:

    • 1、echarts环形使用top: 'center'默认是依据的主标题居中对齐,因此,再去加入副标题时,就会产生没有垂直居中对齐的情况,需要手动修改top: '40%'的百分比
    • 2、clockwise属性设置为true指的是环形为顺时针展示
      参考图例.png
    • 参考代码:
      progressAllotment: {
        title: {
          text: 0 + "%",
          textStyle: {
            color: "#9A9EBA",
            fontSize: 18,
          },
          subtext: "当日配款进度",
          subtextStyle: {
            fontSize: 16,
            color: "#106199",
          },
          align: "auto",
          itemGap: 10,
          left: "center",
          top: "40%",
        },
        angleAxis: {
          max: 100,
          clockwise: true,
          axisLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            show: false,
          },
          splitLine: {
            show: false,
          },
        },
        radiusAxis: {
          type: "category",
          axisLine: {
            show: false,
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            show: false,
          },
          splitLine: {
            show: false,
          },
        },
        polar: {
          center: ["50%", "50%"],
          radius: "160%", //图形大小
        },
    
        series: [
          {
            type: "bar",
            data: [
              {
                name: "当前配款进度",
                value: 0,
                itemStyle: {
                  normal: {
                    color: "#15A3EF",
                  },
                },
              },
            ],
            coordinateSystem: "polar",
            roundCap: true,
            barWidth: 10,
            barGap: "-100%", // 两环重叠
            z: 2,
          },
          {
            type: "bar",
            data: [
              {
                value: 100,
                itemStyle: {
                  color: "#1E3566",
                  shadowColor: "rgba(0, 0, 0, 0.2)",
                  shadowOffsetY: 2,
                },
              },
            ],
            coordinateSystem: "polar",
            roundCap: true,
            barWidth: 10,
            barGap: "-100%", // 两环重叠
            z: 1,
          },
        ],
      },
    
    

    双Y轴折线区域图:
    这里同样有些地方需要留意的,在echarts3.0版本以上,貌似y轴坐标就需要手动去划分刻度以及设置最大值或最小值。

    • 1、双y轴显示:在yAxis配置了两个对象内容的基础上,将series中的第二个对象的yAxisIndex设为1即可
    • 2、左右坐标轴刻度不均等,导致间隔出现大小不一:使用interval: Math.ceil(坐标的最大值 / 4)这样就成功的划分为了4等分
    • 3、折线图渐变区域块的设置:渐变区域的话只需要在areaStyle中去设置渐变颜色即可
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "#74EAB0", // 0% 处的颜色
                },
                {
                  offset: 0.1,
                  color: "#448AC8", // 10% 处的颜色
                },
                {
                  offset: 1,
                  color: "transparent", // 100% 处的颜色
                },
              ]),
            },
    
    • 4、拐点的样式自定义:在series中去自定义itemStyle样式即可
            itemStyle: {
              normal: {
                color: "#3AB578",
                lineStyle: {
                  color: "#3AB578",
                  width: 1,
                },
              },
            },
    
    参考图片.png
    • 参考代码:
     taskNumByMonth: {
        legend: {
          data: ["订单数量", "订单金额", "配款耗时"],
          icon: "circle",
          right: 0,
          textStyle: {
            color: "white",
          },
        },
        grid: {
          left: "5%",
          right: "8%",
          bottom: "8%",
          containLabel: true,
        },
        tooltip: {
          trigger: "axis",
        },
        xAxis: {
          type: "category",
          data: ["16号","19号","21号","24号","27号","30号","3号","6号","9号","12号","15号"],
          boundaryGap: false,
          axisLabel: {
            color: "white",
            fontSize: 12,
          },
          axisLine: {
            lineStyle: {
              color: "#366383",
            },
          },
          axisTick: {
            show: false,
          },
        },
        yAxis: [
          {
            name: "单位: 万元",
            nameTextStyle: {
              color: "white",
            },
            type: "value",
            axisLabel: {
              color: "white",
              fontSize: 12,
            },
            min: 0,
            max: 20000, // 最大值
            interval: Math.ceil(20000 / 4), //  平均分为4份
            splitLine: {
              show: true,
              lineStyle: {
                type: "dashed",
                color: "#395275",
              },
            },
          },
          {
            name: "单位: 分钟",
            nameTextStyle: {
              color: "white",
            },
            type: "value",
            axisLabel: {
              color: "white",
              fontSize: 12,
            },
            min: 0,
            max: 160, // 最大值
            interval: Math.ceil(160 / 4), //  平均分为4份
            splitLine: {
              show: true,
              lineStyle: {
                type: "dashed",
                color: "#395275",
              },
            },
          },
        ],
        series: [
          {
            name: "单位: 万元",
            data: [8000,9000,10000,13000,14000,14000,15000,16000,14800,14000,20000],
            type: "line",
            smooth: false,
            symbol: "circle",
            areaStyle: {
              color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                  offset: 0,
                  color: "#74EAB0", // 0% 处的颜色
                },
                {
                  offset: 0.1,
                  color: "#448AC8", // 10% 处的颜色
                },
                {
                  offset: 1,
                  color: "transparent", // 100% 处的颜色
                },
              ]),
            },
            itemStyle: {
              normal: {
                color: "#3AB578",
                lineStyle: {
                  color: "#3AB578",
                  width: 1,
                },
              },
            },
            yAxisIndex: 0,
          },
          {
            name: "单位: 分钟",
            data: [116, 80, 128, 110, 120, 130, 150, 160, 145, 150, 158],
            type: "line",
            smooth: false,
            symbol: "circle",
            itemStyle: {
              normal: {
                color: "#FCB07E",
                lineStyle: {
                  color: "#FCB07E",
                  width: 1,
                  type: "dotted",
                },
              },
            },
            yAxisIndex: 1,
          },
        ],
      }
    
    3、导入配置项,调用公共组件,开始使用echarts:
    • 模板代码文件:
              <div nz-col nzSpan="12" style="width: 50%;height: 100%;">
                <div class="common">
                  <span class="sub-title left-title">近30天订单量变化趋势图</span>
                  <zj-charts [option]="chartsOption.taskNumByMonth"></zj-charts>
                </div>
              </div>
    
    • 组件ts代码部分:
    import { HttpClient } from "@angular/common/http";
    import { Component, OnDestroy, OnInit, ViewChild } from "@angular/core";
    import * as _ from "lodash";
    import { of, Subscription, zip } from "rxjs";
    import { OrderDataService } from "./order-data.service";
    import { CHARTS_OPTION } from "./charts.options";
    
    interface Org {
      orgName?: string;
      orgAmount?: number;
      orgType?: Object;
    }
    
    @Component({
      selector: "order-data",
      templateUrl: "./order-data.component.html",
      styleUrls: ["./order-data.component.less"],
    })
    export class OrderDataComponent implements OnInit, OnDestroy {
    
      subscriptionList = new Array<Subscription>(1);
      timeHandleList = new Array(1);
    
      objectKeys = Object.keys;
    
      items: Org = {
        orgName: "桃花坞支行",
        orgAmount: 120,
        orgType: {
          "100元": 200,
          "50元": 9,
          "20元": 19,
          "10元": 10,
          "5元": 3,
          "1元": 2,
          "5角": 1,
          "1角": 0,
        },
      };
    
      // 模拟数据
      mock = {
        task: {},
        quota: {},
      };
    
      chartsOption = CHARTS_OPTION;
      constructor(private http: HttpClient, private _ser: OrderDataService) {}
    
      ngOnInit() {
        this.refreshDataOnce();
      }
    
      // 刷新订单数据模块的图表数据
      refreshDataOnce = () => {
        // 模拟数据
        let sourceOne = of({
          process: {
            percent: parseFloat((Math.random() * 100).toFixed(1)),
          },
        });
        this.mock["task"] = {
          total: parseFloat((Math.random() * 1000).toFixed(0)),
          amount: parseFloat((Math.random() * 10000).toFixed(1)),
        };
        this.mock["quota"] = {
          count: parseFloat((Math.random() * 1000).toFixed(0)),
          amount: parseFloat((Math.random() * 10000).toFixed(1)),
        };
        
        this.subscriptionList[0] = zip(
          sourceOne
        ).subscribe(([progressAllotment]) => {
            this.chartsOption.progressAllotment.series[0].data[0].value = progressAllotment["process"].percent;
            this.chartsOption.progressAllotment.title["text"] = progressAllotment["process"].percent + "%";
            this.chartsOption = _.cloneDeep(this.chartsOption);
            this.timeHandleList[0] = setTimeout(this.refreshDataOnce, 3 * 1000);
          },
          () => {
            this.timeHandleList[0] = setTimeout(this.refreshDataOnce, 3 * 1000);
          }
        );
      };
    
      ngOnDestroy(): void {
        this.subscriptionList.forEach((subscription) => subscription.unsubscribe());
        this.timeHandleList.forEach((timeHandle) => clearTimeout(timeHandle));
      }
    }
    
    
    4、结果展示
    图1.png

    相关文章

      网友评论

        本文标题:angular中对echarts图表进行封装(环形进度条、双Y轴

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