(function(){ angular.module('app') .factory("OptionService",["$rootScope","UtilService",optionService]); function optionService($rootScope,UtilService){ var service = {},that = $rootScope; var types = { "line":1, "column":2, "columnstack":3, "bar":4, "area":5, "areastack":6, "arealiner":7, "pie":8, "funnel":9, "columnline":10, "barY":11 } /* *config *color:[],legend:false不显示图例,ispercent:true百分比数据,namesub:[]数据后缀 线数据加后缀情况 *isbartext:true柱图上显示数值,opacity:透明值,barwidth:柱宽 ,title:图标名 *hidelast:n 隐藏最后n条线 issmart:true 小漏斗 */ service.getOption = function(data,type,config){ var chartUtil = new myChart(UtilService,config,$rootScope); var option = chartUtil.init(data,config),seriesData = []; //普通线图 if(types[type] == types.line){ seriesData = chartUtil.lineChart(); } //普通区域图 else if(types[type] == types.area){ seriesData = chartUtil.areaChart(); } //普通区域堆积图 else if(types[type] == types.areastack){ //堆积区域图 seriesData = chartUtil.areaChart(true,false); } //渐变区域图 else if(types[type] == types.arealiner){ //渐变区域图 seriesData = chartUtil.areaChart(false,true); } //普通柱图 else if(types[type] == types.column){ seriesData = chartUtil.columnChart(false); option.yAxis[0].axisTick = option.xAxis[0].axisTick; option.yAxis[0].axisLine = option.xAxis[0].axisLine; } //柱图堆积图 else if(types[type] == types.columnstack){ seriesData = chartUtil.columnChart(true,config.flag); option.yAxis[0].axisTick = option.xAxis[0].axisTick; option.yAxis[0].axisLine = option.xAxis[0].axisLine; } //横向柱图 else if(types[type] == types.bar){ seriesData = chartUtil.barChart(); option.yAxis[0] = chartUtil.getXaxis2(); option.xAxis[0] = chartUtil.getYaxis2(); option.grid.right = 20; } //漏斗 else if(types[type] == types.funnel){ seriesData = chartUtil.funnelChart(); option.tooltip = chartUtil.funnelTooltip(); } //柱图,最后一条线为百分比的线图 else if(types[type] == types.columnline){ seriesData = chartUtil.columnLineChart(); option.yAxis[0].axisTick = option.xAxis[0].axisTick; option.yAxis[0].axisLine = option.xAxis[0].axisLine; option.yAxis.push(chartUtil.getYaxis(true)); } else if(types[type] == types.barY){ seriesData = chartUtil.barChart(true); option.yAxis[0] = chartUtil.getXaxis2(); option.xAxis[0] = chartUtil.getYaxis2(); // option.xAxis[0].show = false; option.grid.right = 20; option.grid.top = 0; var name = data.name,nl = name.length - 1; for(var i=0;i<nl;i++){ option.xAxis.push(chartUtil.getYaxis2()); option.xAxis[i+1].show = false; } } option.series = seriesData; if(angular.isDefined(config.color)){ option.color = config.color; } if(angular.isDefined(config.legend)){ option.legend.show = config.legend; } return option; } var chartUtil2 = new myChart(UtilService); service.getPieOption = function(data,type,config){ var option = chartUtil2.pieChart(data,config); return option; } service.getMapOption = function(data,type,config){ var option = chartUtil2.mapChart(data,config); return option; } service.getLoginMapOption = function(data,type,config){ var option = chartUtil2.loginMapChart(data,config); return option; } return service; } function myChart(utilser,config,$rootScope){ var fontcolor = "#666666", linecolor = "#d5d7d8", family = "SimHei,Arial", legendcolor = "#666666", fontsize = 12; this.UtilService = utilser; this.init = function(data,config){ this.data = data.val; this.name = data.name this.key = data.key; this.chartData = data; this.config = config; var myOptions = this.commonOptions(); myOptions.xAxis = [this.getXaxis()]; myOptions.yAxis = [this.getYaxis()]; return myOptions; } this.commonOptions = function(name){ var perfix = ""; if(this.config.ispercent && this.config.ispercent==true){ perfix += '%'; } var datas = [],top = 0,selected = {}; if(this.name && this.name.length>0){ for(var i=0;i<this.name.length;i++){ var indexof = this.name[i].lastIndexOf("_") datas.push({ name:config.flag?this.name[i].slice(0,indexof==-1?this.name[i].length-1:indexof):this.name[i], icon:"rect" }); } if(this.config.hidelast){ for(var i=this.config.hidelast;i>0;i--){ var n = this.name.slice(0-i)[0]; selected[n] = false; } } } var title = "",that = this; if(this.config.title){ title = this.config.title; if(this.config.legend !=false){ top = 30; } } var options = { title:{ text : title, textStyle:{ color:legendcolor, fontSize:fontsize, fontFamily:family }, left:"center" }, legend: { data: datas, top:top, textStyle:{ color:legendcolor, fontSize:fontsize, fontFamily:family }, itemWidth:10, itemHeight:10, formatter: function (name) { if(datas.length>2){ return echarts.format.truncateText(name, 80, '14px Microsoft Yahei', '…'); }else{ return name; } }, tooltip: { show: true }, selected:selected }, grid : { left:10, top:top+40, bottom:10, right:0, containLabel:true }, tooltip: { trigger: config.flag && config.flag!='hasGro' && config.flag!='nohasGro'?'item':'axis', formatter: function(objs) { var len = objs.length,obj,str=""; if(config.flag && config.flag != 'hasGro' && config.flag!='nohasGro'){ var name = objs.seriesName; if(objs.value!=null && objs.value!='-'){ str += '<span style="color:'+objs.color+'">\u25CF</span>' + name + ' : ' + that.UtilService.decimal2(objs.value,2) + perfix; if(that.config.lastprecent){ str += "%"; } if(that.config.namesub && that.config.namesub.length>0 && that.config.namesub[objs.seriesIndex]){ str += that.config.namesub[objs.seriesIndex]; } str += '<br/>'; } str = objs.name + '<br/>' + str; return str; } for(var i=0;i<len;i++){ obj = objs[i]; var name = obj.seriesName; if(obj.value!=null && obj.value!='-'){ str += '<span style="color:'+obj.color+'">\u25CF</span>' + name + ' : ' + that.UtilService.decimal2(obj.value,2) + perfix; if(that.config.lastprecent && i == len-1){ str += "%"; } if(that.config.namesub && that.config.namesub.length>0 && that.config.namesub[i]){ str += that.config.namesub[i]; } str += '<br/>'; } } str = obj.name + '<br/>' + str; if(config.id){ $rootScope.$emit("tooltipObj",{objs:objs,id:config.id,flag:config.flag}); return ""; } return str; }, axisPointer:{ type:(config.flag=='hasGro' || config.flag=='nohasGro')?"shadow":"line", lineStyle:{ color:linecolor } } }, toolbox: { show: true, feature: { mark: { show: false }, dataView: { show: false, readOnly: false }, saveAsImage: { show: false } } }, calculable: false, color : ['#e8340e','#0088cc', '#61a0a8', '#d48265', '#91c7ae','#749f83', '#ca8622', '#bda29a','#6e7074', '#546570', '#2f4554','#006000','#642100','#6c3365','#484891','#844200','#006030','#003e3e','#584b00','#336666'] } return options; } //x轴设置 this.getXaxis = function(key){ var that = this; var axis = { type: 'category', data: this.key, splitLine : { show : false }, axisLabel : { textStyle:{ color:fontcolor, fontSize:fontsize, fontFamily:family }, formatter:function(value){ if(value){ var objstr = that.UtilService.splitString(value,12); if(that.config.issmart && objstr.len>12){ return objstr.str + "..."; } else{ return value; } } } }, axisTick:{ lineStyle:{ color:linecolor } }, axisLine : { lineStyle:{ color:linecolor } } }; return axis; } /* *横向显示时候的Y轴,eg:bar图 */ this.getXaxis2 = function(key){ var that = this; var axis = { type: 'category', data: this.key, splitLine : { show : false }, axisLabel : { textStyle:{ color:fontcolor, fontSize:fontsize, fontFamily:family }, formatter : function(value) { if(angular.isUndefined(value)){return "";} var obj = that.UtilService.splitString(value,12); if(obj.len > 12){ return obj.str + "..."; }else{ return value; } } }, axisTick:{ lineStyle:{ color:linecolor } }, axisLine : { lineStyle:{ color:linecolor } }, inverse:true }; return axis; } //y轴设置 this.getYaxis = function(ispercent){ var perfix = ""; if((this.config.ispercent && this.config.ispercent==true) || ispercent){ perfix += '%'; } var axis = { type: 'value', axisLabel : { textStyle:{ color:fontcolor, fontSize:fontsize, fontFamily:family }, formatter : function(value) { return toFixedValue(value) + perfix; } }, axisTick:{ show:false, lineStyle:{ opacity:0 } }, axisLine:{ show:false }, splitLine : { show : true, lineStyle:{ color:linecolor, type:'dashed' } }, min:0, splitNumber:4 }; return axis; }; /* *横向显示时候的X轴,eg:bar图 */ this.getYaxis2 = function(){ var perfix = ""; if(this.config.ispercent && this.config.ispercent==true){ perfix += '%'; } var axis = { type: 'value', axisLabel : { textStyle:{ color:fontcolor, fontSize:fontsize, fontFamily:family }, formatter : function(value) { return toFixedValue(value) + perfix; } }, axisTick:{ lineStyle:{ color:linecolor } }, axisLine : { lineStyle:{ color:linecolor } }, splitLine : { show : false }, min:0, splitNumber:3 }; return axis; }; /* *折线图 */ this.lineChart = function(){ var seriesData = []; for (var i = 0; i < this.name.length; i++) { var temp = {}; temp.name = this.name[i]; temp.type = "line"; temp.lineStyle = { normal:{ width:1.2 } } temp.smooth = true; temp.data = this.data[i]; seriesData[i] = temp; } return seriesData; }; /* *区域图 */ this.areaChart = function(isstack,isLiner){ //isLiner渐变色 var seriesData = []; var opac = 0.25; if(this.config.opacity){ opac = this.config.opacity; } for (var i = 0; i < this.name.length; i++) { var temp = {}; temp.name = this.name[i]; temp.type = "line"; temp.data = this.data[i]; if(isstack){ temp.stack = "总量"; } temp.smooth = true; temp.areaStyle = { normal:{ opacity:opac } } if (isLiner) { temp.areaStyle.normal.color = new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ offset: 0, color: this.config.color[i] },{ offset: 1, color: '#fff' }]) } temp.lineStyle = { normal:{ width:1.2 } } seriesData[i] = temp; } return seriesData; }; /*柱图*/ this.columnChart = function(istack,flag){ var seriesData = [],names = []; for (var i = 0; i < this.name.length; i++) { var temp = {}, indexof = this.name[i].lastIndexOf('_'); temp.name = flag?this.name[i].slice(0,indexof==-1?this.name[i].length:indexof):this.name[i]; temp.type = "bar"; temp.barMaxWidth = 18; temp.barGap = 0; temp.data = this.data[i]; if(istack){ temp.stack = "总量"+(flag?this.name[i].slice(indexof==-1?0:indexof):""); } var color = ""; if(names.indexOf(temp.name)>-1){ color = seriesData[i-1].itemStyle.normal.color; }else{ color = this.config.color[i]; } temp.itemStyle = { normal : { color : color } } if(!flag){ temp.itemStyle.emphasis = { //鼠标放上颜色 color : this.config.color[i] } } names.push(temp.name); seriesData[i] = temp; } return seriesData; } /*横向柱图*/ this.barChart = function(ismoreY){ //ismoreY 多个Y轴 var seriesData = []; for (var i = 0; i < this.name.length; i++) { var temp = {}; temp.name = this.name[i]; temp.type = "bar" if(this.config.barwidth){ temp.barMaxWidth = this.config.barwidth; }else{ temp.barMaxWidth = 18; temp.barGap = 0; } if(ismoreY){ temp.xAxisIndex = i; } temp.data = this.data[i]; if(this.config.isbartext && this.config.isbartext==true){ temp.label = { normal: { show: true, // position: 'insideRight', position: 'right', formatter:function(params){ var c = params.data; if(c>0){ return toFixedValue(c); }else{ return ""; } } } }; } seriesData[i] = temp; } return seriesData; } this.pieChart = function(data,config){ var name = data.name,key = data.key,values = data.val[0], arr = []; if(values){ key.filter(function(key,index){ var mydata = []; name.filter(function(n,i){ mydata.push({value:values[key][i],name:n}); }); var obj = { type:'pie', clockwise:false, label: { normal: { show: (name.length>20?false:true) } }, radius : [0, 120], center : data.key.length==1?['50%', '50%']:(index==0?['25%', '50%']:['75%', '50%']), selectedOffset:5, data:mydata }; arr.push(obj); }); } var option = { tooltip: { trigger: 'item', formatter: "{b}: {c} ({d}%)" }, legend: { show:false }, color:config.color, series: arr }; return option; } this.funnelTooltip = function(){ var that = this; var ut = "用户"; if(this.config.isdevice == false){ ut = "用户"; } var tooltip = { trigger: 'axis', formatter: function(obj) { if(obj.componentType == 'markPoint'){ return "转化率"+obj.value; } else{ if(obj.length > 0){ obj = obj[0]; } var index = obj.dataIndex; if(index > 0){ var str = ""; // str += "所有用户 "+ that.UtilService.decimal2(that.data[0][index]) + "% ("+that.data[2][index]+"人) 完成转化" + "<br/>"; // str += "所有用户 "+ that.UtilService.decimal2(that.data[1][index]) + "% ("+(that.data[2][index-1] - that.data[2][index])+"人) 流失"; if(obj){ str = obj.name + '的' + ut + "个数:" +that.data[2][index]+'<br/>'; str += that.key[0] + "到"+ obj.name + '的' + ut + "转化成功率:"+that.data[0][index]+"%" }else{ str = ""; } return str; }else{ return obj.name + '的' + ut + "个数:"+ that.data[2][0]; } } } }; return tooltip; } this.funnelChart = function(){ var that = this; var width = this.config.barwidth,markData = [],seriesData = []; var imgsrc = "image:///images/chartarrow.png",imgsize = [54,26]; var klen = this.key.length; if (klen > 0) { var cellW = (width-70)/klen,mw = 80,position = 'insideTop',color = "#ffffff"; if(klen>5){ mw = 40; } if(this.config.issmart==true){ if(klen>5){ imgsrc = "image:///images/chartarrow2.png"; imgsize = [10,10]; cellW = (width-20)/klen; mw = 30; position = "insideTop"; color = "#666"; } else{ mw = 45; } } else{ var marks = this.chartData.trans4last; for(var i=0;i<marks.length;i++){ markData.push({ value: marks[i]+"%", x: (40+i*5 + cellW*(i+1)) +"px", y: '50%' }) } } for (var i = 0; i < 2; i++) { var temp = {}; // temp.name = this.name[i]; temp.type = "bar"; temp.stack = "转化率"; temp.barMaxWidth = mw; temp.barGap = 0; temp.data = this.data[i]; if(i==0){ temp.label = { normal: { show: true, position: position, formatter: function(obj) { if((obj.value==0 && that.data[2][obj.dataIndex] == 0) || obj.value<10){ return ""; } // return that.UtilService.decimal2(obj.value)+"%" + "\r\n" + that.data[2][obj.dataIndex]; return that.UtilService.decimal2(obj.value)+"%"; }, textStyle:{ color : color, fontFamily:family } } } temp.itemStyle = { normal : { color : this.config.color[0], textStyle:{ color : "#ffffff", fontFamily:family } } } } if(i==1){ temp.itemStyle = { normal : { color : this.config.color[1] }, emphasis : { //鼠标放上颜色 color : this.config.color[1] } } } temp.markPoint = { show : true, symbol:imgsrc, symbolSize : imgsize, label:{ normal:{ formatter: function(obj) { if(klen>5 && that.config.issmart==true){ return ""; } else{ return obj.value; } }, textStyle:{ color : "#ffffff", fontFamily:family } }, emphasis:{ formatter: function(obj) { return obj.value; } } }, data:markData } seriesData[i] = temp; } } return seriesData; } this.mapChart = function(data,config){ var name = data.name,key = data.key,values = data.val[0],mydata = [],max = 0; if(values && values.length>0){ var max = this.UtilService.getMaxByArray(values); max = Math.ceil(max/100)*100; key.filter(function(n,i){ mydata.push({value:values[i],name:n}); }); } var option = { tooltip: { trigger: 'item', formatter: function(params){ if(isNaN(params.value)){ return params.name; }else{ return params.name+"<br/>" + params.seriesName +":"+params.value; } } }, visualMap:{ min:0, max:max, color:['#7ec3f2','#dcebf4'] }, series: [ { name: name[0], type: 'map', mapType: 'china', selectedMode : 'multiple', top:20, bottom:20, label: { normal: { show: true, textStyle:{ fontSize:4, color:fontcolor, fontFamily:family } }, emphasis: { show: true } }, itemStyle:{ normal:{ areaColor:"#eeeeee", borderColor:"#858585" }, emphasis:{ areaColor:"#1fb9e9" } }, data:mydata } ] }; return option; } this.loginMapChart = function(data,config){ var name = data.name,key = data.key,values = data.val[0],mydata = [],max = 0; if(values && values.length>0){ var max = this.UtilService.getMaxByArray(values); max = Math.ceil(max/100)*100; key.filter(function(n,i){ mydata.push({value:values[i],name:n}); }); } var option = { tooltip: { trigger: 'item', show:false, formatter: function(params){ if(isNaN(params.value)){ return params.name; }else{ return params.name+"<br/>" + params.seriesName +":"+params.value; } } }, // visualMap:{ // min:0, // max:max, // color:['#7ec3f2','#dcebf4'] // }, series: [ { name: name[0], type: 'map', mapType: 'china', selectedMode : 'multiple', top:20, bottom:20, label: { normal: { show: false, textStyle:{ fontSize:4, color:fontcolor, fontFamily:family } }, emphasis: { show: true } }, itemStyle:{ normal:{ areaColor:"#424250", borderColor:"#1e1e26" }, emphasis:{ areaColor:"#3c3c4a" } }, data:mydata } ] }; return option; } /*柱图 最后一条为线条*/ this.columnLineChart = function(){ var seriesData = [],len = this.name.length; for (var i = 0; i < len; i++) { var temp = {}; temp.name = this.name[i]; temp.barMaxWidth = 18; temp.barGap = 0; temp.data = this.data[i]; if(i == len-1){ temp.type = "line"; temp.yAxisIndex = 1; } else{ temp.type = "bar"; } temp.itemStyle = { normal : { color : this.config.color[i] }, emphasis : { //鼠标放上颜色 color : this.config.color[i] } } seriesData[i] = temp; } return seriesData; } } function toFixedValue(value){ if (value > 999 & value < 10000) { return (value / 1000).toFixed(1).toString() + "k"; } else if (value >= 10000 && value < 1000000) { return (value / 10000).toFixed(1).toString() + "w"; } else if (value >= 1000000 && value < 1000000000) { return (value / 1000000).toFixed(1).toString() + "m"; } else if (value >= 1000000000) { return (value / 1000000000).toFixed(1).toString() + "b"; } return value; } })();