model-cube.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. if($ == undefined){
  2. $ = jQuery;
  3. }
  4. var dateformat = ['yyyymmdd', 'yyyy-mm-dd', 'yyyy年mm月dd日', 'yyyymm', 'yyyy-mm', 'yyyy年mm月', 'yyyy', 'yyyy年'];
  5. function initcubeTable(){
  6. if($("#cubetable").size() > 0){
  7. $("#cubetable").datagrid("load", {t:Math.random()});
  8. return;
  9. }
  10. var ctx = "<table id=\"cubetable\" title=\"立方体管理\" ><thead><tr><th data-options=\"field:'ck',checkbox:true\"></th><th data-options=\"field:'cubeId',width:80,align:'center'\">标识</th><th data-options=\"field:'cubeName',width:120\">立方体名称</th><th data-options=\"field:'desc',width:120\">立方体说明</th><th data-options=\"field:'dsetName',width:120,align:'center'\">数据集</th></tr></thead></table>";
  11. $("#optarea").html(ctx);
  12. $("#cubetable").datagrid({
  13. singleSelect:true,
  14. collapsible:false,
  15. pagination:false,
  16. border:false,
  17. fit:true,
  18. url:'listCube.action',
  19. toolbar:[{
  20. text:'新增',
  21. iconCls:'icon-add',
  22. handler:function(){
  23. newCube(false);
  24. }
  25. },{
  26. text:'修改',
  27. iconCls:'icon-edit',
  28. handler:function(){
  29. var row = $("#cubetable").datagrid("getChecked");
  30. if(row == null || row.length == 0){
  31. $.messager.alert("出错了。","您还未勾选数据。", "error");
  32. return;
  33. }
  34. newCube(true, row[0].cubeId);
  35. }
  36. },{
  37. text:'删除',
  38. iconCls:'icon-cancel',
  39. handler:function(){
  40. var row = $("#cubetable").datagrid("getChecked");
  41. if(row == null || row.length == 0){
  42. $.messager.alert("出错了。","您还未勾选数据。", "error");
  43. return;
  44. }
  45. delCube(row[0].cubeId);
  46. }
  47. }]
  48. });
  49. }
  50. function delCube(id){
  51. if(confirm("是否确认删除?")){
  52. $.ajax({
  53. type:"POST",
  54. url:"delCube.action",
  55. dataType:"json",
  56. data:{cubeId:id},
  57. success:function(){
  58. $('#cubetable').datagrid('load',{
  59. t:Math.random()
  60. });
  61. },
  62. error:function(){
  63. msginfo("删除立方体出错。");
  64. }
  65. });
  66. }
  67. }
  68. function newCube(isupdate, cubeId){
  69. //清空 delObj 对象, 这个对象用在编辑时,判断哪些内容被删除了。
  70. window.delObj = [];
  71. var cube;
  72. if(isupdate){
  73. $.ajax({
  74. type:"POST",
  75. url:"getCube.action",
  76. async: false,
  77. dataType:"JSON",
  78. data:{cubeId:cubeId},
  79. success:function(resp){
  80. cube = resp;
  81. }
  82. });
  83. }
  84. //数据集
  85. var dsetls = "";
  86. if(isupdate){
  87. dsetls = "<option value='"+cube.dsetId+"'>"+cube.dsetName+'('+cube.priTable+')'+"</option>";
  88. }else{
  89. $.ajax({
  90. type:"POST",
  91. url:"listDataset.action",
  92. async: false,
  93. dataType:"JSON",
  94. data:{},
  95. success:function(resp){
  96. for(i=0; i<resp.length; i++){
  97. var r = resp[i];
  98. dsetls = dsetls + "<option value='"+r.dsetId+"'>"+r.name+'('+r.priTable+')'+"</option>";
  99. }
  100. }
  101. });
  102. }
  103. //立方体
  104. var cstr = "<div style='margin-top:10px;'><table width=\"100%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td valign=\"top\" align=\"right\"><div class=\"easyui-panel\" data-options=\"width:220,height:380,cls:'cubecfg'\" title=\"待选字段\"><ul id=\"cubelefttree\"></ul></div></td> <td align=\"center\" valign=\"top\"><p style=\"height:150px;\"></p><input type=\"button\" title=\"选择\" value=\"&gt;\" onclick=\"ds2cube()\" class=\"btn btn-primary btn-sm\"><br/><br/><input type=\"button\" onclick=\"cube2ds()\" value=\"&lt;\" title=\"移除\" class=\"btn btn-primary btn-sm\"></td><td valign=\"top\"><div class=\"easyui-panel\" data-options=\"width:220,height:380,cls:'cubecfg'\" title=\"维度和度量\"><ul id=\"cuberighttree\"></ul></div></td><td valign=\"top\"><div style=\"width:60px;\"><a href=\"javascript:addgroup();\" id=\"crtfz\" data-options=\"plain:true,iconCls:'icon-add'\">分组</a><br/><a href=\"javascript:editCalcKpi(false);\" id=\"crtcalckpi\" data-options=\"plain:true,iconCls:'icon-add2'\">度量</a><br/><a href=\"javascript:editcubecol();\" id=\"dim_editbtn\" data-options=\"plain:true,iconCls:'icon-edit'\">编辑</a><br/><a href=\"javascript:cube2ds();\" id=\"dim_delbtn\" data-options=\"plain:true,iconCls:'icon-remove'\">删除</a></div></td></tr></table></div>";
  105. var ctx = "<div id=\"crtdataset\" data-options=\"fit:true,border:false,tabPosition:'left'\"><div title=\"基本信息\"><div class=\"textpanel\"><span class=\"inputtext\">立方体名称:</span><input type=\"text\" value=\""+(cube?cube.cubeName:"")+"\" class=\"inputform2\" id=\"name\"><br/><span class=\"inputtext\">立方体说明:</span><input type=\"text\" value=\""+(!cube||cube.desc==null?"":cube.desc)+"\" size=\"50\" id=\"note\" class=\"inputform2\"><br/><span class=\"inputtext\">对应数据集:</span><select id=\"dsetId\" class=\"inputform2\">"+dsetls+"</select>"+(isupdate?" (禁止修改)":"")+"</div></div><div title=\"立方体信息\">"+cstr+"</div></div>";
  106. $('#pdailog').dialog({
  107. title: isupdate?'编辑立方体':'新建立方体',
  108. width: 760,
  109. height: 490,
  110. closed: false,
  111. cache: false,
  112. modal: true,
  113. toolbar:null,
  114. onLoad:function(){
  115. },
  116. content: ctx,
  117. buttons:[{
  118. text:'确定',
  119. iconCls:"icon-ok",
  120. handler:function(){
  121. var name = $("#pdailog #name").val();
  122. var dsetId = $("#pdailog #dsetId").val();
  123. var note = $("#pdailog #note").val();
  124. if(name == ''){
  125. $("#crtdataset").tabs("select", 0);
  126. msginfo("请填写立方体名称!");
  127. return;
  128. }
  129. var c = {};
  130. c.cubeName = name;
  131. c.desc = note;
  132. c.dsetId = dsetId;
  133. if(isupdate){
  134. c.cubeId = cube.cubeId;
  135. }
  136. if(savecubecfg(c, isupdate)){
  137. $('#pdailog').dialog('close');
  138. }
  139. }
  140. },{
  141. text:'取消',
  142. iconCls:"icon-cancel",
  143. handler:function(){
  144. $('#pdailog').dialog('close');
  145. }
  146. }]
  147. });
  148. $(".delcolbtn").linkbutton({plain:true, "iconCls":"icon-cancel"});
  149. $("#crtfz,#crtcalckpi,#dim_editbtn,#dim_delbtn,#adddynacol").linkbutton({});
  150. $("#crtdataset").tabs({});
  151. //初始化左边树形状
  152. var leftTreeView = function(dset, cube){
  153. // var cld = [];
  154. // var dt = [{id:'leftroot',text:dset.master,iconCls:'icon-table', children:cld}];
  155. //获取表
  156. var tbs = [];
  157. var tabExist = function(tname){
  158. var ret = false;
  159. for(k=0; k<tbs.length; k++){
  160. if(tbs[k] == tname){
  161. ret = true;
  162. break;
  163. }
  164. }
  165. return ret;
  166. }
  167. var c = dset;
  168. for(i=0; i<c.cols.length; i++){
  169. var r = c.cols[i];
  170. if(!tabExist(r.tname)){
  171. tbs.push(r.tname);
  172. }
  173. }
  174. var findcols = function(tname){
  175. var ret = [];
  176. for(j=0; j<c.cols.length; j++){
  177. if(c.cols[j].tname == tname){
  178. ret.push(c.cols[j]);
  179. }
  180. }
  181. return ret;
  182. }
  183. //获取表
  184. var dt = [];
  185. for(i=0; i<tbs.length; i++){
  186. var ccld = [];
  187. var nd = {id:tbs[i],text:tbs[i],iconCls:'icon-table', children:ccld};
  188. dt.push(nd);
  189. var cols = findcols(tbs[i]);
  190. for(l=0; l<cols.length; l++){
  191. var r = cols[l];
  192. var node = {id:r.name,text:r.name,iconCls:'icon-dscol',attributes:{tp:'node', vtype:r.type, col:r.name, tname:r.tname, expression:r.expression}}
  193. ccld.push(node);
  194. }
  195. }
  196. //动态字段
  197. if(c.dynamic && c.dynamic != null && c.dynamic.length > 0){
  198. var dynas = {id:'dynaroot', text:"动态字段", iconCls:'icon-table', children:[]};
  199. dt.push(dynas);
  200. for(i=0; i<c.dynamic.length; i++){
  201. var r = c.dynamic[i];
  202. var node = {id:r.name,text:r.name,iconCls:'icon-dscol',attributes:{tp:'node', vtype:r.type, col:r.name, tname:r.tname, expression:r.expression}}
  203. dynas.children.push(node);
  204. }
  205. }
  206. $("#cubelefttree").tree({
  207. data:dt,
  208. onLoadSuccess:function(){
  209. if(isupdate){
  210. //隐藏已选择的维度和指标 列
  211. var cubeObj = c;
  212. var findcol = function(cid){
  213. var ret = null;
  214. for(j=0;j<cubeObj.dims.length;j++){
  215. if(cubeObj.dims[j].alias == cid){
  216. ret = cubeObj.dims[j];
  217. break;
  218. }
  219. }
  220. if(ret == null){
  221. for(j=0;j<cubeObj.kpis.length;j++){
  222. if(cubeObj.kpis[j].alias == cid){
  223. ret = cubeObj.kpis[j];
  224. break;
  225. }
  226. }
  227. }
  228. return ret;
  229. };
  230. window.setTimeout(function(){
  231. var nodes = [];
  232. var roots = $("#cubelefttree").tree("getRoots");
  233. for(j=0; j<roots.length; j++){
  234. var r = roots[j];
  235. nodes = nodes.concat($("#cubelefttree").tree("getChildren", r.target));
  236. }
  237. for(i=0; i<nodes.length; i++){
  238. var id = nodes[i].id;
  239. if(findcol(id) != null){
  240. $(nodes[i].target).attr("hide", "y").hide();
  241. }
  242. }
  243. }, 200);
  244. }
  245. }
  246. });
  247. };
  248. var initlefttree = function(){
  249. $.ajax({
  250. type:"POST",
  251. url:"getDatasetCfg.action",
  252. dataType:"JSON",
  253. data:{dsetId:$("#pdailog #dsetId").val()},
  254. success:function(resp){
  255. var dset = resp;
  256. leftTreeView(dset);
  257. }
  258. });
  259. };
  260. if(isupdate){
  261. leftTreeView(cube);
  262. }else{
  263. initlefttree();
  264. }
  265. $("#pdailog #dsetId").change(function(){
  266. initlefttree();
  267. });
  268. //初始化右边树形状
  269. initRightCubeTree(cube);
  270. }
  271. function initRightCubeTree(cube){
  272. //加载立方体字段
  273. var targdt = [{id:'cbroot', text:'数据立方体', iconCls:'icon-cube', children:[]}];
  274. targdt[0].children.push({id:"cubewd", text:"维度",iconCls:'icon-dim2', children:[]});
  275. targdt[0].children.push({id:"cubedl", text:"度量",iconCls:'icon-kpigroup', children:[]});
  276. if(cube){ //给立方体添加维度及指标
  277. var dims = targdt[0].children[0].children;
  278. var groupexist = function(groupid){
  279. var ls = dims;
  280. var ret = null;
  281. for(k=0; k<ls.length; k++){
  282. if(ls[k].id == groupid){
  283. ret = ls[k];
  284. break;
  285. }
  286. }
  287. return ret;
  288. }
  289. for(i=0; i<cube.dims.length; i++){
  290. var d = cube.dims[i];
  291. var obj = {id:d.id, text:d.text, attributes:{tp:"dim",drag:true,col:d.col_name,tname:d.tname,dispName:d.text,vtype:d.valType,alias:d.alias, dimtype:d.dim_type,colTable:(d.tableName==null?"":d.tableName),colkey:(d.tableColKey==null?"":d.tableColKey), coltext:(d.tableColName==null?"":d.tableColName), dimord:(d.dimord==null?"":d.dimord), dateformat:(d.dateformat==null?"":d.dateformat), calc:d.iscalc==1?true:false, targetId:d.col_id },iconCls:"icon-dim"};
  292. if(d.grouptype != "" && d.grouptype != null){
  293. var group = groupexist(d.grouptype);
  294. if(group == null){
  295. obj = {id:d.grouptype,text:d.groupname, "iconCls":"icon-group", children:[obj],attributes:{tp:'group',dispName:d.groupname,drag:true,targetId:d.grouptype}};
  296. targdt[0].children[0].children.push(obj);
  297. }else{
  298. group.children.push(obj);
  299. }
  300. }else{
  301. targdt[0].children[0].children.push(obj);
  302. }
  303. }
  304. var kpis = targdt[0].children[1].children;
  305. for(i=0; i<cube.kpis.length; i++){
  306. var k = cube.kpis[i];
  307. //对于计算指标,colname 存的是计算公式,而对于非计算指标,需要取alias来代替colname, 在保存的时候会自动拼接
  308. var col = k.alias;
  309. if(k.calcKpi == 1){ //新增度量那创建的计算指标
  310. col = k.colname;
  311. }else if(k.calc == 1){ //数据集创建的动态字段
  312. col = k.colname.substring(k.colname.indexOf('(')+1, k.colname.indexOf(')'));
  313. }
  314. kpis.push({id:k.id, text:k.aggre+'('+k.text+")",attributes:{tp:"kpi",drag:true,aggre:k.aggre,col:col,tname:k.tname, unit:(k.unit==null?"":k.unit), fmt:(k.fmt==null?"":k.fmt), dispName:k.text, alias:k.alias,kpinote:(k.kpi_desc_key==null?"":k.kpi_desc_key),calc:(k.calc==0?false:true),calcKpi:k.calcKpi,targetId:k.colid},iconCls:(k.calcKpi==0?"icon-kpi":"icon-ckpi")});
  315. }
  316. }
  317. $("#cuberighttree").tree({
  318. data:targdt,
  319. dnd:true,
  320. onBeforeDrag:function(target){
  321. if(target.attributes && target.attributes.drag){
  322. return true;
  323. }else{
  324. return false;
  325. }
  326. //return false;
  327. },
  328. onDragEnter:function(target, source){
  329. var node = $("#cuberighttree").tree("getNode", target);
  330. if(!node.attributes || node.attributes.drag ==false ){
  331. return false;
  332. }
  333. //指标不能拖放到维度区域
  334. if(source.attributes.tp == 'kpi' && node.attributes.tp == 'dim'){
  335. return false;
  336. }
  337. //维度不能拖到指标区域
  338. if(node.attributes.tp == 'kpi' && source.attributes.tp == 'dim'){
  339. return false;
  340. }
  341. //分组不能拖到KPI区域
  342. if(source.attributes.tp == 'group' && node.attributes.tp == 'kpi'){
  343. return false;
  344. }
  345. //分组不能拖到分组的下边
  346. var parent = $("#cuberighttree").tree("getParent", target);
  347. if(source.attributes.tp == 'group' && parent.attributes && parent.attributes.tp == 'group'){
  348. return false;
  349. }
  350. return true;
  351. },
  352. onBeforeDrop:function(target, source, point){
  353. var node = $("#cuberighttree").tree("getNode", target);
  354. if(!node.attributes || node.attributes.drag ==false ){
  355. return false;
  356. }
  357. //指标和维度不能拖放到某个指标或维度下边, 只有group 可以
  358. if(node.attributes.tp == 'kpi' && point == 'append'){
  359. return false;
  360. }
  361. if(node.attributes.tp == 'dim' && point == 'append'){
  362. return false;
  363. }
  364. //指标不能拖放到维度区域
  365. if(source.attributes.tp == 'kpi' && node.attributes.tp == 'dim'){
  366. return false;
  367. }
  368. //维度不能拖到指标区域
  369. if(node.attributes.tp == 'kpi' && source.attributes.tp == 'dim'){
  370. return false;
  371. }
  372. //分组不能拖到KPI区域
  373. if(source.attributes.tp == 'group' && node.attributes.tp == 'kpi'){
  374. return false;
  375. }
  376. //分组不能拖到分组的下边
  377. var parent = $("#cuberighttree").tree("getParent", target);
  378. if(source.attributes.tp == 'group' && parent.attributes && parent.attributes.tp == 'group'){
  379. return false;
  380. }
  381. //分组不能拖放到分组的里面
  382. if(source.attributes.tp == 'group' && node.attributes.tp == 'group' && point == 'append'){
  383. return false;
  384. }
  385. return true;
  386. },
  387. onDblClick:function(node){
  388. editcubecol( );
  389. },
  390. onDrop:function(target, source, point){
  391. source.attributes.isupdate = 'y';//拖拽了即设置为已修改
  392. }
  393. });
  394. }
  395. function ds2cube(){
  396. var left = $("#cubelefttree").tree("getSelected");
  397. if(left == null){
  398. $.messager.alert("出错了","您还未从左边选择字段。", "error");
  399. return;
  400. }
  401. if($(left.target).attr("hide") == 'y'){
  402. return;
  403. }
  404. var right = $("#cuberighttree").tree("getSelected");
  405. if(right == null){
  406. $.messager.alert("出错了","您还未选择右边度量或维度。", "error");
  407. return;
  408. }
  409. var parent = $("#cuberighttree").tree("getParent", right.target);
  410. var isCalc = true; //是否是公式?
  411. if(!left.attributes.expression||left.attributes.expression==null||left.attributes.expression==""){
  412. isCalc = false;
  413. }
  414. if(right.text == '度量' || parent.text == '度量'){
  415. //生成ID
  416. var cid = findCubeMaxId($("#cuberighttree").tree("find", "cubedl").target);
  417. var o = {id:cid, text:'sum('+left.text+")",attributes:{tp:"kpi",drag:true,aggre:"sum",col:(!isCalc?left.attributes.col:left.attributes.expression), tname:left.attributes.tname,dispName:left.text,alias:left.id,calc:isCalc,calcKpi:0},iconCls:"icon-kpi"};
  418. if(right.text == '度量'){
  419. $("#cuberighttree").tree("append", {parent:right.target,data:o});
  420. }else{
  421. $("#cuberighttree").tree("insert", {after:right.target,data:o});
  422. }
  423. $(left.target).attr("hide", "y").hide();
  424. }else if(right.text == '维度' || parent.text == '维度' || parent.attributes.tp == 'group'){
  425. var cid = findCubeMaxId($("#cuberighttree").tree("find", "cubewd").target);
  426. var o = {id:cid, text:left.text, attributes:{tp:"dim",drag:true,col:!isCalc?left.attributes.col:left.attributes.expression,tname:left.attributes.tname,dispName:left.text,tname:left.attributes.tname,vtype:left.attributes.vtype,alias:left.attributes.col,calc:isCalc},iconCls:"icon-dim", targetId:""}; //通过targetId 来指引对应数据库的的字段 ID, 用在修改上
  427. if(right.text == '维度' || (parent.text == '维度' && right.attributes.tp == 'group')){
  428. $("#cuberighttree").tree("append", {parent:right.target,data:o});
  429. }else{
  430. $("#cuberighttree").tree("insert", {after:right.target,data:o});
  431. }
  432. $(left.target).attr("hide", "y").hide();
  433. }
  434. }
  435. function editcubecol(){
  436. var right = $("#cuberighttree").tree("getSelected");
  437. if(right == null || !right.attributes){
  438. msginfo("您还未选择需要编辑的度量或维度。");
  439. return;
  440. }
  441. var colid = right.id;
  442. if(!colid){
  443. return;
  444. }
  445. //计算指标特殊处理
  446. if(right.attributes.tp == 'kpi' && right.attributes.calcKpi == 1){
  447. editCalcKpi(true, right.id);
  448. return;
  449. }
  450. var ctx = "";
  451. var atp = ["sum","avg","count", "count(distinct)", "max", "min"];
  452. if(right.attributes.tp == 'dim'){
  453. var cols = $("#cubelefttree").tree("getRoots");
  454. var tabstr = "<option value=\"\"></option>";
  455. var keystr = "<option value=\"\"></option>";
  456. var txtstr = "<option value=\"\"></option>";
  457. var tables = [];
  458. for(i=0; i<cols.length; i++){
  459. var clds = cols[i].children;
  460. for(j=0; j<clds.length; j++){
  461. if(clds[j].attributes){
  462. var tname = clds[j].attributes.tname;
  463. tables.push(tname);
  464. }
  465. }
  466. }
  467. tables = tables.uniqueArray();
  468. for(i=0; i<tables.length; i++){
  469. tabstr = tabstr + "<option value=\""+tables[i]+"\" "+(right.attributes.colTable == tables[i]?"selected":"")+">"+tables[i]+"</option>";
  470. }
  471. var fmtstr = "<option value=\"\"></option>";
  472. for(i=0; i<dateformat.length; i++){
  473. fmtstr = fmtstr + "<option value=\""+dateformat[i]+"\" "+(right.attributes.dateformat==dateformat[i]?"selected":"")+">"+dateformat[i]+"</option>";
  474. }
  475. ctx = "<div class=\"textpanel\"><span class=\"inputtext\">维度字段:</span>"+right.attributes.col+"<br/><span class=\"inputtext\">别名:</span>"+right.attributes.alias+"<br/><span class=\"inputtext\">显示名称:</span><input type=\"text\" id=\"dimname\" name=\"dimname\" class=\"inputform2\" value=\""+right.attributes.dispName+"\"><br/><span class=\"inputtext\">维度类型:</span><select id=\"dimtype\" name=\"dimtype\" class=\"inputform2\"><option value=\"\"></option><option value=\"year\" "+(right.attributes.dimtype=='year'?"selected":"")+">年</option><option value=\"quarter\" "+(right.attributes.dimtype=='quarter'?"selected":"")+">季度</option><option value=\"month\" "+(right.attributes.dimtype=='month'?"selected":"")+">月</option><option value=\"day\" "+(right.attributes.dimtype=='day'?"selected":"")+">日</option><option value=\"prov\" "+(right.attributes.dimtype=='prov'?"selected":"")+">省份</option><option value=\"city\" "+(right.attributes.dimtype=='city'?"selected":"")+">地市</option></select><br/><span class=\"inputtext\">维度格式:</span><select id=\"dateformat\" class=\"inputform2\">"+fmtstr+"</select><br/><span class=\"inputtext\">维度对应表:</span><select id=\"colTable\" class=\"inputform2\" name=\"colTable\">"+tabstr+"</select><br/><span class=\"inputtext\">维度Key字段:</span><select id=\"colkey\" class=\"inputform2\" name=\"colkey\">"+keystr+"</select><br/><span class=\"inputtext\">维度Text字段:</span><select id=\"coltext\" name=\"coltext\" class=\"inputform2\">"+txtstr+"</select><br/><span class=\"inputtext\">排序方式:</span><select id=\"dimord\" name=\"dimord\" class=\"inputform2\"><option value=\"\"></option><option "+(right.attributes.dimord=="asc"?"selected":"")+" value=\"asc\">正序</option><option value=\"desc\" "+(right.attributes.dimord=="desc"?"selected":"")+">倒叙</option></select></div>";
  476. }else if(right.attributes.tp == 'kpi'){
  477. var tpstr = "";
  478. for(i=0; i<atp.length; i++){
  479. tpstr = tpstr + "<option value=\""+atp[i]+"\" "+(atp[i] == right.attributes.aggre ? "selected":"")+">"+atp[i]+"</option>";
  480. }
  481. ctx = "<div class=\"textpanel\"><span class=\"inputtext\">度量字段:</span>"+right.attributes.col+"<br/><span class=\"inputtext\">别名:</span>"+right.attributes.alias+"<br/><span class=\"inputtext\">显示名称:</span><input type=\"text\" id=\"kpiname\" name=\"kpiname\" class=\"inputform2\" value=\""+right.attributes.dispName+"\"><br/>"
  482. + "<span class=\"inputtext\">计算方式:</span><select id=\"kpiaggre\" name=\"kpiaggre\" class=\"inputform2\">"+tpstr+"</select> <br>"
  483. + "<span class=\"inputtext\">度量单位:</span><input type=\"text\" id=\"kpiunit\" name=\"kpiunit\" class=\"inputform2\" value=\""+(right.attributes.unit?right.attributes.unit:"")+"\"> <br>"
  484. + "<span class=\"inputtext\">格式化:</span>" + ftmstr("kpifmt","inputform2",right.attributes.fmt?right.attributes.fmt:"") + "<br/><span class=\"inputtext\">度量解释:</span><textarea name=\"kpinote\" id=\"kpinote\" cols=\"25\" class=\"inputform2\" style=\"height:32px;\" rows=\"2\">"+(right.attributes.kpinote?right.attributes.kpinote:"")+"</textarea></div>";
  485. }else if(right.attributes.tp == 'group'){
  486. ctx = "<div class=\"textpanel\"><span class=\"inputtext\">分组名称:</span><input type=\"text\" id=\"groupname\" name=\"groupname\" value=\""+right.attributes.dispName+"\" class=\"inputform2\"><br/></div>";
  487. }
  488. if($("#dsColumn_div").size() == 0){
  489. $("<div id=\"dsColumn_div\" class=\"easyui-menu\"></div>").appendTo("body");
  490. }
  491. $('#dsColumn_div').dialog({
  492. title: right.attributes.tp == 'group' ? "编辑分组" : "编辑维度及度量",
  493. width: 350,
  494. height: right.attributes.tp == 'group' ? 150 :340,
  495. closed: false,
  496. cache: false,
  497. modal: true,
  498. toolbar:null,
  499. content:ctx,
  500. onLoad:function(){},
  501. onClose:function(){
  502. $('#dsColumn_div').dialog('destroy');
  503. },
  504. buttons:[{
  505. text:'确定',
  506. iconCls:"icon-ok",
  507. handler:function(){
  508. if(right.attributes.tp == 'kpi'){
  509. right.attributes.aggre = $("#dsColumn_div #kpiaggre").val();
  510. right.attributes.fmt = $("#dsColumn_div #kpifmt").val();
  511. right.attributes.unit = $("#dsColumn_div #kpiunit").val();
  512. right.attributes.dispName = $("#dsColumn_div #kpiname").val();
  513. right.attributes.kpinote = $("#dsColumn_div #kpinote").val();
  514. right.attributes.isupdate = "y"; //表示指标已经更改过了。
  515. $("#cuberighttree").tree("update", {target:right.target, text: right.attributes.aggre+ "(" + right.attributes.dispName+")"})
  516. }else
  517. if(right.attributes.tp == 'dim'){
  518. //设置了时间类型维度后,必须设置维度格式
  519. var dtp = $("#dsColumn_div #dimtype").val();
  520. var dtfmt = $("#dsColumn_div #dateformat").val();
  521. if(dtp != "" && (dtp == "year" || dtp == "month" || dtp == "quarter" || dtp == "day") && dtfmt == "" ){
  522. msginfo("请选择时间维度格式。", function(){
  523. $("#dsColumn_div #dateformat").select();
  524. });
  525. return;
  526. }
  527. right.attributes.dispName = $("#dsColumn_div #dimname").val();
  528. right.attributes.dimtype = dtp;
  529. right.attributes.colTable = $("#dsColumn_div #colTable").val();
  530. right.attributes.colkey = $("#dsColumn_div #colkey").val();
  531. right.attributes.coltext = $("#dsColumn_div #coltext").val();
  532. right.attributes.dimord = $("#dsColumn_div #dimord").val();
  533. right.attributes.dateformat = dtfmt;
  534. right.attributes.isupdate = "y"; //表示维度已经更改过了。
  535. $("#cuberighttree").tree("update", {target:right.target, text:$("#dsColumn_div #dimname").val()})
  536. }else if(right.attributes.tp == 'group'){
  537. right.attributes.dispName = $("#dsColumn_div #groupname").val();
  538. //right.attributes.grouptype = $("#dsColumn_div #grouptype").val();
  539. right.attributes.isupdate = "y"; //表示分组已经更改过了。
  540. $("#cuberighttree").tree("update", {target:right.target, text:$("#dsColumn_div #groupname").val()})
  541. }
  542. $('#dsColumn_div').dialog('close');
  543. }
  544. },{
  545. text:'取消',
  546. iconCls:"icon-cancel",
  547. handler:function(){
  548. $('#dsColumn_div').dialog('close');
  549. }
  550. }]
  551. });
  552. if(right.attributes.tp == 'dim'){
  553. var upcolfunc = function(tname, colkey, coltext){
  554. var keystr = "<option value=\"\"></option>";
  555. var txtstr = "<option value=\"\"></option>";
  556. var cols = $("#cubelefttree").tree("getRoots");
  557. for(i=0; i<cols.length; i++){
  558. var c = cols[i];
  559. for(j =0; c.children&&j<c.children.length; j++){
  560. var t = c.children[j];
  561. if(t.attributes && t.attributes.tname == tname){
  562. keystr = keystr + "<option value=\""+t.id+"\" "+(colkey==t.id?"selected":"")+">"+t.id+"</option>";
  563. txtstr = txtstr + "<option value=\""+t.id+"\" "+(coltext==t.id?"selected":"")+">"+t.id+"</option>";
  564. }
  565. }
  566. }
  567. $("#dsColumn_div #colkey").html(keystr);
  568. $("#dsColumn_div #coltext").html(txtstr);
  569. }
  570. $("#dsColumn_div #colTable").change(function(){
  571. upcolfunc($(this).val());
  572. });
  573. if(right.attributes.colTable && right.attributes.colTable != ''){
  574. upcolfunc(right.attributes.colTable, right.attributes.colkey, right.attributes.coltext);
  575. }
  576. }
  577. }
  578. function addgroup(){
  579. if($("#dsColumn_div").size() == 0){
  580. $("<div id=\"dsColumn_div\" class=\"easyui-menu\"></div>").appendTo("body");
  581. }
  582. var gctx = "<div class=\"textpanel\"><span class=\"inputtext\">分组名称:</span><input type=\"text\" value=\"\" id=\"groupname\" name=\"groupname\" class=\"inputform2\"></div>";
  583. $('#dsColumn_div').dialog({
  584. title: "创建维度分组",
  585. width: 300,
  586. height: 180,
  587. closed: false,
  588. cache: false,
  589. modal: true,
  590. toolbar:null,
  591. content:gctx,
  592. onLoad:function(){},
  593. onClose:function(){
  594. $('#dsColumn_div').dialog('destroy');
  595. },
  596. buttons:[{
  597. text:'确定',
  598. iconCls:"icon-ok",
  599. handler:function(){
  600. var name = $("#dsColumn_div #groupname").val();
  601. if(name == ''){
  602. msginfo("请填写分组名称!");
  603. $("#dsColumn_div #groupname").focus();
  604. return;
  605. }
  606. var cid = newGuid();
  607. var dt = {id:cid,text:name, "iconCls":"icon-group", attributes:{tp:'group',dispName:name,drag:true}};
  608. $("#cuberighttree").tree("append",{parent:$("#cuberighttree").tree("find", "cubewd").target, data:[dt]});
  609. $('#dsColumn_div').dialog('close');
  610. }
  611. },{
  612. text:'取消',
  613. iconCls:"icon-cancel",
  614. handler:function(){
  615. $('#dsColumn_div').dialog('close');
  616. }
  617. }]
  618. });
  619. }
  620. function editCalcKpi(update, kpiId){
  621. var kpi;
  622. if(update){
  623. kpi = $("#cuberighttree").tree("getSelected");
  624. }
  625. var atp = ["sum","avg","count","count(distinct)", "max", "min"];
  626. var tpstr = "";
  627. for(i=0; i<atp.length; i++){
  628. tpstr = tpstr + "<option value=\""+atp[i]+"\" "+(kpi && atp[i] == kpi.attributes.aggre ? "selected":"")+">"+atp[i]+"</option>";
  629. }
  630. //查询已选指标
  631. var kpiStr = "";
  632. var ls = [];
  633. var roots = $("#cubelefttree").tree("getRoots");
  634. for(i=0; i<roots.length; i++){
  635. var c = roots[i].children;
  636. for(j=0; j<c.length; j++){
  637. ls.push(c[j]);
  638. }
  639. }
  640. for(i=0; i<ls.length; i++){
  641. var k = ls[i].attributes;
  642. kpiStr = kpiStr + "<button name=\""+k.col+"\" class=\"btn btn-primary btn-xs\">"+ k.col+"</button> ";
  643. }
  644. kpiStr = kpiStr + "<br/>";
  645. for(i=0; i<atp.length; i++){
  646. kpiStr = kpiStr + "<button name=\""+atp[i]+"( )\" class=\"btn btn-primary btn-xs\">"+ atp[i]+"</button> ";
  647. }
  648. var tempId = "k_" + Math.round(Math.random() * 100000);
  649. var ctx = "<div class=\"textpanel\"><span class=\"inputtext\">度量标识:</span><input type=\"text\" class=\"inputform2\" name=\"alias\" id=\"alias\" readonly value=\""+(kpi?kpi.attributes.alias:tempId)+"\">(英文字符)<br/><span class=\"inputtext\">显示名称:</span><input type=\"text\" class=\"inputform2\" name=\"kpiname\" id=\"kpiname\" value=\""+(kpi?kpi.attributes.dispName:"")+"\"><br/><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td valign=\"top\"><span class=\"inputtext\">表 达 式:</span></td><td><textarea rows=\"2\" style=\"height:52px;\" cols=\"40\" id=\"expression\" name=\"expression\" class=\"inputform2\">"+(kpi?kpi.attributes.col:"")+"</textarea></td></tr></tbody></table><div class=\"actColumn\">"+kpiStr+"</div><span class=\"inputtext\">计算方式:</span><select id=\"kpiaggre\" name=\"kpiaggre\" class=\"inputform2\">"+tpstr+"</select><br><span class=\"inputtext\">度量单位:</span><input type=\"text\" value=\""+(kpi?kpi.attributes.unit:"")+"\" class=\"inputform2\" name=\"kpiunit\" id=\"kpiunit\"><br/><span class=\"inputtext\">格式化:</span>" + ftmstr("kpifmt","inputform2",(kpi?kpi.attributes.fmt:"")) + "<br/><span class=\"inputtext\">指标解释:</span><textarea name=\"kpinote\" id=\"kpinote\" cols=\"25\" style=\"height:32px;\" class=\"inputform2\" rows=\"2\">"+(kpi?kpi.attributes.kpinote:"")+"</textarea></div>";
  650. if($("#dsColumn_div").size() == 0){
  651. $("<div id=\"dsColumn_div\" class=\"easyui-menu\"></div>").appendTo("body");
  652. }
  653. $('#dsColumn_div').dialog({
  654. title: update?"编辑表达式度量":"创建表达式度量",
  655. width: 420,
  656. height: 390,
  657. closed: false,
  658. cache: false,
  659. modal: true,
  660. toolbar:null,
  661. content:ctx,
  662. onLoad:function(){},
  663. onClose:function(){
  664. $('#dsColumn_div').dialog('destroy');
  665. },
  666. buttons:[{
  667. text:'确定',
  668. iconCls:"icon-ok",
  669. handler:function(){
  670. var alias = $("#dsColumn_div #alias").val();
  671. var name = $("#dsColumn_div #kpiname").val();
  672. var expression = $("#dsColumn_div #expression").val();
  673. if(alias == ""){
  674. msginfo("请填写度量标识。");
  675. $("#dsColumn_div #alias").focus();
  676. return;
  677. }
  678. if(ischinese(alias)){
  679. msginfo("度量标识只能是英文字符。");
  680. $("#dsColumn_div #alias").focus();
  681. return;
  682. }
  683. if(name == ''){
  684. msginfo("请填写度量名称。");
  685. $("#dsColumn_div #kpiname").focus();
  686. return;
  687. }
  688. if(expression == ''){
  689. msginfo("请填写度量表达式。");
  690. $("#dsColumn_div #expression").focus();
  691. return;
  692. }
  693. if(update){
  694. kpi.attributes.aggre = $("#dsColumn_div #kpiaggre").val();
  695. kpi.attributes.fmt = $("#dsColumn_div #kpifmt").val();
  696. kpi.attributes.unit = $("#dsColumn_div #kpiunit").val();
  697. kpi.attributes.dispName = name;
  698. kpi.attributes.kpinote = $("#dsColumn_div #kpinote").val();
  699. kpi.attributes.col = expression;
  700. kpi.attributes.alias = $("#dsColumn_div #alias").val();
  701. kpi.attributes.isupdate = "y"; //表示计算指标已经更改过了。
  702. $("#cuberighttree").tree("update", {target:kpi.target, text:kpi.attributes.aggre+"("+name+")"});
  703. }else{
  704. var cid = findCubeMaxId($("#cuberighttree").tree("find","cubedl").target);
  705. var o = {id:cid, text:$("#dsColumn_div #kpiaggre").val()+"("+name+")",attributes:{tp:"kpi",calc:true,drag:true,aggre:$("#dsColumn_div #kpiaggre").val(),col:expression, alias:$("#dsColumn_div #alias").val(), dispName:name,tname:"",fmt:$("#dsColumn_div #kpifmt").val(),unit:$("#dsColumn_div #kpiunit").val(),kpinote:$("#dsColumn_div #kpinote").val(),calcKpi:1},iconCls:"icon-ckpi"};
  706. $("#cuberighttree").tree("append", {parent:$("#cuberighttree").tree("find", "cubedl").target, data:[o]});
  707. }
  708. $('#dsColumn_div').dialog('close');
  709. }
  710. },{
  711. text:'取消',
  712. iconCls:"icon-cancel",
  713. handler:function(){
  714. $('#dsColumn_div').dialog('close');
  715. }
  716. }]
  717. });
  718. $("#dsColumn_div .actColumn button").bind("click", function(){
  719. var txt = $(this).attr("name");
  720. insertText2focus(document.getElementById("expression"), txt+" ");
  721. });
  722. }
  723. function findCubeMaxId(target){
  724. var ret = 0;
  725. var ls = $("#cuberighttree").tree("getChildren", target);
  726. for(i=0; i<ls.length; i++){
  727. if(Number(ls[i].id) > ret){
  728. ret = Number(ls[i].id);
  729. }
  730. }
  731. return ret + 1;
  732. }
  733. function cube2ds(){
  734. var right = $("#cuberighttree").tree("getSelected");
  735. if(right == null || !right.attributes){
  736. $.messager.alert("出错了","您还未选择需要删除的度量或维度。","error");
  737. return;
  738. }
  739. if(right.attributes.tp == 'group'){
  740. if($("#cubelefttree").tree("getChildren", right.target).length > 0){
  741. $.messager.alert("出错了","您要删除的分组含有维度,不能删除。", "error");
  742. return;
  743. }
  744. }
  745. if(right.attributes.tp != 'group'){ //分组删除不用关联左边树
  746. var id = right.attributes.alias; //通过 refId 引用s数据集的字段ID
  747. var cld = [];
  748. var ls = $("#cubelefttree").tree("getRoots");
  749. for(i=0; i<ls.length; i++){
  750. var c = ls[i].children;
  751. for(j=0; j<c.length; j++){
  752. cld.push(c[j]);
  753. }
  754. }
  755. for(i=0; i<cld.length; i++){
  756. if(cld[i].id == id){
  757. $(cld[i].target).attr("hide", "n").show();
  758. break;
  759. }
  760. }
  761. }
  762. if(window.delObj){
  763. window.delObj.push({'type':right.attributes.tp, id: right.attributes.targetId}); //在修改立方体时用来删除的内容
  764. }
  765. $("#cuberighttree").tree("remove", right.target);
  766. }
  767. function ftmstr(id, cls, curfmt){
  768. var str = "<select id=\""+id+"\" name=\""+id+"\" class=\""+cls+"\">";
  769. str = str + "<option value=\"\"></option><option "+(curfmt=='#,###'?"selected":"")+" value=\"#,###\">整数</option><option "+(curfmt=='#,###.00'?"selected":"")+" value=\"#,###.00\">小数(保留两位)</option><option "+(curfmt=='#,###.0000'?"selected":"")+" value=\"#,###.0000\">小数(保留四位)</option><option "+(curfmt=='0.00%'?"selected":"")+" value=\"0.00%\">百分比</option>";
  770. str = str + "</select>";
  771. return str;
  772. }
  773. function savecubecfg(pageJson, update){
  774. var cubeDim = [];
  775. var dims = $("#cuberighttree").tree("getChildren", $("#cuberighttree").tree("find", "cubewd").target);
  776. if(dims.length == 0){
  777. $("#crtdataset").tabs("select", 1);
  778. msginfo("您还未配置维度。");
  779. return false;
  780. }
  781. var curGroup = null;
  782. for(i=0; i<dims.length; i++){
  783. var d = dims[i];
  784. if(d.attributes.tp == "group"){
  785. curGroup = d;
  786. }else{
  787. var obj = {name:d.attributes.dispName, type:d.attributes.dimtype,col:d.attributes.col, tname:d.attributes.tname, alias:d.attributes.alias, vtype: d.attributes.vtype, colTable:d.attributes.colTable,colkey:d.attributes.colkey,coltext:d.attributes.coltext,dimord:d.attributes.dimord, dateformat:d.attributes.dateformat,calc:(d.attributes.calc&&d.attributes.calc==true?1:0),targetId:d.attributes.targetId,isupdate:d.attributes.isupdate};
  788. var p = $("#cuberighttree").tree("getParent", d.target);
  789. if(p.attributes && p.attributes.tp == "group"){
  790. obj.groupName = p.text;
  791. obj.groupId = p.id;
  792. }else{
  793. obj.groupName = "";
  794. obj.groupId = "";
  795. }
  796. cubeDim.push(obj);
  797. }
  798. }
  799. var cubeKpi = [];
  800. var kpis = $("#cuberighttree").tree("getChildren", $("#cuberighttree").tree("find", "cubedl").target);
  801. if(kpis.length == 0){
  802. $("#crtdataset").tabs("select", 1);
  803. msginfo("您还未配置度量。");
  804. return false;
  805. }
  806. for(i=0; i<kpis.length; i++){
  807. var t = kpis[i];
  808. cubeKpi.push({name:t.attributes.dispName,col:t.attributes.col,tname:t.attributes.tname,alias:t.attributes.alias,fmt:t.attributes.fmt,unit:t.attributes.unit,aggre:t.attributes.aggre,kpinote:t.attributes.kpinote,calc:(t.attributes.calc&&t.attributes.calc==true?1:0),calcKpi:t.attributes.calcKpi,targetId:t.attributes.targetId,isupdate:t.attributes.isupdate});
  809. }
  810. pageJson.dims = cubeDim;
  811. pageJson.kpis = cubeKpi;
  812. if(update){
  813. pageJson.delObj = window.delObj;
  814. }
  815. var json = JSON.stringify(pageJson);
  816. __showLoading();
  817. if(update){
  818. $.ajax({
  819. type:"POST",
  820. url:"updateCube.action",
  821. contentType : "application/json",
  822. dataType:"JSON",
  823. data:json,
  824. success:function(resp){
  825. __hideLoading();
  826. if(resp.result == 1){
  827. $.messager.alert('提示信息', "立方体更新成功。", "info");
  828. $('#cubetable').datagrid('load',{
  829. t:Math.random()
  830. });
  831. }else{
  832. msginfo("立方体更新失败。" + resp.msg);
  833. }
  834. },
  835. error:function(){
  836. __hideLoading();
  837. msginfo("立方体更新失败。");
  838. }
  839. });
  840. }else{
  841. $.ajax({
  842. type:"POST",
  843. url:"saveCube.action",
  844. dataType:"JSON",
  845. contentType : "application/json",
  846. data:json,
  847. success:function(resp){
  848. __hideLoading();
  849. $.messager.alert('提示信息', "立方体创建成功。", "info", function(){
  850. $('#cubetable').datagrid('load',{
  851. t:Math.random()
  852. });
  853. });
  854. },
  855. error:function(){
  856. __hideLoading();
  857. msginfo("立方体创建失败。");
  858. }
  859. });
  860. }
  861. return true;
  862. }