指标核心逻辑


以simplelabel为例,下面讲解一下开发指标逻辑的注意事项,下面是其代码部分。

/**
 * Created by FreezeSoul on 2016/4/7.
 */
define([
    "app/core/base",
    "app/core/util",
    "jquery",
    "underscore",
    'loglevel',
    'jqueryTmpl',
    'jQueryUUID'
], function (Chart, Util, $, _, log) {

    var property = {
        config: "property",
        option: [
            {
                group: '基础',
                id: 'LabelInitText',
                name: '初始文本',
                enable: false,
                type: 'text',
                value: '',
                default: '',
                link: 'text',
                tooltip: '文本标签初始值'
            },
            {
                group: '基础',
                id: 'LabelFontSize',
                name: '字体大小',
                enable: false,
                type: 'number',
                value: 14,
                default: 14,
                link: 'fontSize',
                tooltip: '文本字体大小'
            },
            {
                group: '基础',
                id: 'LabelFontColor',
                name: '字体颜色',
                enable: false,
                type: 'color',
                value: '#000000',
                default: '#000000',
                link: 'fontColor',
                tooltip: '文本字体颜色'
            },
            {
                group: '基础',
                id: 'LabelBorderPadding',
                name: '内边距值',
                enable: false,
                type: 'padding',
                value: [5,5,5,5],
                default: [5,5,5,5],
                link: 'padding',
                tooltip: '文本内边距值'
            },
            {
                group: '基础',
                id: 'LabelBorderWidth',
                name: '边框宽度',
                enable: false,
                type: 'number',
                value: 1,
                default: 1,
                link: 'borderWidth',
                tooltip: '文本边框宽度'
            },
            {
                group: '基础',
                id: 'LabelBorderStyle',
                name: '边框样式',
                enable: false,
                type: 'select',
                value: 'solid',
                default: 'solid',
                data: [{
                    value: 'dotted',
                    text: '点线边框'
                }, {
                    value: 'dashed',
                    text: '虚线边框'
                }, {
                    value: 'solid',
                    text: '实线边框'
                }, {
                    value: 'double',
                    text: '两个边框'
                }, {
                    value: 'groove',
                    text: '3D沟槽边框'
                }, {
                    value: 'ridge',
                    text: '3D脊边框'
                }, {
                    value: 'inset',
                    text: '3D嵌入边框'
                }, {
                    value: 'outset',
                    text: '3D突出边框'
                }],
                link: 'fontStyle',
                tooltip: '文本边框样式'
            },
            {
                group: '基础',
                id: 'LabelBorderColor',
                name: '边框颜色',
                enable: false,
                type: 'color',
                value: '#000000',
                default: '#000000',
                link: 'borderColor',
                tooltip: '文本边框颜色'
            },
            {
                group: '基础',
                id: 'LabelBackColor',
                name: '背景颜色',
                enable: false,
                type: 'color',
                value: 'transparent',
                default: 'transparent',
                link: 'backColor',
                tooltip: '文本背景颜色,透明色transparent'
            },
            {
                group: '基础',
                id: 'LabelBangDing',
                name: '绑定文本',
                enable: false,
                type: 'textBinding',
                dataset: '',
                ctype: 'all',
                column: {},
                tooltip: '文本绑定'
            }
        ],
        MapOption: function (option) {
            Util.linkOption(this.option, option);
        }
    };

    var label = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._element = null;
            this._container = null;
            this._option = {
                Series: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    text: "标签控件",
                    padding: [5, 5, 5, 5],
                    fontSize: 14,
                    fontColor: "#000000",
                    fontStyle: "",
                    borderWidth: 1,
                    borderColor: "#000000",
                    backColor: "transparent"
                }
            };
        },
        init: function (element) {
            try {
                this._uuid = $.uuid();
                this._container = element;
            } catch (e) {
                log.error(e);
            }
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        _render: function (option) {
            var $element = $.tmpl('<span id="${id}" class="label-text">${text}</span>', $.extend(true, {
                id: this._uuid
            }, option));
            if (option.fontSize && option.fontSize > 0) {
                $element.css("font-size", option.fontSize + "px")
            }
            if ($.isArray(option.padding) && option.padding.length == 4) {
                if (option.padding[0] && option.padding[0] > 0)
                    $element.css("padding-top", option.padding[0]);
                if (option.padding[1] && option.padding[1] > 0)
                    $element.css("padding-right", option.padding[1]);
                if (option.padding[2] && option.padding[2] > 0)
                    $element.css("padding-bottom", option.padding[2]);
                if (option.padding[3] && option.padding[3] > 0)
                    $element.css("padding-left", option.padding[3]);
            }
            if (option.fontColor) {
                $element.css("color", option.fontColor)
            }
            if (option.borderWidth && option.borderWidth > 0) {
                $element.css("border-width", option.borderWidth + "px")
            }
            if (option.borderColor) {
                $element.css("border-color", option.borderColor)
            }
            if (option.fontStyle) {
                $element.css("border-style", option.fontStyle)
            }
            if (option.backColor) {
                $element.css("background-color", option.backColor)
            }
            $element.css("display", "inline-block");
            $(this._container).empty();
            $element.appendTo(this._container);
            this._bindEvent($element);
            return $element;
        },
        _bindEvent: function (element) {
            var _this = this;
            $(element).on("click", function (e) {
                if (_this._layout
                    && _this._layout.navigate
                    && _this._option.Events
                    && _this._option.Events.length > 0) {

                    var registerEvent = _.findWhere(_this._option.Events, {Event: "LabelClick"});
                    if (registerEvent) {
                        var pageId = registerEvent.PageId;
                        var params = registerEvent.Params;
                        var args = [];
                        var dParam = _.findWhere(params, {Name: "文本"});
                        if (dParam && dParam.ParamName) {
                            args.push({
                                ParamName: dParam.ParamName,
                                ParamValue: $(element).find(".label-text").text()
                            });
                        }
                        _this._layout.navigate(pageId, args);
                    }
                    e.preventDefault();
                }
            });
        },
        example: function () {
            try {
                this._element = this._render(this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        _bindData: function (data) {
            var bindProperty = _.findWhere(this._option.Extend.option, {type: 'textBinding'});
            if (!bindProperty || !bindProperty.dataset) return;
            var dataSetCode = bindProperty.dataset;
            var table = data[dataSetCode];
            if (table && table.length > 0 && bindProperty.column) {
                var row = table[0];
                var columnName = bindProperty.column.ColumnName;
                if (columnName) {
                    this._option.Option.text = row[columnName];
                }
            }
        },
        setData: function (data) {
            try {
                this._readProperty();
                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend
                ) {
                    this._bindData(data);
                }
                this._element = this._render(this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
            } catch (e) {
                log.error(e);
            }
        },
        getElement: function () {
            return this._element;
        }
        getChart: function () {
            return this._element;
        }
    });

    return {
        Chart: label,
        Property: property
    };
});

