百度 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]
  }]
})
相關文章
相關標籤/搜索