百度 ECharts Angular 封装

前言

近期项目中须要可视化图表,刚好 echarts 发布新版本,便选择了 echarts做为基础图表库。可是github 上基于 echarts 的封装大部分为基于2.X版本的封装,与项目不符合。html

基于3.0+的版本 https://github.com/liekkas/ng-echarts,可是使用方式上跟个人设想不符合,因此选择从新封装,https://github.com/bornkiller/echarts-nggit

基本功能初步封装完毕,但愿共同改进。angularjs

运行环境

  • angularjs - 1.3+github

  • echarts - 3.0+shell

项目使用

bower install echarts-ng --save
angular.module('application', ['echarts-ng']);

此封装由$echarts服务与echarts属性指令组成,需配合使用。canvas

基础全局配置以下:promise

{
  theme: 'macarons',
  driftPalette: true,
  title: {
    left: 'center',
    top: 'top',
    padding: [20, 10, 10, 10]
  },
  backgroundColor: 'rgba(255, 255, 255, .5)',
  legend: {
    left: 'center',
    top: 'top',
    padding: [20, 10, 10, 10]
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
  }
}

可经过如下方式修改默认全局配置方式。app

angular.module('application').config(function($echartsProvider) {
  $echartsProvider.setGlobalOption(newGlobalOption)
});
  • 生成echarts示例标示IDecharts

$scope.DISTRIBUTION_ID = $echarts.generateInstanceIdentity();
  • 声明echarts必须数据ide

$scope.distribution = {
    xAxis : [
      {
        type : 'category',
        data : ['周一','周二','周三','周四','周五','周六','周日']
      }
    ],
    yAxis : [
      {
        type : 'value'
      }
    ],
    series : [
      {
        name:'联盟广告',
        type:'bar',
        data:[220, 182, 191, 234, 290, 330, 310]
      }
    ]
  };
  • 使用指令绘制实例

<div echarts="DISTRIBUTION_ID" config="distribution"></div>

FAQ

  • ID缺失, 指令会直接抛出异常

  • 实例容器高度缺失,会致使echarts绘制错误,并不会直接抛出。若是数据正常,绘制异常,务必检查高度问题。

  • 在控制器或服务中,能够直接获取到echarts实例,用于connect, group等操做。

// the param is the instance id generated before
// the method return promise with the instance object
$echarts.queryEchartsInstance($scope.DISTRIBUTION_ID);
  • 性能考量,指令内部并无过多watch,当series为空,实例自动进入loading,当series改变,会自动重绘。 但其余选项并不会触发重绘,如xAxis, tooltip等等,须要显式更新.

// start the specific instance loading
// which triggered automatically when you empty the series
// also, manually operate just fine
$echarts.updateEchartsInstance($scope.DISTRIBUTION_ID);

// update the specific instance
$echarts.updateEchartsInstance($scope.DISTRIBUTION_ID, $scope.distribution);

调色板加强

调色板为单实例方式,在实例内部依据顺序选取不一样色调。可是不一样实例之间并不遵循此原则。在多个类型类似,数据类似,却又没法合并为一个实例时,色彩效果说不上人性化。(此处仅为我的使用偏好)
能够修改默认配置driftPalette来修改默认行为。

原始效果

QQ20160415-2.png-47.5kB

指令封装调整效果

QQ20160415-1.png-47.7kB

关于tooltip设置

以前使用highcharts做为图表库,tooltip在配置对象直接设置外,另外存在plotOption选项,能够依据不一样图表类型,启用不一样的tooltip。这个可能存在部分不便,但影响不大。

关于容器盒高度初始化

众所周知,echarts主要实现方式为canvas,从而要求初始化之时容器尺寸必须可知,不然会直接致使错误,且3.0+版本后,会造成静默错误(此处错误为绘制错误,高度为1px)。基于封装,通常容器元素宽度肯定,基于此前提,设定echarts-dimension属性,用以传递宽高比,在指令内部设定内嵌样式声明容器高度,保障图表绘制正确。此属性非必须,能够经过CSS方式控制,仅为快捷控制方式。

$scope.distribution = {
  identity: $echarts.generateInstanceIdentity(),
  dimension: '16:9',
  config: {
    xAxis: {
      type: 'category',
      data: ["日用品数", "伙食费", "交通费", "水电费", "房租"]
    },
    yAxis: {
      type: 'value'
    },
    series: [{
      name: '生活费',
      type: 'bar',
      data: [300, 900, 200, 300, 1200]
    }]
  }
};
<div echarts="distribution.identity" echarts-dimension="distribution.dimension" config="distribution.config"></div>

关于容器盒高度动态调整