整体代码风格采用了AMD方式做了包装,此示例中采用了通用属性设计器的支持,所以返回类型包含Property(通用属性部分详解请参见 指标通用属性 章节)

下面针对实现方法重点讲解:

  • 所有指标插件的实现都要求采用Chart.extend方式继承平台接口,其Chart是通过define引用的"app/core/base"脚本实例。
  • 接口方法constructor是构造指标插件的实例的调用方法,通常放置一些与数据无关的类型定义等操作。方法参数传入页面布局实例对象。
  • 接口方法init是初始化指标插件的调用方法,在这里一般会做指标插件的初始化操作。方法参数传入一个dom元素,是用来装载指标插件的HMTL element元素。方法支持返回 JavaScript Promises 对象,可以将一些异步初始化操作放置于此(如AMD异步资源加载、Ajax服务请求代码等),具体可参见如下:

同步初始化方式:

init: function (element) {
    try {
        this._uuid = $.uuid();
        this._container = element;
    } catch (e) {
        log.error(e);
    }
}

异步初始化方式:

init: function (element) {
    try {
        var _this = this;
        var deferred = $.Deferred();
        require([FindMapJsFile(this._option.Option.mapType)], function () {
            _this._chart = ec.init(element, null, {
                renderer: 'canvas'
            });
            _this._bindEvent();
            deferred.resolve(_this._chart);
        });
        return deferred.promise();
    } catch (e) {
            log.error(e);
    }
}
  • 接口方法example是设计器调用加载示例数据的方法,在方法里需要准备一组示例数据初始化指标插件。
  • 接口方法setData是指标插件绑定数据集后,数据集填充指标所需调用的方法,传入参数为数据json对象。

    {
      "yuetongji": [
          {
              "value": 312, 
              "month": "一月"
          }, 
          {
              "value": 142, 
              "month": "二月"
          }, 
          {
              "value": 412, 
              "month": "三月"
          }, 
          {
              "value": 421, 
              "month": "四月"
          }, 
          {
              "value": 234, 
              "month": "五月"
          }, 
          {
              "value": 785, 
              "month": "六月"
          }, 
          {
              "value": 249, 
              "month": "七月"
          }, 
          {
              "value": 675, 
              "month": "八月"
          }, 
          {
              "value": 689, 
              "month": "九月"
          }, 
          {
              "value": 642, 
              "month": "十月"
          }, 
          {
              "value": 423, 
              "month": "十一月"
          }, 
          {
              "value": 753, 
              "month": "十二月"
          }
      ]
    }
  • 接口方法setOptiongetOption是平台设计器在指标编辑时设置与获取指标设置参数的方法。

    {
      "Binding": [ ], 
      "Events": [ ], 
      "Extend": { }, 
      "Option": { }
    }

