调用方法:
var parameter = { url: 'json/report.txt', data: data, marker: 'value', titleClick: function (t) { alert(t.html()); } }; $('#container').latticeControl(parameter);
其中data为:
{"success":true,"data":[{"title":"OTHER","data":{"January":2378579,"February":2026040,"March":2247718,"April":3055005, "May":3427766,"June":4043157},"total":1.7178265E7},{"title":"Suzhou","data":{"January":2414166,"February":2056633, "March":2455726,"April":2287793,"May":2228349,"June":2159281},"total":1.3601948E7},{"title":"Nanjing", "data":{"January":1618640,"February":1480353,"March":1763553,"April":1751279,"May":1640309,"June":1603294}, "total":9857428.0},{"title":"Wuxi","data":{"January":1207621,"February":1081559,"March":1306533,"April":1202234, "May":1158849,"June":1121379},"total":7078175.0},{"title":"Nantong","data":{"January":901609,"February":899929, "March":1057929,"April":950595,"May":917272,"June":889076},"total":5616410.0},{"title":"Changzhou", "data":{"January":838039,"February":762853,"March":920973,"April":853114,"May":812868,"June":800531},"total":4988378.0}, {"title":"Suqian","data":{"January":255216,"February":263098,"March":316585,"April":279431,"May":275249,"June":268625}, "total":1658204.0}],"currentDim":"city_host","availableDims":[{"id":"is_campus","num":3},{"id":"is_iphone","num":3}, {"id":"city_host","num":14},{"id":"sex","num":3},{"id":"city_user","num":15},{"id":"ages","num":7},{"id":"user_type","num":2}, {"id":"charge_type","num":6}],"max":17178265,"sum":8.3638812E7,"totalItems":14,"page":1,"totalPage":1}
/* parameter: { } */ $.fn.latticeControl = function (parameter) { var nativeObj = $(this); var commonFn = (function () { //Format integer function _formatIntNum(amtstr) { var isInt = function (num) { return (num % 1 === 0); }; var amtstr = (isInt(amtstr)) ? amtstr : Number(amtstr).toFixed(0); amtstr = "" + amtstr; var a, renum = ''; var j = 0; var a1 = '', a2 = '', a3 = ''; var tes = /^-/; var isCurrency = (typeof (isCurrency) != 'undefined') ? isCurrency : true; a = amtstr.replace(/,/g, ""); a = a.replace(/[^-\.,0-9]/g, ""); a = a.replace(/(^\s*)|(\s*$)/g, ""); if (tes.test(a)) a1 = '-'; else a1 = ''; a = a.replace(/-/g, ""); if (a != "0" && a.substr(0, 2) != "0.") a = a.replace(/^0*/g, ""); j = a.indexOf('.'); if (j < 0) j = a.length; a2 = a.substr(0, j); a3 = a.substr(j); j = 0; for (i = a2.length; i > 3; i = i - 3) { renum = "," + a2.substr(i - 3, 3) + renum; j++; } renum = a1 + a2.substr(0, a2.length - j * 3) + renum + a3; return renum; } //Get the width of container function _getContainerWidth() { var strWidth = new String(nativeObj.css('width')); var width = parseInt(strWidth); return width; } //Handle the maxmize value function _handleMaxValue(maxvalue) { if (maxvalue < 100) { return 100; } else { if (maxvalue < 1000) { return 1000; } else { var strvalue = new String(maxvalue.toFixed(0)); var intvalue = parseInt(strvalue.substring(0, 2)); return (intvalue + 1) * _exp(strvalue.length - 2); } } function _exp(num) { var value = 10; for (var i = 1; i < num; i++) { value = value * 10; } return value; } } //Transfer input data function _transferData(obj) { // {'title': 'TIANJIN', 'amount': '', 'data': [['January', '20%'], ['February', '15%'], ['March', '9%'], ['May', '8%'], ['June', '5%'], ['July', '43%']]} var max = _handleMaxValue(obj.max); var reArray = []; var result = ''; for (var i = 0; i < obj.data.length; i++) { var dataArray = []; result = '{"sum": "' + obj.sum + '", "pagesize": "' + obj.totalItems + '", "title": "'; result += obj.data[i].title; result += '", "amount": '; result += '"' + obj.data[i].total + '", '; result += '"data": '; for (var item in obj.data[i].data) { //result += '["' + item + '", "' + obj.data[i].data[item] / max + '", "' + obj.data[i].data[item] + '"]'; dataArray.push([item, _transferPercent(obj.data[i].data[item]), obj.data[i].data[item], ((obj.data[i].data[item] / obj.data[i].total) * 100).toFixed(2) + "%" ]); } result += JSON.stringify(dataArray); dataArray = []; result += '}'; reArray.push(eval('(' + result + ')')); } return reArray; function _transferPercent(num) { return ((num / max) * 100).toFixed(2) + "%"; } } //Create lattices html code function _getLatticeHtml(data, marker) { var result = '', sp = true; if (marker != null && marker != undefined) { sp = (marker === 'percentage'); } for (var i = 0; i < data.length; i++) { result += '<div class="row" data-page="' + data[i].pagesize + '" data-amount="' + data[i].sum + '">'; //part result += '<ul class="noliststyle">'; result += '<li class="marginbottom"><span class="title"> ' + data[i].title + '</span><span class="show" data="' + ((i === 0) ? '%' : '') + _transferPercent(data[i].amount / data[i].sum) + '">' + ((i === 0) ? '%' : '') + _transferPercent(data[i].amount / data[i].sum) + '</span></li>'; result += '<li>'; result += '<ul class="lattice-part noliststyle">'; var width, itemwidth, bodywidth = _getContainerWidth(); var containerwidth = bodywidth - 120 - (data[i].data.length - 1) * 3; var sumwidthofli = 0; for (var k = 0; k < data[i].data.length; k++) { width = sp ? parseFloat(data[i].data[k][3]) : parseFloat(data[i].data[k][1]); itemwidth = Math.round(width * containerwidth / 100); itemwidth = itemwidth === 0 ? 3 : itemwidth; if (k === 0) { result += '<li marker="first" style="' + itemwidth + 'px"><a title="month">'; } else { if (k === (data[i].data.length - 1)) { result += '<li style="' + (sp ? (containerwidth - sumwidthofli) : itemwidth) + 'px"><a title="month">'; } else { result += '<li style="' + itemwidth + 'px"><a title="month">'; } } sumwidthofli += itemwidth; result += (data[i].data[k][0] + '</a> <a>|</a> <a title="value" percentvalue="' + _switchPercent(data[i].data[k][3]) + '" figurevalue="' + _formatIntNum(data[i].data[k][2]) + '">' + (sp ? data[i].data[k][3] : _formatIntNum(data[i].data[k][2])) + '</a></li>'); } if (!sp) { result += '<li class="fill" style="' + (containerwidth - sumwidthofli - 3) + 'px"></li>'; } result += '<li class="last" data="' + _formatIntNum(data[i].amount) + '">' + _formatIntNum(data[i].amount) + '</li>'; result += '</ul>'; result += '</li>'; result += '</ul>'; result += '</div>'; } return result; function _transferPercent(num) { return (num * 100).toFixed(2); } function _switchPercent(str) { var pstr = new String(str); pstr = pstr.replace('%', ''); return pstr; } function _getFillWidth(pdata) { var psum = 0; for (var pi = 0; pi < pdata.length; pi++) { psum += parseFloat(_switchPercent(pdata[pi][1])); } var result = parseInt((100 - psum) / 100 * containerwidth); return result; } } //Move lattice function _moveLattice(lattice) { //get the class attribute var thisClass = lattice.attr("class"); //when the class of this item is 'first' or 'last', do nothing if (thisClass === "last" || lattice.attr("marker") === "first") { return; } var twidth = new String(lattice.css("width")); var width = parseInt(twidth.replace('px', '')); var arrayli = _getLeftItem(lattice.parent(), _getMarginLeft(lattice)); lattice.animate({ marginLeft: '0px' }); for (var i = 0; i < arrayli.length; i++) { arrayli[i].animate({ marginLeft: (_getMarginLeft(arrayli[i]) + width + 3) }); } } //Recover lattices that in front of current lattice and reset the current one function _recoverLattices(lattice, targetLattice) { var latticeWidth = _getCssAttr(lattice, 'width'); //Recover the lattices that in front of current lattice first var frontArray = _getFrontOf(), sumWidth = 0; for (var i = 0; i < frontArray.length; i++) { frontArray[i].animate({ marginLeft: _getCssAttr(frontArray[i], 'margin-left') - latticeWidth - 3 }); sumWidth += (_getCssAttr(frontArray[i], 'width') + 3); } //Recover the current lattice lattice.removeClass('moved').removeAttr('marker'); if (sumWidth !== 0) { lattice.animate({ marginLeft: sumWidth }, 500, function() { if (targetLattice !== null) { _moveLattice(targetLattice); } }); } else { _moveLattice(targetLattice); } function _getFrontOf() { var array = []; var target = lattice.prev(); while (target.is('li')) { array.push(target); target = target.prev(); } return array; } } //Get the css attribute 'margin-left' of appointed object function _getMarginLeft(obj) { var strleft = new String(obj.css('margin-left')); var l = parseInt(strleft.replace('px', '')); return l; } //Get the css attribute and convert it to integer function _getCssAttr(obj, css) { var str = new String(obj.css(css)); var result = parseFloat(str.replace('px', '')); return result; } //Get the lattice whose css attribute 'margin-left' is less than the appointed function _getLeftItem(containerobj, marginleft) { var result = []; containerobj.find("li").each(function () { var l = _getMarginLeft($(this)); if (l < marginleft) { result.push($(this)); } }); return result; } return { formatIntNum: _formatIntNum, getContainerWidth: _getContainerWidth, getLatticeHtml: _getLatticeHtml, getCssAttr: _getCssAttr, moveLattice: _moveLattice, recoverLattices: _recoverLattices, transferData: _transferData } })(); nativeObj.html(commonFn.getLatticeHtml(commonFn.transferData(parameter.data), parameter.marker)); //Set the css attribute 'margin-left' for every lattice in every row nativeObj.find('.row .lattice-part li').each(function () { strwidth = new String($(this).css("width")); if ($(this).index() > 0) { width += 3; if ($(this).attr("class") != "last") { $(this).css('margin-left', (width + 'px')); } width += parseInt(strwidth.replace('px', '')); } else { width = parseInt(strwidth.replace('px', '')); } }); //Here, create a div, put it in the page, it'll be used to show the detail information of every lattice when mouse-hover event triggers var hoverContainer = document.createElement('div'); hoverContainer.id = 'container_showLatticeData'; //Set the class to this object hoverContainer.className = 'lattice-data'; $(hoverContainer).appendTo($('body')); //Add mouse-hover event for every lattice in every row nativeObj.find('.row .lattice-part li[class!="last"]').hover(function () { var offset = $(this).offset(); if (commonFn.getCssAttr($(this), 'margin-left') === 0) { var titleWidth = new String($(this).parent().parent().prev().find('span:eq(0)').css('width')); titleWidth = titleWidth.replace('px', ''); var intWidth = parseInt(titleWidth) + 10; offset.left += intWidth; } $('#container_showLatticeData').html($(this).html()).css({ left: offset.left, top: offset.top - 29 }).show(); if (!$(this).hasClass('clicked') && !$(this).hasClass('moved')) { $(this).addClass('hover'); } }, function () { $('#container_showLatticeData').hide(); $(this).removeClass('hover'); }); //Add click event for every lattice in every row nativeObj.find('.row .lattice-part li[class!="last"]').click(function () { var index = $(this).index(), arrayLi = [], thisClass = $(this).attr('class'), moved = ($(this).parent().find('li[marker="moved"]').length > 0); nativeObj.find('.row').each(function () { arrayLi.push($(this).find('.lattice-part li:eq(' + index + ')')); //Remove the attribute 'marker' of the first lattice if (thisClass === 'clicked') { $(this).find('.lattice-part li:eq(0)').removeAttr('marker'); } //Recover the attribute of the first lattice if (thisClass === 'moved') { $(this).find('.lattice-part li:eq(0)').attr('marker', 'first'); var lastLattice = $(this).find('.lattice-part li[class="last"]'), showSpan = $(this).find('span[class="show"]'); lastLattice.html(lastLattice.attr('data')); showSpan.html(showSpan.attr('data')); } if (thisClass === 'hover') { $(this).find('.lattice-part li').removeClass('clicked').removeClass('moved'); var targetLattice = $(this).find('li:eq(' + index + ') a:eq(2)'); $(this).find('.lattice-part li[class="last"]').html(targetLattice.attr('figurevalue')); $(this).find('span[class="show"]').html(targetLattice.attr('percentvalue')); } }); for (var i = 0; i < arrayLi.length; i++) { if (thisClass === 'clicked') { if (moved) { commonFn.recoverLattices(arrayLi[i].parent().find('li[marker="moved"]'), arrayLi[i]); } else { commonFn.moveLattice(arrayLi[i]); } arrayLi[i].addClass('moved').removeClass('clicked').attr('marker', 'moved'); } else if (thisClass === 'hover') { arrayLi[i].addClass('clicked').removeClass('hover'); } else if (thisClass === 'moved') { commonFn.recoverLattices(arrayLi[i], null); } } }); //Add title click event nativeObj.find('.row span[class="title"]').click(function () { parameter.titleClick($(this)); }); };