[组件] TopN 排行榜

废话不说,直接看代码,最后会给出一个示例:

/**

 * TopN 排行榜组件

 *

 * @param {Array} data    排行数据

 * @param {Number} N      即TopN的N

 * @param {Object} config 配置对象,格式为:

 *                        {

 *                          headers: [],        // 每一项的header信息,如"北京"的header为"城市",

 *                                              // 每一项都是HTML字符串

 *                                              // 也可以是Function,返回一段HTML代码

 *                          showHeader: false,  // 是否显示headers

 *

 *                          keys: [],           // 每一项数据的key

 *                          values: [],         // 如需定义结构,元素为Function,返回一段HTML

 *                                              // 一般传null即可

 *                          mainKey: 'xx',      // 比较项

 *                          sorted: false,      // 数据是否已排序

 *                        }

 *

 *                        headers(如果有), keys, values的长度保持一致

 *

 *                        如有色块,约定className为valueBar,如果色块旁边需附有值说明,约定className

 *                        为valueLiteral,如下:

 *                        <div class="valueBar"></div><div class="valueLiteral">100</div>

 */

function TopN(data, N, config) {

    this.data = data;

    this.N = N;

    this.config = config || {};



    // 对应的DOM节点

    this.node = null;



    if (!this.config.sorded) {

        this.data.sort(this.sort());

    }

}

TopN.prototype = {

    constructor: TopN,



    /**

     * @param {HTMLElement} parentNode 插入TopN组件的父元素

     */

    initDOM: function() {

        



        return function(parentNode) {

            if (!parentNode || parentNode.nodeType !== 1) return;

            

            var config = this.config, html = ['<table class="ui_TopN">'],

                i, len = config.keys.length;

            

            // 加col

            html.push('<colgroup>');

            for (i = 1; i <= len; i++) {

                html.push('<col class="column' + i + '" />');

            }

            html.push('</colgroup>');



            // 拼装header部分

            if (config.showHeader) {

                html.push('<thead><tr>');



                var headers = config.headers;

                for (i = 0, len = headers.length; i < len; i++) {

                    html.push('<th>');

                    

                    html.push(headers[i] || ' ');



                    html.push('</th>');

                }



                html.push('</tr></thead>');

            }

            

            // 拼装排行部分

            html.push('<tbody>');



            // 遍历前N 项数据

            var keys = config.keys, key,

                values = config.values, value,

                items = this.data, item, 

                j, size = values.length;

    

            for (i = 0, len = this.N; i < len; i++) {

                item = items[i];



                html.push('<tr>');

                

                // 遍历每项数据的keys

                for (j = 0; j < size; j++) {

                    key = keys[j];

                    value = values[j];

                    

                    if (key) {

                        key = item[key];

                    } else {

                        // key为空表示序号项

                        key = i + 1;

                    }

                   

                    if (typeof value === 'function') {

                        value = value(key);

                    } else {

                        value = key;        

                    }



                    html.push('<td>');

                    html.push(value);

                    html.push('</td>');

                }



                html.push('</tr>');

            }



            html.push('</tbody></table>');



            var doc = parentNode.ownerDocument,

                div = doc.createElement('div');

            div.innerHTML = html.join('');



            this.node = div.firstChild;

 

            parentNode.appendChild(this.node);

            

            if ($('valueBar', this.node)[0]) {

                this.autoWidth();

            }

        }

    }(),

    

    autoWidth: function() {

        var maxValue = this.data[0][this.config.mainKey], maxWidth;

        

        var valueBars = $('valueBar', this.node), bar,

            valueLiterals = $('valueLiteral', this.node), literal;



        // 进到这里,valueBars肯定不为空,所以就看valueLiterals是否为空

        maxWidth = valueBars[0].parentNode.offsetWidth - (valueLiterals[0] ? valueLiterals[0].offsetWidth : 0);

        

        var data = this.data, mainKey = this.config.mainKey, percentage, width;



        for (var i = 0, len = valueBars.length; i < len; i++) {

            bar = valueBars[i];

            

            percentage = data[i][mainKey] / maxValue;

            width = maxWidth * percentage;

            width = Math.max(4, width);

            

            bar.style.width = width + 'px';

            if (!bar.innerHTML) {

                bar.innerHTML = ' ';

            }

        }

    },



    /**

     * 排序方法,作为Array.prototype.sort()的参数

     * @return {Function}

     */

    sort: function() {

        var key = this.config.mainKey;

        return  function(item1, item2) {

            if (item1 && typeof item1[key] !== 'undefined' &&

                item2 && typeof item2[key] !== 'undefined') {

                var value1 = '' + item1[key];

                var value2 = '' + item2[key];

                return -1 * value1.localeCompare(value2);

            }

        }

    }

}

function $(className, node){

    node = node || document;

    return node.getElementsByClassName(className);

}  


接着给例子,请先把TopN组件存为topN.js:

<!DOCTTYPE html>

<html>

    <head>

        <script src="topN.js"></script>

		<script>

			var data = [

				{name:'北京', input:5000},

				{name:'上海', input:4000},

				{name:'深圳', input:6000},

				{name:'广州', input:3000},

				{name:'天津', input:7000},

			]

            var top3 = new TopN(data, 3, {



                headers: [null, '城市', '值', '还是城市'],



                showHeader: true,



                keys: [null, 'name', 'input', 'name'],



                values: [null, null, function(s){

                    return '<div class="valueBar"></div><span class="valueLiteral">'+s+'</span>';    

                }, function(value){

                    return '<b>'+value+'</b>'

                }],



                mainKey: 'input'



            })



            window.onload = function(){

                top3.initDOM(document.body);

			}

			

        </script>

        <style>

            ol {

                border:2px solid blue;

            }

            

            .column3 {

                width:300px;

                

            }

            .valueBar {

                background:blue;

            }

        </style>

    </head>

    <body>

    </body>

</html>

  

你可能感兴趣的:(top)