关闭

【详解】添加分渠道注册量显示

446人阅读 评论(0) 收藏 举报
分类:

本例中,我们要做的是,

在原有echart表格的基础上,添加新的数据显示。

【大致思想】

分析原有表格中某项数据的显示原理,根据此原理,将我们所需要的数据展现出来。

即,最关键的就是分析数据库的数据,是通过一个怎样的过程,以图表的形式展现的。


第一步、分析

这一步,我们直到最后做出来,才刚刚搞清楚我们需要的原理。也即是说,这一步其实是最重要的。

接下来我们首先叙述下分析原理过程中的问题,然后再解释原理。

【问题】

我们依样画葫芦试着做的时候,遇到一个比较大的问题是,页面不停的刷新,刷新了一下午也刷不出最后的结果。

这里的原因可能有两点,

一者,

js错误,即,JSP页面不显示的原因,是JSP页面的代码出错了。

显而易见,显示的部分应当是不会出错的。因为我们根本就不需要动这部分。

JSP代码中的另一部分,js是我们改过的,所以,分析可能是这里出错。

二者,

后台出错,即,Controller中的某部分代码出错了。因为我们改了这部分里的一些代码。

【分析问题】

以上两个可能的问题,我们需要确定是哪一个。

我们首先需要知道,

前者js错误需要在F12控制台选项的js菜单中观察,我们怀疑js出错的时候,往往要到这里看有没有报错。

后者Controller代码报错,是在Eclipse的控制台中报错的。


最后我们分析得知,是js报错,但根本原因还是Controller中的代码错了。所以是二者都有错!

但js的报错信息,告诉我们哪里错了,我们从报错的地方追溯回去,才发现了问题所在。


【原理】

因为我们做的这个例子,是要在图表中显示新加的数据。新加的,我们要做的事情有人已经做过了。

我们要做的,要分析已经实现的部分的原理。

【数据流】

这里提出一个私人定义的概念,数据流。

即分析,我们看到的东西是从哪里来的。将这条路线画出来。正向推,反向推都是可以的。

接下来我们采用反向推!

以最接近我们要求的注册量为例:

{ 
		            	/* 注册量 */
		                name : chart_line_names[i][0],
		                type : 'line',
		                data : data.list[i].data[0],
		                markPoint : {
		                    data : [ {
		                        type : 'max',
		                        name : '最大值'
		                    }, {
		                        type : 'min',
		                        name : '最小值'
		                    } ]
		                },
		                markLine : {
		                    data : [ {
		                        type : 'average',
		                        name : '平均值'
		                    } ]
		                }
		            },	

这里涉及到ECharts的知识。我们发现,图中的这条数据线的显示,所需的数据来自data。

 data : data.list[i].data[0]
