叶子绿

分享自己的一些前端经验,做改变世界的产品。 再次出发…

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

   去年,苏嗲有提过HightChart控件.详见highcharts.com,自己一直有关注.最新出的版本是1.2.4,基本稳定下来了.这个网站的人员宣称,在1.5版本时实现3D效果.超期待哦.还等什么,拿过来给我们的前台框架添下光啊.

  拿来主义是不错,可是在于嗲的前台上扩展有些困难哦.所幸,经过好几天不懈的努力.总算实现了.

第一个麻烦是基于Ext适配器的实现,因为HightChart组件是基于Jquery或者MooTools框架的,总不能为了一个报表组件引进Jquery或MoolTools吧.以下是部分代码:

window.HighchartsAdapter = {
    getAjax: function (url, callback){
        Ext.Ajax.request({
            url: url,
            success: function (response){
                callback(response.responseText);
            }
        });
    },
    hyphenate: function (str){
        return str.replace(/([A-Z])/g, function (a, b){
            return '-' + b.toLowerCase();
        });
    },
    addEvent: function (el, event, fn){
        var xel = Ext.get(el);
        if (xel) xel.addListener(event, fn);
    },
    fireEvent: function (el, event, eventArguments, defaultFunction){// if fireEvent is not available on the object, there hasn't been added

        if (el.fireEvent) el.fireEvent(event, eventArguments);// fire the default if it is passed and it is not prevented above

        if (defaultFunction) defaultFunction(event);
    },
    animate: function (el, params, options){//jQuery(el).animate(params, options);
        var element = Ext.fly(el);
        var opt = {};
        var duration = 1.5;
        var callback = null;
        for (var p in params){
            opt[p] = {
                to: (params[p] + "").replace("px", "")
            };
        }
        for (var l in options){
            if (l === "complete") callback = options[l];
        }
        element.animate(opt, duration, callback, "easeOut", "run");
    },
    each: function (arr, fn){
        for (var i = 0, len = arr.length; i < len; i++) if (fn.call(arr[i], arr[i], i, arr) === false) return i;
    },
    map: function (arr, fn){
        var results = [];
        if (arr) for (var i = 0, len = arr.length; i < len; i++){
            results[i] = fn.call(arr[i], arr[i], i, arr);
        }
        return results;
    },
    merge: function (){
        var args = arguments;
        return Sail.jqextend(true, null, args[0], args[1], args[2], args[3]);
    },
    grep: function (arr, fn){
        return arr.filter(fn);
    }
};

var merge = window.HighchartsAdapter["merge"];

  在于嗲平台上扩展的实现:

Sail.widget.ext.ux_chart = function (config){
    this.title = "myReport";
    this.sub_title;
    this.url;
    this.theme = "grid";
    this.stacking = '';
    this.x_rotation = 0;
    this.y_rotation = 0;
    this.series_root = "dataset.report";
    this.xAxis_root = "dataset.categories";
    this.margin = Highcharts["defaultOptions"]["chart"]["margin"];
    this.legend_layout = '';
    this.xAxis = [];
    this.yAxis = [];//[{name:"",color:"",unit:""}]
    this.series = [];//[{name:"",type:"",data:[]}]
    this.formatter = function (){
        if (this.point && this.point.name && Sail.isEmpty(this.point.name)) return '<b>' + this.point.name + '</b><br/>' + this.y;
        else return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y;
    };
    Sail.widget.ext.ux_chart.superclass.constructor.call(this, config);
};