其中指标参数中Binding为绑定对象,描述了绑定数据集的结构与信息,一般用于setData操作中,示例结构如下:

"Binding": [
    {
        "Name": "月统计分析", 
        "Dimensions": [
            {
                "Code": "月份", 
                "Name": "月份", 
                "DataType": "string", 
                "AnalysisType": "dimension", 
                "Column": "month"
            }
        ], 
        "Measures": [
            {
                "Code": "数值", 
                "Name": "2012年", 
                "DataType": "int", 
                "AnalysisType": "measure", 
                "Column": "value"
            }
        ], 
        "DataSetCode": "yuetongji", 
        "PushFrequency": 0
    }
]

指标参数的Events为事件对象,描述了指标事件发生的参数信息,一般用于指标参数的事件处理逻辑中,ParamName对应数据集定义的参数,实例结构如下:

"Events": [
    {
        "Event": "SeriesClick", 
        "Params": [
            {
                "ParamName":"#序列名称#",
                "Value": "SeriesName", 
                "Name": "序列名称"
            }, 
            {
                "ParamName":"#序列维度值#",
                "Value": "Dimension", 
                "Name": "序列维度值"
            }, 
            {
                "ParamName":"#序列度量值#",
                "Value": "Measure", 
                "Name": "序列度量值"
            }
        ], 
        "PageId": 18
    }
]

指标参数的Extend为扩展数据,一般用于存储通用属性设计器的设置信息,但不强制,可参见上面的示例代码处理方式。

指标参数的Option为参数数据,一般用于存储指标的配置参数信息,在指标设计模式下的代码模式所加载的内容。

EditorCode

  • 接口方法resize在窗体与容器变化时调用,需实现指标插件的重绘。
  • 接口方法showLoadinghideLoading用于显示与隐藏加载动画的操作。
  • 接口方法dispose需实现指标插件的释放逻辑,回收资源。
  • 接口方法getElement需返回指标插件的DOM对象。
  • 接口方法getChart需返回指标插件的实例对象。

results matching ""

    No results matching ""