js基于echarts库实现堆积柱状图排序

论坛 期权论坛 期权     
方游天下   2019-6-29 21:28   9512   0
客户需求:
将a,b,c,d四个季度某产品的瑕疵统计结果可视化在堆积柱状图上,每个柱子从上往下依次递增!
瑕疵统计的结果如下:
result = {'杂质': [1, 2, 3, 4],          '毛丝': [2, 3, 4, 5],          '脱漆': [3, 2, 3, 1],          '粉点': [3, 2, 1, 3],          '刮痕': [2, 4, 5, 1],          '磨损': [1, 2, 4, 3],          '凹陷': [4, 1, 1, 3],          '形变': [4, 2, 2, 1],          '白点': [3, 3, 2, 3],          '油污': [2, 3, 2, 1],          '橘皮': [2, 2, 1, 4],          '烤漆': [3, 2, 2, 1],          '擦灰': [2, 1, 2, 2]};可视化界面如下:

将一个季度的所有瑕疵堆积在一起,每个季度的瑕疵按从大到小的顺序从下往上排列。
实现这个可视化界面除了js文件当然需要html和css文件。如下:
html
  1. [/code][b]css[/b]
  2. [list][*][*][*][*][*][*][*][/list][code]#2_chart{
复制代码
  1.   position:absolute;
复制代码
  1.   top:10%;
复制代码
  1.   right:10%;
复制代码
  1.   height: 80%;
复制代码
  1.   width: 50%;
复制代码
  1. }
复制代码
只截取了相关代码,其它必须代码自主补上。
接下来就是最重要的部分了。
第一步:
实例化一个图表,获取数据(这里我直接在js中初始化一个结果代替,这个结果从后台传入也可以),定义颜色列表:
  1. var myChart = echarts.init(document.getElementById('chart'),'chalk');
复制代码
  1. var result = {'杂质': [1, 2, 3, 4],
复制代码
  1.               '毛丝': [2, 3, 4, 5],
复制代码
  1.               '脱漆': [3, 2, 3, 1],
复制代码
  1.               '粉点': [3, 2, 1, 3],
复制代码
  1.               '刮痕': [2, 4, 5, 1],
复制代码
  1.               '磨损': [1, 2, 4, 3],
复制代码
  1.               '凹陷': [4, 1, 1, 3],
复制代码
  1.               '形变': [4, 2, 2, 1],
复制代码
  1.               '白点': [3, 3, 2, 3],
复制代码
  1.               '油污': [2, 3, 2, 1],
复制代码
  1.               '橘皮': [2, 2, 1, 4],
复制代码
  1.               '烤漆': [3, 2, 2, 1],
复制代码
  1.               '擦灰': [2, 1, 2, 2]};
复制代码
  1.     var colorlist = ['#ffcc99', '#cc9999', '#ffcccc',
复制代码
  1.                      '#ff99cc', '#cc99cc', '#ffccff',
复制代码
  1.                      '#cc99ff', '#ccccff', '#99ccff',
复制代码
  1.                      '#ccffff', '#99ffcc', '#ccffcc',
复制代码
  1.                      '#ccff99', '#ffffcc', '#66ffff'];
复制代码
第二步:为每一季度每种瑕疵结果添加颜色和瑕疵名:
  1. var array1 = [add_color(result['杂质'], colorlist[0], '杂质'),
复制代码
  1.               add_color(result['毛丝'], colorlist[1], '毛丝'),
复制代码
  1.               add_color(result['脱漆'], colorlist[2], '脱漆'),
复制代码
  1.               add_color(result['粉点'], colorlist[3], '粉点'),
复制代码
  1.               add_color(result['刮痕'], colorlist[4], '刮痕'),
复制代码
  1.               add_color(result['磨损'], colorlist[5], '磨损'),
复制代码
  1.               add_color(result['凹陷'], colorlist[6], '凹陷'),
复制代码
  1.               add_color(result['形变'], colorlist[7], '形变'),
复制代码
  1.               add_color(result['白点'], colorlist[8], '白点'),
复制代码
  1.               add_color(result['油污'], colorlist[9], '油污'),
复制代码
  1.               add_color(result['橘皮'], colorlist[10], '橘皮'),
复制代码
  1.               add_color(result['烤漆'], colorlist[11], '烤漆'),
复制代码
  1.               add_color(result['擦灰'], colorlist[12], '擦灰')];
复制代码
add_color为自定义的函数:
  1. function add_color(arr, color, name){
复制代码
  1.     return arr.map(function(item){
复制代码
  1.         return [item, color, name]})
复制代码
  1. };
复制代码
使用map方法给数组中每一个元素添加颜色和瑕疵名,组成新数组。
这是的array1是含2层嵌套的数组了,13*4*3。分别对应13中瑕疵,4个季度,3即(数量、颜色、名称)

第三步:将array1转置
  1. array2 = translate(array1);
复制代码
translate是自定义的函数:如下
  1. function translate(arr2d){
复制代码
  1.      var newarr = arr2d[0].map(function(col){
复制代码
  1.          return arr2d.map(function(row){
复制代码
  1.              return row[arr2d[0].indexOf(col)];})
复制代码
  1.          });
复制代码
  1.      return newarr
复制代码
  1. }
复制代码
因为js不存在多维数组的说法,只有嵌套,所以通过类似转置的操作,将同一季度13种瑕疵的结果放在一个数组中。

第四步:使用map方法对每个季度的结果按大小排序
  1. array2 = array2.map(arr_sort);