Ext.extend(Sail.widget.ext.ux_chart, Sail.widget, {
    defaultHeight: 400,
    defaultWidth: 800,
    defaultSeriesType: "line",
    initComponent: function (){},
    clean_config: function (){
        this.title = "myReport";
        this.sub_title;
        this.url = "";
        this.theme = "grid";
        this.stacking = '';
        this.legend_layout = '';
        this.x_rotation = 0;
        this.y_rotation = 0;
        this.margin = Highcharts["defaultOptions"]["chart"]["margin"];
        this.series_root = "dataset.report";
        this.xAxis_root = "dataset.categories";
        this.xAxis = [];
        this.yAxis = [];//[{name:"",color:"",unit:""}]
        this.series = [];//[{name:"",type:"",data:[]}]
        this.formatter = function (){
            if (this.point && this.point.name && ! Sail.isEmpty(this.point.name)) return '<b>' + this.point.name + '</b><br/>' + this.y;
            else return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y;
        }
    },
    getHeight: function (){
        return this.height || this.defaultHeight;
    },
    setHeight: function (height){
        this.getOCD().style.height = height || this.getHeight();
    },
    getWidth: function (){
        return this.width || this.defaultWidth;
    },
    setWidth: function (width){
        this.getOCD().style.width = width || this.getWidth();
    },
    getEl: function (){
        return this.el;
    },
    setTheme: function (theme){
        this.theme = theme;
        Highcharts.setOptions(_THEMES[this.theme]);
    },
    getTheme: function (){
        return this.theme;
    },
    init_config: function (config){
        if ( ! Sail.isEmpty(config)) Ext.apply(this, config);
        this.options = {};
        Highcharts.setOptions(_THEMES[this.theme]);
        this.options = {
            chart: {
                renderTo: this.getOCD(),
                margin: this.margin,
                defaultSeriesType: this.defaultSeriesType
            },
            credits: {
                enabled: true,
                href: "http://www.talkweb.com.cn",
                target: "_self",
                text: "talkweb.com.cn"
            },
            title: {
                text: this.title
            },
            subtitle: {
                text: this.sub_title
            },
            xAxis: [{
                categories: this.xAxis,
                labels: {
                    rotation: this.x_rotation || 0,
                    align: 'center',
                    style: {
                        font: 'normal 13px Verdana, sans-serif'
                    }
                }
            }],
            yAxis: ! Sail.isEmpty(this.yAxis) ? this.yAxis : {
                title: {
                    enabled: false,
                    text: ""
                }
            },
            tooltip: {
                enabled: true,
                formatter: this.formatter
            },
            legend: {
                layout: 'vertical',
                style: {
                    left: '120px',
                    bottom: 'auto',
                    right: 'auto',
                    top: '100px'
                },
                backgroundColor: '#FFFFFF'
            },
            plotOptions: {
                column: {
                    dataLabels: {
                        rotation: this.y_rotation || 0,
                        enabled: this.y_rotation !== 0,
                        color: '#FFFFFF',
                        align: "right"
                    },
                    stacking: Sail.isEmpty(this.stacking) ? '' : "normal"
                },
                area: {
                    stacking: 'percent',
                    lineColor: '#ffffff',
                    lineWidth: 1,
                    marker: {
                        lineWidth: 1,
                        lineColor: '#ffffff'
                    }
                }
            },
            series: this.series
        };
        if (Sail.isEmpty(this.legend_layout)) this.options.legend = Highcharts["defaultOptions"]["legend"];
        if (Sail.isArray(this.yAxis) && ! Sail.isEmpty(this.yAxis)){
            var units_rs = {};
            this.options.yAxis = [];
            Ext.each(this.yAxis, function (el, i, s){
                this.options.yAxis.push({
                    title: {
                        text: el.name,
                        margin: i > 0 ? 70 * i : 70,
                        style: {
                            color: el.color
                        }
                    },
                    labels: {
                        formatter: function (){
                            return this.value + el.unit || "";
                        },
                        style: {
                            color: el.color
                        }
                    },
                    opposite: i > 0 ? true : false
                });
                units_rs[el.name] = el.unit || "";
            }, this);
            this.options.tooltip["formatter"] = function (){
                return '<b>' + this.series.name + '</b><br/>' + this.x + ': ' + this.y + units_rs[this.series.name];
            };
        }
        if (this.url){
            var self = this;
            Sail.postData(this.url, {}, function (flag, rs){
                if (flag){
                    self.xAxis = Sail.splat(Sail.getSubObj(rs, self.xAxis_root));
                    self.series = Sail.splat(Sail.getSubObj(rs, self.series_root));
                    self.options.xAxis[0]["categories"] = self.xAxis;
                    self.options.series = self.series;
                    self.el = new Highcharts.Chart(self.options);
                }
            });
        }
        else this.el = new Highcharts.Chart(this.options);
    },
    load: function (config){
        if (this.el) this.el.destroy();
        var this_obj = this;
        (function (){
            this_obj.clean_config();
        }).createSequence(function (){
            this.init_config(config);
        }, this)();
    },
    createWidgetElement: function (){
        this.init_config();
    }
});

  以下是使用示例:

1

  改变数据源

2

  示例如图:

3

  配置参数说明,hightchart组件的配置参数非常麻烦.在于嗲平台上扩展后,虽然简化了配置.但要配合一定的后台数据结构.这个还可以再修正.

  以下作又部分参数作一个简短的说明.

type : "ux_chart" 报表的组合类型,值固定.
name :  报表名称,方便之后引用.
title :报表标题.
sub_title :报表副标题.
url:请求数据地址.
theme:报表皮肤.有dark-blue,dark-green,grid,default,gray,minimal.默认为grid,个人觉得这个最好看.
series_root:Y轴后台数据结构名称定制.默认为"dataset.report".
xAxis_root:X轴后台数据结构名称定制.默认为"dataset.categories".
yAxis:Y轴坐标轴定制,可以定义多个,详见示例.
legend_layout:定义图例的布局.horizontal or vertical.

x_rotation:x轴旋转角度,默认值0

y_rotation:y轴旋转角度,默认值0

margin:报表边辐.有默认值

svn地址 http://svn.talkweb.com.cn/svn/TBpl/MES产品化项目/01_工作区/04_编码/GUIF
示例文件名称 : ux_chart_1.html ,注意文件的引用.如图:
4

总结一下:
发布了一个ms_util.js文件,视需要可以作为对框架文件的必要补充.框架的文件未变动,所以对所有项目是兼容的.
这个文件主要是提供了hightchart报表控件的扩展,引进了hightchart库.
提供了一个遍历表单组件的方法.非常灵活哦.
简化了combox组件的配置,提供一个简单的赋值方法.
为sDate组件提供了set_current_date方法以设置默认值.
修正了框架一些不太好的地方.

重点说明一下:框架已经提供了报表的实现,虽然简单.但满足了作为报表的所有功能.并且在许多项目中有应用.这个是于嗲的原创,想学习js实现报表的话,不妨将这部分好好研究一下.另外,于嗲的框架平台的扩展性还是很强的,再赞一个.

posted on 2010-04-13 18:54  叶子绿  阅读(2157)  评论(5编辑  收藏  举报