在实际项目中,默认准许宽度固定,可是碰到比较棘手的问题(主要为条形图)。基于不一样条件统计,会出现不一样的统计项(category数据不一样),若是高度保持定高,便会出现单个条块太高的现象。

若是以多条目为准设定高度,效果符合预期。
QQ20160418-1_meitu_2.jpg-175.5kB

但切换条目较少的数据源后,效果勉强能够接受。
QQ20160418-2_meitu_1.jpg-68.9kB

当存在单条目极端值,效果几乎惨不忍睹。
QQ20160418-3.png-15.1kB

因此须要根据series数据动态调整容器高度的能力。在实际项目中,为了应对这种状况,大量使用ng-style,获取数据后,在控制器或服务内部计算相应的高度。固然这种方案并没有不妥,可是自觉得动态调整高度的事情应该交给图表来实现,因此在封装中添加动态调整高度。目前实现的方式有很大限制,图表类型必须为bar,并且Y坐标轴为category, 在config中指定dynamic: true便可,不然可能出现异常结果。简单测试效果以下:

极端单项表现:

QQ20160418-5.png-18.2kB

较少三项表现:

QQ20160418-7.png-26.6kB

正常多项表现:

QQ20160418-4.png-35.3kB

所有代码以下:

<form class="form">
  <div class="form-group">
    <label class="control-label" for="data-source">请选择数据源:</label>
    <select class="form-control" id="data-source"
          ng-options="item as item.description for item in optionalDistributionList" ng-model="chosenDistribution"
      ng-change="handleDistributionChange(chosenDistribution)">
      <option value="">请选择数据源:</option>
    </select>
  </div>
</form>
<section class="row">
  <div echarts="distribution.identity" echarts-dimension="distribution.dimension" config="distribution.config"></div>
</section>
$scope.optionalDistributionList = [
  {
    account: 'World',
    description: '这是个多条目系列',
    config: {
      xAxis: {
        type: "value"
      },
      yAxis: {
        type: "category",
        data: ["条目A", "条目B", "条目C", "条目D", "条目E", "条目F", " 条目G", "条目H", "条目I"]
      },
      dynamic: true,
      series: [{
        name: "专属统计",
        type: "bar",
        data: [15, 25, 7, 9, 8, 5, 12, 9, 2]
      }]
    }
  },
  {
    account: 'Medium',
    description: '这是个中等条目系列',
      config: {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: ["条目A", "条目B", "条目C"]
        },
        dynamic: true,
        series: [{
          name: '专属统计',
          type: 'bar',
          data: [22, 5, 16]
        }]
      }
    },
    {
      account: 'Single',
      description: '这是个单条目系列',
      config: {
        xAxis: {
          type: 'value'
        },
        yAxis: {
          type: 'category',
          data: ["条目A"]
        },
        dynamic: true,
        series: [{
          name: '专属统计',
          type: 'bar',
          data: [22]
        }]
      }
    }
  ];

$scope.chosenDistribution = $scope.optionalDistributionList[0];
$scope.distribution = {
  identity: $echarts.generateInstanceIdentity(),
  dimension: '16:9',
  config: $scope.chosenDistribution.config
};

$scope.handleDistributionChange = function(item) {
  $scope.distribution.config = item.config;
};

关于瀑布流

highcharts存在专用的{type: 'waterfall'}echarts并无专用类型,通常经过条形图+辅助条形图配合stack属性来实现,此处会进行简化加强。部分代码以下所示:

<div echarts="distribution.identity" config="distribution.config"></div>
$scope.distribution = {
  identity: $echarts.generateInstanceIdentity(),
  config: {
    xAxis: {
      type: 'category',
      splitLine: {show: false},
      data: ["日用品数", "伙食费", "交通费", "水电费", "房租", "总费用"]
    },
    yAxis: {
      type: 'value'
    },
    series: [{
      name: '生活费',
      type: 'waterfall',
      data: [300, 900, 200, 300, 1200, 2900]
    }]
  }
};

瀑布流对series要求仅含有单项数据,且图表类型必须为waterfall,表示开启waterfall处理方式。如上述代码所示。不然不会进行加强处理。

未开启瀑布流效果以下所示:

QQ20160416-2.png-29.4kB

开启瀑布流效果以下所示:

QQ20160416-1.png-30.4kB

同时须要注意,在显示调用对应方法更新图表时,必须注明waterfall选项,以下所示:

$echarts.updateEchartsInstance($scope.distribution.identity, {
  series: [{
    name: '生活费',
    type: 'waterfall',
    data: [400, 1000, 100, 400, 1100, 3000]
  }]
})
相关文章
相关标签/搜索