再分析,data中的data是哪里来的

 function base_member_regist_cnt_doChart(data){
来自于这里,画图的js函数doChart所需的数据都来自于这个方法传进来的参数data

再分析,这个data是哪里来的

var jsonObj= data.chartDatas;
base_member_regist_cnt_doChart(jsonObj);
来自于jsonObj,jsonObj又来自于data.chartDatas

分析这里的data是哪儿的。【注意:我们分析数据来源时,只分析源,不需要管data.balabala里的balabala这些东西】

$.getJSON(base_member_regist_cnt_url, paramdata, function (data) {
我们发现data是通过访问链接得到的JSON数据。

分析下paramdata是哪里来的。

function base_member_regist_cnt_genJson(paramdata){
var $form = $(form);
var paramdata = $form.serializeArray();
base_member_regist_cnt_genJson(paramdata);
我们发现paramdata来自于form。

<form id="form1" action="chart/base_member_regist_cnt.html" method="get" onsubmit="return base_member_regist_cnt_submit(this);">
                    <div class='ichartjs_details' style="margin-left:200px;margin-bottom:10px">
                    	   日期:<input type="text" id="base_member_regist_cnt_startDate" name="startDate" class="date"  minDate="2010-07-15" value="" maxDate="{%y}-%M-{%d}" />
                           与  
                         <input type="text" id="base_member_regist_cnt_compareDate" name="compareDate" class="date"  minDate="2010-07-15" value="" maxDate="{%y}-%M-{%d}" />
                           与  前<select name="intervalDay" id="base_member_regist_cnt_intervalDay">
                             <option value="3" >3日</option>
                             <option value="7" >7日</option>
                             <option value="30">1个月</option>
                         </select>平均值  
                         <button type="submit">比较</button><br />
                         
                    </div>
</form>
也即是,来自于表单的提交。

我们如果想得到这个JSON数据,就需要传递paramdata,才能够得到。

@RequestMapping("/base_member_regist_cnt.json")
public String base_member_regist_cnt(String startDate,String compareDate, String intervalDay, ModelMap modelMap) throws MyException, ParseException {
我们找到了要访问的链接。而且这个链接的确是返回了一个jsonView。

也就是说,这个名为base_member_regist_cnt的方法中,在jsonView中装入了数据。

我们接下来就是要分析,它是怎么在这个方法里取得数据并把它装入jsonView的。

该方法的精简版方法体如下

         if(startDate == null || startDate.trim().length() == 0) {
             startDate=dateUtil.getString(new Date(), "yyyy-MM-dd");
         }
         if(intervalDay == null || intervalDay.trim().length() == 0) {
             intervalDay="7";
         }
         if(compareDate == null || compareDate.trim().length() == 0) {
             Date date=dateUtil.addDay(new Date(), -Integer.valueOf(intervalDay));
             compareDate=dateUtil.getString(date, "yyyy-MM-dd");
         }
        ParamMap paramMap=new ParamMap();
        paramMap.put("startDate", startDate);
        paramMap.put("compareDate", compareDate);
        paramMap.put("intervalDay", intervalDay);
        EChartsData eChartsData=new EChartsData(paramMap);
        
        String sqlStr;
        String[] hoursLabels = LabelUtil.getLabelByIntBegin_00(24);
        ECharts eCharts2 = new ECharts(hoursLabels);
        
        //当日注册数
        List<Map<String,Object>> list2;
        sqlStr = stringUtil.formatMsg(
                "select DATE_FORMAT(b.CREATED_DATE,'%H') as label,count(MEMBER_ID) as STARTDATE_COUNT from moyoyo_member.BASE_INFO b where DATE_FORMAT(b.CREATED_DATE,'%Y-%m-%d') = '{0}' group by DATE_FORMAT(b.CREATED_DATE,'%H')", 
                new Object[]{startDate});
        list2 = chartDataService.getChartList(sqlStr);
        eCharts2.add(LabelUtil.getValue(list2, hoursLabels,"label","STARTDATE_COUNT"));
        
        List<Map<String,Object>> list21;
        sqlStr = stringUtil.formatMsg(
                "select DATE_FORMAT(b.CREATED_DATE,'%H') as label,count(MEMBER_ID) as COMPAREDATE_COUNT from moyoyo_member.BASE_INFO b where DATE_FORMAT(b.CREATED_DATE,'%Y-%m-%d') = '{0}' group by DATE_FORMAT(b.CREATED_DATE,'%H')", 
                new Object[]{compareDate});
        list21 = chartDataService.getChartList(sqlStr);
        eCharts2.add(LabelUtil.getValue(list21, hoursLabels,"label","COMPAREDATE_COUNT"));
        
        Date date=dateUtil.getDateObj(startDate);
        date=dateUtil.addDay(date, -Integer.valueOf(intervalDay));
        String compareStartDate=dateUtil.getString(date, "yyyy-MM-dd");
        
        List<Map<String,Object>> list22;
        sqlStr = stringUtil.formatMsg("select DATE_FORMAT(b.CREATED_DATE,'%H') as label,round(count(MEMBER_ID)/{0},0) as AVG_COUNT from moyoyo_member.BASE_INFO b where b.CREATED_DATE >= '{1}' and b.CREATED_DATE<'{2}' group by DATE_FORMAT(b.CREATED_DATE,'%H')"
                , new Object[]{intervalDay,compareStartDate,startDate});
        list22 = chartDataService.getChartList(sqlStr);
        eCharts2.add(LabelUtil.getValue(list22, hoursLabels,"label","AVG_COUNT")); 
        eChartsData.add(eCharts2);
        
        modelMap.addAttribute("chartDatas", eChartsData);
        return "jsonView";
    }
根据以上方法体的代码,我们依然反向来推!

jsonView 的数据肯定是来自于modelMap

        modelMap.addAttribute("chartDatas", eChartsData);

modelMap中的数据来自于eChartsData。

eChartsData中的又装入了eCharts2。

        eChartsData.add(eCharts2);
而eCharts2中的数据又是eCharts2 add了三次得到的。

        eCharts2.add(LabelUtil.getValue(list2, hoursLabels,"label","STARTDATE_COUNT"));
        eCharts2.add(LabelUtil.getValue(list21, hoursLabels,"label","COMPAREDATE_COUNT"));
        eCharts2.add(LabelUtil.getValue(list22, hoursLabels,"label","AVG_COUNT")); 
而add的内容中又包含了list2,list21,list22三个list。

        list2 = chartDataService.getChartList(sqlStr);
        list21 = chartDataService.getChartList(sqlStr);
        list22 = chartDataService.getChartList(sqlStr);
而每个list又是通过sqlStr取得的数据。

这样看来,

方法这种不变的东西,如果重复了很多遍,我们只需要分析一次就可以,我们需要找的,是这一个方法追溯到最后,

不一样的那个参数,而这个参数绝对是很明显的那种。

sqlStr = stringUtil.formatMsg(
                "select DATE_FORMAT(b.CREATED_DATE,'%H') as label,count(MEMBER_ID) as STARTDATE_COUNT from moyoyo_member.BASE_INFO b where DATE_FORMAT(b.CREATED_DATE,'%Y-%m-%d') = '{0}' group by DATE_FORMAT(b.CREATED_DATE,'%H')",
                new Object[]{startDate});
就像这样!而这里就是我们得到数据的地方。SQL从数据库中取得数据。

至此,我们要分析的原理,其实就是数据流已经分析完成了。

我们看到了数据从哪里来,到哪里去。

我们要注意的是,没有分析到最明显的参数那一步时,就不算分析完,因为还没有找到数据的源头。


【知识】

JSON格式的数据。什么是JSON数据?

我们在分析代码的时候,怀疑过为什么直接return一个jsonView就可以返回数据呢?

这个JSONVIEW到底是什么东西。经过研究,我们可以知道:

json是一种轻量级的数据交换格式。可以是一堆键值对,也可以是一堆数组。这里我们没有分析出它是什么?

但是没有关系,只需要知道json数据就是可以封装一大堆数据的数据对象。

否则,我们在JSP中画图的时候为什么总是传递JSON对象呢?23333333333


第二步、搭建框架

我们从需求就可以知道,我们要改动的关键地方就是SQL。

我们需要增加多少个数据,就按原理分析的来,增加多少个一样的部分。

这些一样的部分!是体力活!最后我们才专注于改动SQL。


第三步、改动SQL

这里的SQL又涉及到了联表查询。又是我们比较头疼的这种联表查询。

本例中,其实我们实际做的时候是很快就把SQL写好了,只是一直不太确定是不是正确的。

这里如何判断是否SQL正确呢?

一个最好用且最常用的办法,【我们也是今天才明确这个东西的作用】

使用Navicat的查询功能。


我们看下Navicat的界面,发现查询选项是在某个数据库的菜单下的,这个数据库中有很多的表。

我们要做的联表查询,肯定是在一个数据库中做的。

所以我们活用这个查询功能。

这里再提出一个私人的定义。

【SQL调试器】

我们可以把Navicat的查询功能当做一个SQL的调试器,我们不确定写出来的SQL是不是对的,

换句话说,就是它能不能够取到数据,取到的数据是否正确,这些东西,

查询之后,是可以直接在界面中看到的。如果有错,选择不到我们需要的数据,随时修改就可以。

而且这样做还有一个好处,Navicat中有美化SQL格式的功能。

我们可以更加清晰的看到SQL的语法,如果哪里需要修改,也很清晰明了。


最终我们用来联表查询的SQL例子如下:

SELECT
    DATE_FORMAT(b.CREATED_DATE, '%H') AS label,
    count(d.MEMBER_ID) AS STARTDATE_COUNT
FROM
    moyoyo_member.BASE_INFO b
LEFT JOIN moyoyo_member.DETAIL_INFO d ON b.MEMBER_ID = d.MEMBER_ID
WHERE
    DATE_FORMAT(b.CREATED_DATE, '%Y-%m-%d') = '{0}'
AND d.CHANNEL_TYPE = 1
GROUP BY
    DATE_FORMAT(b.CREATED_DATE, '%H')
发现其实意外的简单。其它几个SQL,只要照猫画虎,按照原来的SQL来写就可以啦。


第四步、画图

接下来,到了最为关键的一步。画图!

我们拿到了数据,并且传回来了。怎么来画这个图呢?

还是分析原来已经画好的图的原理。

                      function base_member_regist_cnt_doChart(data){
				$("input#base_member_regist_cnt_startDate").val(data.paramMap['startDate']);
				$("input#base_member_regist_cnt_compareDate").val(data.paramMap['compareDate']);
				$("#base_member_regist_cnt_intervalDay").val(data.paramMap['intervalDay']);
				chart_titles = ['用户注册情况','当日注册数量比较'];
				
				chart_line_names = [
				                    ['总数'],
				                    [data.paramMap['startDate']+' 注册量',
				                     data.paramMap['startDate']+' WAP 注册量',
				                     data.paramMap['startDate']+' WEB 注册量',
				                     data.paramMap['startDate']+' APP 注册量',
				                     data.paramMap['startDate']+' SDK 注册量',
				                     data.paramMap['compareDate']+' 注册量',
				                     data.paramMap['compareDate']+' WAP 注册量',
				                     data.paramMap['compareDate']+' WEB 注册量',
				                     data.paramMap['compareDate']+' APP 注册量',
				                     data.paramMap['compareDate']+' SDK 注册量',
				                     '前'+data.paramMap['intervalDay']+'天平均注册量',
				                     '前'+data.paramMap['intervalDay']+'天 WAP 平均注册量',
				                     '前'+data.paramMap['intervalDay']+'天 WEB 平均注册量',
				                     '前'+data.paramMap['intervalDay']+'天 APP 平均注册量',
				                     '前'+data.paramMap['intervalDay']+'天 SDK 平均注册量',
				                    ]
				                   ];
画图主要靠这个js函数,doChart来完成。

先定义了一堆title和图例的名字。。。。

接下来,要画图的data传递进来了,这个函数是如何处理这个data的呢?

i = 1
				if(data.list[i].data[0].length==0){
					chart_div = document.getElementById('base_member_regist_cnt_canvasDiv' + i)
					html = '';
					html+='<div style="font-size: 14px;text-align: center; width: 100%;height:100%;color:red">'
		    		html+= data.paramMap["startDate"]+ chart_titles[i] + ' 暂时没有数据'
		      		html+= '</div>'

		      		chart_div.innerHTML=html;
				}
				if(data.list[i].data[0].length>0){
				echarts.init(document.getElementById('base_member_regist_cnt_canvasDiv' + i)).setOption({
		            title : {
		                text : data.paramMap["startDate"]+ chart_titles[i],
		                x : "center"
		            },
		            tooltip : {
		                trigger : 'axis'
		            },
		            legend : {
		                data : chart_line_names[i],
		                y    : 'bottom'  
		            },
		            toolbox : {
		                show : true,
		                feature : {
		                    dataView : {
		                        show : true,
		                        readOnly : false
		                    },
		                    magicType : {
		                        show : true,
		                        type : [ 'line', 'bar' ]
		                    },
		                    restore : {
		                        show : true
		                    },
		                    saveAsImage : {
		                        show : true
		                    }
		                }
		            },
		            calculable : true,
		            xAxis : [ {
		                type : 'category',
		                data : data.list[i].labels
		            } ],
		            yAxis : [ {
		                type : 'value',
		                scale : true,
		                name : '注册数量',
		                axisLabel : {
		                    formatter : '{value} 个'
		                }
		            } ],
		            series : [  
		              
		              { 
		            	/* 注册量 */
		                name : chart_line_names[i][0],
		                type : 'line',
		                data : data.list[i].data[0],
		                markPoint : {
		                    data : [ {
		                        type : 'max',
		                        name : '最大值'
		                    }, {
		                        type : 'min',
		                        name : '最小值'
		                    } ]
		                },
		                markLine : {
		                    data : [ {
		                        type : 'average',
		                        name : '平均值'
		                    } ]
		                }
		            },	
到这一步,完全就是ECharts的知识了。

如何定义坐标轴,如何定义图例,如何定义标题等等等等。

这些东西都已经写好了,我们只需要添加新的数据进去就可以了。

经过分析,我们可以知道,series里面是一条一条的数据。我们新添加一项数据,就是在这里添加。

根据特定的格式添加就去就好了,很简单!

【图例问题】

图画出来以后,我们发现有个问题,图例过于混乱了,


如何整理这个图例呢?

【图例相关的修改】

要整理图例,要修改的是-------图例相关代码!

legend : {
    data : chart_line_names[i],
    textStyle:{fontSize:12},
    //x:'left',
    //y:'50px',
    //orient:'vertical',
    y    : '365px',
},
在整理这个图例的过程中,我们主要修改了legend(英文意思就是传奇、图例)

中的x、y,即图例的位置。因为图例最开始与图表重合了,我们将图例向下移动,即调整y的坐标,最终发现y的坐标为365px比较合适。

这个365px是图例与图表顶端的距离。

后来发现怎么修改都不合适,只能调整图例字体的大小,

textStyle:{fontSize:12},
才调整到了一个比价合适的状态,如下!


另一种方法,其实可以不用修改字体的大小,转而修改字的多少,把图例简化,如:

2015-11-23注册量改为11-23,就可以节省不少空间。该例中,图例不合适的原因就是太多,占的空间也太多了!

修改的过程中,我们用到了js取子字符串的知识。

【js取子字符串】

data.paramMap['startDate'].substr(5,5),
即substr函数,表示从第几位开始,取几位数!

【js检测数据的传送】

这个问题我们之前就说过,这里又用到了,但是没有想起来用,所以再重申一遍。

alert()的用法。相当于Java代码中的System.out.println,相当于Python代码中的print。

加了alert(),我们刷新页面的时候,就会自动跳出包含了数据信息的提示框。



【ECharts表格的默认选中或默认不选中】

接下来我们要实现另一个效果,即,刚刷出页面的时候,需要只显示前五条记录。其它的数据默认不显示。

我们从ECharts的官方网站例子中了解到应当在legend的selected中进行设置。

option = {
    legend: {
        orient: 'horizontal', // 'vertical'
        x: 'right', // 'center' | 'left' | {number},
        y: 'top', // 'center' | 'bottom' | {number}
        backgroundColor: '#eee',
        borderColor: 'rgba(178,34,34,0.8)',
        borderWidth: 4,
        padding: 10,    // [5, 10, 15, 20]
        itemGap: 20,
        textStyle: {color: 'red'},
        selected: {
            '降水量' : false
        },
        data: [
            {
                name:'蒸发量',
                icon : 'image://../asset/ico/favicon.png',
                textStyle:{fontWeight:'bold', color:'green'}
            },
            '降水量','最高气温', '最低气温'
        ]
    },
其中,将'降水量'这一项设置为false,刷新页面的时候降水量这一项就会默认不选中。

本例中,我们的图例很多,而且图例的名字不是死的,而是由每天的日期与其它字符串组成的。

chart_line_names = [
                    ['总数'],
                    [data.paramMap['startDate'].substr(5,5),
                     data.paramMap['startDate'].substr(5,5)+' WAP',
                     data.paramMap['startDate'].substr(5,5)+' WEB',
                     data.paramMap['startDate'].substr(5,5)+' APP',
                     data.paramMap['startDate'].substr(5,5)+' SDK',
<pre name="code" class="javascript">                     data.paramMap['compareDate'].substr(5,5),
<pre name="code" class="javascript">                     data.paramMap['compareDate'].substr(5,5)+' WAP',
                     data.paramMap['compareDate'].substr(5,5)+' WEB',
                     data.paramMap['compareDate'].substr(5,5)+' APP',
                     data.paramMap['compareDate'].substr(5,5)+' SDK',
                     '前'+data.paramMap['intervalDay']+'天平均',
                     '前'+data.paramMap['intervalDay']+'天 WAP 平均',
                     '前'+data.paramMap['intervalDay']+'天 WEB 平均',
                     '前'+data.paramMap['intervalDay']+'天 APP 平均',
                     '前'+data.paramMap['intervalDay']+'天 SDK 平均',
                    ]
                   ];



官方的例子中,这种效果实现时,图例名字是死的,直接写出来。

这里如果我们直接传参数进去,

if(data.list[i].data[0].length>0){<pre name="code" class="javascript">echarts.init(document.getElementById('base_member_regist_cnt_canvasDiv' + i)).setOption({
 title : {
                            text : data.paramMap["startDate"]+ chart_titles[i],
                            x : "center"
                        },
                        tooltip : {
                            trigger : 'axis'
                        },
                        legend : {
                            data : chart_line_names[i],
                            textStyle:{fontSize:12},
                            //x:'left',
                            //y:'50px',
                            //orient:'vertical',
                            y    : '365px',
                            selected:{
                              chart_line_names[1][0]:false 
                            }
                        },
});


这种写法,没有达到我们想要的效果。

即,

官方的写法只适用于图例名字死的时候,

如果图例名字为变量,这样写是不行的,因为这个变量的值,传不到legend中的selected中去。

最终,我们只能改变代码的结构来达到目的。如下:

先定义一个option

option= {
                        title : {
                            text : data.paramMap["startDate"]+ chart_titles[i],
                            x : "center"
                        },
                        tooltip : {
                            trigger : 'axis'
                        },
                        legend : {
                            data : chart_line_names[i],
                            textStyle:{fontSize:12},
                            //x:'left',
                            //y:'50px',
                            //orient:'vertical',
                            y    : '365px',
                           selected:{}    
                          },
option.legend.selected[chart_line_names[1][5]] = false;
option.legend.selected[chart_line_names[1][6]] = false;
option.legend.selected[chart_line_names[1][7]] = false;
option.legend.selected[chart_line_names[1][8]] = false;
option.legend.selected[chart_line_names[1][9]] = false;
option.legend.selected[chart_line_names[1][10]] = false;
option.legend.selected[chart_line_names[1][11]] = false;
option.legend.selected[chart_line_names[1][12]] = false;
option.legend.selected[chart_line_names[1][13]] = false;
option.legend.selected[chart_line_names[1][14]] = false;
echarts.init(document.getElementById('base_member_regist_cnt_canvasDiv' + i)).setOption(option);
}
即先定义好option,然后再定义option中的legend中的selected属性。

这样最终可以达到我们想要的效果。

【注意】

这样的修改,代码结构发生了变化。还有一个地方需要注意,

我们要在option定义完后再修改legend中的selected属性值,需要现在option中声明一下有selected这么个属性。

 legend : {
                            data : chart_line_names[i],
                            textStyle:{fontSize:12},
                            //x:'left',
                            //y:'50px',
                            //orient:'vertical',
                            y    : '365px',
                           selected:{}    
                          },
否则会js报错,option.legend.selected没有被定义。

修改过这个图例以后的效果如下:



接下来我们要做的另外一件事情,是自定义tooltip,我们现在的代码中,

tooltip是默认样式的,

 tooltip : {
            trigger : 'axis'
 },
即跟着图例走。

我们想定义我们想要的悬浮框,就需要自己来写!

【自定义ECharts悬浮框样式】

实现这个自定义的悬浮框,我们参考的是ECharts官方的例子代码,最终成功实现!

官方的代码如下:

option = {
    tooltip : {         // Option config. Can be overwrited by series or data
        trigger: 'axis',
        //show: true,   //default true
        showDelay: 0,
        hideDelay: 50,
        transitionDuration:0,
        backgroundColor : 'rgba(255,0,255,0.7)',
        borderColor : '#f50',
        borderRadius : 8,
        borderWidth: 2,
        padding: 10,    // [5, 10, 15, 20]
        position : function(p) {
            // 位置回调
            // console.log && console.log(p);
            return [p[0] + 10, p[1] - 10];
        },
        textStyle : {
            color: 'yellow',
            decoration: 'none',
            fontFamily: 'Verdana, sans-serif',
            fontSize: 15,
            fontStyle: 'italic',
            fontWeight: 'bold'
        },
        formatter: function (params,ticket,callback) {
            console.log(params)
            var res = 'Function formatter : <br/>' + params[0].name;
            for (var i = 0, l = params.length; i < l; i++) {
                res += '<br/>' + params[i].seriesName + ' : ' + params[i].value;
            }
            setTimeout(function (){
                // 仅为了模拟异步回调
                callback(ticket, res);
            }, 1000)
            return 'loading';
        }
        //formatter: "Template formatter: <br/>{b}<br/>{a}:{c}<br/>{a1}:{c1}"
    },
    toolbox: {
        show : true,
        feature : {
            mark : {show: true},
            dataView : {show: true, readOnly: false},
            magicType : {show: true, type: ['line', 'bar', 'stack', 'tiled']},
            restore : {show: true},
            saveAsImage : {show: true}
        }
    },
    calculable : true,
    xAxis : {
        data : ['周一','周二','周三','周四','周五','周六','周日']
    },
    yAxis : {
        type : 'value'
    },
    series : [
        {
            name:'坐标轴触发1',
            type:'bar',
            data:[
                {value:320, extra:'Hello~'},
                332, 301, 334, 390, 330, 320
            ]
        },
        {
            name:'坐标轴触发2',
            type:'bar',
            data:[862, 1018, 964, 1026, 1679, 1600, 157]
        },
        {
            name:'数据项触发1',
            type:'bar',
            tooltip : {             // Series config.
                trigger: 'item',
                backgroundColor: 'black',
                position : [0, 0],
                formatter: "Series formatter: <br/>{a}<br/>{b}:{c}"
            },
            stack: '数据项',
            data:[
                120, 132,
                {
                    value: 301,
                    itemStyle: {normal: {color: 'red'}},
                    tooltip : {     // Data config.
                        backgroundColor: 'blue',
                        formatter: "Data formatter: <br/>{a}<br/>{b}:{c}"
                    }
                },
                134, 90,
                {
                    value: 230,
                    tooltip: {show: false}
                },
                210
            ]
        },
        {
            name:'数据项触发2',
            type:'bar',
            tooltip : {
                show : false,
                trigger: 'item'
            },
            stack: '数据项',
            data:[150, 232, 201, 154, 190, 330, 410]
        }
    ]
};
这个代码例子乍看很复杂,我们这里再提出一个私人的定义。

【代码简化法则】

有一个需求,我们需要编程来实现功能会有以下几种情况:

一者,从头开始写,这个时候我们需要寻找例子来参考,官方的或是私人的,有可能是比较复杂的例子;

二者,一部分有人已经做过了,本例就是这样。

这个时候我们需要做的就是理清楚逻辑。

看清楚代码的逻辑,我们要做的就是把代码简化到只剩逻辑!这就是简化!

比如以上这个自定义悬浮框的例子代码,我们可以去掉很多东西。

比如悬浮框的样式定制,字体定制,模拟异步回调等等。这些都是无关紧要的东西,我们可以去掉。

知道最后我们可以清楚的看到自定义悬浮框的核心代码,tooltip部分。

 tooltip : {
            trigger : 'axis',
            formatter: function (s) {
               var res = 'Formatter:<br/>'+s[0].name;
               for (var i = 0, l = s.length; i < l; i++) {
                  res += '<br/>' + s[i].seriesName + ' 注册量 : ' + s[i].value;
               }
             return res;
            }
},
这部分代码的意思是:

当鼠标移到光标时,会有数据传回来,装入参数s中,

然后这个function会执行下面的代码,实现对tooltip的定制。

这里的这个参数s,可以随意起名字,比如params等等。

这个参数之所以可以这样使用,我们可以类比AJAX的数据回调,function(data)这个data就可以随意起名字,

参数名字只不过是传回来的数据的一个容器,AJAX中不过是习惯性的起名为data而已。


最终我们的效果图如下!



截图快捷键:ctrl+alt+a









0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:77926次
    • 积分:2420
    • 等级:
    • 排名:第15922名
    • 原创:171篇
    • 转载:2篇
    • 译文:0篇
    • 评论:8条
    最新评论