huang-xiao-jian / echarts-ng

angularjs decoration for Baidu echarts.
MIT License
78 stars 23 forks source link

echarts-ng新版本实现 #8

Closed huang-xiao-jian closed 7 years ago

huang-xiao-jian commented 7 years ago

前言

个人项目中使用echarts-ng,彼时没有基于echarts3的封装,但使用过程中,感觉不够顺畅,重构早有打算,但始终无法付诸实践。后续接触ES6, rollup, webpack等新东西,于是元旦三天进行较大的重构,意图修复之前存在的问题。

遗留问题

新版本实现

实现Angular2迁移简单化,需要关键实现做到框架无关,剔除框架特异性考量。

Monkey Patch

创建包装实例,作为echarts实际接口与控制器内部调用的中间层。包装实例在DOM连接之后,完全为echarts instance,在连接之前,使用monkey patch实现部分方法,几乎全部支持链式调用。

monkey patch实现(连接之前即可使用):

实例工具类函数基本不会再连接之前调用,进行延迟挂载即可:

样例

目前仅提供临时开发样例,后续会通过其他方式,大概理解新版本使用方式即可。

/**
 * @description - develop helper for showcase
 * @author - bornkiller <hjj491229492@hotmail.com>
 */
(function (angular) {
  'use strict';

  angular.module('echarts-showcase', ['echarts-ng'])
    .controller('ShowcaseController', ['$echarts', '$timeout', function ($echarts, $timeout) {
      this.themes = ['vintage', 'dark', 'macarons', 'infographic', 'shine', 'roma'];
      this.theme = 'vintage';
      this.show = true;
      this.mediaOptions = [
        {
          option: {
            legend: {
              orient: 'horizontal',
              left: 'center',
              top: 'top'
            },
            grid: {
              right: '10%'
            }
          }
        },
        {
          query: {
            maxWidth: 850
          },
          option: {
            legend: {
              orient: 'vertical',
              right: 10,
              top: '10%'
            },
            grid: {
              right: '15%'
            }
          }
        }
      ];
      this.options = {
        tooltip: {
          trigger: 'axis'
        },
        legend: {
          data: ['邮件营销', '联盟广告', '视频广告', '直接访问', '搜索引擎']
        },
        xAxis: [
          {
            type: 'category',
            boundaryGap: false,
            data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
          }
        ],
        yAxis: [
          {
            type: 'value'
          }
        ],
        series: [
          {
            name: '邮件营销',
            type: 'line',
            stack: '总量',
            areaStyle: { normal: {} },
            data: [120, 132, 101, 134, 90, 230, 210]
          },
          {
            name: '联盟广告',
            type: 'line',
            stack: '总量',
            areaStyle: { normal: {} },
            data: [220, 182, 191, 234, 290, 330, 310]
          },
          {
            name: '视频广告',
            type: 'line',
            stack: '总量',
            areaStyle: { normal: {} },
            data: [150, 232, 201, 154, 190, 330, 410]
          },
          {
            name: '直接访问',
            type: 'line',
            stack: '总量',
            areaStyle: { normal: {} },
            data: [320, 332, 301, 334, 390, 330, 320]
          },
          {
            name: '搜索引擎',
            type: 'line',
            stack: '总量',
            areaStyle: { normal: {} },
            data: [820, 932, 901, 934, 1290, 1330, 1320]
          }
        ]
      };

      this.legends = [
        { description: '邮件营销', selected: true },
        { description: '联盟广告', selected: true },
        { description: '视频广告', selected: true },
        { description: '直接访问', selected: true },
        { description: '搜索引擎', selected: true }
      ];

      this.instance = $echarts.create(this.theme, {}, this.mediaOptions);

      this.instance
        .showLoading()
        .on('click', (event) => {
          console.log(event);
        })
        .on('legendselectchanged', (event) => {
          console.log(event);
        });

      $timeout(() => {
        this.instance.setOption(this.options).hideLoading();
      }, 1200);

      this.handleThemeChange = () => {
        this.instance = $echarts.create(this.theme).setOption(this.options);
      };

      this.handleLegendChange = (name, selected) => {
        this.instance.dispatchAction({
          type: selected ? 'legendSelect' : 'legendUnSelect',
          name: name
        })
      };

      this.toggleSwitchStatus = () => {
        this.show = !this.show;
      };

      this.sync = _.debounce(() => {
        this.instance.resize();
      }, 100);

      window.addEventListener('resize', this.sync);
    }]);

  angular.bootstrap(document.body, ['echarts-showcase'], { strictDi: true });
})(angular);

录屏地址:https://www.opentest.co/share/56a9c8b0d0be11e688ecd510bcea4514

特别注意

moux1024 commented 7 years ago

tooltip的支持还是使用plotOption来控制吗?在原readme里没能找到plotOption的用法,所以现在还不会调整toolkit。或请详述,有demo更好啦。 ps:readme里本页的链接地址尾部多了个“。”结果访问404了

huang-xiao-jian commented 7 years ago

@moux1024 echarts好像没有plotOption这个选项,现在的实现基本就是把实例的控制器权完全交给开发者,从而进行更精细的纯手动控制的状态,tooltip配置最终通过setOption方法生效。demo的话,正在写,会单独放置另外一个仓库。

huang-xiao-jian commented 7 years ago

DEMO: https://github.com/bornkiller/echarts-showcase