复制代码
arr_sort为自定义的函数:
  1. function arr_sort(arr2d){
复制代码
  1.     return arr2d.sort(function(first, second){
复制代码
  1.         return second[0] - first[0]})  // 按2维数组0号元素值从大到小排序
复制代码
  1.     }
复制代码
这个函数的功能是按2维数组0号元素的值从大到小排列,并返回二维数组(这里2维数组也是指嵌套数组),原始数组也会改变!所以即使重命名一个array3,array2结果依然会改变,沿用array2。

第五步:将array2转置回去
  1. array3 = translate(array2);
复制代码
到这里,结果已经重新排序完成了,array3已经便会了13*4*3的形式,只不过折这13行对应的结果已经不是原本的13种瑕疵了,而是每个季度13种瑕疵按序排列的结果了,虽然我们打乱了每一种瑕疵的结果,但是由于我们事先为每一种结果添加了颜色和瑕疵名,所以我们可以用颜色来表现瑕疵种类!
不过echarts图表柱状堆积图接收数据的方式是数组,所以我们剔除颜色和瑕疵名生成一个新数组!
第六步:剔除颜色和瑕疵名:
  1. array4 = array3.map(del_color);
复制代码
del_color是自定义函数,与add_color是逆运算
  1. function del_color(list){
复制代码
  1.     return list.map(function(item){
复制代码
  1.         return item[0]})
复制代码
  1. };
复制代码
最后一步:画图(series中有一个itemstyle属性,可以自定义颜色,我就是通过自定义每块柱状图的颜色,从而实现用颜色表现图形)
  1.     option = {
复制代码
  1.         title: {
复制代码
  1.             text: '设置title'
复制代码
  1.         },
复制代码
  1.         tooltip: {
复制代码
  1.             trigger: 'axis',
复制代码
  1.             axisPointer: {
复制代码
  1.                 type: 'cross',
复制代码
  1.                 crossStyle: {
复制代码
  1.                     color: '#999'
复制代码
  1.                 }
复制代码
  1.             }
复制代码
  1.         },
复制代码
  1.         toolbox: {
复制代码
  1.             feature: {
复制代码
  1.               saveAsImage: {show: false}
复制代码
  1.             }
复制代码
  1.         },
复制代码
  1.         legend: {
复制代码
  1.             data:['杂质', '毛丝', '脱漆', '粉点', '刮痕', '磨损', '凹陷',
复制代码
  1.                   '形变', '白点', '油污', '橘皮', '烤漆', '擦灰'],
复制代码
  1.             selectedMode:false,  //此处必须为false
复制代码
  1.         },
复制代码
  1.         xAxis: [
复制代码
  1.             {
复制代码
  1.                 type: 'category',
复制代码
  1.                 data: ['a', 'b', 'c', 'd'],
复制代码
  1.                 axisPointer: {
复制代码
  1.                     type: 'shadow'
复制代码
  1.                 }
复制代码
  1.             }
复制代码
  1.         ],
复制代码
  1.         yAxis: [{}, {
复制代码
  1.             type: 'value',
复制代码
  1.             name: '数量',
复制代码
  1.             min: 0,
复制代码
  1.             max: 40,
复制代码
  1.             interval: 5,
复制代码
  1.             axisLabel: {
复制代码
  1.                 formatter: '{value}'}
复制代码
  1.             }],
复制代码
  1.         series: [
复制代码
  1.             {
复制代码
  1.                 name:array3[0][0][2],
复制代码
  1.                 type:'bar',
复制代码
  1.                 yAxisIndex: 1,
复制代码
  1.                 stack:'数量',
复制代码
  1.                 label: {
复制代码
  1.                     normal: {
复制代码
  1.                         show: true,
复制代码
  1.                         position: 'inside'
复制代码
  1.                     }
复制代码
  1.                 },
复制代码
  1.                 data:array4[0],
复制代码
  1.                 itemStyle:{normal:{color: function(params){
复制代码
  1.                                    return array3[0][params.dataIndex][1];}
复制代码
  1.                           }}
复制代码
  1.             },
复制代码
  1.             . //与上下相似,省略10次
复制代码
  1.             . //
复制代码
  1.             {
复制代码
  1.                 name:array3[12][0][2],
复制代码
  1.                 type:'bar',
复制代码
  1.                 yAxisIndex: 1,
复制代码
  1.                 stack:'数量',
复制代码
  1.                 label: {
复制代码
  1.                     normal: {
复制代码
  1.                         show: true,
复制代码
  1.                         position: 'inside'
复制代码
  1.                     }
复制代码
  1.                 },
复制代码
  1.                 data:array4[12],
复制代码
  1.                 itemStyle:{normal:{color: function(params){
复制代码
  1.                                    return array3[12][params.dataIndex][1];}
复制代码
  1.                           }}
复制代码
  1.             }
复制代码
  1.         ],
复制代码
  1.     };
复制代码
  1. [/code][code]    // 使用刚指定的配置项和数据显示图表。
复制代码
  1.     myChart2.setOption(option);
复制代码
selectedMode设置为false是因为echarts根本没有对柱状图排序的功能,这里强制性改变数据顺序和颜色,legend对应的数据已经不是完全真实的数据,这是一个伪排序方法,所以需要禁止选中legend。
(不仅echarts没有堆积柱状图排序功能,像D3.js,charts.js,Highcharts ,Fusioncharts,Flot等都没有这功能,目前为止,我还没发现有那个工具实现了此功能)
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:10
帖子:2
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP