Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

echarts-ng新版本实现 #8

Closed
18 tasks done
huang-xiao-jian opened this issue Jan 2, 2017 · 3 comments
Closed
18 tasks done

echarts-ng新版本实现 #8

huang-xiao-jian opened this issue Jan 2, 2017 · 3 comments

Comments

@huang-xiao-jian
Copy link
Owner

前言

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

遗留问题

新版本实现

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

Monkey Patch

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

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

  • group分组属性
  • showLoading, hideLoading
  • clear
  • dispose(不支持链式调用,因为实例已销毁)
  • resize
  • on
  • off

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

  • getWidth
  • getHeight
  • getDom
  • getOption
  • getDataURL
  • getConnectedDataURL
  • isDisposed
  • dispatchAction
  • convertToPixel
  • convertToPixel
  • containPixel

样例

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

/**
 * @description - develop helper for showcase
 * @author - bornkiller <[email protected]>
 */
(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

特别注意

  • 单实例如果需要重复连接,务必注意时间先后顺序。如果连接之后销毁实例,但包装实例未销毁,例如使用ng-if等指令,重连接之前,所有操作全部丢失,所以重连接后方可进一步操作,暨ng-if=true条件先于后续操作;
  • 动态调整DOM尺寸,可以连接后直接调用echarts#resize方法;
  • 瀑布图快捷方式后续以其他方式提供;
@moux1024
Copy link

moux1024 commented Jan 3, 2017

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

@huang-xiao-jian
Copy link
Owner Author

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

@huang-xiao-jian
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants